Inicio de programación en posición de memoria diferente a 0x0000 lpcxpresso1769

67 views
Skip to first unread message

carlos cabas

unread,
Nov 26, 2014, 6:36:55 AM11/26/14
to embeb...@googlegroups.com
Hola a todos, estoy trabajando en un bootloader desde SD y he logrado actualizar el firmware desde la SD pero tengo problema al ejecutar el nuevo código, analizando la memoria flash del micro logro ver que el firmware está presente. el código del bootloader está programado en el sector 0x0000 y el código de usuario a partir del sector 0x8000, el problema es, que cuando realizo el salto en el contador de programa hacia la dirección 0x8000 la primera instrucción (el inicio del main()) me envía al inicio nuevamente, como si reiniciara el programa.


supongo que debe ser porque el programa que estoy booteando está programado a partir de la memoria 0x0000 con lo cual es lógico que me envíe al inicio nuevamente.

mi pregunta es que instrucción uso para indicarle a mi programa desde que posición  de memoria quiero que inicie ? probé con la instrucción assembler asm(".ORG 0x8000")  y no logro hacer que funcione.

Estoy usando el IDE LPCxpresso y la placa LPCxpresso1769.

Les agradezco su aporte y colaboración, de antemano Muchas Gracias.

--
Cordialmente;

Carlos Cabas Meriño
Ingeniero Electrónico
Est. Posgrado Automatización Industrial (UBA)
Técnico Profesional en Contabilidad y Finanzas
CCNA CISCO Certified.

carlos cabas

unread,
Nov 26, 2014, 3:28:48 PM11/26/14
to embeb...@googlegroups.com
Bueno despues de un dia completo dedicado al tema, comparto la solucion.

Para inidicarle al programa en que posicion de memoria quieren que inicie su firmware, deben ir a la carpeta debug que genera el compilador. en él, se crean 3 archivos :

<"nombre_del_proyecto">_Debug_lib.ld 
<"nombre_del_proyecto">_Debug_mem.ld
<"nombre_del_proyecto">_Debug.ld 

estos archivos almacenan la informacion del target especifico, en este caso lpc1769 (Cortex-M3), deben editar el archivo <"nombre_del_proyecto">_Debug_mem.ld

