2.4.9.其他注意事项

2.4.9.1.原子访问

  • 对最多 32 位全局变量的写入是原子操作(int、float 等)。
  • 对大于 32 位(64 位 long double,结构)全局变量的写入,禁用/重新启用与写入相关的中断。这可确保写入器会在读取器访问整个变量之前更新该变量,并避免使变量处于不一致或不完整的状态。

列表 2.3 是来自 C2000Ware 中的数字控制库的代码片段,说明了禁用与结构更新相关的中断以确保对整个结构进行原子更新。请参阅 TMS320C28x 优化 C/C++ 编译器用户指南中的表 7-6“TMS320C28x C/C++ 编译器”,详细了解 __enable_interrupt()__disable_interrupt() 内在函数。

列表 2.3 禁用中断以确保原子结构更新
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
uint16_tval=__disable_interrupts();p->Kp=p->sps->Kp;p->Ki=p->sps->Ki;p->Kd=p->sps->Kd;p->Kr=p->sps->Kr;p->c1=p->sps->c1;p->c2=p->sps->c2;p->Umax=p->sps->Umax;p->Umin=p->sps->Umin;DCL_restoreInts(v);// If interrupts were originally enabled, re-enable themif(0U==(val&0x1))__enable_interrupts();

2.4.9.2.从 C 语言代码调用 asm 函数

从 C 语言代码调用任何 asm 函数都必须遵循 C 语言调用和寄存器规则。请参阅 TMS320C28x 优化 C/C++ 编译器用户指南中的第 7.2 节“寄存器规则”、第 7.3 节“函数结构和调用规则”和第 7.5 节“同时使用 C/C++ 与汇编语言”。

任何违反这些规则的行为都可能导致应用程序在 -Ooff 时可以运行,但在更高的优化级别下无法运行。

2.4.9.3.未经初始化的变量

  • 使用未经初始化的变量会导致未定义的行为
  • 应用程序使用未经初始化变量的行为可能会随着优化级别而改变,从而使调试变得困难
  • 局部变量
    • 使用之前必须在应用程序中显式初始化
  • 全局变量
    • C 语言标准规定,在程序开始运行之前,必须将没有显式初始化的全局 (extern) 和静态变量初始化为 0。
    • C 语言运行时初始化行为在 COFF 和 EABI 中有所不同
    • 有关详细信息,请参阅 TMS320C28x 优化 C/C++ 编译器用户指南 - 第 7.10.3 节“COFF 变量的自动初始化”和第 7.10.4 节“EABI 变量的自动初始化”。