我有一个裸机程序(驱动程序),它读/写一些内存映射寄存器。
例如:

void foo_read(uint64_t reg_base, uint32_t *out_value)
{
    *out = READREG(reg_base + FOO_REG_OFFSET);
}

reg_base是内存映射设备的基址(64位
地址)
FOO_REG_OFFSET是寄存器的偏移量(#define FOO_REG_OFFSET0x00000123)寄存器“foo”是32位“wide”。
READREG的定义如下:
#define READREG(address)    (*(uint32_t*)(address))

你可以猜到Misra2008对无符号long long到pointer的转换不满意(报告了5-2-7/5-2-8)我的问题是:什么是访问内存和消除MISRA警告的最佳/合适的方法在转换为指针之前,我曾尝试转换为uintptr,但是This didn't help
谢谢您。

最佳答案

好的,这里有几点-首先,您对READ_REG的定义缺少一个volatile——应该是

#define READREG(address)    (*(uint32_t volatile *)(address))

其次——这当然是CPU特有的——一般来说,从奇数地址(偏移量0x123)读取32位的值是行不通的——至少它会很慢(多个总线周期),在许多体系结构中,您会遇到处理器异常(顺便说一下,请注意,指针算术在这里不起作用,因为这两个值是在转换为指针之前添加的。)
回答你原来的问题:
访问内存和摆脱MISRA的最佳/适当方法是什么
警告
好吧——你违反了米斯拉的规定(在这种情况下,你必须这么做,我们都去过……)所以你会得到警告。
所以你需要做的是以一种有纪律的、系统的和容易识别的方式来抑制警告在我看来,没有比Quantum Platform(QP)事件驱动框架(Event driven framework)的代码更好的例子和解释了这一点,它是开源的明确地:
查看QP's MISRA Compliance矩阵以获取如何处理该问题的示例——例如,只需在PDF中搜索Q_UINT2PTR_CAST
查看QP的实际源代码,例如macro that wraps/encapsulates such "int to ptr" casts(这样做的方式很容易识别,并且很容易在一个地方更改/取消警告)
最后,查看PC Lint配置文件qpc.lnt,在这里您可以看到如何/在哪里在一个地方抑制警告这在this app note第6.3节中有解释:
6.3规则5-2-8(要求)
具有整数类型或指向void类型的指针的对象不应是
已转换为指针类型的对象。
QP/C++应用程序在需要时可能偏离规则5-2-8。
直接访问特定的硬编码硬件地址QP/C++
framework将这种偏差封装在宏Q_UINT2PTR_CAST()中。
以下代码段提供了此宏的用例:
#define QK_ISR_EXIT() . . . \
*Q_UINT2PTR_CAST(uint32_t, 0xE000ED04U) = \
我没有时间谈论米斯拉警告请求、合规性问题等,但上面给了你所需要的一切。
P.S.不确定你所指的MISRA指南——对于C,有2004和2012的指导方针,对于C++,有2008条准则(我知道,它几乎是2017)!

关于c - 处理内存访问时避免将整数转换为指针的最佳方法(MISRA 2008),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40307281/

10-13 00:06