2025-11-26 11:12 PM
Hello.
I'm using STM32H747XI with touchgfx designer 4.24.2 and Free RTOS 10.3.1.
In this RTOS I setup some threads(with osPriorityNormal 24) and a Periodic Timer at 400ms.
I notice that when I start this thread
void threadEntryPoint() {
// Pulisco la FIFO del'RX USART
__HAL_UART_FLUSH_DRREGISTER(BARCODE_UART);
char msg[BARCODE_LENGTH+1];
while (;;) {
memset(msg, 0, sizeof(msg));
// Appena vedo il primo carattere ...
if ( HAL_UART_Receive ( BARCODE_UART, (uint8_t*)&msg[0], 1, 50 ) == HAL_OK ) {
// ... ricevo gli altri
HAL_UART_Receive ( BARCODE_UART, (uint8_t*)&msg[1], BARCODE_LENGTH - 1, 50 );
if (strchr(msg, BARCODE_SUFFIX)) {
queue.put(msg);
}
}
}
}
Timer will not trigger.
Is the reason that I have no osDelay ? Or a priority question ?
Thankyou in advance.
2025-11-27 12:35 AM - edited 2025-11-27 12:41 AM
@MauFanGilaMedical wrote:Is the reason that I have no osDelay ? Or a priority question ?
Have you tried using a osDelay() in your task?
@MauFanGilaMedical wrote:Timer will not trigger.
Can you describe what type of timer you are using: Software timer (Freertos)/or Hardware timer (Tim1, ...)
Is preemption enabled in your FreeRTOS config (USE_PREEMPTION)?
The problem with not having a osDelay in your task is that the operating system is never allowed to run any task/functionality (like timers), if they have a lower priority than the running task or if preemption is disabled.
2025-11-27 2:22 AM
I use Software timer (Freertos), PREEMPTION is Enabled.
I don't know the Timer priority: is there a parameter to set it ?
2025-11-27 2:44 AM - edited 2025-11-27 2:52 AM
https://freertos.org/Documentation/02-Kernel/02-Kernel-features/05-Software-timers/03-Timer-daemon-configuration
See documentation of FreeRTOS software timers. The parameter in the ioc.-File is shown in the screenshot:
Increasing this parameter to a higher value than osPriorityNormal should work.
Give it a try and get back to me if it works.
Afterwards i would suggest rewriting your
void threadEntryPoint() {function. The problem is that this function blocks for up to 50 milliseconds each time HAL_UART_Receive is called. Instead use a lower timeout and instead check once per millisecond if something arrived, maybe something like the following (used autotranslate for comments):
void BarcodeTask(void *argument)
{
char msg[BARCODE_LENGTH + 1];
uint8_t c;
// Pulisco la FIFO del'RX USART
__HAL_UART_FLUSH_DRREGISTER(BARCODE_UART);
for (;;)
{
memset(msg, 0, sizeof(msg));
size_t idx = 0;
// Appena vedo il primo carattere ...
int attempts = 0;
while (attempts < 50)
{
/* timeout molto corto per evitare HAL_Delay() */
if (HAL_UART_Receive(BARCODE_UART, &c, 1, 0) == HAL_OK)
{
msg[idx++] = c;
break;
}
/* se non arriva nulla, cedo la CPU */
osDelay(1);
attempts++;
}
/* se non ho ricevuto nulla nelle 50 iterazioni → riparto */
if (idx == 0)
continue;
// ... ricevo gli altri
HAL_UART_Receive ( BARCODE_UART, (uint8_t*)&msg[1], BARCODE_LENGTH - 1, 50 );
if (strchr(msg, BARCODE_SUFFIX))
{
queue.put(msg);
}
}
}Edit: Changed suggested code example.
Will work if the Data is not permanently received, otherwise might lead to same issue. Could rewrite the second HAL_UART_Receive to also be non-blocking.
2025-11-27 3:54 AM - edited 2025-11-27 3:54 AM
I hope you realize that for this code to work, the thread you present above must be the only one wit the highest priority. Otherwise UART data may not be received.
It is generally a very bad idea to use any non-interrupt, non-DMA functions under RTOS, especially for UART.