上一篇随笔说了,需要清除bss段,我们现在定义main函数如下:
注意这个全局变量是没有初始值的,即存放在bss段中,如果我们的启动文件没有清除bss段,串口的输出将是你想不到情况。比如,现在程序运行执行了++操作20次,你下次快速断电再上电的时候,g_Char2的值是接着之前的值增加的,而增加了清除bss段之后,每次重新上电,都是从0开始的。到这里我是觉得纳闷的,我们程序是重定位到了sdram的,既然是ram中,掉电不就应该是马上丢失数据了吗?然后查询了一下资料,发现:
然后我就多等了一些时间,果然,可以看到sdram数据在慢慢丢失,又涨知识了~
现在我们在start.S中增加清除bss段的代码:
/* 清除BSS段 */ ldr r1, =bss_start ldr r2, =bss_end mov r3, #0 clean: strb r3, [r1] add r1, r1, #1 cmp r1, r2 bne clean
连接脚本也需要更改:
SECTIONS { .text 0: {*(.text)} .rodata : {*(.rodata)} .data 0x30000000 :AT(0x800) { data_load_add = LOADADDR(.data); data_start = . ; *(.data) data_end = . ; } .bss : { bss_start = .; *(.bss) *(COMMON) ; bss_end = .; } }
这样(上面链接脚本中bss段中.bss *(COMMEN)后那个分号仅仅为了美观,会被连接器忽略的,这个在ld连接器那篇文章中有讲到)就可以看到串口输出了,是从ascii码0开始打印的。
时间: 2024-11-12 18:41:51