【问题标题】:How does this sfrw(x,x_) macro work (msp430)?这个 sfrw(x,x_) 宏是如何工作的 (msp430)?
【发布时间】:2014-06-05 17:50:14
【问题描述】:

我刚刚在使用 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. 为什么第 5 行宏的右侧没有“x_”?

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

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


编辑:更多信息

9    #define __MSPGCC_PERIPHERAL__ __attribute__((__d16__))

【问题讨论】:

    标签: c gcc macros interrupt msp430


    【解决方案1】:

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

    2) 不能说。 要求使用所有参数,显然写这篇文章的人认为他们不需要它。

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

    首先要了解的是 asm 位在做什么。通常(好的,有时)当你声明一个变量(foo)时,编译器将它自己的“内部”名称分配给变量(即_foo)。但是,当与 asm 模块(或其他语言)交互时,有时您需要能够指定要使用的确切名称,不允许编译器以任何方式对其进行修改。这就是这个 asm 正在做的事情(参见 Asm Labels)。所以当你抛开所有#define 废话时,你得到的是:

    extern volatile __MSPGCC_PERIPHERAL__ unsigned int TA0IV __asm__("__TA0IV");
    

    由于您发布的定义是“外部”,大概在某处(未显示),因此有一个名为 __TA0IV 的符号正在被定义。而且由于访问它不能正常工作,它似乎正在被 MIS 定义。

    需要注意的是,我还没有尝试过,我会发现这更具可读性:

    #define TA0IV_                0x036E
    
    inline int ReadInterruptNumber()
    {
       int retval;
       asm volatile("movl (%c1), %0": "=rm" (retval) : "i" (TA0IV_));
       return retval;
    }
    

    FWIW。

    【讨论】:

    • 2) 宏的第二个值保存特殊功能寄存器的实际地址(0x036E),肯定不会被忽略。这些 sfrw 宏几乎被用于每个 SFR,并且在大多数情况下它们按预期工作(另请参阅我的原始帖子的编辑)。
    • 正如您自己观察到的,x_“没有出现在右侧。”您可以通过使用 -E 编译来检查自己。我只是在输出中看不到任何“0x036E”。 MSGPCC 显然只是影响变量的长度。由于这在其他地方有效,这表明在其他地方与 __TA0IV 的正确定义有关。正如我所提到的,上面的代码将其定义为“extern”。鉴于此代码使用“asm”来创建符号名称,这表明 extern 是在汇编代码中定义的。那么问题是为什么您的代码没有找到相同的(工作)符号?缺少依赖项?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 2022-11-24
    • 2013-12-22
    相关资源
    最近更新 更多