这是我的链接器脚本:
MEMORY {
text (rx) : ORIGIN = 0x000000, LENGTH = 64K
data (rw!x) : ORIGIN = 0x800100, LENGTH = 0xFFA0
}
SECTIONS {
.vectors : AT (0x0000) { entry.o (.vectors); }
.text : AT (ADDR (.vectors) + SIZEOF(.vectors)) { * (.text.startup); * (.text); * (.progmem.data); _etext = .; }
.data : AT (ADDR (.text) + SIZEOF (.text)) { PROVIDE (__data_start = .); * (.data); * (.rodata); * (.rodata.str1.1); PROVIDE (__data_end = .); } > data
.bss : AT (ADDR (.bss)) { PROVIDE (__bss_start = .); * (.bss); PROVIDE (__bss_end = .); } > data
__data_load_start = LOADADDR(.data);
__data_load_end = __data_load_start + SIZEOF(.data);
}
这是我的初始化代码。重置时调用init
。
.section .text,"ax",@progbits
/* Handle low level hardware initialization. */
.global init
init: eor r1, r1
out 0x3f, r1
ldi r28, 0xFF
ldi r29, 0x02
out 0x3e, r29
out 0x3d, r28
rjmp __do_copy_data
rjmp __do_clear_bss
jmp main
/* Handle copying data into RAM. */
.global __do_copy_data
__do_copy_data: ldi r17, hi8(__data_end)
ldi r26, lo8(__data_start)
ldi r27, hi8(__data_start)
ldi r30, lo8(__data_load_start)
ldi r31, hi8(__data_load_start)
rjmp .L__do_copy_data_start
.L__do_copy_data_loop: lpm r0, Z+
st X+, r0
.L__do_copy_data_start: cpi r26, lo8(__data_end)
cpc r27, r17
brne .L__do_copy_data_loop
rjmp main
/* Handle clearing the BSS. */
.global __do_clear_bss
__do_clear_bss: ldi r17, hi8(__bss_end)
ldi r26, lo8(__bss_start)
ldi r27, hi8(__bss_start)
rjmp .L__do_clear_bss_start
.L__do_clear_bss_loop: st X+, r1
.L__do_clear_bss_start: cpi r26, lo8(__bss_end)
cpc r27, r17
brne .L__do_clear_bss_loop
问题是初始化代码在复制过程中会暂停。这是我的符号表的编辑转储,如果它对任何人都有帮助。
00000000 a __tmp_reg__
...
00000000 t reset
...
00000001 a __zero_reg__
...
0000003d a __SP_L__
...
00000074 T main
0000009a T init
000000ae T __do_copy_data
000000c6 T __do_clear_bss
...
00000446 A __data_load_start
00000446 T _etext
0000045b A __data_load_end
00800100 D __data_start
00800100 D myint
00800115 B __bss_start
00800115 D __data_end
00800115 b foobar.1671
00800135 B ticks
00800139 B __bss_end
答案 0 :(得分:3)
C旨在用于冯·诺依曼架构。 AVR是以哈佛为基础的。这意味着C期望字符串在RAM中。因此,如果您查看最终将作为十六进制复制到AVR芯片的任何elf二进制文件的反汇编,您将看到两个部分:__do_copy_data
和__do_clear_bss
[需要时] ]。这些例程在链接阶段添加,可以满足C语言的基本需求。因此,您在指针中看到的可能是指向错误的地址。换句话说,它们要么指向程序空间中的地址,要么是从数据空间[不同的地址总线]读取。或者你是故意从数据空间读取但没有复制字符串。
请参阅:
avr/pgmspace.h
FAQ: ROM Array and scroll down for strings
当然,Atmel提供的AVR指令集,特别是将程序存储器复制到数据存储器的指令
编辑以反映新问题和评论:您对两个部分的汇编看起来都不错。我将不得不仔细查看您的链接器脚本,以检查是否有任何有趣的业务。既然你正在编写一个引导加载程序,你介意我问你是否看过bootloader support on AVR-libc?
答案 1 :(得分:0)
http://deans-avr-tutorials.googlecode.com/svn/trunk/Progmem/Output/Progmem.pdf 本文档可能有助于澄清AVR的闪存/ RAM存储器的使用。
答案 2 :(得分:0)
我实际上已经开始工作了。我所要做的就是在SREG
中启用读写外部RAM的功能。我知道,这很明显和简单,但它被埋没在数据表中,并且记录很少。
这个资源很有帮助,但我的芯片没有任何文档。如果您遇到此问题,请查看AVR的数据表并查看其相关性。对于AVR的所有变体,该过程并不相同。