繁体   English   中英

如何解决MISRA C:2012规则11.6?

[英]How to resolve MISRA C:2012 Rule 11.6?

我正在利用Microchip的样本nvmem.c文件功能将数据写入PIC32单片机的特定存储器地址。 当我尝试使用它时,显示以下MISRA错误:我只是在出现错误的地方发布了示例代码。 我的整个代码已编译并且可以正常工作。

1] 在NVMemWriteWord((void )APP_FLASH_MARK_ADDRESS,(UINT)_usermark)中从“ unsigned int”显式转换为“ void ” [MISRA 2012 Rule 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);

采用

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指针强制转换为无符号整数地址。

建议:

#define ADDRESS (volatile uint32_t*)0x9D007FF0U
NVMemWriteWord( ADDRESS, _usermark) ;

决不强制转换为void* -目的void*是,你可以放心地和没有明确的投任何其他指针类型分配给它。 _usermark强制转换可能是必需的,也可以不是必需的,但应避免不必要的显式强制转换-它们可以抑制重要的编译器警告。 您应该按照以下优先顺序进行类型转换:

  • 类型协议-完全相同的类型。
  • 类型兼容性-较小的类型到较大的类型,相同的符号。
  • 类型大小写-不得已(例如,较大到较小的类型,符号不匹配,指针往返整数)。

在这种情况下,由于NVMemWriteWord只是将address转换为整数,因此使用void*可能不合适。 如果在其他情况下实际上正在使用指针,则它可能是有效的。

MISRA-C:2012第12章中有关指针转换的整个内容都很挑剔。 没错,因为这是非常危险的领域。

11.6是一个健全的规则,禁止从整数到void*转换。 基本原理是阻止对齐错误。 无论如何,没有太多理由要进行此类转换。

值得注意的是,还有两个严格但建议性的规则11.4禁止从整数到指针的转换,而规则11.5则完全禁止使用void* 不可能进行与硬件相关的编程并遵循11.4,因此必须忽略该规则。 但是您没有理由使用void*

在此特定的转换中,您可以通过使用uint32_t并完全避免使用指针来摆脱uint32_t

在寄存器访问的一般情况下,您必须使用volatile限定的指针进行转换: (volatile uint32_t*)ADDRESS ,假设MCU使用32位寄存器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM