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

时间:2014-06-05 17:50:14

标签: c gcc macros interrupt msp430

我刚用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_);
  1. 第5行第一个宏的这一部分是做什么的?

    asm (" __" #x)

  2. 为什么没有" x _"在第5行宏观的右侧?

  3. 最后也是最重要的问题:为什么第4行的常规类型转换按预期工作,但第3行的类型转换没有?

  4. BTW我使用的是gcc-4.7.0。


    编辑:更多信息

    9    #define __MSPGCC_PERIPHERAL__ __attribute__((__d16__))
    

1 个答案:

答案 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。