AnsweredAssumed Answered

CAN Driver bug (?!)

Question asked by Beck.Karl_Michael on Apr 16, 2015
Latest reply on Jul 14, 2016 by Beck.Karl_Michael

I think i found an bug in the CAN driver. Explain me this:

a) Receiving
1. In the example application HAL_CAN_Receive_IT is called from HAL_CAN_RxCpltCallback
2. Looking in the implementation of the driver we see that HAL_CAN_RxCpltCallback is called from CAN_Receive_IT
3. CAN_Receive_IT is called from the HAL_CAN_IRQHandler
4. Going back to HAL_CAN_Receive_IT looking at the implementation we see it uses __HAL_LOCK which exclusively locks the CAN_HandleTypeDef
5. So conclusion: HAL_CAN_Receive_IT is called from an interrupt and exclusively locks the CAN_HandleTypeDef

b) Sending
1. An application will call either HAL_CAN_Transmit_IT or HAL_CAN_Transmit in the main routine.
2. Looking at the implementation we see both methods also use __HAL_LOCK

c) The Bug occurs
1. So an application sends a can message in the main routine 
2. The the rx interrupt occurs while the main task is inside HAL_CAN_Transmit_IT or HAL_CAN_Transmit. (Rember the CAN_HAndleTypeDef is locked: b.2)
3. Now the rx interrupt tries also to lock (a.4)
4. Of course this will fail because it's also locked by b.2

d) The resulting phenomena

1. The sample application will call it's error handler, going to while(1); Of course this is not acceptable.

2. If we'd ignored the error looking in the implementation of HAL_CAN_Receive_IT we see that it does not too much but it enables the rx interrupts.
   => So if we'd ignore the error we will no more get interrupts of incoming messages.

Of course it's very unlikely the bug occurs in the sample application with low busload. But i have it here in the System, still trying to figure out how to deal with this Rx-Acknoledge done by  HAL_CAN_Receive_IT. But looking at the above insight there is no solution - just a fundemantal bug inside the Can Driver. Actually there should be separate lock handles for rx + tx. Then it should work.

Did i miss something? The conclusion will be just not to use the can driver and write another one... or maybe modify it to use two seperate lock-objects....

Still i'm not sure if i use the Driver correctly but following the example code provided one traps into this.