硬汉嵌入式论坛

 找回密码
 立即注册
查看: 806|回复: 12
收起左侧

[CAN/FDCAN] STM32H7的CANFD隐藏了个诡异设计,TX FIFO还能触发TX BUFFER中断【问题解决,11楼】

[复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107049
QQ
发表于 2023-10-31 12:15:51 | 显示全部楼层 |阅读模式
无论是在CANFD模式下还是经典CAN模式下,使用TX FIFO的情况下,并开启了TX FIFO发送空中断。

HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_TX_FIFO_EMPTY, 0);        
        

而TX BUFFER仅仅是开启下面这个中断,不做任何其它处理。特别注意,32个TX BUFFER,仅这个0x00000100,BUFFER8可以触发中断,开其它TX BUFFER不行。
HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_TX_COMPLETE, 0x00000100);



实际测试发现,TX FIFO回调和TX BUFFER回调都可以进入。


[C] 纯文本查看 复制代码
/*
*********************************************************************************************************
*        函 数 名: HAL_FDCAN_TxFifoEmptyCallback
*        功能说明: Tx FIFO发送完成回调函数
*        形    参: hfdcan
*        返 回 值: 无
*********************************************************************************************************
*/
void HAL_FDCAN_TxFifoEmptyCallback(FDCAN_HandleTypeDef *hfdcan)
{
        if (hfdcan == &hfdcan1)
        {
                bsp_PutMsg(MSG_CAN1_TxFIFO, 0);
        }
        
        if (hfdcan == &hfdcan2)
        {
                bsp_PutMsg(MSG_CAN2_TxFIFO, 0);                
        }
}

/*
*********************************************************************************************************
*        函 数 名: HAL_FDCAN_TxBufferCompleteCallback
*        功能说明: Tx Buffer发送完成标志
*        形    参: hfdcan
*        返 回 值: 无
*********************************************************************************************************
*/
void HAL_FDCAN_TxBufferCompleteCallback(FDCAN_HandleTypeDef *hfdcan, uint32_t BufferIndexes)
{
        if (hfdcan == &hfdcan1)
        {
                bsp_PutMsg(MSG_CAN1_TxBuffer, 0);
        }
        
        if (hfdcan == &hfdcan2)
        {
                bsp_PutMsg(MSG_CAN2_TxBuffer, 0);                
        }        
}




回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107049
QQ
 楼主| 发表于 2023-10-31 12:22:44 | 显示全部楼层

123.png
回复

使用道具 举报

8

主题

157

回帖

181

积分

初级会员

积分
181
发表于 2023-11-3 14:56:11 | 显示全部楼层
本帖最后由 yunqi 于 2023-11-3 15:18 编辑

发送完成前,先进入发送FIFO空,处理了回调。原因是因为此前设置了FIFO空中断,当dedicated buffer 发送完成(准确的是说数据从影子寄存器全部搬出去的时候)时候,IR的FIFO空置位。


[C] 纯文本查看 复制代码
  /* Tx FIFO empty interrupt management ***************************************/
  if (__HAL_FDCAN_GET_IT_SOURCE(hfdcan, FDCAN_IT_TX_FIFO_EMPTY) != 0U)
  {
    if (__HAL_FDCAN_GET_FLAG(hfdcan, FDCAN_FLAG_TX_FIFO_EMPTY) != 0U)
    {
      /* Clear the Tx FIFO empty flag */
      __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_TX_FIFO_EMPTY);

#if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
      /* Call registered callback*/
      hfdcan->TxFifoEmptyCallback(hfdcan);
#else
      /* Tx FIFO empty Callback */
      HAL_FDCAN_TxFifoEmptyCallback(hfdcan);
#endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
    }
  }

  /* Transmission Complete interrupt management *******************************/
  if (__HAL_FDCAN_GET_IT_SOURCE(hfdcan, FDCAN_IT_TX_COMPLETE) != 0U)
  {
    if (__HAL_FDCAN_GET_FLAG(hfdcan, FDCAN_FLAG_TX_COMPLETE) != 0U)
    {
      /* List of transmitted monitored buffers */
      TransmittedBuffers = hfdcan->Instance->TXBTO;
      TransmittedBuffers &= hfdcan->Instance->TXBTIE;

      /* Clear the Transmission Complete flag */
      __HAL_FDCAN_CLEAR_FLAG(hfdcan, FDCAN_FLAG_TX_COMPLETE);

#if USE_HAL_FDCAN_REGISTER_CALLBACKS == 1
      /* Call registered callback*/
      hfdcan->TxBufferCompleteCallback(hfdcan, TransmittedBuffers);
#else
      /* Transmission Complete Callback */
      HAL_FDCAN_TxBufferCompleteCallback(hfdcan, TransmittedBuffers);
#endif /* USE_HAL_FDCAN_REGISTER_CALLBACKS */
    }
  }


回复

使用道具 举报

8

主题

157

回帖

181

积分

初级会员

