我正在使用Microchip的示例nvmem.c文件功能将数据写入PIC32微控制器的特定存储器地址。当我尝试使用它时,显示以下MISRA错误:我只是在出现错误的地方发布了示例代码。我的整个代码已编译并且可以正常工作。
1]在NVMemWriteWord((void )APP_FLASH_MARK_ADDRESS,(UINT)_usermark);
处从“ unsigned int”显式转换为“ void ” [MISRA 2012规则11.6,必需]
如何解决此错误?
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);
答案 0 :(得分:2)
使用
uint8_t NVMemWriteWord(unsigned int address, uint32_t data)
{
uint8_t res;
NVMADDR = KVA_TO_PA(address);
NVMDATA = data;
res = NVMemOperation(NVMOP_WORD_PGM);
}
和
#define ADDRESS 0x9D007FF0U
NVMemWriteWord(ADDRESS,(uint32_t)_usermark);
相反。从功能上讲,它与示例完全等效,只是避免了将void指针强制转换为无符号整数地址。
答案 1 :(得分:1)
建议:
#define ADDRESS (volatile uint32_t*)0x9D007FF0U
NVMemWriteWord( ADDRESS, _usermark) ;
从不强制转换为void*
-void*
的目的是您可以安全地为其分配任何其他指针类型,而无需显式强制转换。 _usermark
的强制转换可能有必要,也可能没有必要,但应避免不必要的显式强制转换-它们可以抑制重要的编译器警告。您应该按照以下优先顺序进行类型转换:
在这种情况下,由于NVMemWriteWord
仅将address
强制转换为整数,因此使用void*
可能不合适。如果在其他情况下实际上正在使用指针,则它可能是有效的。
答案 2 :(得分:0)
关于指针转换的整个MISRA-C:2012第12章都相当挑剔。没错,因为这是非常危险的领域。
11.6是一个健全的规则,禁止从整数到void*
的转换。基本原理是阻止对齐错误。无论如何,没有太多理由要进行此类转换。
值得注意的是,还有两个严格但建议性的规则11.4禁止从整数到指针的转换,而规则11.5则完全禁止使用void*
。不可能进行与硬件相关的编程并遵循11.4,因此必须忽略该规则。但是您没有理由使用void*
。
在此特定类型的转换中,您可以通过使用uint32_t
并完全避免使用指针来摆脱困境。
在寄存器访问的一般情况下,您必须使用volatile
限定指针(volatile uint32_t*)ADDRESS
进行转换,假设MCU使用32位寄存器。