2023-04-13 06:03 AM
Hello,
When I m using more thant 2 TPDOs (configured with the OD_editor), the 2 first TPDOs are sent and then, nothing happens.
In
CO_CANsend
I have the error
CO_ERROR_TX_OVERFLOW. If i only use 2 TPDOs, it works perfectly.
When i put a breakpoint before CO_process_TPDO, then it works and send all TPDOS, but the device will no longer receive any commands.
Here you can see the configuration in the OD_editor. If i check "invalid" for one TPDO it works fine.
I asked the question on the git hub repo, and they told me that i might be a driver problem.
I m using the HAL library
2023-04-13 07:16 AM
From the description it appears you are attempting to send CAN messages after all three outgoing mailboxes are in use. This is a driver problem, not CANopen. When you transmit a message, do you check to see if a mailbox is available? If no mailboxes are available you have to stall the write until a CAN TX interrupt notifies you that a mailbox is open for the next message.
There are three hardware mailboxes in an STM32. If you write more than two TPDOs at the same time chances are good you will have to wait for prior writes to complete.
I've used CANopen with up to five TPDOs as well as NMT heartbeats and EMCY alerts, so there is no inherent limitation in CANopen on number of active messages. The hardware limitation is in bus latency and contention for a transmit slot. The more nodes on your network, all sending TPDOs and NMT heartbeats, the more likely you will use up all three TX mailboxes. Without checking for availability you are certain to encounter a TX overflow.
Jack Peacock
2023-04-14 01:59 AM
Hello,
In the fuction to send CAN frames, there is already the fuction to check the mail box
CO_ReturnError_t CO_CANsend(CO_CANmodule_t *CANmodule, CO_CANtx_t *buffer)
{
CO_ReturnError_t err = CO_ERROR_NO;
/* Verify overflow */
if(buffer->bufferFull){
if(!CANmodule->firstCANtxMessage){
/* don't set error, if bootup message is still on buffers */
CO_errorReport((CO_EM_t*)CANmodule->em, CO_EM_CAN_TX_OVERFLOW, CO_EMC_CAN_OVERRUN, buffer->ident);
}
err = CO_ERROR_TX_OVERFLOW;
}
uint32_t TxMailboxNum;
/* if CAN TX buffer is free, send message */
CO_LOCK_CAN_SEND();
prepareTxHeader(&TxHeader, buffer);
if ((CANmodule->CANtxCount == 0) &&
(HAL_CAN_GetTxMailboxesFreeLevel(CANmodule->CANbaseAddress) > 0 )) {
CANmodule->bufferInhibitFlag = buffer->syncFlag;
if( HAL_CAN_AddTxMessage(CANmodule->CANbaseAddress, &TxHeader, &buffer->data[0], &TxMailboxNum) != HAL_OK)
{
err = CO_ERROR_HAL;
}
else
{
;/*do nothing*/
}
}
/* if no buffer is free, message will be sent in the task */
else
{
buffer->bufferFull = true;
CANmodule->CANtxCount++;
}
CO_UNLOCK_CAN_SEND();
return err;
}
when i go in debug, I can see the 2 firts TPDOs sent correctly. Then, for the third, buffer->bufferFull = 1 so it repport the CO_ERROR_TX_OVERFLOW error.
I saw someone in another forum telling it was the clock for it's case, could it be this ?