2012-06-08 13 views
5

Primero algunos antecedentes. En un pequeño entorno, los datos se pueden almacenar en los registros, en el sram, en el eeprom o en el espacio del programa. Register y sram son volátiles mientras que el eeprom y el espacio del programa no lo son. (Es decir:. Estancia de datos cuando no está encendido)En un pequeño ejemplo, ¿cómo se almacenan los datos en sram inicializados cuando se enciende el microcontrolador?

Al programar en C (usando las bibliotecas avr-gcc), un código típico podría ser:

#define F_CPU 8000000UL 
#include <inttypes.h> 
#include <avr/io.h> 
#include <avr/pgmspace.h> 
#include <avr/eeprom.h> 

//This data is put in the eeprom 
const uint8_t dat_eeprom EEMEM= 0xab; 
//This data is put in the program space 
const uint8_t dat_pgm_space PROGMEM= 0xcd; 
//This data is stored in the sram 
uint8_t dat_sram = 0xef; 

int main(){ 
    while(1){ 
    ;; 
    } 
} 

Compilar con:

avr-gcc -g -mmcu=attiny44 -o test.elf test.c 

y extraer un .hex Intel desde el .elf:

avr-objcopy -j .text -j .data -O ihex test.elf test.hex 

obtenemos la siguiente test.hex:

:1000000011C023C022C021C020C01FC01EC01DC0FF 
:100010001CC01BC01AC019C018C017C016C015C01C 
:1000200014C0CD0011241FBECFE5D1E0DEBFCDBF8F 
:1000300010E0A0E6B0E0EAE5F0E002C005900D9225 
:10004000A236B107D9F702D006C0DACFCF93DF933B 
:0A005000CDB7DEB7FFCFF894FFCF65 
:02005A00EF00B5 
:00000001FF 

Y la siguiente Desensamblaje:

00000000 <.sec1>: 
0: 11 c0   rjmp .+34  ; 0x24 
     <...skipped interrupt vector table...> 
20: 14 c0   rjmp .+40  ; 0x4a 
22: cd 00   .word 0x00cd ; this is our data stored in the program mem. 
24: 11 24   eor r1, r1 
26: 1f be   out 0x3f, r1 ; 63 
28: cf e5   ldi r28, 0x5F ; 95 
2a: d1 e0   ldi r29, 0x01 ; 1 
2c: de bf   out 0x3e, r29 ; 62 
2e: cd bf   out 0x3d, r28 ; 61 
30: 10 e0   ldi r17, 0x00 ; 0 
32: a0 e6   ldi r26, 0x60 ; X register low byte ; address of dest. in 
34: b0 e0   ldi r27, 0x00 ; X register high byte; sram 
36: ea e5   ldi r30, 0x5A ; z register low byte ; address of data in 
38: f0 e0   ldi r31, 0x00 ; z register high byte; program memory 
3a: 02 c0   rjmp .+4   ; 0x40 
3c: 05 90   lpm r0, Z+ 
3e: 0d 92   st X+, r0 
40: a2 36   cpi r26, 0x62 ; 98 
42: b1 07   cpc r27, r17 
44: d9 f7   brne .-10  ; 0x3c 
      <...skipped rcall to main...> 
5a: ef 00   .word 0x00ef ; this is our data that 
             should be stored in the sram. 

Entonces, ¿cómo son los datos (0xEF) que queríamos poner en SRAM inicializado?
La respuesta es a través de una rutina antes principal.

Los datos que se deben almacenar en el sram se encuentran en la dirección 0x5a, en el espacio del programa. Se pone en la SRAM de la siguiente manera:

  1. El x registrarse bytes alto y bajo se establecen para la dirección de donde queremos poner los datos en la SRAM (0x60) tenga en cuenta que esta dirección no es. en la memoria del programa pero en la memoria de datos.
  2. Lo mismo para el registro z, pero con la dirección donde están los datos en el espacio del programa (0x5a)
  3. el contenido de la memoria del programa en la dirección almacenada en el registro z se carga en el registro r0 a través del lpm código de operación Tenga en cuenta que el valor del registro z se incrementa para apuntar a los datos siguientes (eventual, aquí ninguno) para cargar en el sram.
  4. los datos en r0 se almacenan en el sram en la dirección almacenada en el registro x.
  5. Repita hasta que se hayan inicializado todos los datos que deberían estar en sram.

Esto sucede antes de una llamada a la principal.

¿Hay una respuesta mejor/más clara?

Respuesta

-1

Si desea datos en su SRAM, su programa tiene que ponerlo allí.

Allí, hizo eso por usted.

+0

Sí, ahora es obvio para mí, pero dediqué un poco de tiempo a entender por qué los datos que quería en el sram estaban al final del .hex. Espero que ayude a alguien. – user1443332

1

Correcto, en el mundo de las herramientas gnu y, ciertamente, formas similares con otras herramientas.

al enlazador se le dan datos .text, .data, .bss y tiene que colocarlo en el binario. para un sistema basado en flash, nada específico para avr, lo mismo para todas las plataformas, toda la información no volátil tiene que estar en flash. La secuencia de comandos del vinculador le dice al vinculador que el segmento .data tiene dos hogares, un hogar está insertado con .text y cualquier otra cosa en el flash, y luego un hogar en el espacio de direcciones del ram. Usted crea su secuencia de comandos del vinculador con algunas palabras clave que el vinculador completará con variables externas en su código de inicio (la llamada que llama a main).Este código usa estas variables para copiar .data a ram y a cero .bss antes de llamar a main para que las suposiciones de lenguaje C (las variables unificadas sean cero y las variables inicializadas sean las que el código las inicializó). Si escribe su código para que nunca suponga que una variable se inicializa antes que main, entonces no tendrá que hacer nada de esto, su código de inicialización principal puede simplemente establecer el puntero de la pila y la rama en main.

Cuestiones relacionadas