我刚用msp430f5529(TI启动板)遇到了一个有趣的现象。在尝试了不同的方法后,我找到了解决方案,但我不明白这里发生了什么。
此代码是定时器中断服务程序(ISR)的一部分。特殊功能寄存器(SFR) TA0IV 应该保存触发ISR的中断号的值。
1 unsigned int index;
2
3 index = TA0IV; // Gives wrong value: 19874
4 index = *((volatile unsigned int *) TA0IV_); // Correct value: 4
TA0IV在这里用宏定义:
5 #define sfrw_(x,x_) volatile __MSPGCC_PERIPHERAL__ unsigned int x __asm__("__" #x)
6 #define sfrw(x,x_) extern sfrw_(x,x_)
7 #define TA0IV_ 0x036E /* Timer0_A5 Interrupt Vector Word */
8 sfrw(TA0IV, TA0IV_);
第5行第一个宏的这一部分是做什么的?
asm (" __" #x)
为什么没有" x _"在第5行宏观的右侧?
最后也是最重要的问题:为什么第4行的常规类型转换按预期工作,但第3行的类型转换没有?
BTW我使用的是gcc-4.7.0。
9 #define __MSPGCC_PERIPHERAL__ __attribute__((__d16__))
答案 0 :(得分:0)
1)#是预处理器" stringify"运营商。您可以使用-E编译器开关查看其影响。 Google" c stringify"详情。
2)无法说出来。所有参数都没有被使用,显然无论谁写这个都决定了他们并不需要它。
3)我会对这一个进行拍摄,但由于我没有所有的源代码或硬件并且无法进行实验,我可能无法获得它完全正确。也许足够接近你需要的东西。
首先要了解的是asm位正在做什么。通常(好的,有时)当你声明一个变量(foo)时,编译器会分配它自己的内部'变量的名称(即_foo)。但是,当与asm模块(或其他语言)连接时,有时您需要能够指定要使用的确切名称,而不允许编译器以任何方式对其进行修改。这就是这个主题的作用(见Asm Labels)。因此,当你把所有#define废话都放在一边时,你得到的是:
extern volatile __MSPGCC_PERIPHERAL__ unsigned int TA0IV __asm__("__TA0IV");
由于您发布的定义是" extern,"大概是某处(未示出),有一个名为__TA0IV的符号被定义。并且由于访问它并不正常,它似乎正在进行MIS定义。
有了我已经做过的警告,我觉得这更具可读性:
#define TA0IV_ 0x036E
inline int ReadInterruptNumber()
{
int retval;
asm volatile("movl (%c1), %0": "=rm" (retval) : "i" (TA0IV_));
return retval;
}
FWIW。