积分
181
发表于 2023-11-3 15:29:51 | 显示全部楼层

之所以BufferIndex是0x0000100,因为中断处理传入的参数是
[C] 纯文本查看 复制代码
TransmittedBuffers = hfdcan->Instance->TXBTO;
      TransmittedBuffers &= hfdcan->Instance->TXBTIE;
HAL_FDCAN_TxBufferCompleteCallback(hfdcan, TransmittedBuffers);
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107049
QQ
 楼主| 发表于 2023-11-3 15:35:04 | 显示全部楼层
yunqi 发表于 2023-11-3 15:29
之所以BufferIndex是0x0000100,因为中断处理传入的参数是
[mw_shl_code=c,true]TransmittedBuffers = hf ...

设计不合理。

下载 (8).png
回复

使用道具 举报

8

主题

157

回帖

181

积分

初级会员

积分
181
发表于 2023-11-3 15:37:40 | 显示全部楼层
本帖最后由 yunqi 于 2023-11-3 16:06 编辑

和楼下重复。
回复

使用道具 举报

8

主题

157

回帖

181

积分

初级会员

积分
181
发表于 2023-11-3 15:46:41 | 显示全部楼层

已经麻木了,没有碰到新的问题前,感觉不出大厂的这种设计合不合理。

HAL_FDCAN_ActivateNotification的第三个参数,建议初始化的时候,把发送中断用到的发送位,全部设置成1。
英飞凌的SDK就是这么干的,只要启用发送中断,就会把所有设置的发送元素全部用中断处理。也避免了1楼遇到的困惑问题。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107049
QQ
 楼主| 发表于 2023-11-3 16:08:00 | 显示全部楼层
yunqi 发表于 2023-11-3 15:46
已经麻木了,没有碰到新的问题前,感觉不出大厂的这种设计合不合理。

HAL_FDCAN_ActivateNotification ...

最初我是HAL_FDCAN_ActivateNotification第3个参数全开出现的1楼问题,直接进入TX BUFFER CALLBACK了,后来才锁定到是0x00000100这个开就会进入。
回复

使用道具 举报

8

主题

157

回帖

181

积分

初级会员

积分
181
发表于 2023-11-3 16:17:48 | 显示全部楼层
eric2013 发表于 2023-11-3 16:08
最初我是HAL_FDCAN_ActivateNotification第3个参数全开出现的1楼问题,直接进入TX BUFFER CALLBACK了,后 ...

‘0x00000100’, 这应该是个例,按照上边流程,第三个参数随便一个值,FIFO空触发后都会进入发送完成回调。

顺便再说问题,启用BRS后,时间戳可能不准,因为如果用can bit计时,数据段和仲裁段的can bit time(波特率)不一致可能导致时间戳不准确。不知道ST的是不是有这样的问题。
解决办法是用博世后出的TSU模块,或者加入专用外部计数器。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107049
QQ
 楼主| 发表于 2023-11-3 16:45:19 | 显示全部楼层
yunqi 发表于 2023-11-3 16:17
‘0x00000100’, 这应该是个例,按照上边流程,第三个参数随便一个值,FIFO空触发后都会进入发送完成回 ...

1、那不对,我没有开专用tx buffer,也没开buffer请求的情况下,就不该进入这个if条件,而这个0x00000100是进入if的判断了。
if (__HAL_FDCAN_GET_IT_SOURCE(hfdcan, FDCAN_IT_TX_COMPLETE) != 0U)

2、ST没这个问题。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107049
QQ
 楼主| 发表于 2023-11-3 17:21:31 | 显示全部楼层
yunqi 发表于 2023-11-3 16:17
‘0x00000100’, 这应该是个例,按照上边流程,第三个参数随便一个值,FIFO空触发后都会进入发送完成回 ...

非常感谢讨论,锁定到最根本的原因了,0x00000100是几是由用户分配的专用BUFFER和FIFO大小后,FIFO在TX BUFFER的位置决定的。然后TX FIFO这个位置为空后触发发送空,发送完成后,触发TC发送完成中断

下载 (9).png


回复

使用道具 举报

8

主题

157

回帖

181

积分

初级会员

积分
181
发表于 2023-11-3 18:07:22 | 显示全部楼层
eric2013 发表于 2023-11-3 17:21
非常感谢讨论,锁定到最根本的原因了,0x00000100是几是由用户分配的专用BUFFER和FIFO大小后,FIFO在TX B ...

你是不是用了8个TX dedicated buffer, 剩下的配置成FIFO了。
那FIFO是从 buffer index-8 起始
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107049
QQ
 楼主| 发表于 2023-11-3 18:15:26 | 显示全部楼层
yunqi 发表于 2023-11-3 18:07
你是不是用了8个TX dedicated buffer, 剩下的配置成FIFO了。
那FIFO是从 buffer index-8 起始

对,正好前面8个专用buffer。我说怎么是这么诡异的一个值。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-16 06:04 , Processed in 0.199887 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表