Hi,
Using uTasker (with excellent results) on an automotive project. On the CAN-side of things I'm seeing a peculiar behaviour in a specific corner case. The corner case is one where my device is the only device switched on the CAN bus with another, that should receive my messages, being turned on a few seconds later. What happens is that the TX buffers quickly get filled up, but, oddly, they don't ever timeout, contrary to what's described in the documentation. The documentation suggests that the buffers will be freed after a certain number of retries.
After looking through the code, I noticed that the CAN_TX_BUF_ACTIVE flag is only cleared in case there's no ACK coming, not if the message can't be sent. Page 10 of the uTasker CAN documentation suggests that the expected behaviour is for the buffer to be returned to an inactive state by the driver, informing the application that the message couldn't be delivered.
if ((ulError & CAN_ACK_ERR) != 0) { // a transmission received no ack
(...)
while (i-- != 0) {
if ((ptrCanQue->ucMode & CAN_TX_BUF_ACTIVE) != 0) { // this buffer is presently transmitting a message
if (++(ptrCanQue->ucErrors) >= MAX_TX_CAN_TRIES) { // we allow a few attempts before quitting (it also filters counting normal active buffers)
ptrMessageBuffer->ulCode_Len_TimeStamp = ((ptrMessageBuffer->ulCode_Len_TimeStamp & ~CAN_CODE_FIELD) | MB_TX_INACTIVE); // stop transmission
can_error_int_message[MSG_DESTINATION_TASK] = ptrCanQue->TaskToWake;
if ((ptrCanQue->ucMode & CAN_TX_BUF_REMOTE) != 0) {
can_error_int_message[MSG_INTERRUPT_EVENT] = CAN_TX_REMOTE_ERROR;
ptrCanQue->ucMode = (CAN_TX_BUF | CAN_RX_BUF_FULL | CAN_TX_BUF_REMOTE); // mark that it is an errored transmission buffer
}
else {
can_error_int_message[MSG_INTERRUPT_EVENT] = CAN_TX_ERROR;
ptrCanQue->ucMode = (CAN_TX_BUF | CAN_RX_BUF_FULL); // mark that it is an errored transmission buffer
}