2014-09-02 03:33 AM
Hi,
I have discovered several unfortunate behaviors of the HAL CAN module in the Cube package according to how I would like to use it. Please read through them and let me know your input.1. HAL_CAN_Transmit for polled CAN transmission waits until the CAN BUS message has been clocked to the BUS instead of just checking the HW tx buffers, putting it to the HW buffer, returning OK and moving on. This means it takes 500+ microseconds to send just a single CAN message at 250Kbit where the CPU is just wasted in a spin lock. I don't really see why you would need this functionality but fair enough. My complaint is that you cannot use the HAL_CAN_Transmit to skip this timeout functionality of waiting for the message to be clocked to the bus. If you give a timeout parameter of zero, then the function will return HAL_TIMEOUT even though it was put to the HW buffer just fine and will be transmitted shortly. Suggested change: if the timeout parameter is zero, skip all the timeout functionality, put the message to the HW buffer if one is free and return HAL_OK. I am aware that this will also have an impact on the HAL CAN modules internal State variable but that shouldn't matter for the polled functionality (and the internal state variable really shouldn't be used). Alternatively a HAL_CAN_Transmit_NonBlocking function could be made with this functionality. Any input?2. It seems the HAL_CAN_Transmit_IT function does not use the three CAN HW buffers since it will never pass the condition in the start of the function if there is a transmission in progress.:if((tmp == HAL_CAN_STATE_READY) || (tmp == HAL_CAN_STATE_BUSY_RX))This means the function will never be able to put a second CAN message in the HW buffer if the HW buffer already has a single CAN message in it causing performance issues? I can see how the HAL CAN state variable can be nice for debugging purposes etc, but really don't think this sw CAN state should be used in the behavior of the HAL CAN drivers - we should instead use the CAN control registers - e.g. do we have a free slot in the HW CAN buffer then put the CAN message in it and return OK, without depending on the CAN state software variable. Unless I have misread the code it really seems to me that using HAL_CAN_Transmit_IT we only use one third of our available HW CAN buffers. Any Input?3. General missing HAL_UNLOCK calls lots of places in the HAL CAN module in the case of bus errors. (Already reported as far as I can see)I have fixed all the above bugs in my own git repo of the cube package but I'm sure someone else will appreciate the above fixes went into the next cube package as well.Thanks,Lars #bug #timeout #can #stm32cubef42015-04-01 08:01 AM
Thanks for the reply
The problem was in the configuration, you had to put:void CAN1_Init(CAN_HandleTypeDef *canTxHandlePtr){ /*##-1- Configure the CAN1 peripheral #######################################*/ /* Can1 configured as follow: - */ canTxHandlePtr->Instance = CAN1; canTxHandlePtr->Init.Prescaler = 16; canTxHandlePtr->Init.Mode = CAN_MODE_LOOPBACK; canTxHandlePtr->Init.SJW = CAN_SJW_1TQ; canTxHandlePtr->Init.BS1 = CAN_BS1_8TQ; canTxHandlePtr->Init.BS2 = CAN_BS2_1TQ; canTxHandlePtr->Init.TTCM = DISABLE; canTxHandlePtr->Init.ABOM = ENABLE; canTxHandlePtr->Init.AWUM = ENABLE; canTxHandlePtr->Init.NART = DISABLE; canTxHandlePtr->Init.RFLM = DISABLE; canTxHandlePtr->Init.TXFP = ENABLE; if(HAL_CAN_Init(canTxHandlePtr) != HAL_OK) { BSP_LED_Toggle(LED4); /* Transmition Error */ Error_Handler(); }else{ BSP_LED_Toggle(LED3); }}
But, now the CAN1 transmit and the CAN2 not receive. Whats is the possible problem??2016-01-26 12:10 AM
The issues reported in the original post are still there in stm32f4xx_hal_can version 1.4.2. Lars if you are still there please share a link to fixes you have implemented in HAL CAN driver.
Samir