cancel
Showing results for 
Search instead for 
Did you mean: 

TouchGFX initialization should not use FreeRTOS API before initialization

MMess.1
Associate III

I probably found a design issue by the code generated by the STM32CubeMX for TouchGFX project.

When using project generated by STM32CubeMX, the main.c initialization looks like this:

int main(void)
{
  // Generated initialisation code ...
  MX_TouchGFX_Init();
  /* Call PreOsInit function */
  MX_TouchGFX_PreOSInit();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Init scheduler */
  osKernelInitialize();  /* Call init function for freertos objects (in freertos.c) */
  MX_FREERTOS_Init();

  /* Start scheduler */
  osKernelStart();
  /* We should never get here as control is now taken by the scheduler */
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

Here you see the MX_TouchGFX_Init() function called to initialize the TouchGFX library. Underlaying it calls the name_init() which is part of the static linked library. During the nema initialization the static linked code somewhere calls the FreeRTOS API by calling osSemaphoreNew().

Calling FreeRTOS API functions before initializing the FreeRTOS is not intended, so the global interrupts are disabled. 

If a FreeRTOS API function is called before the scheduler has been started then interrupts will deliberately be left disabled, and not re-enable again until the first task starts to execute. From FreeRTOS FAQ

I had the same issue from my own code and also see that some other users have problems, because all custom code using HAL_Delay funtions between TouchGFX initialisation and FreeRTOS initialization will block the whole application. See discussion here.

Can the generated TouchGFX Code be adapted, so that the initialization does not call FreeRTOS API functions or the initialization is done within the TouchGFX Task it self?

Best regards

Martin

5 REPLIES 5
MMess.1
Associate III

Does really nobody care about this topic?

Svenn Dahlstrom
Associate III

I'm having the exact same problem. And in Cube MX there is an option in Project Manager -> Advanced Settings to check for "Do Not Generate Function Call" but that does not work either.
 

SvennDahlstrom_0-1692625331480.png

I have to remove the line MX_TouchGFX_Init() the first time I generate code with Cube MX after updating Cube MX or the firmware library to a new version.

ST, Please fix this issue!

Best regards
Svenn

MMess.1
Associate III

Can some from @st or from the CubeMX Team please have a look at this?

Zaher
Senior II

When you have a FreeRTOS based project, not only TouchGFX, but any API call to HAL_Delay() before the scheduler starts, which is very common for LCD and other peripheral initialization code, will cause the whole application to block. I found a quick solution, or a workaround if you will, for this problem by doing the following:

1- Use a timer as a time base

2- Configure the IRQ priority for SysTick before scheduler starts, like this:

int main(void)
{
  // Generated initialisation code ...
  MX_TouchGFX_Init();
  /* Call PreOsInit function */
  MX_TouchGFX_PreOSInit();
  /* USER CODE BEGIN 2 */
  /* Configure the SysTick handler priority */
  NVIC_SetPriority(TIM8_TRG_COM_TIM14_IRQn, 0); // TIM14 is used as a Timebase Source
  /* USER CODE END 2 */

  /* Init scheduler */
  osKernelInitialize();  /* Call init function for freertos objects (in freertos.c) */
  MX_FREERTOS_Init();

  /* Start scheduler */
  osKernelStart();
  /* We should never get here as control is now taken by the scheduler */
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

Well, while it might not be the best way to do it, it worked for me!

 

Zaher

 

HRidd.2
Associate III

Expanding on  @Zaher 's answer a little bit, I had the same problem, and it did have to do with ISR priority.

The issue:
- OsWrappers.cpp creates a semaphore + queue for purposes of framebuffer swapping BEFORE the FreeRTOS scheduler is called

- This is "allowed" behavior in FreeRTOS, however ANY interrupts with a lower (higher integer number) priority than configMAX_SYSCALL_INTERRUPT_PRIORITY (in FreeRTOSConfig.h) will be disabled until the kernel starts

- The intention of this in the API is to block any ISRs from firing that might call scheduler related API functions before the kernel starts, which is not allowed

- By default, my TIM6 SysTick source had an interrupt priority of 15, lower priority than configMAX_SYSCALL_INTERRUPT_PRIORITY of 5

- This ISR doesn't call any FreeRTOS API functions, so it can safely be increased in priority to < 5, and it will no longer be disabled by these calls


- Things now function as expected

Hope this helps someone!