在C中使用@进行变量声明


11

我正在阅读一些C代码,并在程序中遇到此声明:

unsigned char serv_ctr @0x0002;

有人可以指出我的文档,还是解释Mplab XC8 v1.35 C编译器中的“ @ 0x0002”


14
我想这是将变量放置在特定地址的编译器扩展。
尤金(Eugene Sh)。

2
这个问题可能会使#mplab标签受益,因为事实证明这是Mplab特定的。
sylvainulg

只是为了得到它:这是本网站的主题吗?我认为这属于SO。还是可以在这里请求微控制器编程。这将使这个问题在哪里变得不清楚。
再见SE

6
@KamiKaze 我在这里可以问什么话题?主题列出“为裸机或RTOS应用程序编写固件”,主题列出为“ PC编程软件”。由于这似乎与嵌入式系统编程有关,因此一看便会成为话题。它可能可以对堆栈溢出主题不自行使其题外话这里。
的CVn

@KamiKaze感谢您的提问,我有类似的问题(我不是该SE的普通用户)
GPPK,

Answers:


20

这是为了指定一个绝对地址来放置变量。
XC8编译器手册第27页的2.5.2节“绝对寻址”中

可以使用以下__at()结构将变量和函数放置在绝对地址中
……
2.5.2.2差异
8位编译器已使用@符号指定绝对地址。


6

@是C语言的常见非标准扩展,它使您可以在特定地址声明变量。它可以用于内存映射的硬件寄存器等。在这种情况下,还必须声明变量volatile,因此您的示例不正确。

其他编译器使用诸如__attribute__(section...或之类的东西#pragma ...,它们全都是非标准C语言。

工具链这样做的唯一合理原因(如果有的话)是在糟糕的调试器上启用寄存器调试。非标准语法将确保寄存器成为链接器输出和调试信息的一部分。继而可以让您在糟糕的调试器中监视寄存器,就像您可以监视任何其他变量一样。

如果您有一个好的调试器,它将为您的特定MCU提供支持和了解。然后,您不需要在C代码中使用非标准的废话,而是可以编写纯的,可移植的标准C:

#define serv_ctr ( *(volatile uint8_t*)0x0002u )

1
尽管要求编译器接受后一种形式,但允许实现以其认为合适的任何方式将数字映射到地址。此外,我见过的大多数编译器都使用@具有多个内存空间或其他问题的符号目标平台,因此,大多数使用@符号声明的事物的行为都将与没有扩展的情况有所不同。
supercat

1

简短扩展:

从xc8 2.0起,此功能不再起作用。您现在必须编写:

unsigned char serv_ctr __at(0x0002);

将变量(serv_ctr)放在绝对地址(0x0002)上。

@如果将编译器设置设置为使用“ C90”格式,则使用XC8 2.0可以使用语法编译旧代码。该设置如下所示,位于“ XC8全局选项”下,称为“ C标准”。


但是,许多其他嵌入式系统编译器也支持@语法,而不仅是Mplab。
隆丁
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.