HAL_FDCAN_AddMessageToTxFifoQ関数でFIFOバッファにセットしたデータが出力されないことがある
解決したいこと
CPU:「STM32H723ZGT6」を使用してCAN通信処理を実装しています。
CANデータの送信処理としてHAL_FDCAN_AddMessageToTxFifoQ関数を使用しています。
この関数でCAN出力データをFIFOバッファにセット~送信していますが正常に送信されないことがあります。
この原因を突き止めたいと考えております。
分かっていること
この問題は必ず再現するわけではなく何度かCAN通信していると起きます。
ソースコード
void CanSendProc(void)
{
int i;
int box;
uint32_t canid;
uint32_t Tickstart;
uint8_t sendbuf[32];
// 送信間隔を300usec以上空ける
if( gTimer.can_interval ){
set_led( ECU_LED, FALSE );
return;
}
if( gCan.sgptr == gCan.ssptr ){
set_led( ECU_LED, FALSE );
return;
}
FDCAN_TxHeaderTypeDef txheader;
if( !HAL_FDCAN_GetTxFifoFreeLevel(&hfdcan1) ){
txheader.Identifier = gCan.send[gCan.sgptr].canid;
txheader.IdType = FDCAN_STANDARD_ID;
txheader.TxFrameType = FDCAN_DATA_FRAME;
switch(gCan.send[gCan.sgptr].len){
case 0: txheader.DataLength = FDCAN_DLC_BYTES_0; break;
case 1: txheader.DataLength = FDCAN_DLC_BYTES_1; break;
case 2: txheader.DataLength = FDCAN_DLC_BYTES_2; break;
case 3: txheader.DataLength = FDCAN_DLC_BYTES_3; break;
case 4: txheader.DataLength = FDCAN_DLC_BYTES_4; break;
case 5: txheader.DataLength = FDCAN_DLC_BYTES_5; break;
case 6: txheader.DataLength = FDCAN_DLC_BYTES_6; break;
case 7: txheader.DataLength = FDCAN_DLC_BYTES_7; break;
case 8:
case 9:
case 10:
case 11: txheader.DataLength = FDCAN_DLC_BYTES_8; break;
case 12:
case 13:
case 14:
case 15: txheader.DataLength = FDCAN_DLC_BYTES_12; break;
case 16:
case 17:
case 18:
case 19: txheader.DataLength = FDCAN_DLC_BYTES_16; break;
case 20:
case 21:
case 22:
case 23: txheader.DataLength = FDCAN_DLC_BYTES_20; break;
case 24:
case 25:
case 26:
case 27:
case 28:
case 29:
case 30:
case 31: txheader.DataLength = FDCAN_DLC_BYTES_24; break;
case 32:
case 33:
case 34:
case 35:
case 36:
case 37:
case 38:
case 39:
case 40:
case 41:
case 42:
case 43:
case 44:
case 45:
case 46:
case 47: txheader.DataLength = FDCAN_DLC_BYTES_32; break;
case 48:
case 49:
case 50:
case 51:
case 52:
case 53:
case 54:
case 55:
case 56:
case 57:
case 58:
case 59:
case 60:
case 61:
case 62:
case 63: txheader.DataLength = FDCAN_DLC_BYTES_48; break;
default:
txheader.DataLength = FDCAN_DLC_BYTES_64;
break;
}
txheader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
txheader.BitRateSwitch = FDCAN_BRS_OFF;
if( gIO.dsw & 0x01 ){
txheader.FDFormat = FDCAN_CLASSIC_CAN;
}else {
txheader.FDFormat = FDCAN_FD_CAN;
}
txheader.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
txheader.MessageMarker = 0;
set_led( ECU_LED, TRUE );
for(i=0;i<(sizeof(sendbuf)/sizeof(sendbuf[0]));i++){
sendbuf[i] = 0;
}
memcpy(sendbuf, gCan.send[gCan.sgptr].buf, sizeof(gCan.send[gCan.sgptr].buf));
if(!get_relay(CAN_RL)){
sci_printf(COM_SCI, "get_relay CAN_RL OFF!!!\r\n");
}
Tickstart = HAL_GetTick();
if (HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &txheader, sendbuf) != HAL_OK){
sci_printf(COM_SCI, "NOT HAL OK)\r\n");
Error_Handler();
}
/* Check transmission occurred before timeout */
while(HAL_FDCAN_IsTxBufferMessagePending(&hfdcan1, FDCAN_TX_BUFFER0) != 0)
{
if((HAL_GetTick() - Tickstart) > 1000) // 1000msec
{
sci_printf(COM_SCI, "Send NG!!!!!\r\n");
}
}
if( ++gCan.sgptr >= 256 ) gCan.sgptr = 0;
}
}
ソースについて
以下部分で出力データをFIFOバッファにセット~送信しています。
エラーにはなっておらず正常終了しています。
if (HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &txheader, sendbuf) != HAL_OK){
sci_printf(COM_SCI, "NOT HAL OK)\r\n");
Error_Handler();
}
FIFOバッファにデータが残っていないかを以下でチェックしています。
このループは抜けているためFIFOバッファに残っているわけではないと考えています。
/* Check transmission occurred before timeout */
while(HAL_FDCAN_IsTxBufferMessagePending(&hfdcan1, FDCAN_TX_BUFFER0) != 0)
{
if((HAL_GetTick() - Tickstart) > 1000) // 1000msec
{
sci_printf(COM_SCI, "Send NG!!!!!\r\n");
}
}
原因として何が考えられるかを知りたく、
お力をお借りできますと幸いです。よろしくお願いいたします。