2024-12-16 10:38 PM
Hi there,
I have an IIC sensor connected to the MCU. And I read the sensor data at 50Hz.
However, there are sometimes some IIC communication errors present with HAL_I2C_ERROR_TIMEOUT.
My project is based on FreeRTOS with 4 Tasks, the sensor data collection task is one of the tasks, and the priority of this one isn't the highest.
I try to read the sensor data by the blocking API "HAL_I2C_Master_Transmit()" and "HAL_I2C_Master_Receive()".
I want to know if is there any possibility that the HAL_I2C_ERROR_TIMEOUT is caused by the blocking API in the sensor data collection task being interrupted by higher-priority tasks.
If yes, how to modify the code? Change to "HAL_I2C_Master_Transmit_IT()" and "HAL_I2C_Master_Receive_IT()" is OK?
(Because the frequency of the error is very low, it's not easy to position the root reason by test.)
(And can't include "HAL_I2C_Master_Transmit()" and "HAL_I2C_Master_Receive()" in "taskENTER_CRITICAL()" and "taskExit_CRITICAL()" to keep others task's realtime)
Thanks for your help!
Solved! Go to Solution.
2024-12-18 12:15 AM
Yes you can, but it would frequently cause errors, so you shouldn't use them. In particular, UART_Receive has no chance to work at all (but non-blockig UART_Receive_IT is just slightly less error-prone, so I would avoid HAL_UART stuff at all).
Use non-blocking versions.
You will likely need to use "complete" callbacks. Contrary to what's written above, you don't need to enable callbacks in HAL. This option setting is needed only for dynamic registration of callbacks (rarely needed). If you use static callbacks (common case), you only need to write the routine.
2024-12-17 07:31 PM
if you want use "HAL_I2C_Master_Transmit_IT()" and "HAL_I2C_Master_Receive_IT()", you need set the macro "USE_HAL_I2C_REGISTER_CALLBACKS"(in stm32g4xx_hal_conf.h) to 1.
And rewrite the callback function that you need. (the callback function lists can refer to HAL_I2C_Init() function)
Of course, you need to enable the IIC interrupt.
2024-12-18 12:15 AM
Yes you can, but it would frequently cause errors, so you shouldn't use them. In particular, UART_Receive has no chance to work at all (but non-blockig UART_Receive_IT is just slightly less error-prone, so I would avoid HAL_UART stuff at all).
Use non-blocking versions.
You will likely need to use "complete" callbacks. Contrary to what's written above, you don't need to enable callbacks in HAL. This option setting is needed only for dynamic registration of callbacks (rarely needed). If you use static callbacks (common case), you only need to write the routine.
2024-12-18 01:36 AM
Thanks for your reply.
but non-blockig UART_Receive_IT is just slightly less error-prone
I need to confirm that you mean the non-blocking API(such as HAL_UART_Receive_IT and HAL_I2C_Master_Transmit_IT) is also error-prone, am I right?
If that is what you mean, how do you do this work?
Do you replace to use HAL by accessing the register directly?
2024-12-18 02:21 AM - edited 2024-12-18 02:22 AM
From my perspective and experience the HAL_UART stuff is useless in a real world. Usually, you must always be ready to receive UART data. HAL is not ready for this unless you call some form of Receive. When this Receive completes (sync or async, no difference) and you don't reactivate reception, you loose incoming data.
In real world, the reception should never never be deactivated. The closest you may get to this with HAL is to call Receive_IT in the Receive callback, but why do we ever need to spend the precious MCU time on doing that?
2024-12-18 05:15 PM