This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
附加的项目是一个基于 HALCoGen 的项目、用于 RM48L952、它使用 RTI 中断。 源代码由 HALCoGen 创建、指定"TI 工具"、有两种构建配置:
a.使用 TI ARM v20.2.5的 Debug_TI_ARM_CGT
b.使用 TI ARM Clang v1.3.0的 Debug_TI_clang
添加 Debug_TI_clang 编译配置后、对源代码和链接器命令文件进行了一些调整、以允许编译和运行这两种编译器、 将修改保留在 HALCoGen //用户代码中*/块中,以便在使用 HALCoGen 重新生成驱动程序代码时保留修改。
source/RTI.c 源文件包含以下 HALCoGen 创建的 rtiCompare0Interrupt()中断处理程序,该处理程序调用用户提供的处理程序:
/* USER CODE BEGIN (73) */ /* Work-around for TI ARM CLANG not understanding CODE_STATE and INTERRUPT pragmas */ void rtiCompare0Interrupt(void) __attribute__((target("arm"))) __attribute__((interrupt("IRQ"))); /* USER CODE END */ /** @fn void rtiCompare0Interrupt(void) * @brief RTI1 Compare 0 Interrupt Handler * * RTI1 Compare 0 interrupt handler * */ #pragma CODE_STATE(rtiCompare0Interrupt, 32) #pragma INTERRUPT(rtiCompare0Interrupt, IRQ) /* SourceId : RTI_SourceId_022 */ /* DesignId : RTI_DesignId_022 */ /* Requirements : HL_SR95 */ void rtiCompare0Interrupt(void) { /* USER CODE BEGIN (74) */ /* USER CODE END */ rtiREG1->INTFLAG = 1U; rtiNotification(rtiNOTIFICATION_COMPARE0); /* USER CODE BEGIN (75) */ /* USER CODE END */ }
TI arm v20.2.5编译器为 rtiCompare0Interrupt()生成以下内容,保留浮点寄存器,这大概是因为 TI arm v20.2.5不知道被调用函数是否可以使用浮点寄存器:
865 { rtiCompare0Interrupt(): 08001660: E92D500F push {r0, r1, r2, r3, r12, r14} 08001664: EEF8CA10 vmrs r12, fpexc 08001668: E92D1000 stmdb r13!, {r12} 0800166c: EEF1CA10 vmrs r12, fpscr 08001670: E92D1000 stmdb r13!, {r12} 08001674: ED2D0B10 vpush {d0, d1, d2, d3, d4, d5, d6, d7} 869 rtiREG1->INTFLAG = 1U; 08001678: E30FCC88 movw r12, #0xfc88 0800167c: E34FCFFF movt r12, #0xffff 08001680: E3A00001 mov r0, #1 08001684: E58C0000 str r0, [r12] 870 rtiNotification(rtiNOTIFICATION_COMPARE0); 08001688: EBFFFF9C bl rtiNotification 0800168c: ECBD0B10 vpop {d0, d1, d2, d3, d4, d5, d6, d7} 08001690: E8BD1000 ldm r13!, {r12} 08001694: EEE1CA10 vmsr fpscr, r12 08001698: E8BD1000 ldm r13!, {r12} 0800169c: EEE8CA10 vmsr fpexc, r12 080016a0: E8BD500F pop {r0, r1, r2, r3, r12, r14} 080016a4: E25EF004 subs pc, r14, #4
而 TI ARM Clang v1.3.0编译器为 不保留浮点寄存器的 rtiCompare0Interr()生成以下代码:
865 { rtiCompare0Interrupt(): 08001630: E92D5C0F push {r0, r1, r2, r3, r10, r11, r12, r14} 08001634: E28DB014 add r11, r13, #0x14 08001638: E7C2D01F bfc r13, #0, #3 0800163c: E30FEC88 movw r14, #0xfc88 08001640: E3A00001 mov r0, #1 08001644: E34FEFFF movt r14, #0xffff 869 rtiREG1->INTFLAG = 1U; 08001648: E58E0000 str r0, [r14] 870 rtiNotification(rtiNOTIFICATION_COMPARE0); 0800164c: E3A00001 mov r0, #1 08001650: EBFFFFAA bl rtiNotification 874 } 08001654: E24BD014 sub r13, r11, #0x14 08001658: E8BD5C0F pop {r0, r1, r2, r3, r10, r11, r12, r14} 0800165c: E25EF004 subs pc, r14, #4
TI ARM Clang v1.3.0编译器为 rtiCompare0Interr()对 rtiNotification()的调用生成了"无中断属性的函数调用可能是 clobber interree 的 VFP 寄存器"警告:
Building file: "../source/rti.c" Invoking: Arm Compiler "C:/ti/ccs1030/ccs/tools/compiler/ti-cgt-armllvm_1.3.0-beta.1/bin/tiarmclang.exe" -c -march=armv7r -mcpu=cortex-r4 -mfloat-abi=hard -mfpu=vfpv3-d16 -mlittle-endian -marm -O2 -I"C:/Users/mr_halfword/E2E_example_projects/RM48L952_rtiblinky" -I"C:/Users/mr_halfword/E2E_example_projects/RM48L952_rtiblinky/include" -I"C:/ti/ccs1030/ccs/tools/compiler/ti-cgt-armllvm_1.3.0-beta.1/include" -D_INLINE -gdwarf-3 -Werror=ti-intrinsics -fno-short-wchar -fcommon -ffunction-sections -MMD -MP -MF"source/rti.d_raw" -MT"source/rti.o" -std=gnu90 -o"source/rti.o" "../source/rti.c" In file included from ../source/rti.c:54: In file included from C:/Users/mr_halfword/E2E_example_projects/RM48L952_rtiblinky/include\rti.h:53: In file included from C:/Users/mr_halfword/E2E_example_projects/RM48L952_rtiblinky/include/reg_rti.h:52: C:/Users/mr_halfword/E2E_example_projects/RM48L952_rtiblinky/include/sys_common.h:95:9: warning: __little_endian__ is a legacy TI macro that is not defined in clang compilers and will evaluate to 0, use '!defined(__ARM_BIG_ENDIAN)' instead [-Wti-macros] #ifndef __little_endian__ ^ ../source/rti.c:858:9: warning: pragma CODE_STATE is a legacy TI pragma and not supported in clang compilers. use '__attribute__((target("code_state")))' instead [-Wti-pragmas] #pragma CODE_STATE(rtiCompare0Interrupt, 32) ^ ../source/rti.c:859:9: warning: pragma INTERRUPT is a legacy TI pragma and not supported in clang compilers. use '__attribute__((interrupt("int_kind")))' instead [-Wti-pragmas] #pragma INTERRUPT(rtiCompare0Interrupt, IRQ) ^ ../source/rti.c:870:5: warning: call to function without interrupt attribute could clobber interruptee's VFP registers [-Wextra] rtiNotification(rtiNOTIFICATION_COMPARE0); ^ 4 warnings generated. Finished building: "../source/rti.c"
该警告建议为安全起见,应 将名为 rtiNotification()的函数标记为中断函数。 但是、在尝试使用 include/rti.h 中的以下内容时、程序不再正常运行:
/* USER CODE BEGIN (6) */ void rtiNotification(uint32 notification) __attribute((interrupt)); /* USER CODE END */
[引用]为 Arm Cortex-R 处理器进行编译时、编译器将生成代码以保留通用寄存器、并生成一系列指令以影响处理器的适当异常返回[/引用]
发生这种情况时 ,rtiCompare0Interr()和 rtiNotification()都被标记为中断函数:
a. rtiCompare0Interrupt() 是从 IRQ 中调用的。
b. rtiCompare0Interr()被称为 rtiNotification()。
c.当 rtiNotification()尝试返回时,由于已被标记为中断,编译器生成的结束尝试执行异常返回时,重新输入函数,然后处理器将其全部时间都用在 rtiNotification()函数中。
对于 TI ARM Clang v1.3.0编译器、当调用具有未知副作用的函数时、调用其他函数以保留 VFP 寄存器的中断处理程序的正确方法是什么?
当 从 ARM 上的中断调用非中断函数时、我发现警告 、这似乎是 在 LLVM 中添加了"调用不带中断属性的函数可能是 clobber interree 的 VFP 寄存器"警告时、 但是 、如果中断函数调用其他函数、获得与 TI ARM v20.2.5相同的行为并保留 VFP 寄存器(出于安全考虑)的正确方法是什么?
此外、 "call to function without interrupt attribute can clobber interruptee 的 VFP 寄存器"的文本会引起一些误解、因为向被调用函数添加中断属性会破坏代码。
在 有关 pragma 和属性的 tiarmclang 文档中 ,它声明...
tiarmclang 编译器不会生成代码以在标有 中断 属性的函数中保留 FPU 寄存器。 如果在中断范围内需要浮点运算、则必须手动保留 FPU 寄存器。
谢谢、此致、
乔治