Interrupt Handling and a Task

Hi @manu,

Are you able to resolve this? If not, would you please share the complete project? Which hardware are you using?

Thanks.

Hi,

@jefftenney

When configCHECK_FOR_STACK_OVERFLOW and configUSE_MALLOC_FAILED_HOOK
I get missing symbols for

Undefined symbol vApplicationMallocFailedHook (referred from heap_4.o).
Undefined symbol vApplicationStackOverflowHook (referred from tasks.o).

in OSWrappers.cpp CMSIS OS2 they are appear to be defined thus:

void vApplicationStackOverflowHook(xTaskHandle xTask,
                                   signed portCHAR* pcTaskName)
{
    while (1);
}

void vApplicationMallocFailedHook(xTaskHandle xTask,
                                  signed portCHAR* pcTaskName)
{
    while (1);
}

What would you like me to define them as ?

Thanks

Hi ,

@aggarg,

It still appears to be in limbo.

Hardware description:

/**
 * FreeRTOS ISR TaskNotification test
 * MCU used: STM32H743ZI
 * Board used: NUCLEO-H743ZI2 (MB1364C)
 * Debug over ST Link Virtual COM Port
 */

Attached the complete project in here

LL_FreeRTOS_ISR_Thread.zip (43.3 KB)

Here are the ones ST generates, which are compatible with the native FreeRTOS prototypes.

void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
{
   ( void ) pcTaskName;
   ( void ) pxTask;

   /* Run time stack overflow checking is performed if
   configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2.  This hook
   function is called if a stack overflow is detected. */
   taskDISABLE_INTERRUPTS();
   for( ;; );
}

void vApplicationMallocFailedHook( void )
{
   /* vApplicationMallocFailedHook() will only be called if
   configUSE_MALLOC_FAILED_HOOK is set to 1 in FreeRTOSConfig.h.  It is a hook
   function that will get called if a call to pvPortMalloc() fails.
   pvPortMalloc() is called internally by the kernel whenever a task, queue,
   timer or semaphore is created.  It is also called by various parts of the
   demo application.  If heap_1.c or heap_2.c are used, then the size of the
   heap available to pvPortMalloc() is defined by configTOTAL_HEAP_SIZE in
   FreeRTOSConfig.h, and the xPortGetFreeHeapSize() API function can be used
   to query the size of free heap space that remains (although it does not
   provide information on how the remaining heap might be fragmented). */
   taskDISABLE_INTERRUPTS();
   for( ;; );
}

Also I looked briefly at your project. I don’t think the Tick ISR is installed correctly. FreeRTOS uses SysTick, and the HAL must use a different timer. So this is outdated:

/* IMPORTANT: This define MUST be commented when used with STM32Cube firmware, 
              to prevent overwriting SysTick_Handler defined within STM32Cube HAL */
/* #define xPortSysTickHandler SysTick_Handler */

You’ll probably need to uncomment that #define. If you use CubeMX, you should be able to tell it to use a different timer (not SysTick) for the HAL tick. Of course maybe you don’t need the HAL at all.

Also just noticed you are starting systick manually – and before FreeRTOS is running. Best to let FreeRTOS do that so the SysTick ISR doesn’t run before FreeRTOS is ready for it.

Copy/Pasted the hooks:

I am using the LL API, rather than HAL. Being a simple test application it does not need the LL/HAL does not require SysTick, so commented out the SysTick handler, such that FreeRTOS can overlay the handler.

#if 0
/**
  * @brief  This function handles SysTick Handler.
  * @param  None
  * @retval None
  */
void SysTick_Handler(void)
{
}
#endif

Or do I need to do anything explicit for FreeRTOS to take over SysTick ?

SysTick is initialized for 1mS; What would FreeRTOS be expecting, SysTick to be ?

After building:

Running, it looks thus:

  1. FreeRTOS will configure SysTick automatically. It expects to find SysTick in its reset condition.
  2. The FreeRTOS SysTick handler (xPortSysTickHandler) doesn’t have the right CMSIS name, so it won’t be installed as the handler. However, if you uncomment that #define, then the FreeRTOS SysTick handler will have the right CMSIS name and will become the handler for SysTick IRQs. (See startup_stm32h743xx.s)

Enabled SysTick back again

Modified SystemClock_Config:

