【发布时间】:2021-11-28 08:05:45
【问题描述】:
我知道用 GCC 声明内存映射寄存器的主要方法有两种(有很多变体,使用双域,每个外围设备的数据结构等...):
- 要么使用指向正确地址的指针,如
volatile uint32_t *pMyRegister = (uint32_t *)0xDEADBEEFUL; - 或者定义一个变量并像
volatile uint32_t MyRegister __attribute((section(".register_section")));一样手动映射它,然后映射LD文件中的部分。
不幸的是,这些方式似乎都不符合 MISRA-C 编码规则,第一种方式是因为存在未经授权(由 MISRA)从整数到指针的强制转换,第二种方式是因为属性关键字。
我的问题是:有没有办法(使用第二种解决方案)在不影响代码的 ANSI 特性的情况下映射节中的变量(即没有编译器特定的关键字)。
谢谢
【问题讨论】:
-
注意:有时您可能会编写直接与硬件交互的代码(或低级特定细节):如果您可以证明 MISRA-C 允许您违反某些规则(称为偏差)必须在非常具体的情况下打破规则,以允许低级别的交互。 MISRA 无法验证低级别的特定事物,因为它更像是一组“通用”规则。 See also this SO question.
-
您使用的是哪个 MISRA-C 版本?
-
@LucaPolito MISRA-C 可以而且应该绝对验证低级别的东西,它在源代码上作为整体使用。对于内联汇编等它肯定无法验证的东西,对于如何处理这些代码也有特殊的规则。
-
@Lundin 是的,你是对的。我并不是说 MISRA-C 不能用于验证低级程序,我只是说它不能验证特定于低级的方面,例如地址
0xABCD是一个有效的硬件地址。 MISRA-C 与平台无关。当你有低级程序时必须特别小心,因为 MISRA-C 通常需要对这类事情进行人工验证(例如合理地偏离规则)。