Author Topic: CAN TX Timeout  (Read 125 times)

Offline AlexS

  • Newbie
  • *
  • Posts: 22
    • View Profile
CAN TX Timeout
« on: January 14, 2020, 01:08:08 PM »
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
                        }



Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3014
    • View Profile
    • uTasker
Re: CAN TX Timeout
« Reply #1 on: January 15, 2020, 02:07:28 PM »
Alex

What is the state of the bus that doesn't allow the frame to be sent?
Do you see that there is an error interrupt that occurs that could be used to clear the buffer?

If it is a passive error (never can send and continuously waits until it can) it may be necessary to monitor with an application timer and subsequently abort/flush buffers.

Regard

Mark

Offline AlexS

  • Newbie
  • *
  • Posts: 22
    • View Profile
Re: CAN TX Timeout
« Reply #2 on: January 15, 2020, 02:27:05 PM »
Very happy to monitor with the application, but not sure how I can abort and flush the buffers. It is indeed a passive error, where the other device on the bus (and the termination resistor as a consequence) are not active initially after my device starts.

Thanks!
« Last Edit: January 15, 2020, 04:19:15 PM by AlexS »

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3014
    • View Profile
    • uTasker
Re: CAN TX Timeout
« Reply #3 on: January 16, 2020, 03:46:18 PM »
Hi Alex

I will look into a method to identify and clear blocked tx buffers - it has been quite some time since working at the CAN driver level so I'll need a little time to refresh on the details.

Regards

Mark

Offline AlexS

  • Newbie
  • *
  • Posts: 22
    • View Profile
Re: CAN TX Timeout
« Reply #4 on: January 17, 2020, 06:13:57 AM »
Thanks, Mark! Looking forward to it as it's a bit of a blocker at the moment. :) I did a bit of my own digging and it seems like there's no code path to handle a flush request on a CAN interface.  As you know I'm on the old uTasker version (Jan 2019), so not sure if you've added anything in between.

Regards,
Alex