void SystemClock_Config(void)
{
	LL_FLASH_SetLatency(LL_FLASH_LATENCY_4);		/* Configure flash latency */
	if (LL_FLASH_GetLatency() != LL_FLASH_LATENCY_4)
		while (1) {}

	LL_PWR_ConfigSupply(LL_PWR_LDO_SUPPLY);			/* Config power supply, voltage scale */
	LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE0);

	LL_RCC_HSE_EnableBypass();				/* Configure HSE */
	LL_RCC_HSE_Enable();					/* Enable HSR */
	while (!LL_RCC_HSE_IsReady()) {}

	LL_RCC_PLL_SetSource(LL_RCC_PLLSOURCE_HSE);		/* PLL source = HSE */
	LL_RCC_PLL1P_Enable();
	LL_RCC_PLL1Q_Enable();
	LL_RCC_PLL1_SetVCOInputRange(LL_RCC_PLLINPUTRANGE_8_16);
	LL_RCC_PLL1_SetVCOOutputRange(LL_RCC_PLLVCORANGE_WIDE);
	LL_RCC_PLL1_SetM(1);
	LL_RCC_PLL1_SetN(120);
	LL_RCC_PLL1_SetP(2);
	LL_RCC_PLL1_SetQ(20);
	LL_RCC_PLL1_SetR(2);
	LL_RCC_PLL1_Enable();
	while (!LL_RCC_PLL1_IsReady()) {}

	/* Intermediate AHB prescaler 2 when target frequency clock is higher than 80 MHz */
	LL_RCC_SetAHBPrescaler(LL_RCC_AHB_DIV_2);
	LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL1);
	LL_RCC_SetSysPrescaler(LL_RCC_SYSCLK_DIV_1);
	LL_RCC_SetAHBPrescaler(LL_RCC_AHB_DIV_2);
	LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_2);
	LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_2);
	LL_RCC_SetAPB3Prescaler(LL_RCC_APB3_DIV_2);
	LL_RCC_SetAPB4Prescaler(LL_RCC_APB4_DIV_2);

//	/* Configure systick */
//	LL_Init1msTick(480000000);				/* SysTick = 1mS */
//	LL_SYSTICK_SetClkSource(LL_SYSTICK_CLKSOURCE_HCLK);

	LL_SetSystemCoreClock(480000000);			/* 480Mhz */
	LL_RCC_SetUSARTClockSource(LL_RCC_USART234578_CLKSOURCE_PCLK1);
}

Running , it looks thus:

 -------------------------
  -* STM32H7x TMR Test *-
 -------------------------
 (252) TMR_Thread: Start Timer

I was expecting to see the interrupts firing, but no joy. :-/

The FreeRTOSConfig.h file has this:

/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
standard names. */
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#ifdef USE_OS_SYSTICK
#define xPortSysTickHandler OS_SysTick
#else
#define xPortSysTickHandler SysTick_Handler
#endif

This project does not build as there are missing files. Would you please attach a complete buildable project.

Thanks.

Possible you hit an assert. It appears TIM2 is using interrupt priority 0 (the highest). That priority is too high to be making FreeRTOS API calls from. Do you have a working debugger to be able to see when you hit configASSERT() or stack overflow or malloc failure etc?

Thanks and Bingo!

Changing from Priority 0 to 5 did the trick!

NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),5, 0));
-------------------------
-* STM32H7x TMR Test *-
-------------------------
(252) TMR_Thread: Start Timer
(258) TMR_Thread: TIM2 Update
(258) TMR_Thread: TIM2 Update
(258) TMR_Thread: TIM2 Update
(258) TMR_Thread: TIM2 Update
(258) TMR_Thread: TIM2 Update
(258) TMR_Thread: TIM2 Update

@aggarg

The “missing files” are part of the Cube package: STM32Cube_FW_H7_V1.7.0

The LL (HAL) Files that I am using from the Cube package:
stm32h7xx_ll_pwr.c
stm32h7xx_ll_rcc.c
stm32h7xx_ll_utils.c
stm32h7xx_ll_adc.c

and nothing more.

The other files that I am using from the FreeRTOS (Cube H7 package itself)

heap_4.c
port.c
list.c
queue.c
timers.c
tasks.c

Now that works, when you have multiple peripherals: Ethernet, ADC, Timer and so on.
What priorities should be assigned to each ?

I guess the Ethernet peripheral should get a higher priority to avoid buffer overruns ?

For Cortex-M, it is essential that ISRs that make use of FreeRTOS APIs have a logical priority equal to or below that set by the configMAX_SYSCALL_INTERRUPT_PRIORITY.

Read more details here: https://www.freertos.org/RTOS-Cortex-M3-M4.html

There are many asserts to catch incorrect priority configuration - It is recommended to have configASSERT defined during development.

Thanks.