Reading a value from raw memory (MISRA compliant)

落花浮王杯 提交于 2019-12-13 01:23:44

问题


I'm trying to read the value of a variable previously write on NVM flash.

My code is:

uintptr_t address = getAddress();
//[MISRA C++ Rule 5-2-8] cast from unsigned int to pointer
uint16_t value = *(reinterpret_cast<uint16_t*>(address)); 

The problem is the cast from uintptr_t to pointer is not allowed in MISRA. Do anyone knows a way to access this memory?

I'm breaking one of the big rules of MISRA. Using dynamic memory (the contents of flash is dynamic so the address of data is variable). Only cause if you're thinking of declare a const pointer to the flash address and access it after the data is write.

What are the rules for if not for break them? :)


回答1:


As I see it. I only have 2 "solutions" to the problem:

1.- Don't be MISRA compliant.

2.- Use static addresses on a dynamic environment:

At compile time:

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

Define the required sections on linker script.

At runtime:

When dynamic allocation is called for table1. Static table1 address is returned and so on.




回答2:


MISRA C++ (Required) Rule 5-2-8 is attempting to stop you doing things, which lead to unspecified behaviour. The equivalent MISRA C:2012 guideline is (Advisory) Rule 11.4

And in general converting an integer to a pointer is undesirable, as there are a variety of possible problems, not least to do with alignment.

The MISRA C guideline has some extra narrative

Casting between a pointer and an integer type should be avoided where possible, but may be necessary when addressing memory mapped registers or other hardware specific features.

The correct method for dealing with this is to raise a deviation. This documents the reason why you need to do it, but also makes you consider the consequences, and to show that you are mitigating them.




回答3:


If getAddress() returns an integral type which is actually supposed to be used like a pointer, let's assume it's 2-byte aligned since your datum is 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;



回答4:


Extending on @IvanPajuelo's answer (my proposed edit seems to have been rejected) - there are in fact THREE options, not just the two specified by @IvanPajuelo:

  1. Don't be MISRA compliant
  2. Fudge things to "shut up the checker"
  3. Deviate

The Guidelines document explains the mechanism for dis-applying a rule via a Deviation, and this is one of those situations that a Deviation is certainly valid.

So much so, that work is ongoing on documenting some standard Approved Deviations - of which this is one of them (classification R6 in this document)!!

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

(You may need to be Logged In to the Bulletin Board to access the download)



来源:https://stackoverflow.com/questions/25720358/reading-a-value-from-raw-memory-misra-compliant

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!