c - 这个 sfrw(x,x_) 宏如何工作(msp430)?

标签 c gcc macros interrupt msp430

我刚刚在 msp430f5529(TI launchpad)上遇到了一个有趣的现象。在尝试了不同的方法之后,我找到了解决方案,但我不明白这里发生了什么。

此代码是定时器中断服务例程 (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_);
  1. 第 5 行第一个宏的这一部分有什么作用?

    asm("__"#x)

  2. 为什么第 5 行宏的右侧没有“x_”?

  3. 最后一个也是最重要的问题:为什么第 4 行的常规类型转换可以按预期工作,而第 3 行的类型转换却不能?

顺便说一句,我使用 gcc-4.7.0。

<小时/>

编辑:更多信息

9    #define __MSPGCC_PERIPHERAL__ __attribute__((__d16__))

最佳答案

1) # 是预处理器“字符串化”运算符。您可以使用 -E 编译器开关查看其影响。谷歌“c stringify”了解详细信息。

2) 不能说。并不是要求所有参数都被使用,而且显然无论谁写了这个都决定他们不需要它。

3)我会尝试一下这个,但由于我没有所有源代码或硬件并且无法进行实验,所以我可能不会完全正确。也许足够接近您所需要的。

首先要了解 asm 位的作用。通常(好吧,有时)当您声明变量(foo)时,编译器会为该变量分配自己的“内部”名称(即_foo)。然而,当与 asm 模块(或其他语言)交互时,有时您需要能够指定要使用的确切名称,不允许编译器以任何方式破坏它。这就是这个 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。

关于c - 这个 sfrw(x,x_) 宏如何工作(msp430)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24066842/

相关文章:

c - 对 timeval 成员使用 unsigned long 有好处吗?

计算 GFP 载荷 FCS

c - 带限制指针的 GCC 别名检查

c - 从内联汇编调用函数时针对符号重定位 R_X86_64_PC32

perl - 如何检查 Mac 操作系统是 32 位还是 64 位?

C 库与编译器一起分发还是直接由操作系统分发?

c++ - Vista 窗口标题中的图片(标识)

c - 在 gcc 中如何计算逻辑表达式 2 > -3

c++ - 组合预处理器宏和变量

c - 全局变量、可重入代码和线程安全