主题中讨论的其它部件:HALCOGEN、 TMS570LS3137
大家好!
我一直在尝试(并且成功)使 HALCoGen 输出可使用 ARM GCC 工具链编译的代码(不使用 CCS -不确定这是否会影响 CCS/Linaro),并偶然发现了 HALCoGen 输出的一部分问题:
sys_startup.c 中启动序列的一部分:
/* sourceId:startup_sourceId_001 */
/* DesignId:startup_DesignId_001 */
/*要求:HL_SR508 */
void _c_int00 (void)
{
/*用户代码开始(5)*/
/*用户代码结束*/
/*初始化内核寄存器以避免 CCM 错误*/
_coreInitRegisters_();
这里的问题是_coreInitRegisters_()不符合 EABI (它不能兼容)、并且可以避免使用堆块化寄存器 GCC。 这就产生了以下情况:
00000f88 <_c_int00>:
f88: e3e04000 mvn R4、#0
f8c: ebfffc5d BL 108 <_coreInitRegisters_>
f90: ebfffc8a BL 1C0 <_coreInitStackPointer_>
f94: ebfffca4 BL 22c <_coreEnableEventBusExport_>
f98: ebfffd0e BL 3d8 <_errata_CORTEXR4_66_>
f9c: ebfffd07 BL 3c0 <_errata_CORTEXR4_57_>
Fa0/: e514301b LDR R3,[R4,#-27] ;0xffffff5.
fa4: e3130902 TST R3,#32768 ;0x8000
请注意、R4一开始就被置位、GCC 不希望它在0xfa0处的 LDR 之前更改[EABI 表示 R4为被调用方保存]、但它确实如此、因此这会导致此时的数据中止。 由于 sys_startup.c 中的此代码代码,取指令会降低:
/*SAFETYMCUSW 139 S MR:13.7 "硬件状态位读取检查"*/
如果((SYS_EXCE异常 和安全装置复位)!=0U)则为其他
[具有讽刺意味的是、0xffffe5实际上是"正确的"、因为 R4返回0而不是停留在-1、它应该访问0xffe4、如果 R4仍然为-1。]
针对这个问题的一个简单的权变措施是告诉 GCC 它的寄存器将被刷写:
/*用户代码开始(6)*/
_ASM____volatile__(":"r0"、"r1"、"r2"、"r3"、"R4"、"R5"、"r6"、"r7"、"r8"、"r8"、"R9"、"r10"、"r11"、"r11"、"r11"、"R12"、"r14");
/*用户代码结束*/
请注意这对输出的作用:
00000f88 <_c_int00>:
f88: ebfffc5e BL 108 <_coreInitRegisters_>
f8c: e3e04000 mvn R4、#0
f90: ebfffc8a BL 1C0 <_coreInitStackPointer_>
f94: ebfffca4 BL 22c <_coreEnableEventBusExport_>
f98: ebfffd0e BL 3d8 <_errata_CORTEXR4_66_>
f9c: ebfffd07 BL 3c0 <_errata_CORTEXR4_57_>
Fa0/: e514301b LDR R3,[R4,#-27] ;0xffffff5.
fa4: e3130902 TST R3,#32768 ;0x8000
MVN 现已在非 EABI 兼容函数调用后移动-其他函数调用充分符合 EABI、不会中断- LDR 成功。
对此可能有一种更巧妙的解决方案、但只要允许 GCC 按顺序分配内容、对不符合 EABI 的汇编函数的任何调用都可能会有问题。
这可能会在 HALCoGen 中修复。
仅供参考,在使用 CCS 和 TI 编译器进行编译时(HALCoGen 会发出 TI 代码),我们可以看到:
00003c44 <_c_int00>:
3c44: ebfffde3 BL 33d8 <_coreInitRegisters_>
3c48: ebfffe10 BL 3490 <_coreInitStackPointer_>
3c4c: ebfffe2a BL 34fc <_coreEnableEventBusExport_>
3c50: ebfffe92 BL 36a0 <_errata_CORTEXR4_66_>
3c54: ebfffe8d BL 3690 <_errata_CORTEXR4_57_>
3c58: e3e0401b mvn R4、#27
3c5c: e594c000 LDR IP、[R4]
3c60: e31c0902 TST IP,#32768 ;0x8000
虽然它在存储器中的饱和值比 GCC 输出高一些、但我们可以看到它不像 GCC 那样提早分配 R4、因此可以避免这一问题。
此致、
Patrick Herborn。