AVR从零编写最小启动代码与链接脚本的技术疑问
针对ATtiny2313裸机启动代码与链接脚本的疑问解答
问题1:编译器是否已识别CKEL、SUT、SREG等熔丝位符号?是否需要自行声明?
- SREG:这是AVR的状态寄存器,avr-gcc配套的avr-libc已经在对应芯片的头文件(引入
<avr/io.h>后会自动加载ATtiny2313的寄存器定义)里预定义好了,直接用就行,不需要自行声明。 - CKEL、SUT:这俩属于熔丝位配置,不是程序代码中可访问的寄存器符号,avr-gcc本身不会将其识别为代码符号。如果需要在熔丝烧写阶段指定相关配置,avr-libc的
<avr/fuse.h>里针对ATtiny2313提供了对应的宏(比如FUSE_CKSEL、FUSE_SUT系列宏),但这些是用来生成熔丝烧写命令的,不是写在程序里的变量或寄存器。程序代码里完全不需要声明它们,熔丝是通过编程器单独烧写的硬件配置项。
问题2:AVR生成的各个内存段是否会被使用?是否强制要求所有段都被使用?
不需要强制使用所有段,只需要处理核心必要的段,其余不用的可以直接忽略:
- 必须处理的段:
.text:存放程序代码,链接脚本必须将其映射到Flash的起始地址(ATtiny2313的Flash起始地址为0x0000,复位向量就在此处)。.data:存放初始化过的全局/静态变量,这些数据默认存在Flash中,启动代码需要在进入main()前将其复制到RAM对应地址。.bss:存放未初始化的全局/静态变量,启动代码需要在进入main()前将这段内存清零。.init0:AVR复位后会跳转到0x0000地址,这个段就是复位入口的位置,你的启动代码(比如复位向量、栈指针初始化、.data复制、.bss清零逻辑)必须放在这里,链接脚本要将其链接到Flash起始地址。
- 可选/可忽略的段:
.eeprom:存放需要持久化在EEPROM的数据,不需要的话可以在链接脚本里不定义或留空。.noinit:存放不需要清零的未初始化变量,如果你不需要这类变量,完全可以忽略这个段。.initN(N从1到8)、.finiN:这些是初始化/终止钩子函数的段,比如.init1可用于硬件初始化钩子,不需要的话链接脚本里可以不处理,或者将其地址设为0(跳过执行)。.note.gnu.avr.deviceinfo:这是avr-gcc自动生成的设备信息段,链接器会自动处理,你不需要特意在链接脚本中配置,也不影响程序运行。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

