1

这是我的链接器脚本:

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
4

3 回答 3

3

C 被设计用于冯诺依曼架构。AVR 是基于哈佛的。这意味着 C 期望字符串在 RAM 中。因此,如果您查看任何最终将作为十六进制复制到 AVR 芯片的 elf 二进制文件的反汇编,您将看到两个部分:__do_copy_data__do_clear_bss[当需要时]。这些在链接阶段添加的例程负责 C 语言的基本需求。因此,您在这里看到的指针很可能指向错误的地址。换句话说,它们要么指向程序空间中的地址,但您正在从数据空间[不同地址总线]读取。或者您故意从数据空间中读取,但没有复制字符串。

看:

avr/pgmspace.h 常见问题解答:ROM Array 并向下滚动查看字符串 ,当然还有 Atmel 提供的 AVR 指令集,特别是将程序存储器复制到数据存储器的指令

编辑以反映新问题和评论:您的两个部分的装配对我来说都不错。我将不得不仔细检查您的链接器脚本,以检查那里是否有任何有趣的业务。由于您正在编写引导加载程序,您介意我问您是否看过AVR-libc 上的引导加载程序支持吗?

于 2013-07-09T00:23:18.820 回答
0

http://deans-avr-tutorials.googlecode.com/svn/trunk/Progmem/Output/Progmem.pdf 本文档可能有助于阐明 AVR 的闪存/ram 存储器的使用。

于 2013-07-09T21:14:29.730 回答
0

我真的让它工作了。我所要做的就是在SREG. 我知道,这是非常明显和简单的,但它被隐藏在数据表中,而且记录得很差。

这个资源很有帮助,但没有我的芯片的任何文档。如果您遇到此问题,请查看 AVR 的数据表并了解其相关性。对于 AVR 的所有变体,该过程并不相同。

如何使用外部 RAM。

于 2013-07-20T06:16:58.373 回答