Colocar una variable clave en la memoria flash interna

0

Estoy tratando de colocar una variable llamada secret_key en la ubicación 0x08002000 en STM32Nucleo-board que tiene STM32L476RG a bordo con 1MB de flash.

Pregunta 1: ¿Por qué no puedo colocar el código en la sección de ROM personalizada ( SECRET_IROM1 )?
Pregunta 2: ¿Cuál es el error que estoy cometiendo? ?

Todavía soy un novato en el tema de Linker.

Puedo hacerlo (aún no lo subestimo, por qué otra sección de RO también sigue mi nueva dirección de la variable secret_key) si defino la dirección que está en la sección predeterminada para RO en el archivo de dispersión. Si creo una nueva sección, la asignación no está sucediendo. Puedo ver la dirección asignada como se esperaba, pero el valor de secret_key no está visible en esa ubicación.

la imagen de abajo muestra lo que sucede cuando declaro que la dirección está fuera del rango de la sección predeterminada.

Sección de código donde se declara la variable:

unsigned long long int array4[6]={0};
unsigned long long int array[6]={12};

unsigned long long int arra2[4] = {0x1111111111111111,0x2222222222222222,0x3333333333333333,0x4444444444444444};
const long secret_key[3] __attribute__((section(".ARM.__at_0x8001800"))) = {0xABABABAB,0xCDCDCDCD, 0xEFEFEFEF};
extern int addsum(int, int);

int main()
       {
    long long int array3[100] = {1,2,3,4,5,6,7};
    array[1] = arra2[1] - array[0]+array3[1]*2+array3[2]*2+addsum(array[1],array[2])+array4[2]+(int)secret_key[0];
    while(1);
}

Mapa de memoria a continuación:

Contenidodelarchivodedispersiónacontinuación:

;*************************************************************;***Scatter-LoadingDescriptionFilegeneratedbyuVision***;*************************************************************LR_IROM10x080000000x00100000{;loadregionsize_regionER_IROM10x080000000x00002000{;loadaddress=executionaddress*.o(RESET,+First)*(InRoot$$Sections).ANY(+RO)}SECRET_IROM10x080020000x00000030{;loadaddress=executionaddress*(.ARM.__at_0x8001800);secretkey}RW_IRAM10x200000000x00000100{;RWdataproject2.o(+RW)}RW_IRAM20x200001000x00000100{;RWdataproject2.o(+ZI)}RW_IRAM30x200002000x00000300{;RWdataproject.o(+ZI)}RW_IRAM40x200005000x00000200{;RWdataproject.o(+RW)}RW_IRAM50x200007000x00001000{;RWdata.ANY(+RW,+ZI)}}

Segundocaso:dondenofunciona

Códigoaquí:

unsignedlonglongintarray4[6]={0};unsignedlonglongintarray[6]={12};unsignedlonglongintarra2[4]={0x1111111111111111,0x2222222222222222,0x3333333333333333,0x4444444444444444};constlongsecret_key[3]__attribute__((section(".ARM.__at_0x8002100"))) = {0xABABABAB,0xCDCDCDCD, 0xEFEFEFEF};
extern int addsum(int, int);

int main()
       {
    long long int array3[100] = {1,2,3,4,5,6,7};
    array[1] = arra2[1] - array[0]+array3[1]*2+array3[2]*2+addsum(array[1],array[2])+array4[2]+(int)secret_key[0];
    while(1);
}

archivo de dispersión asociado aquí:

; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************

LR_IROM1 0x08000000 0x00100000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00001800  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }

  SECRET_IROM1 0x08002100 0x00000030  {  ; load address = execution address
  *(.ARM.__at_0x8002100) ; secret key
  }

  RW_IRAM1 0x20000000 0x00000100  {  ; RW data
   project2.o (+RW)
   }

  RW_IRAM2 0x20000100 0x00000100  {  ; RW data
   project2.o (+ZI)
   }

  RW_IRAM3 0x20000200 0x00000300  {  ; RW data
   project.o (+ZI)   
  }

  RW_IRAM4 0x20000500 0x00000200  {  ; RW data
   project.o (+RW)   
  }

  RW_IRAM5 0x20000700 0x00001000  {  ; RW data
   .ANY (+RW,+ZI)   
  }
}

mapa de memoria a continuación:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

ResultadosdelasugerenciadeJeroen3

Estoy esperando que los valores cargados en la variable secret_key sean visibles en la región de memoria flash, pero no lo es.

    
pregunta Umar

1 respuesta

2

secretkey.c:

const long secret_key[3] __attribute__((used)) = {0xABABABAB,0xCDCDCDCD, 0xEFEFEFEF};

__attribute__((used)) para evitar que se elimine si no se utiliza en ninguna parte.

secretkey.h:

extern const long secret_key[3];

scatterfile.sct:
Cree una región y un archivo C, luego agregue la parte RO (solo lectura) de ese archivo C a la región. Nada más.

; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************

LR_IROM1 0x08000000 0x00002000 {    ; load region size_region
  ER_IROM1 0x08000000 0x00002000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }

  RW_IRAM1...
}

LR_SECRET_IROM1 0x08002000 0x00000030  {                         
  SECRET_IROM1 0x08002000 0x00000030  {
    secretkey.o (+RO)
  }
}

Ahora tiene dos regiones de carga ( lr_ ), el programador programa estos bloques de memoria (regiones) en flash. LR_IROM1 y LR_SECRET_IROM1 .
Dentro de las regiones de carga están regiones de ejecución . Aquí es donde el código hace referencia a los objetos de. ER_IROM1 , RW_IRAM1 y SECRET_IROM1 .

La mayoría de las veces las direcciones de la región de carga y ejecución son idénticas.
Pero puede tener una región de carga para flash, y una región de ejecución para sram.
Por ejemplo con variables preinicializadas. Esto significa que el enlazador debe insertar el algoritmo dispersión de carga . Esto copia los datos de la ubicación de flash donde se programan los datos en flash, a la ubicación utilizable prevista en sram. (es decir, donde el código cree que están las variables)

Este algoritmo se llama desde el archivo startup.s , y realiza el salto a int main(void) , para Keil este algoritmo se inicia llamando a __main en startup.s .

Pero cuando la región de ejecución ya es igual a la región de carga, no se requiere copia. Como con el código real, y tu ahora con constante.

En mi versión anterior (y en la parte de su pregunta), la constante se colocó dentro de una región de ejecución, lo que significa que se programó usando .ANY (+RO) y luego se copió en la ubicación deseada. Excepto que el código no puede escribir en flash, por lo tanto, nada se cambiaría allí.

Consulte también, Guía del usuario de Armlink del compilador ARM®: 8.2 Sintaxis de un archivo de dispersión
También recomendaría mirar el archivo de memoria .map que genera el enlazador. Puedes usarlo para verificar cómo se junta tu imagen. Hice una pequeña herramienta para esto.
La casilla de verificación está en target settings -> listing -> linker listing .

Tus regiones de RAM son un poco extrañas. No creo que haya una ventaja en el uso de múltiples regiones de 256 tamaños.

En su lugar, puedes usar todas las regiones de SRAM:
- 96 kByte a 0x20000000
- 32 kByte a 0x10000000

    
respondido por el Jeroen3

Lea otras preguntas en las etiquetas