Assembly 在avr tiny中,当微控制器通电时,如何初始化存储在sram中的数据?

Assembly 在avr tiny中,当微控制器通电时,如何初始化存储在sram中的数据?,assembly,avr,avr-gcc,Assembly,Avr,Avr Gcc,首先是一些背景。在avr微型机中,数据可以存储在寄存器、sram、eeprom或程序空间中。寄存器和sram是易失性存储器,而eeprom和程序空间则不是。(即:未通电时数据保持不变。) 使用c编程(使用avr gcc库)时,典型代码可能如下所示: #define F_CPU 8000000UL #include <inttypes.h> #include <avr/io.h> #include <avr/pgmspace.h> #include <av

首先是一些背景。在avr微型机中,数据可以存储在寄存器、sram、eeprom或程序空间中。寄存器和sram是易失性存储器,而eeprom和程序空间则不是。(即:未通电时数据保持不变。)

使用c编程(使用avr gcc库)时,典型代码可能如下所示:

#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){
    ;;
    }
}
并从.elf中提取intel.hex:

avr-objcopy -j .text -j .data -O ihex test.elf test.hex
我们得到以下test.hex:

:1000000011C023C022C021C020C01FC01EC01DC0FF
:100010001CC01BC01AC019C018C017C016C015C01C
:1000200014C0CD0011241FBECFE5D1E0DEBFCDBF8F
:1000300010E0A0E6B0E0EAE5F0E002C005900D9225
:10004000A236B107D9F702D006C0DACFCF93DF933B
:0A005000CDB7DEB7FFCFF894FFCF65
:02005A00EF00B5
:00000001FF
以及以下文件:

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.
00000000:
0:11 c0 rjmp.+34;0x24
20:14 c0 rjmp.+40;0x4a
22:CD00,字0x00cd;这是我们存储在程序mem中的数据。
24:11 24提高采收率r1,r1
26:1f输出0x3f,r1;63
28:cf e5 ldi r28,0x5F;95
2a:d1 e0本地设计院r29,0x01;1.
2c:断开0x3e,r29;62
2e:cd bf out 0x3d,r28;61
30:10 e0本地设计院r17,0x00;0
32:a0 e6本地设计院r26,0x60;X寄存器低字节;目的地地址。在里面
34:B0E0本地设计院r27,0x00;X寄存器高字节;sram
36:ea e5本地设计院r30,0x5A;z寄存器低字节;中的数据地址
38:f0 e0本地设计院r31,0x00;z寄存器高字节;程序存储器
3a:02 c0 rjmp.+4;0x40
3c:05 90 lpm r0,Z+
3e:0d 92 st X+,r0
40:a2 36消费物价指数r26,0x62;98
42:b1 07 cpc r27,r17
44:d9 f7 brne-10;0x3c
5a:ef 00。字0x00ef;这是我们的数据
应存储在sram中。
那么,我们想要放入sram的数据(0xef)是如何初始化的呢?
答案是通过主程序之前的例行程序

应存储在sram中的数据位于程序空间中的地址0x5a处。通过以下方式将其放入sram:

  • x寄存器高字节和低字节设置为我们要将数据放入sram的地址。(0x60)注意,该地址不在程序内存中,而是在数据内存中
  • 与z寄存器相同,但具有数据在程序空间中的地址(0x5a)
  • 存储在z寄存器中的地址处的程序存储器的内容通过lpm操作码加载到寄存器r0中。请注意,z寄存器值会增加到下一个要加载到sram的数据(最终,此处为无)上的点
  • 然后,r0中的数据存储在sram中x寄存器中存储的地址处
  • 重复此操作,直到应在sram中的所有数据都已初始化
  • 这种情况发生在rcall呼叫干管之前


    有更好/更清晰的答案吗?

    如果您想要SRAM中的数据,您的程序必须将其放在那里


    在gnu工具的世界里,当然还有与其他工具类似的方式


    链接器是.text、.data、.bss数据,必须将其放入二进制文件中。对于基于flash的系统,没有特定于avr的内容,对于所有平台都是一样的,所有非易失性信息都必须在flash上。链接器脚本告诉链接器,.data段有两个主地址,一个主地址用.text和flash中的其他内容固定,然后在ram地址空间中固定一个主地址。您可以使用链接器将填充到启动代码(调用main的asm)中的外部变量的一些关键字来创建链接器脚本。此代码在调用main之前使用这些变量将.data复制到ram和zero out.bss,以便C语言假设(单位化变量为零,初始化变量是您的代码初始化的变量)。如果您编写的代码从不假设变量在main之前初始化,那么您就不必执行任何操作,您的pre-main init代码可以简单地设置堆栈指针并将其分支到main。

    是的,现在这对我来说很明显,但我花了一点时间弄清楚为什么sram中需要的数据位于.hex的末尾。希望它能帮助别人。
    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.