我试图读取先前在NVM闪存上写入的变量的值。
我的代码是:
uintptr_t address = getAddress();
//[MISRA C++ Rule 5-2-8] cast from unsigned int to pointer
uint16_t value = *(reinterpret_cast<uint16_t*>(address));
问题是在MISRA中不允许从uintptr_t转换为指针。有谁知道一种访问这种记忆的方法?
我打破了MISRA的一大规则。使用动态内存(闪存的内容是动态的,因此数据的地址是可变的)。只有在您考虑声明一个指向闪存地址的const指针并在数据写入后访问它时才会导致。
如果没有打破他们的规则是什么? :)
答案 0 :(得分:1)
我看到了。我对此问题只有2个“解决方案”:
1.-不要符合MISRA标准。
2.-在动态环境中使用静态地址:
在编译时:
const Table1 table1 __attribute__ ((section (".table1space")));
const Table2 table2 __attribute__ ((section (".table2space")));
在链接描述文件中定义必需的部分。
在运行时:
为table1调用动态分配时。返回静态table1地址,依此类推。
答案 1 :(得分:1)
MISRA C ++(必需),规则5-2-8试图阻止您执行操作,从而导致不确定的行为。等效的MISRA C:2012准则是(咨询)规则11.4
并且通常不希望将整数转换为指针,因为存在许多可能的问题,尤其是与对齐有关。
MISRA C准则有一些额外的叙述
在可能的情况下,应避免在指针和整数类型之间进行转换,但在寻址存储器映射的寄存器或其他特定于硬件的功能时可能有必要。
用于解决此问题的 正确 方法是提高偏差。这说明了您需要这样做的原因 为什么 ,但也使您 考虑 后果,以及< strong> 显示 表明您正在缓解它们。
答案 2 :(得分:0)
如果getAddress()
返回一个实际上应该像指针一样使用的整数类型,那么我们假设它是2字节对齐的,因为你的数据是uint16_t
:
uintptr_t offset = getAddress();
assert(offset % sizeof(uint16_t) == 0);
uint16_t* address = 0;
address += offset / sizeof(uint16_t);
uint16_t value = *address;
答案 3 :(得分:0)
延伸@ IvanPajuelo的答案(我提议的编辑似乎已被拒绝) - 实际上有三个选项,而不仅仅是@IvanPajuelo指定的两个选项:
指南文档解释了通过偏差解除规则的机制,这是偏差当然有效的情况之一。
这么多,正在进行的工作是记录一些标准的批准偏差 - 其中就是其中之一(本文件中的分类R6)!!
http://www.misra.org.uk/forum/viewtopic.php?f=54&t=1253 http://www.misra.org.uk/forum/download/file.php?id=627
(您可能需要登录公告牌才能访问下载)