嵌入式c或嵌入式c ++中是否有“ @”运算符?如果是,请向我解释以下代码?

时间:2018-10-11 06:06:40

标签: c embedded pic hi-tech-c

代码:

static volatile unsigned char   TMR0    @ 0x01;

static volatile unsigned char   PORTA   @ 0x05;

static volatile unsigned char   PORTB   @ 0x06;

static volatile unsigned char   PORTC   @ 0x07;

此代码来自PIC16F877A的HT-PICC编译器pic.h库文件

我了解static volatile和其他关键字的含义。 这里的Timer0寄存器地址为0x01,但是为什么要在其前面使用@?它与指针有关吗?

3 个答案:

答案 0 :(得分:6)

它是许多嵌入式编译器中常见的编译器扩展,可让您将变量放在绝对内存地址中。

摘自HI-TECH C编译器手册:

  

3.5.4绝对变量

     

大多数变量可以通过以下声明在绝对地址中:   构造   @ address ,其中 address 是内存中要放置变量的位置。这样的变量称为绝对变量。

     

3.5.4.1   数据存储器中的绝对变量

     

绝对变量主要用于将C标识符的地址与   一个特殊的功能寄存器,但可用于将普通变量置于绝对位置   数据存储器中的地址。

在您的示例中:

static volatile unsigned char   TMR0    @ 0x01;

TMR0大概是8位无符号硬件寄存器,位于地址0x01。

答案 1 :(得分:4)

它是位于特定存储位置(@)处的变量。因此,在地址TMR0处有一个8位变量0x01。在PIC的Hi-Tech C编译器手册中,请参阅第3.4.4节“指针类型”以获取更多信息。

在香草C中,等效值为:

static volatile unsigned char * TMR0 = (volatile unsigned char *) 0x01;

@运算符用于内存非常低的体系结构,以帮助减少内存占用。

答案 2 :(得分:2)

这是用于在特定地址分配变量的常见非标准符号。在您的情况下,它用于将硬件寄存器映射到C变量。

具体地说,@的目的是允许链接程序/调试器将寄存器当作对象使用。这意味着您可以像在任何其他变量中一样,在调试器中为其添加监视或读写断点。

否则,如果不需要在调试器中查看这些内容,则可以使用标准的C语言:

#define TMR0 (*(volatile uint8_t*)0x01u)

当然,不需要为硬件寄存器分配空间,因为无论C程序做什么,它们已经存在于硬件中。

好的调试器带有MCU支持,并且可以选择在单独的窗口中查看MCU特定的寄存器。因此,将@用于寄存器/寄存器映射的主要原因是因为工具链附带了糟糕的调试器。不幸的是,这是我对嵌入式工具链的经验:调试器越差,编译器提供的寄存器映射就越混乱。

但是@符号也可以用于声明特定位置的RAM / ROM变量。其他编译器的其他非标准扩展使用各种#pragma___declspec(section...__attribute__(section...。如果存在标准方法,那会很好,但可惜没有。