I’ve set up a project with LL library using TIM7 as the clock source for FreeRTOS, where FreeRTOS is configured outside CubeMX. Running on STM32H743ZI2 Nucleo board
Everything works independently, but not with vTaskStartScheduler(). Without vTaskStartScheduler, the timer, UART, ticks, everything works correctly. It is a simple blink program, but I am not able to decipher if it is a problem with interrupt priority for TIMER7 (which needs to be high since it is the clock source of FreeRTOS) or stack issue or something else entirely. Completely set up by m,e but just stuck very close to working condition. Please help.
main.c
int main(void)
{
MPU_Config();
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_UART4_Init();
MX_TIM7_Init();
BSP_LED_Init(LED_GREEN);
BSP_LED_Init(LED_YELLOW);
BSP_LED_Init(LED_RED);
char stringForError[] = "Error for freeRTOS 0";
char stringForSucceess0[] = "Success for freeRTOS 0";
LL_TIM_EnableCounter(TIM7); // Start counting
write_data_to_uart((uint8_t *)&stringForSucceess0, sizeof(stringForSucceess0));
TaskHandle_t xTaskHandle1;
TaskHandle_t xTaskHandle2;
TaskStatus_t xTaskDetails;
eTaskState xTaskState;
BaseType_t ret = xTaskCreate(blinkLeds, "Blink_Multiple_LED", 128 * 2, NULL, configMAX_PRIORITIES - 2, &xTaskHandle1);
if(ret != pdPASS){
write_data_to_uart((uint8_t *)&stringForError, sizeof(stringForError));
write_data_to_uart((uint8_t *)&ret, sizeof(ret));
LL_GPIO_TogglePin(GPIOE, LL_GPIO_PIN_1);
}
ret = xTaskCreate(blinkLED, "Blink_1_LED" , 128 * 2, NULL, configMAX_PRIORITIES - 2, &xTaskHandle2);
if(ret != pdPASS){
write_data_to_uart((uint8_t *)&stringForError, sizeof(stringForError));
write_data_to_uart((uint8_t *)&ret, sizeof(ret));
LL_GPIO_TogglePin(GPIOB, LL_GPIO_PIN_14);
}
char stringForSucceess[] = "Success for freeRTOS 1";
write_data_to_uart((uint8_t *)&stringForSucceess, sizeof(stringForSucceess));
markTaskScheduleRunning();
vTaskStartScheduler();
while (1)
{
}
}
static void MX_TIM7_Init(void)
{
LL_TIM_InitTypeDef TIM_InitStruct = {0};
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM7);
NVIC_SetPriority(TIM7_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 1, 0));
NVIC_EnableIRQ(TIM7_IRQn);
LL_TIM_EnableIT_UPDATE(TIM7);
TIM_InitStruct.Prescaler = 63;
TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
TIM_InitStruct.Autoreload = 999;
LL_TIM_Init(TIM7, &TIM_InitStruct);
LL_TIM_EnableARRPreload(TIM7);
LL_TIM_SetTriggerOutput(TIM7, LL_TIM_TRGO_UPDATE);
LL_TIM_DisableMasterSlaveMode(TIM7);
}
static void blinkLeds(void *argument){
write_data_to_uart((uint8_t*)(&stringForMessage1), sizeof(stringForMessage1));
LL_GPIO_TogglePin(GPIOB, LL_GPIO_PIN_14| LL_GPIO_PIN_0);
vTaskDelay(pdMS_TO_TICKS(500));
}
static void blinkLED(void *argument){
write_data_to_uart((uint8_t*)(&stringForMessage2), sizeof(stringForMessage2));
LL_GPIO_TogglePin(GPIOE, LL_GPIO_PIN_1);
vTaskDelay(pdMS_TO_TICKS(1000));
}
void vApplicationIdleHook(void)
{
char stringForIdle[] = "Idle task is running";
write_data_to_uart((uint8_t*)(&stringForIdle), sizeof(stringForIdle));
vTaskDelay(pdMS_TO_TICKS(1000));
}
FreeRTOSConfig.h
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
extern uint32_t SystemCoreClock;
/******************************************************************************/
/* Hardware description related definitions. **********************************/
/******************************************************************************/
#define configCPU_CLOCK_HZ ( SystemCoreClock )
/******************************************************************************/
/* Scheduling behaviour related definitions. **********************************/
/******************************************************************************/
#define configTICK_RATE_HZ ( ( unsigned long ) 1000 )
#define configUSE_SYS_TICK 0 // Ensure SysTick is enabled for FreeRTOS
#define configUSE_PREEMPTION 1
#define configUSE_TIME_SLICING 1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
#define configUSE_TICKLESS_IDLE 1
#define configMAX_PRIORITIES 5U
#define configMINIMAL_STACK_SIZE 128U
#define configMAX_TASK_NAME_LEN 8U
#define configTICK_TYPE_WIDTH_IN_BITS TICK_TYPE_WIDTH_32_BITS
#define configIDLE_SHOULD_YIELD 1
#define configTASK_NOTIFICATION_ARRAY_ENTRIES 1U
#define configQUEUE_REGISTRY_SIZE 0U
#define configENABLE_BACKWARD_COMPATIBILITY 1
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 0
#define configSTACK_DEPTH_TYPE size_t
#define configMESSAGE_BUFFER_LENGTH_TYPE size_t
#define configUSE_NEWLIB_REENTRANT 0
/******************************************************************************/
/* Software timer related definitions. ****************************************/
/******************************************************************************/
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1U )
#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
#define configTIMER_QUEUE_LENGTH 10U
/******************************************************************************/
/* Memory allocation related definitions. *************************************/
/******************************************************************************/
#define configSUPPORT_STATIC_ALLOCATION 1
#define configSUPPORT_DYNAMIC_ALLOCATION 1
#define configTOTAL_HEAP_SIZE (16 * 1024U)
#define configAPPLICATION_ALLOCATED_HEAP 0
#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0
#define configUSE_MINI_LIST_ITEM 0
/******************************************************************************/
/* Interrupt nesting behaviour configuration. *********************************/
/******************************************************************************/
/*
#define configKERNEL_INTERRUPT_PRIORITY 0U
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 0U
#define configMAX_API_CALL_INTERRUPT_PRIORITY 0U
*/
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
#define __NVIC_PRIO_BITS 4U
#define configMAX_SYSCALL_INTERRUPT_PRIORITY (5 << (8 - __NVIC_PRIO_BITS)) // = 80
/******************************************************************************/
/* Hook and callback function related definitions. ****************************/
/******************************************************************************/
#define configUSE_IDLE_HOOK 1
#define configUSE_TICK_HOOK 0
#define configUSE_MALLOC_FAILED_HOOK 1
#define configUSE_DAEMON_TASK_STARTUP_HOOK 0
#define configCHECK_FOR_STACK_OVERFLOW 2
/******************************************************************************/
/* Run time and task stats gathering related definitions. *********************/
/******************************************************************************/
#define configGENERATE_RUN_TIME_STATS 0
#define configUSE_TRACE_FACILITY 1
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
#define configKERNEL_PROVIDED_STATIC_MEMORY 1
/******************************************************************************/
/* Definitions that include or exclude functionality. *************************/
/******************************************************************************/
#define configUSE_TASK_NOTIFICATIONS 1
#define configUSE_MUTEXES 1
#define configUSE_RECURSIVE_MUTEXES 1
#define configUSE_COUNTING_SEMAPHORES 1
#define configUSE_QUEUE_SETS 1
#define configUSE_APPLICATION_TASK_TAG 1
#define configOVERRIDE_DEFAULT_TICK_CONFIGURATION 1
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_xResumeFromISR 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_xTaskGetCurrentTaskHandle 1
#define INCLUDE_uxTaskGetStackHighWaterMark 1
#define INCLUDE_xTaskGetIdleTaskHandle 1
#define INCLUDE_eTaskGetState 1
#define INCLUDE_xEventGroupSetBitFromISR 1
#define INCLUDE_xTimerPendFunctionCall 1
#define INCLUDE_xTaskAbortDelay 1
#define INCLUDE_xTaskGetHandle 1
#define INCLUDE_xTaskResumeFromISR 1
#define vPortSVCHandler vPortSVCHandler
#define xPortPendSVHandler xPortPendSVHandler
#define xPortSysTickHandler xPortSysTickHandler
#endif /* FREERTOS_CONFIG_H */
stm32h7xx_it.c:
static uint32_t counter = 0;
static char data[] = "1 second done!!!\r";
static char stringForSysTick[] = "SysTick is running\r";
static bool isTaskScheduleRunning = false;
void xPortSysTickHandler(void);
void markTaskScheduleRunning(void);
void TIM7_IRQHandler(void)
{
if (LL_TIM_IsActiveFlag_UPDATE(TIM7)) {
if(isTaskScheduleRunning){
xPortSysTickHandler();
}
counter++;
if (counter == 1000) {
counter = 0;
write_data_to_uart((uint8_t *)&data, sizeof(data));
if(isTaskScheduleRunning){
write_data_to_uart((uint8_t *)&stringForSysTick, sizeof(stringForSysTick));
}
}
}
void markTaskScheduleRunning(void){
char stringForTaskSchedule[] = "Task schedule is running\r";
write_data_to_uart((uint8_t *)&stringForTaskSchedule, sizeof(stringForTaskSchedule));
isTaskScheduleRunning = true;
} LL_TIM_ClearFlag_UPDATE(TIM7);
}