[英]How to resolve MISRA C:2012 Rule 11.6?
I am utilizing Microchip sample nvmem.c file function to write data into particular memory address of PIC32 Microcontroller. 我正在利用Microchip的样本nvmem.c文件功能将数据写入PIC32单片机的特定存储器地址。 When I am trying to use it showing following MISRA error: I just posted sample code where I got an error.
当我尝试使用它时,显示以下MISRA错误:我只是在出现错误的地方发布了示例代码。 My whole code is compiled and working fine.
我的整个代码已编译并且可以正常工作。
1] explicit cast from 'unsigned int' to 'void ' [MISRA 2012 Rule 11.6, required] at NVMemWriteWord((void )APP_FLASH_MARK_ADDRESS,(UINT)_usermark);
1] 在NVMemWriteWord((void )APP_FLASH_MARK_ADDRESS,(UINT)_usermark)中从“ unsigned int”显式转换为“ void ” [MISRA 2012 Rule 11.6,必填] ;
How can I resolve this error? 如何解决此错误?
nvmem.c
uint8_t NVMemWriteWord(void* address, uint32_t data)
{
uint8_t res;
NVMADDR = KVA_TO_PA((uint32_t)address); //destination address to write
NVMDATA = data;
res = NVMemOperation(NVMOP_WORD_PGM);
}
test.c
#define ADDRESS 0x9D007FF0U;
NVMemWriteWord((void*)ADDRESS,(uint32_t)_usermark);
Use 采用
uint8_t NVMemWriteWord(unsigned int address, uint32_t data)
{
uint8_t res;
NVMADDR = KVA_TO_PA(address);
NVMDATA = data;
res = NVMemOperation(NVMOP_WORD_PGM);
}
and 和
#define ADDRESS 0x9D007FF0U
NVMemWriteWord(ADDRESS,(uint32_t)_usermark);
instead. 代替。 Functionally it is exactly equivalent to the example, it just avoids the cast from a void pointer to an unsigned integer address.
从功能上讲,它与示例完全等效,只是避免了将void指针强制转换为无符号整数地址。
Suggest: 建议:
#define ADDRESS (volatile uint32_t*)0x9D007FF0U
NVMemWriteWord( ADDRESS, _usermark) ;
Never cast to void*
- the purpose of void*
is that you can assign any other pointer type to it safely and without explicit cast. 决不强制转换为
void*
-目的void*
是,你可以放心地和没有明确的投任何其他指针类型分配给它。 The cast of _usermark
may or may not be necessary, but unnecessary explicit casts should be avoided - they can suppress important compiler warnings. _usermark
强制转换可能是必需的,也可以不是必需的,但应避免不必要的显式强制转换-它们可以抑制重要的编译器警告。 You should approach type conversions in the following order of preference: 您应该按照以下优先顺序进行类型转换:
In this instance since NVMemWriteWord
simply casts address
to an integer, then the use of void*
may not be appropriate. 在这种情况下,由于
NVMemWriteWord
只是将address
转换为整数,因此使用void*
可能不合适。 If in other contexts you are actually using a pointer, then it may be valid. 如果在其他情况下实际上正在使用指针,则它可能是有效的。
The whole of MISRA-C:2012 chapter 12 regarding pointer conversions is quite picky. MISRA-C:2012第12章中有关指针转换的整个内容都很挑剔。 And rightly so, since this is very dangerous territory.
没错,因为这是非常危险的领域。
11.6 is a sound rule that bans conversions from integers to void*
. 11.6是一个健全的规则,禁止从整数到
void*
转换。 The rationale is to block alignment bugs. 基本原理是阻止对齐错误。 There aren't many reasons why you would want to do such conversions anyway.
无论如何,没有太多理由要进行此类转换。
Notably, there's also two rigid but advisory rules 11.4 which bans conversions from integers to pointers, and 11.5 which pretty much bans the use of void*
entirely. 值得注意的是,还有两个严格但建议性的规则11.4禁止从整数到指针的转换,而规则11.5则完全禁止使用
void*
。 It isn't possible to do hardware-related programming and follow 11.4, so that rule has to be ignored. 不可能进行与硬件相关的编程并遵循11.4,因此必须忽略该规则。 But you have little reason to use
void*
. 但是您没有理由使用
void*
。
In this specific cast you can get away by using uint32_t
and avoiding pointers entirely. 在此特定的转换中,您可以通过使用
uint32_t
并完全避免使用指针来摆脱uint32_t
。
In the general case of register access, you must do a conversion with volatile
-qualified pointers: (volatile uint32_t*)ADDRESS
, assuming that the MCU uses 32 bit registers. 在寄存器访问的一般情况下,您必须使用
volatile
限定的指针进行转换: (volatile uint32_t*)ADDRESS
,假设MCU使用32位寄存器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.