Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/tfs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 这个sfrw(x,x_u)宏是如何工作的(msp430)?_C_Gcc_Macros_Interrupt_Msp430 - Fatal编程技术网

C 这个sfrw(x,x_u)宏是如何工作的(msp430)?

C 这个sfrw(x,x_u)宏是如何工作的(msp430)?,c,gcc,macros,interrupt,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 *) TA

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

    asm(“x”)

  • 为什么在第5行的宏的右侧没有“x_”

  • 最后一个也是最重要的问题:为什么第4行上通常的类型转换工作如预期的那样,而第3行上的却没有

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


    编辑:更多信息 1) #是一个预处理器“stringify”操作符。您可以使用-E编译器开关来查看此操作的影响。谷歌“c stringify”获取详细信息

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

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

    首先要了解的是asm位在做什么。通常(好的,有时)当您声明一个变量(foo)时,编译器会为该变量(ie\u foo)指定自己的“内部”名称。但是,在与asm模块(或其他语言)接口时,有时需要能够指定要使用的确切名称,而不允许编译器以任何方式破坏它。这就是这个asm所做的(请参阅)。因此,当你撇开所有“定义”的废话时,你得到的是:

    extern volatile __MSPGCC_PERIPHERAL__ unsigned int TA0IV __asm__("__TA0IV");
    
    由于您发布的定义是“extern”,可能在某个地方(未显示),因此有一个名为uu TA0IV的符号正在被定义。而且,由于访问它的工作不正常,它似乎被错误地定义了

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

    #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是在汇编代码中定义的。那么问题是,为什么您的代码找不到相同的(工作)符号?缺少依赖关系?
    #define TA0IV_                0x036E
    
    inline int ReadInterruptNumber()
    {
       int retval;
       asm volatile("movl (%c1), %0": "=rm" (retval) : "i" (TA0IV_));
       return retval;
    }