【问题标题】:How do most embedded C compilers define symbols for memory mapped I/O?大多数嵌入式 C 编译器如何为内存映射 I/O 定义符号?
【发布时间】:2015-02-14 04:27:36
【问题描述】:

我经常像这样写入内存映射的 I/O 引脚

P3OUT |= BIT1;

我假设 P3OUT 被我的预处理器替换为类似的东西:

*((unsigned short *) 0x0222u)

但我今天挖了一个 H 文件并看到了以下内容:

 volatile unsigned short P3OUT @ 0x0222u;

在此之前还有一些扩展正在进行,但通常是这样。正在使用符号“@”。除此之外,还有一些关于使用 C 语言扩展集的#pragma。我假设这是对链接器的某种指令,并且实际上一个符号被定义为位于内存映射中的那个位置。

对于大多数编译器大多数发生的事情,我的假设是否正确?一种方式或另一种方式重要吗? @ 符号是从哪里来的,是某种标准吗?

我正在使用 IAR Embedded 工作台。

这个问题和这个问题类似:How to place a variable at a given absolute address in memory (with GCC)。 它符合我认为我的编译器正在做的事情。

【问题讨论】:

标签: c macros c-preprocessor c99


【解决方案1】:

标题中问题的简短回答是“不同”。更糟糕的是,针对同一目标处理器的不同供应商的编译器将使用不同的方法。这个

volatile unsigned short P3OUT @ 0x0222u;

是将变量放置在固定地址的常用方法。但是您还会看到它用于识别内存映射位置中的各个位 = 特别是对于具有位宽指令(如 PIC 系列)的微控制器。

这些是 C 标准没有解决的问题,恕我直言,因为小型嵌入式微控制器最终将成为 C 的主要市场(是的,我知道内核是用 C 编写的,但是很多用户-空间的东西正在转向 C++)。

我实际上加入了 C 委员会,试图推动这一领域的变革,但我的赞助消失了,而且这是一个非常昂贵的爱好。

类似的领域是将函数声明为 ISR。

This document 展示了我们考虑的一种方法

【讨论】:

  • 恕我直言,C 作为嵌入式语言存在一些主要缺陷,我一直希望标准委员会能够改进它或开发更好的东西;有兴趣聊这些吗?
  • 是的,但我负担不起每年自费旅行两周。委员会已经意识到这个问题,我希望它最终会得到解决
  • 知道 C 是否会定义真正可移植的整数类型或位域吗?例如,我希望看到 wrap32_t 的行为类似于 uint32_t except,它将免于任何与 int-size 相关的促销活动;即使在 int 为 64 位的系统上,两个 wrap32_t 值的乘积或 wrap32_t 和有符号值的总和也会是 wrap32_t
  • 这听起来像是对促销规则的根本性改变。委员会很保守(小c)
  • 正如我希望实现的那样,对现有整数类型的所有操作将继续像往常一样运行。只有新类型的行为会有所不同。正如我所看到的,现有规则已经发展,因为希望避免要求实现以破坏预先存在的代码的方式进行更改。如果新类型使用当前指定为“保留”的名称定义并且未被任何现有实现使用,则要求这些新类型使用新规则不会迫使实现以破坏现有代码的方式行事......
【解决方案2】:

尽管像(unsigned char *)0x1234 这样的表达式在许多编译器上会产生一个指向硬件地址0x1234 的指针,但标准中的任何内容都不需要转换为指针的整数与结果地址之间的任何特定关系。该标准唯一规定的是,如果一个特定的整数类型至少与intptr_t 一样大,并且将指针转换为该特定类型会产生一些值,那么将该特定值转换回原始指针类型将产生一个指针等价于原来的。

IAR 编译器提供了一个非标准扩展,允许编译器请求将变量放置在指定的硬编码地址。与使用宏创建指针表达式相比,这提供了一些优势。一方面,它确保这些变量在语法上被视为变量;虽然在合法代码中使用指针组合表达式时通常会被正确解释,但非法代码可能会因编译时错误而编译失败,但会产生与预期效果不同的东西。此外,IAR 语法定义了链接器可用的符号,因此可以在汇编语言模块中使用。相比之下,定义指针组合宏的 .H 文件将无法在汇编语言模块中使用;将在 C 和汇编代码中使用的任何硬件都需要在两个不同的地方指定其地址。

【讨论】:

  • 这是一个非常好的观点 W.R.T.能够从程序集中访问符号。
  • 实际上,对于小型 micros,汇编器和编译器通常是紧密耦合的,并且汇编器通常可以“使用”C 头文件(至少对于预处理器宏而言)
  • @kdopen:汇编器和编译器非常紧密地耦合在一起,许多汇编器使用 C 风格的预处理器,但我认为我没有见过可以使用 C 风格的语法进行转换的汇编器指向指针的整数。
猜你喜欢
  • 2016-05-27
  • 2017-06-08
  • 2011-12-15
  • 2017-05-17
  • 1970-01-01
  • 2011-01-19
  • 1970-01-01
  • 1970-01-01
  • 2016-11-16
相关资源
最近更新 更多