2025-01-27 07:08 AM - edited 2025-01-27 11:53 PM
I am developing a project with STM32 using the STM32G473CET6 chip and working on a CAN bus system. In this project, the STM32 sends messages to the bus, processes the received messages, and responds accordingly. For example, the message 10170001 queries the I/Os states of device 01, and the response consists of 8 messages containing the I/Os,dev states, PWM values, etc. However, if there are multiple devices on the bus, when I query device 02 with the message 10170002, it seems to print some of the responses from the previously sent message 10170001 (e.g., 2 out of the 8 messages). Then, on the third query, it finally sends the correct I/O states of device 02. It feels like there is some kind of overflow or buffering issue within the STM32, but when I check the FIFO levels, everything seems fine. My termination resistors are also properly configured. What could be causing this strange behavior? thank you
1 - My termination resistors are correctly placed at both ends of the bus. 2 - I have implemented mechanisms to monitor FIFO levels. 3 - I used an analyzer to track the messages on the bus. 4 - I don't think this is a hardware issue, as the same problem occurs on both devices. 5 - My CAN bus speed is 500 kbps, but I am observing this issue even when sending a low number of test messages on the bus.
/* main can line fifo0 callback */ void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs) { FDCAN_RxHeaderTypeDef bufRxHdrCan; uint8_t payloadCan[8]; if ((RxFifo0ITs & FDCAN_IT_RX_FIFO0_NEW_MESSAGE) != RESET) { if (HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0,&bufRxHdrCan,payloadCan) == HAL_OK) { dbgPrintf("Can1 new message in RxFifo0\n"); dbgPrintf("RxHeader.Identifier: %x\n", bufRxHdrCan.Identifier); dbgPrintf("RxHeader.DataLength: %x\n", bufRxHdrCan.DataLength); CanMessage canMsg; memcpy(canMsg.data,payloadCan,bufRxHdrCan.DataLength); canMsg.id = bufRxHdrCan.Identifier; canMsg.len = bufRxHdrCan.DataLength; ParsedID id = canMessageParseId(canMsg.id); dbgTrace("ParsedID.pgn : %d\n", id.pgn); dbgTrace("ParsedID.sourceAddr: %d\n", id.sourceAddr); dbgTrace("ParsedID.targetAddr: %d\n", id.targetAddr); if((id.targetAddr == gAppSettings.devAddress) || (id.targetAddr == BROADCAST_ADDRESS)) { gSysMsg sysMsg; sysMsg.dataDesc.msgId = canMsg.id; sysMsg.dataDesc.msgsrc=SRC_CANA; sysMsg.dataLen = canMsg.len; memcpy(sysMsg.dataBuffer,payloadCan,sysMsg.dataLen); gRingBufPush(&sysMsgRingBuf,(void*)(&sysMsg)); } return; } dbgPrintf("ERROR: Fifo0Callback HAL_FDCAN_GetRxMessage\n"); Error_Handler(1); // id 1 } } /* can message send */ bool canMessageSend(CanLine cLine,CanMessage *pCanMsg) { FDCAN_HandleTypeDef *phfdcan = phfdcanMain; FDCAN_TxHeaderTypeDef TxHeader; TxHeader.Identifier = pCanMsg->id; TxHeader.DataLength = pCanMsg->len; TxHeader.IdType = FDCAN_EXTENDED_ID; if(TxHeader.DataLength > 0) { TxHeader.TxFrameType = FDCAN_DATA_FRAME; } else { TxHeader.TxFrameType = FDCAN_REMOTE_FRAME; } TxHeader.ErrorStateIndicator = FDCAN_ESI_PASSIVE; TxHeader.BitRateSwitch = FDCAN_BRS_OFF; TxHeader.FDFormat = FDCAN_CLASSIC_CAN; TxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS; TxHeader.MessageMarker = 0; dbgTrace("canMessageSend\n"); dbgTrace("id = %d\n", pCanMsg->id); dbgTrace("len = %d\n",pCanMsg->len); while (HAL_FDCAN_GetTxFifoFreeLevel(phfdcan) == 0); if (HAL_FDCAN_AddMessageToTxFifoQ(phfdcan,&TxHeader,pCanMsg->data)!= HAL_OK) { dbgPrintf("ERROR:HAL_FDCAN_AddMessageToTxFifoQ-MIO\n"); return false; } return true; }
2025-01-27 07:39 AM - edited 2025-01-27 07:42 AM
Hello @MKT12 and welcome to the community,
Your request is not clear especially this statement:
@MKT12 wrote:
For example, the message 10170001 queries the I/Os states of device 01, and the response consists of 8 messages containing the I/Os,dev states, PWM values, etc. However, if there are multiple devices on the bus, when I query device 02 with the message 10170002, it seems to print some of the responses from the previously sent message 10170001 (e.g., 2 out of the 8 messages). Then, on the third query, it finally sends the correct I/O states of device 02.
Not sure if these details are relevant for your description but need to be concise but at the same time not too verbose to lose the comprehension not too short to lose the information. May be better to share a sketch of your G4 node with other nodes on the bus and another one on how do you send/receive CAN frames and at which message rate (not the baudrate but the time between the messages).
See Tips on posting.
2025-01-27 02:56 PM
You need to show code. What do you do when you get a CAN interrupt?
2025-01-27 11:55 PM - edited 2025-01-27 11:56 PM
Now I added the send and receive codes, I didn't have my computer with me yesterday.thanks
2025-01-27 11:56 PM
Now I added the send and receive codes, I didn't have my computer with me yesterday.thnks
2025-01-28 01:41 AM
Hi,
I did not analyse Your Code, but HAL_FDCAN_RxFifo0Callback() is called inside the HAL_FDCAN_IRQHandler(), so probably not a good place to do printf's.
Martin