ST意法半导体
直播中

南风一号

9年用户 1048经验值
擅长:EMC/EMI设计
私信 关注
[问答]

关于STM32 CAN通信发送函数HAL_CAN_AddTxMessage()的最后一个参数填0和定义一个变量取地址的问题求解

问题:
关于STM32 CAN通信 发送函数 HAL_CAN_AddTxMessage()的最后一个参数填0和定义一个变量取地址的问题,如果直接传0,我实验发现 STM32F103C8T6 会出现卡死的情况,进入了硬件中断,而对于STM32F429IGT6则不会卡死,能够正常运行;如果定义一个uint32_t类型的变量,取变量的地址传参进去,两个片子都能够正常运行,目前搞不懂什么原因,对于直接传0进去,我知道这是不规范的,相当于传入了一个空指针进去,而跳到函数内部发现,HAL_CAN_AddTxMessage()函数还对此指针进行了解引用,这肯定是非法,但是同样的情况对于F429IGT6却能正常运行,这令我非常不解。望请大佬解答!
下面是我自己写的CAN2发送函数:

  • uint32_t mailbox = 10;void CAN2_UsrSendTest(void){ CAN_TxHeaderTypeDef TxHead; TxHead.IDE = CAN_ID_STD; TxHead.StdId = 0x10; TxHead.RTR = CAN_RTR_DATA; TxHead.DLC = 8; uint8_t payload[8]; if(HAL_CAN_AddTxMessage(&hcan2, &TxHead, payload, 0) != HAL_OK) {     Error_Handler();     }}
源码中HAL_CAN_AddTxMessage()函数对pTxMailbox进行了解引用

回帖(1)

余温重顾

2025-3-12 17:47:20

关于你提到的 HAL_CAN_AddTxMessage() 函数最后一个参数的问题,确实涉及到对指针的操作和不同STM32芯片的行为差异。以下是对这个问题的详细分析:


1. HAL_CAN_AddTxMessage() 函数简介


HAL_CAN_AddTxMessage() 是STM32 HAL库中用于发送CAN消息的函数,其原型通常如下:


HAL_StatusTypeDef HAL_CAN_AddTxMessage(CAN_HandleTypeDef *hcan, CAN_TxHeaderTypeDef *pHeader, uint8_t aData[], uint32_t *pTxMailbox);


  • hcan: CAN外设的句柄。

  • pHeader: 指向CAN消息头结构的指针。

  • aData[]: 要发送的数据数组。

  • pTxMailbox: 指向一个 uint32_t 类型的变量,用于返回发送邮箱的编号。


2. 最后一个参数的作用


最后一个参数 pTxMailbox 是一个指向 uint32_t 类型的指针,用于返回发送消息时使用的邮箱编号。这个参数是可选的,如果不需要返回邮箱编号,可以传入 NULL


3. 传入 0 的问题


当你传入 0 时,实际上你传入的是一个空指针(NULL)。在C语言中,解引用空指针是未定义行为,通常会导致程序崩溃或进入硬件异常中断。


4. 不同芯片的行为差异


你观察到在 STM32F103C8T6 上传入 0 会导致卡死,而在 STM32F429IGT6 上则不会。这种差异可能由以下原因引起:




  • 硬件差异:不同系列的STM32芯片在硬件实现上可能存在差异,尤其是内存管理和异常处理机制。STM32F429IGT6 可能在某些情况下对空指针的解引用有更好的容错性,或者它的异常处理机制没有立即触发硬件中断。




  • 编译器优化:不同芯片使用的编译器或优化级别可能不同,导致代码行为不一致。某些编译器可能会对空指针的解引用进行优化,从而避免了立即崩溃。




  • HAL库版本:不同芯片可能使用了不同版本的HAL库,库的实现可能存在差异,导致对空指针的处理方式不同。




5. 规范的做法


为了避免这种未定义行为,建议始终传入一个有效的指针,而不是 0NULL。即使你不需要返回邮箱编号,也应该传入一个有效的变量地址。例如:


uint32_t TxMailbox;
HAL_StatusTypeDef status = HAL_CAN_AddTxMessage(&hcan, &TxHeader, aData, &TxMailbox);

如果你不需要邮箱编号,可以传入 NULL


HAL_StatusTypeDef status = HAL_CAN_AddTxMessage(&hcan, &TxHeader, aData, NULL);

6. 总结



  • 传入 0NULL 会导致未定义行为,可能导致程序崩溃或进入硬件中断。

  • 不同芯片的行为差异可能由硬件、编译器优化或HAL库版本引起。

  • 规范的做法是传入一个有效的指针,即使不需要返回邮箱编号,也应传入 NULL 而不是 0


通过遵循这些规范,可以避免因未定义行为导致的程序异常。

举报

更多回帖

发帖
×
20
完善资料,
赚取积分