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:
- 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.
- Lo mismo para el registro z, pero con la dirección donde están los datos en el espacio del programa (0x5a)
- 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.
- los datos en r0 se almacenan en el sram en la dirección almacenada en el registro x.
- 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?
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