vApplicationTickHook creating problem in scheduling other task (STM32F4 and GCC Compiler)

Hi,
Problem 1:
I have been facing some issue with vApplicationTickHook, if I call uart_printf inside this function, then in start it schedule tasks two-three times after it does not schedule tasks. It only goes inside vApplicationTickHook. If I comment uart_printf then everything work fine.Please tell me why it is happening? Even my tick interrupt 100ms and uart_printf using 115200 baud rate (polling mode) and I am sending 4 (“Tick”)charaters, so I think it is not the case of nested interrupt or tick miss.

int
main(int argc, char* argv[])
{
// At this stage the system clock should have already been configured
// at high speed.

  // Infinite loop
  while (1)
    {
	  /* Configure the hardware ready to run the test. */
	  prvSetupHardware();

	  xTaskCreate(vApplicationTaskTest, "TestTask", configMINIMAL_STACK_SIZE, (void * ) NULL, tskIDLE_PRIORITY+1UL, NULL);
	  xTaskCreate(vApplicationTaskTest2, "TestTask2", configMINIMAL_STACK_SIZE, (void * ) NULL, tskIDLE_PRIORITY+1UL, NULL);

	  /* Start the scheduler. */
	  vTaskStartScheduler();

	  /* Should never be reached */
	  for( ;; );    }
}

#pragma GCC diagnostic pop

static void prvSetupHardware( void ){

	/* Setup STM32 system (clock, PLL and Flash configuration) */
	SystemInit();

}

/*
 * Callbacks/Hooks
 */

void vApplicationTickHook( void ){

	uart_printf("Tick");
  // NOTE: if I comment it then it works fine
}

void vApplicationIdleHook( void ){

	uart_printf("Entered vApplicationIdleHook\n");

}

void vApplicationMallocFailedHook( void ){

	uart_printf("Entered vApplicationMallocFailedHook\n");
	for(;;);
}

void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName){

	( void )pxTask;
	( void )pcTaskName;

	for(;;);
}

/*
 * Tasks
 */

void vApplicationTaskTest( void *pvParameters){

	while(1){
		uart_printf("In Task vApplicationTaskTest\n");
	}
}

void vApplicationTaskTest2( void *pvParameters){

	while(1){
		uart_printf("\tIn Task vApplicationTaskTest2\n");
	}
}`Preformatted text`

->>>>>>>>>>>>>>>>>>>>>
Output Seriar Terminal:
In Task vApplicationTaskTest
In Task vApplicationTaskTest
In Task vApplicationTaskTest
Tick
Tick
Tick
Tick
Tick
Tick
…goes on
->>>>>>>>>>>>>>>>>>>>>>>
Problem 2:
If I put uart_printf in between critical section (enable and disable Irq) of vApplicationTickHook and other two task, then it works fine. Even I am call uart_printf inside vApplication, as mentioned below code.

  int
main(int argc, char* argv[])
{
  // At this stage the system clock should have already been configured
  // at high speed.

  // Infinite loop
  while (1)
    {
	  /* Configure the hardware ready to run the test. */
	  prvSetupHardware();

	  xTaskCreate(vApplicationTaskTest, "TestTask", configMINIMAL_STACK_SIZE, (void * ) NULL, tskIDLE_PRIORITY+1UL, NULL);
	  xTaskCreate(vApplicationTaskTest2, "TestTask2", configMINIMAL_STACK_SIZE, (void * ) NULL, tskIDLE_PRIORITY+1UL, NULL);

	  /* Start the scheduler. */
	  vTaskStartScheduler();

	  /* Should never be reached */
	  for( ;; );    }
}

#pragma GCC diagnostic pop

static void prvSetupHardware( void ){

	/* Setup STM32 system (clock, PLL and Flash configuration) */
	SystemInit();

}

/*
 * Callbacks/Hooks
 */

void vApplicationTickHook( void ){

__disable_IRQ();
	uart_printf("Tick");
 __enable_IRQ();
}

void vApplicationIdleHook( void ){

	uart_printf("Entered vApplicationIdleHook\n");

}

void vApplicationMallocFailedHook( void ){

	uart_printf("Entered vApplicationMallocFailedHook\n");
	for(;;);
}

void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName){

	( void )pxTask;
	( void )pcTaskName;

	for(;;);
}

/*
 * Tasks
 */

void vApplicationTaskTest( void *pvParameters){

	while(1){
__disable_IRQ();
		uart_printf("In Task vApplicationTaskTest\n");
__enable_IRQ();
	}
}

 `void vApplicationTaskTest2( void *pvParameters)`

    	while(1){
    __disable_IRQ();
    		uart_printf("\tIn Task vApplicationTaskTest2\n");
    __enable_IRQ();
    	}
    }

Problem 3:
If I use trace_printf (system call over debugger) instead of serial uart then it works fine. Even I think trace_printf slower than uart serial.
Please help me to figure out how to debug this problem and why it is happening

The tick hook is called on every OS tick interrupt, from the kernel context. The idle hook runs in the idle task, and might be preempted by the tick ISR. Be very careful what code you run in these hooks. The tick hook should be fast, and neither of them should block. The uart_printf is using a shared resource so this is asking for trouble.

A common solution is to use a dedicated task to do the prints. This “logger” task reads from a queue and prints it. It should be the only call of uart_printf in your code.

To make it easy to use, make two print functions that just sends the string to the logger task, one using xQueueSend (used from tasks, including the idle hook) and the other one using xQueueSendFromISR (used from interrups, including the tick hook)

As my Problem3: , then my question is it should also create problem with trace_printf, it is also share resource?
Might be Trace_printf disable interrupts before entering in it?

Problem 3:
If I use trace_printf (system call over debugger) instead of serial uart then it works fine. Even I think trace_printf slower than uart serial.

It depends on how trace_printf is implemented. I would guess it uses semihosting since you say it is slower than the UART version. In that case it is not using any physical resources in the processor, apart from a RAM buffer. And since it works, it doesn’t seem necessary to disable interrupts.

In general, you should not disable interrupts but use mutexes instead (https://www.freertos.org/CreateMutex.html).
Disabling interrupts stops the FreeRTOS tick and thereby prevents the task scheduling from working as intended.
When using mutexes, other unrelated tasks can still execute.

The reason why it worked when you disable interrupts in the idle hook is that you had uart_printf calls in the tick hook, that could preempt and conflict with the uart_printf calls in the idle hook. But this is bad practice.

Use a dedicated logger task for handling the uart_printf instead. If this is the only place where uart_printf is used, you don’t need to use a mutex either.