gpt4 book ai didi

assembly - 在 avr tiny 中,当微 Controller 通电时,数据如何存储在 sram 中初始化?

转载 作者:行者123 更新时间:2023-12-03 17:19:57 25 4
gpt4 key购买 nike

首先介绍一下背景。在 avr tiny 中,数据可以存储在寄存器、sram、eeprom 或程序空间中。寄存器和 sram 是 volatile 存储,而 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){
;;
}
}

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

并从 .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.

那么我们想要放入 sram 的数据 (0xef) 是如何初始化的呢?
答案是通过 main 之前的例程。

应该存储在 sram 中的数据位于程序空间中的地址 0x5a。它以下列方式放入 sram:
  • x 寄存器的高低字节设置为我们想要将数据放入 sram 的地址。(0x60) 注意这个地址不在程序存储器中,而是在数据存储器中。
  • z 寄存器相同,但数据在程序空间中的地址 (0x5a)
  • 存储在 z 寄存器中的地址处的程序存储器的内容通过 lpm 操作码加载到寄存器 r0 中。请注意,z 寄存器值递增以指向(最终,此处为无)下一个要加载到 sram 中的数据。
  • 然后将 r0 中的数据存储在 sram 中存储在 x 寄存器中的地址处。
  • 重复直到所有应该在 sram 中的数据都被初始化。

  • 这发生在对 main 的 rcall 之前。

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

    最佳答案

    是的,在 gnu 工具世界中,当然与其他工具类似。

    链接器获得 .text、.data、.bss 数据,并且必须将其放入二进制文件中。对于基于闪存的系统,avr 没有什么特别的,所有平台都一样,所有非 volatile 信息都必须在闪存上。链接器脚本告诉链接器 .data 段有两个 home,一个 home 用 .text 和 flash 中的其他任何内容添加,然后在 ram 地址空间中添加一个 home。您可以使用一些关键字来制作链接器脚本,链接器将这些关键字填充到引导代码(调用 main 的 asm)中的外部变量中。此代码使用这些变量在调用 main 之前将 .data 复制到 ram 并将 .bss 归零,以便 C 语言假设(未初始化的变量为零,初始化的变量是您的代码将它们初始化为的)。如果您编写代码时永远不会假设变量在 main 之前被初始化,那么您就不必执行任何这些操作,您的 pre-main init 代码可以简单地将堆栈指针和分支设置为 main。

    关于assembly - 在 avr tiny 中,当微 Controller 通电时,数据如何存储在 sram 中初始化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10942063/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com