我有一个裸机程序(驱动程序),它读/写一些内存映射寄存器。 e.g:
void foo_read(uint64_t reg_base, uint32_t *out_value)
{
*out = READREG(reg_base + FOO_REG_OFFSET);
}
#define FOO_REG_OFFSET
0x00000123
)的偏移量。注册" foo"是32位"宽"。READREG的定义如下:
#define READREG(address) (*(uint32_t*)(address))
你可以猜测MISRA 2008对于从无符号长指针到指针的演员表示不满意(报道为5-2-7 / 5-2-8)。我的问题是:访问内存和摆脱MISRA警告的最佳/适当方式是什么?我已经尝试在转换为指针之前强制转换为uintptr_t,但This didn't help。
谢谢。
答案 0 :(得分:1)
在这里确定一些事项 - 首先,您对READ_REG
的定义缺少volatile
- 它应该类似于
#define READREG(address) (*(uint32_t volatile *)(address))
其次 - 这当然是CPU特定的 - 一般来说,从奇数地址(偏移量0x123)读取32位值不会起作用 - 至少它会很慢(多个总线周期)在许多架构上,您将遇到处理器异常。 (顺便说一句,请注意,指针算术不会在这里发挥作用,因为在投射到指针之前会添加2个值。)
回答你原来的问题:
访问内存和摆脱MISRA的最佳/适当方式是什么? 警告
嗯 - 你 违反了MISRA规则(在这种情况下,我们必须在那里......)所以你会得到警告。
因此,您需要做的是以严谨,系统和易于识别的方式抑制警告。在我看来,没有比Quantum Platform(QP)事件驱动框架的代码更好的例子和解释,它是开源的。具体做法是:
Q_UINT2PTR_CAST
宏6.3规则5-2-8(req)
具有整数类型或指向void类型的指针的对象不应该是 转换为具有指针类型的对象。
QP / C ++应用程序可能会在需要时偏离规则5-2-8 直接访问特定的硬编码硬件地址。 QP / C ++ 框架将此偏差封装在宏
Q_UINT2PTR_CAST()
中。 以下代码段提供了此宏的用例:#define QK_ISR_EXIT() . . . \
*Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = \
我没有时间谈论MISRA警告抑制,合规性问题等,但上述内容为您提供了所需的一切。
P.S。不确定你指的是哪种MISRA指南 - 对于C,有2004和& 2012年指南,对于C ++,有2008年的指导方针(我知道,它差不多是2017年!)