起因
移植lettershell后在gcc的ld文件中加入指令表的起始和结束符号
.rodata :
{
. = ALIGN(4);
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
_shell_command_start = .;
KEEP (*(shellCommand))
_shell_command_end = .;
. = ALIGN(4);
} >FLASH
经过
代码编译没问题,一开始也能正常跑,但是增加了一段新代码后直接硬件中断报错,使用cmBacktrace追踪到报错地:shellInit->shellSeekCommand->strcmp错误类型为precise data access violation即精确的总线访问错误,可能为访问地址出错导致,增加打印信息发现打印的数据有空指针并且shellSeekCommand中判断按键类型理应进的都没进,查看map如下:
0x0000000008009446 _shell_command_start = .
*(shellCommand)
*fill* 0x0000000008009446 0x2
shellCommand 0x0000000008009448 0x20 ./User/Component/litter-shell/port/shell_port.o
0x0000000008009448 shellCommandreboot
0x0000000008009458 shellCommandscanT
shellCommand 0x0000000008009468 0x20 ./User/Component/litter-shell/src/log.o
0x0000000008009468 shellCommandhexdump
0x0000000008009478 shellCommandlogSetLevel
shellCommand 0x0000000008009488 0x120 ./User/Component/litter-shell/src/shell.o
0x0000000008009488 shellCommandclear
0x0000000008009498 shellCommandkeys
0x00000000080094a8 shellCommandvars
0x00000000080094b8 shellCommandcmds
0x00000000080094c8 shellCommandusers
0x00000000080094d8 shellCommandhelp
0x00000000080094e8 shellKey0x0D000000
0x00000000080094f8 shellKey0x0A000000
0x0000000008009508 shellKey0x1B5B337E
0x0000000008009518 shellKey0x7F000000
0x0000000008009528 shellKey0x08000000
0x0000000008009538 shellKey0x09000000
0x0000000008009548 shellKey0x1B5B4400
0x0000000008009558 shellKey0x1B5B4300
0x0000000008009568 shellKey0x1B5B4200
0x0000000008009578 shellKey0x1B5B4100
0x0000000008009588 shellCommandsetVar
0x0000000008009598 shellUserDefault
0x00000000080095a8 _shell_command_end = .
0x00000000080095a8 . = ALIGN (0x4)
可以看到我的第一个指令的地址为0x0000000008009448与0x0000000008009446差了2,相当于使变量都偏移了两个字节导致处理的时候地址错乱了
解决
修改下ld文件:确保**_shell_command_start**地址在四字节位置上
.rodata :
{
. = ALIGN(4);
_shell_command_start = .;
KEEP (*(shellCommand))
_shell_command_end = .;
*(.rodata) /* .rodata sections (constants, strings, etc.) */
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
. = ALIGN(4);
} >FLASH
总结
直接对地址操作的时候注意字节对齐和补齐的问题