Ubicación del código del programa AVR

Estoy trabajando con un ATmega328P y quería interactuar con la memoria flash escribiendo datos con las macros proporcionadas por avr-libc . Este es el mapa de memoria de mi chip:

Mapa de memoria ATmega
(fuente: avr-tutorials.com )

No entiendo dónde se encuentra exactamente el código del programa cuando se compila. Lo que quiero decir es: ¿Cómo puedo estar seguro de que la dirección que uso en boot_page_fill y boot_page_write no se usa para el código del programa? ¿Necesito usar la opción del enlazador "–section-start" para mover el código del programa a una ubicación específica y asegurarme de que la página flash que voy a usar no sobrescriba ese código?

NOTA: Los datos para escribir en la memoria flash se desconocen en el momento de la compilación.

Como dije, ¡ya lo leí! pero mi pregunta sigue sin estar clara. ¿Cuál es la relación entre la ubicación de las páginas flash en las que voy a escribir y la ubicación del código del programa?
Lo que le digas al enlazador. Si no quieres que choquen, debes asegurarte de que no lo hagan.
Las funciones boot_page_xxxx son llamadas por el gestor de arranque que se ejecuta en la sección flash de arranque . Es decir, normalmente está cargando una imagen binaria en la sección flash de la aplicación . No necesita preocuparse por las secciones , etc. Solo necesita pasar el binario al cargador de arranque, generalmente a través de serie/USB o leerlo desde un disco flash externo (SPI). ¿O intenta implementar un cargador de arranque que pueda actualizarse solo?
"Normalmente", el código del programa se encuentra en la dirección 0. Como ya se mencionó, puede decirle al enlazador que use una dirección diferente. Después del reinicio, el controlador ejecuta el código que comienza en la dirección 0 de forma predeterminada. Puede configurar fusibles para decirle al controlador que ejecute primero el código desde la sección flash de arranque. El código de la sección de inicio debe asegurarse de saltar a la dirección 0 una vez que haya terminado. En todos los casos, deberá conocer el tamaño de su código y calcular dónde es seguro escribir en la memoria flash sin sobrescribir el código de la aplicación. ¡Tenga en cuenta que solo es posible escribir flash desde la sección de flash de arranque!
@ Rev1.0 Entonces, si quiero reservar 3 páginas de flash para escribir una matriz en el futuro. ¿Tengo que decirle al enlazador que mueva el código del programa a la dirección 0x180 (desde e/page 128 bytes)? ¿Es una buena idea ubicar el número de páginas ya conocido en la parte superior del flash y luego decirle al enlazador que coloque el código del programa debajo?
Colocaría mis datos de usuario justo antes del cargador de arranque (la dirección de inicio del cargador de arranque depende de la configuración del fusible) y dejaría la aplicación en la dirección 0. Tenga en cuenta que NO PUEDE escribir ningún dato en el flash desde la aplicación "normal". Tienes que usar un gestor de arranque. No estoy seguro de que esto sea lo que tienes en mente.
@Rev1.0 ¡Sí! ¡gracias por la recomendación! Lo que dijiste no es un problema porque avr-libc tiene macros que interactúan con la memoria flash haciendo todo el "trabajo sucio" por mí.
Tenga en cuenta que las funciones avr-libc NO pueden escribir memoria flash cuando el código también se ejecuta desde la sección de la aplicación.
mira esto, muy claramente explicado: en.wikipedia.org/wiki/Data_segment

Respuestas (1)

A menos que sintonice su enlazador, el programa siempre comenzará en la dirección 0 y crecerá. Además, si tiene un gestor de arranque, comenzará en una de las direcciones predefinidas (ya sea 0xF80, 0xF00, 0E00 o 0xC00, consulte la tabla 26-7 en la hoja de datos) y, por lo general, irá a la parte superior de la memoria.

Cuando las personas usan la memoria flash para datos, generalmente la colocan lo más alto posible. Entonces:

(1) Determine la parte superior de la memoria; esto depende del gestor de arranque que tenga. Si tiene Optiboot, generalmente toma 512 o 256 palabras: https://code.google.com/p/optiboot/wiki/HowOptibootWorks , por lo que asumiremos que comienza en 0xE00.

(2) Determine cuántos datos necesita. Digamos que necesita 256 (0x100) bytes. Esto significa que colocará su bloque de datos en 0xE00 - 0x100 = 0xD00. Puede pasar valores entre 0xD00 y 0xDFE a las funciones boot_page_*.

(3) Escriba su programa.

(4) Compruebe cuánto espacio ocupa. Puede tomar hasta (0xD00 - 1) = 3328 bytes. Cuando compilo desde la línea de comandos, uso 'avr-size' para eso:

$ avr-size -C --mcu=atmega328 firmware.elf
AVR Memory Usage
----------------
Device: atmega328

Program:     904 bytes (2.8% Full)
(.text + .data + .bootloader)

Data:          2 bytes (0.1% Full)
(.data + .bss + .noinit)

Mire la sección 'programa': solo se usan 904 bytes, queda mucho espacio. Si ve un número de 3328 o más allí, haga su programa más corto. De lo contrario, el programa se compilará y cargará, pero se bloqueará aleatoriamente.