Programación de bytes de opción ARM mediante directivas de ensamblaje

Entonces, al mirar la hoja de datos de un controlador ARM específico, encontramos que el espacio de direcciones se mapea de la siguiente manera:

ingrese la descripción de la imagen aquí

Hay varias formas de lograr esto, una de las cuales es a través de un archivo generado automáticamente que tiene el siguiente contenido (resumido):

; Option byte organization
;-------------------------
;   Address     [31:24] [23:16] [15:8] [7:0]
; 0x1FF80000       -     nRDP      -    RDP     (0xFF5500AA)
; 0x1FF80004       -     nUSER     -    USER    (0xFF870078)
; 0x1FF80008     nWRP1   nWRP0   WRP1   WRP0    (0xFFFF0000)
; 0x1FF8000C     nWRP3   nWRP2   WRP3   WRP2    (0xFFFF0000)

FLASH_OPT       EQU     1

RDP             EQU     0xAA
nRDP            EQU     RDP:EOR:0xFF
WRP00           EQU     0x00
WRP01           EQU     0x00
WRP02           EQU     0x00
WRP03           EQU     0x00
nWRP00          EQU     WRP00:EOR:0xFF
nWRP01          EQU     WRP01:EOR:0xFF
nWRP02          EQU     WRP02:EOR:0xFF
nWRP03          EQU     WRP03:EOR:0xFF
USER            EQU     0x78
nUSER           EQU     USER:EOR:0xFF

IF      FLASH_OPT <> 0
    AREA    |.ARM.__AT_0x1FF80000|, CODE, READONLY
        DCB     RDP,   0x00,   nRDP,   0xFF      
        DCB     USER,  0x00,   nUSER,  0xFF      
        DCB     WRP00, WRP01,  nWRP00, nWRP01
        DCB     WRP02, WRP03,  nWRP02, nWRP03
ENDIF

Parece como si este archivo simplemente brindara una forma muy configurable de establecer estos bytes de opción, pero ¿cómo se hace? Investigué un poco y resulta que la AREAdirectiva le dice al ensamblador que genere una nueva área, en este caso un área de código que será de solo lectura .

Además, la DCBdirectiva asigna memoria, en este caso 16 bytes, y los inicializa con los respectivos valores proporcionados.

Mi pregunta, entonces, es ¿dónde está la especificación con respecto a la ubicación de este bloque de memoria recién asignado? Es decir, ¿cómo se escribe el valor de este bloque de 16 bytes en los registros apropiados (0x1FF80000, etc.)?

La única mención de esta dirección viene dada por el |.ARM.__AT_0x1FF80000|argumento pasado a AREA. Sin embargo, este primer argumento es solo el nombre de esta nueva área según la documentación .

O tal vez la mejor pregunta es: ¿Cómo podemos especificar dónde se almacenará un ÁREA en la memoria?

Scripts de enlace, por lo general. En los compiladores basados ​​en gcc, estos son archivos de texto con una extensión .ld.
@BrianDrummond, este ejemplo proviene de un archivo de ensamblaje llamado STM32xxxx_MD_OPT.s

Respuestas (1)

El enlazador ARM coloca automáticamente secciones con el prefijo __aten la dirección especificada. En el código C, especificaría la sección usando el sectionatributo, así:

// place flash_key in a section called .ARM.__at_0x8000
long flash_key __attribute__((section(".ARM.__at_0x8000")));

Puede controlar el comportamiento pasando --autoat o --noautoat al enlazador.

Consulte Colocación de una clave en la memoria flash con una sección __at de la Guía del usuario de ARM Linker para obtener más detalles.

¡Gracias! ¿Es necesario el prefijo .ARM.o la convención en este caso?
.ARM.es necesario al especificar el nombre de la sección, pero también puede colocar los datos en la dirección usando el atatributo. Ver Colocación de secciones __at en una dirección específica . Por supuesto, esto solo se aplica al propio compilador de ARM, no a GCC ni a ningún otro.