MEMORY
{
  /* Define each memory region */
  MFlash512 (rx) : ORIGIN = 0x0, LENGTH = 0x80000 /* 512k */
  RamLoc32 (rwx) : ORIGIN = 0x10000000, LENGTH = 0x8000 /* 32k */
  RamAHB32 (rwx) : ORIGIN = 0x2007c000, LENGTH = 0x8000 /* 32k */



Por:

MFlash512 (rx) : ORIGIN = 0x0, ------>  ( Editar por la posición de inicio del firmware)
LENGTH = 0x80000 /* 512k */ ------>  ( restar de 0x80000 el valor asignado a ORIGIN - para el caso de 512kb de flash)


De esta forma el compilador genera el archivo .axf o .bin  para programarlo a partir de la posición de memoria asignada a ORIGIN.


cualquier inquietud no duden en escribirme.


Saludos.

Ismael Luceno

unread,
Nov 26, 2014, 4:57:31 PM11/26/14
to carlos cabas, embeb...@googlegroups.com
No termino de entender exactamente el problema que tenías. En principio
parecería que algún salto posterior te hacia vuelve atrás, claro que
sin una muestra no hay forma de saber con certeza.

En cualquier caso la solución es incorrecta.

Suponiendo que lo que tenés ahí definido sea lo relativo al "código de
usuario", y el origen que estás definiendo es el de eso, y no del
firmware (aunque no sé que clase de diferenciación estás haciendo...),
la solución sería funcional, pero no por eso correcta.

El problema es que no queda nada claro eso, ni en este, ni en el
mensaje anterior. Supongo que, en parte, no hubo respuestas justamente
por eso.

De no ser el caso, y lo que estás definiendo es la dirección origen del
firmware, te funciona de casualidad, y no es lo que le querés decir
realmente al enlazador.

Antes que nada, hay que aclarar que el comando MEMORY indica la
disposición de la memoria del dispositivo, para que el enlazador tenga
una idea de dónde poner las cosas, no es algo a cambiar de acuerdo al
software, y debería ser lo mismo para ambas partes.

Una de las posibles soluciones correctas es enviar diferentes ficheros a
diferentes posiciones. E.g.:

SECTIONS {
firmware 0: firmware_*.o
usercode 0x8000: *
}

Esa supongo que sería la forma más sencilla, aunque también se puede
hacer en base al nombre de los símbolos, sección, etc.

La parte relativa a la memoria hay que dejarla como estaba
originalmente, pues sería la definición correcta.

Los detalles están sujetos a que haya interpretado correctamente la
descripción, claro está, pero el resto aplica de manera genérica.

Saludos.

> El 26 de noviembre de 2014, 8:36, carlos cabas
> <ing.car...@gmail.com> escribió:
>
> > Hola a todos, estoy trabajando en un bootloader desde SD y he
> > logrado actualizar el firmware desde la SD pero tengo problema al
> > ejecutar el nuevo código, analizando la memoria flash del micro
> > logro ver que el firmware está presente. el código del bootloader
> > está programado en el sector 0x0000 y el código de usuario a partir
> > del sector 0x8000, el problema es, que cuando realizo el salto en
> > el contador de programa hacia la dirección 0x8000 la primera
> > instrucción (el inicio del main()) me envía al inicio nuevamente,
> > como si reiniciara el programa.
> >
> >
> > supongo que debe ser porque el programa que estoy booteando está
> > programado a partir de la memoria 0x0000 con lo cual es lógico que
> > me envíe al inicio nuevamente.
> >
> > mi pregunta es que instrucción uso para indicarle a mi programa
> > desde que posición de memoria quiero que inicie ? probé con la
> > instrucción assembler asm(".ORG 0x8000") y no logro hacer que
> > funcione.
> >
> > Estoy usando el IDE LPCxpresso y la placa LPCxpresso1769.
> >
> > Les agradezco su aporte y colaboración, de antemano Muchas Gracias.
> >
> > --
> > *Cordialmente;*
> >
> > *Carlos Cabas Meriño*
> > *Ingeniero Electrónico*
> > *Est. Posgrado Automatización Industrial (UBA)*
> >
> > *Técnico Profesional en Contabilidad y Finanzas*
> > *CCNA CISCO Certified.*
> >
>
>
>

CoLo!

unread,
Dec 5, 2014, 2:28:12 AM12/5/14
to embeb...@googlegroups.com, carlos cabas
Hola,
si entendí bien o que querés hacer es compilar un programa, para luego cargarlo (a través de un bootloader) en una dirección específica (0x8000 en este caso) en vez de la dirección por defecto.
Luego en alguna parte de tu bootloader hacer algo así como:

- en asm de mips (si la función no tiene parámetros)
 jr ra  # o algo parecido a esto

- o en c
{
 void * function_ptr=0x8000
 function_ptr();
}

¿Es así?


Si es así, te muestro la solución con un ejemplo para MIPS, supongo podrás llevarlo a ARM.
Tengo un archivo main.c con:

int main() {
  int a=0;
  a++;
  return a;
}

# compilo main.c (y solo compilo -c)
$ mips-linux-gcc -c -o0 main.c -o main.o

# linkeo main.o
# indicando que el inicio del programa (lo que se suele llamar entry del programa) es "main"
# y que empiece en la dirección de memoria 0x0000
$ mips-linux-ld main.o -Ttext 0000 -emain -o programa1

# hago lo mismo pero ahora en la dirección 0x8000
$ mips-linux-ld main.o -Ttext 8000 -emain -o programa2

# muestro disassemble de los programas:
$ mips-linux-objdump programa1 -d

programa1:     file format elf32-tradbigmips


Disassembly of section .text:

00000000 <main>:
   0: 27bdffe8 addiu sp,sp,-24
   4: afbe0014 sw s8,20(sp)
   8: 03a0f021 move s8,sp
   c: afc00008 sw zero,8(s8)
  10: 8fc20008 lw v0,8(s8)
  14: 00000000 nop
  18: 24420001 addiu v0,v0,1
  1c: afc20008 sw v0,8(s8)
  20: 8fc20008 lw v0,8(s8)
  24: 03c0e821 move sp,s8
  28: 8fbe0014 lw s8,20(sp)
  2c: 27bd0018 addiu sp,sp,24
  30: 03e00008 jr ra
  34: 00000000 nop


# ahora para el programa2, es decir el de la posición de memoria 0x8000
$ mips-linux-objdump programa2 -d

programa2:     file format elf32-tradbigmips


Disassembly of section .text:

00008000 <main>:
    8000: 27bdffe8 addiu sp,sp,-24
    8004: afbe0014 sw s8,20(sp)
    8008: 03a0f021 move s8,sp
    800c: afc00008 sw zero,8(s8)
    8010: 8fc20008 lw v0,8(s8)
    8014: 00000000 nop
    8018: 24420001 addiu v0,v0,1
    801c: afc20008 sw v0,8(s8)
    8020: 8fc20008 lw v0,8(s8)
    8024: 03c0e821 move sp,s8
    8028: 8fbe0014 lw s8,20(sp)
    802c: 27bd0018 addiu sp,sp,24
    8030: 03e00008 jr ra
    8034: 00000000 nop


En el ejemplo se ve que uno de los programas está preparado para ser ejecutado desde la posición 0x0000 y el otro desde la posición 0x8000.

Con -emain le decimos que algo llamado "main" es el comienzo de nuestro programa.
Con -Ttext 8000 le indicamos que el inicio de la sección ".text" (es decir lo ejecutable de tu programa) va en la posición 0x8000.

Espero esto responda tu pregunta

Saludos

Federico Zacchigna










> >
>
>
>

--
-- Recibiste este mensaje porque estás suscripto al Grupo Google Embebidos32. Para postear en este grupo, escribe un email a embeb...@googlegroups.com. Para des-suscribirte, envía un email a embebidos32...@googlegroups.com. Para más opciones, visita el sitio del grupo en https://groups.google.com/d/forum/embebidos32?hl=es
---
Has recibido este mensaje porque estás suscrito al grupo "Embebidos32" de Grupos de Google.
Para anular la suscripción a este grupo y dejar de recibir sus mensajes, envía un correo electrónico a embebidos32...@googlegroups.com.
Para obtener más opciones, visita https://groups.google.com/d/optout.

Ismael Luceno

unread,
Dec 5, 2014, 8:33:43 AM12/5/14
to CoLo!, embeb...@googlegroups.com, carlos cabas
On Fri, 5 Dec 2014 04:27:47 -0300
"CoLo!" <color...@gmail.com> wrote:
<...>
> En el ejemplo se ve que uno de los programas está preparado para ser
> ejecutado desde la posición 0x0000 y el otro desde la posición 0x8000.
>
> Con *-emain* le decimos que algo llamado "main" es el comienzo de
> nuestro programa.
> Con *-Ttext 8000* le indicamos que el inicio de la sección ".text" (es
> decir lo ejecutable de tu programa) va en la posición 0x8000.
>
> Espero esto responda tu pregunta
<...>

Sería mejor hacerlo en un solo paso via "-Wl,"; pero como está usando
un IDE, probablemente no hay Makefile de por medio :(.

Por cierto, ¿estabas pensando en que le enlaza algún crt0? Me quedé con
la duda también... no debería, pero me acuerdo que una vez me pasó algo
del estilo con un gcc 2.9x que tenía las specs mal, hace muchos años
ya...
Reply all
Reply to author
Forward
0 new messages