1

我正在尝试读取以前在 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 指针并在写入数据后访问它时才会导致。

如果不打破它们,规则是什么?:)

4

4 回答 4

1

照我看来。我对这个问题只有两个“解决方案”:

1.- 不要符合 MISRA。

2.- 在动态环境中使用静态地址:

在编译时:

const Table1 table1 __attribute__ ((section (".table1space")));
const Table2 table2 __attribute__ ((section (".table2space")));

在链接描述文件中定义所需的部分。

在运行时:

为 table1 调用动态分配时。返回静态 table1 地址,依此类推。

于 2014-09-08T11:39:17.917 回答
1

MISRA C++(必需)规则 5-2-8 试图阻止您做导致未指定行为的事情。等效的 MISRA C:2012 指南是(咨询)规则 11.4

通常将整数转换为指针是不可取的,因为存在各种可能的问题,尤其是与对齐有关。

MISRA C 指南有一些额外的叙述

应尽可能避免在指针和整数类型之间进行转换,但在寻址内存映射寄存器或其他硬件特定功能时可能需要。

处理这个问题的正确方法是提出偏差。这记录了您需要这样做的原因,但也让您考虑后果,并表明您正在减轻它们。

于 2019-09-25T08:26:06.793 回答
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;
于 2014-09-08T09:04:11.833 回答
0

扩展@IvanPajuelo 的答案(我提议的编辑似乎已被拒绝) - 实际上有三个选项,而不仅仅是@IvanPajuelo 指定的两个:

  1. 不要符合 MISRA
  2. 捏造东西以“关闭检查器”
  3. 偏离

指南文档解释了通过偏差取消应用规则的机制,这是偏差肯定有效的情况之一。

如此之多,记录一些标准批准偏差的工作正在进行中 - 这是其中之一(本文档中的分类 R6)!

http://www.misra.org.uk/forum/viewtopic.php?f=54&t=1253 http://www.misra.org.uk/forum/download/file.php?id=627

(您可能需要登录公告板才能访问下载)

于 2014-11-10T20:59:51.137 回答