cancel
Showing results for 
Search instead for 
Did you mean: 

Free RTOS TImer and Thread

MauFanGilaMedical
Associate III

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.

4 REPLIES 4
M_Schmidt
Associate II


@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.

I use Software timer (Freertos), PREEMPTION is Enabled.

I don't know the Timer priority: is there a parameter to set it ?

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:

M_Schmidt_0-1764239987974.png

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.

gbm
Principal

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.

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice