Basic task for blinking not working

I have created a basic task just to blink an LED. After debugging, it seems like the task was entered but it did not run further.
I am trying to add FreeRTOS manually (without any config or code generator) in STM32F407VET6 board. IDE used is STM32Cube.

#include "main.h"

void GPIO_INIT(void);
void TaskHeartBeat(void *pvParameters);
void swDelay (unsigned int T);
int main(void)
{
	SystemClockSetup();
	GPIO_INIT();
	UART_INIT(115200, UART_NoParity);

	//SET_HIGH(LED2);
	SET_HIGH(LED1);
	if(xTaskCreate(TaskHeartBeat, "HeartBeat", configMINIMAL_STACK_SIZE, NULL, 2, NULL))
		UART_TxSTRING("#TC ");
        vTaskStartScheduler();
	for(;;);	
}


void TaskHeartBeat(void *pvParameters)
{
	 for(;;)
	 {
		TOGGLE(LED1);
		TOGGLE(LED2);
		UART_TxSTRING("#A ");
		vTaskDelay(pdMS_TO_TICKS(1000));
	 }
	 vTaskDelete(NULL);
}

#TC was printed successfully.
I tried to print a message “#A” inside the task but only # was received on the Serial Terminal. I am not able to figure out where this is failing.

Below is a snapshot of FreeRTOSConfig.h

#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
  #include <stdint.h>
  extern uint32_t SystemCoreClock;
#endif
#ifndef CMSIS_device_header
#define CMSIS_device_header "stm32f4xx.h"
#endif /* CMSIS_device_header */

#define configENABLE_FPU                         0
#define configENABLE_MPU                         0

#define configUSE_PREEMPTION                     1
#define configSUPPORT_STATIC_ALLOCATION          0
#define configSUPPORT_DYNAMIC_ALLOCATION         1
#define configUSE_IDLE_HOOK                      0
#define configUSE_TICK_HOOK                      0
#define configCPU_CLOCK_HZ                       ( 8000000 )
#define configTICK_RATE_HZ                       ((TickType_t)1000)
#define configMAX_PRIORITIES                     ( 56 )
#define configMINIMAL_STACK_SIZE                 ((uint16_t)128)
#define configTOTAL_HEAP_SIZE                    ((size_t)15360)
#define configMAX_TASK_NAME_LEN                  ( 16 )
#define configUSE_TRACE_FACILITY                 1
#define configUSE_16_BIT_TICKS                   0
#define configUSE_MUTEXES                        1
#define configQUEUE_REGISTRY_SIZE                8
#define configUSE_RECURSIVE_MUTEXES              1
#define configUSE_COUNTING_SEMAPHORES            1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION  0
/* USER CODE BEGIN MESSAGE_BUFFER_LENGTH_TYPE */
/* Defaults to size_t for backward compatibility, but can be changed
   if lengths will always be less than the number of bytes in a size_t. */
#define configMESSAGE_BUFFER_LENGTH_TYPE         size_t

These two are the UART functions if needed for reference

void UART_TxSTRING (char *string)		
{	
	for(unsigned char i=0 ; *(string + i) != '\0' ; i++)
		UART_TxBYTE(*(string+i));
}

void UART_TxBYTE(char tx_data)
{	
	while(!(USART1->SR & USART_SR_TC));
		UART_DREG = (tx_data & 0xFF);  //UART_DREG is a macro for USART1->DR
}

It’s maybe not the problem but I wouldn’t recommend to use configMINIMAL_STACK_SIZE for your application tasks(s). Simply because usually it’s just not enough. Better start with a larger size und tailor it later.
Also you should define configASSERT , enable stack overflow checking for development/debugging. That’s very helpful.
Is the FreeRTOS SysTick working as expected resp. is TaskHeartBeat toggling the LEDs with the right frequency when commenting out UART_TxSTRING ?

Thank you for the response.
Even if i remove UART_TxString(), the result is same. The LEDs just toggle once. I even used 500 instead of configMINIMAL_STACK_SIZE but the issue is still there.

Then it seems the SysTick isn’t ticking.
In case you use the defaults:
in FreeRTOSConfig.h

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

and verify the corresponding entries in your exception table:

...
    .pfnSVC_Handler         = (void*) SVC_Handler,
...
    .pfnPendSV_Handler      = (void*) PendSV_Handler,
    .pfnSysTick_Handler     = (void*) SysTick_Handler,

Do you have a debugger attached ? Then you could easily check, that the SysTick_Handler or alternatively the FreeRTOS function xTaskIncrementTick is invoked periodically after starting the scheduler.

I am currently using the Chinese ST-Link V2. It doesn’t support debugging as of now. Might need to tweak its hardware to get the debugger running.
Also I figured out that configCPU_CLOCK_HZ should be 168MHz instead of 8MHz (as 8MHz is the Xtal Freq. which is then fed to the PLL)
Where can I find that exception table?

The broken clock config might be also the reason for a (very) wrong tick rate.
The exception table is part of the sources. Just grep for … SysTick_Handler or Reset_Handler and I’m sure you’ll find it.
ST-Link V2 should be fine. Better try to get the debugger working. Believe me, you’ll really need it sooner or later :wink:

/******************************************************************************
*
* The minimal vector table for a Cortex M3. Note that the proper constructs
* must be placed on this to ensure that it ends up at physical address
* 0x0000.0000.
* 
*******************************************************************************/
   .section  .isr_vector,"a",%progbits
  .type  g_pfnVectors, %object
  .size  g_pfnVectors, .-g_pfnVectors
    
    
g_pfnVectors:
  .word  _estack
  .word  Reset_Handler
  .word  NMI_Handler
  .word  HardFault_Handler
  .word  MemManage_Handler
  .word  BusFault_Handler
  .word  UsageFault_Handler
  .word  0
  .word  0
  .word  0
  .word  0
  .word  SVC_Handler
  .word  DebugMon_Handler
  .word  0
  .word  PendSV_Handler
  .word  SysTick_Handler
  
  /* External Interrupts */
  .word     WWDG_IRQHandler                   /* Window WatchDog              */                                        
  .word     PVD_IRQHandler                    /* PVD through EXTI Line detection */                        
  .word     TAMP_STAMP_IRQHandler             /* Tamper and TimeStamps through the EXTI line */            
  .word     RTC_WKUP_IRQHandler               /* RTC Wakeup through the EXTI line */                      
  .word     FLASH_IRQHandler                  /* FLASH                        */                                          
  .word     RCC_IRQHandler                    /* RCC                          */                                            
  .word     EXTI0_IRQHandler                  /* EXTI Line0                   */                        
  .word     EXTI1_IRQHandler                  /* EXTI Line1                   */                          
  .word     EXTI2_IRQHandler                  /* EXTI Line2                   */                          
  .word     EXTI3_IRQHandler                  /* EXTI Line3                   */                          
  .word     EXTI4_IRQHandler                  /* EXTI Line4                   */                          
  .word     DMA1_Stream0_IRQHandler           /* DMA1 Stream 0                */                  
  .word     DMA1_Stream1_IRQHandler           /* DMA1 Stream 1                */                   
  .word     DMA1_Stream2_IRQHandler           /* DMA1 Stream 2                */                   
  .word     DMA1_Stream3_IRQHandler           /* DMA1 Stream 3                */                   
  .word     DMA1_Stream4_IRQHandler           /* DMA1 Stream 4                */                   
  .word     DMA1_Stream5_IRQHandler           /* DMA1 Stream 5                */                   
  .word     DMA1_Stream6_IRQHandler           /* DMA1 Stream 6                */                   
  .word     ADC_IRQHandler                    /* ADC1, ADC2 and ADC3s         */                   
  .word     CAN1_TX_IRQHandler                /* CAN1 TX                      */                         
  .word     CAN1_RX0_IRQHandler               /* CAN1 RX0                     */                          
  .word     CAN1_RX1_IRQHandler               /* CAN1 RX1                     */                          
  .word     CAN1_SCE_IRQHandler               /* CAN1 SCE                     */                          
  .word     EXTI9_5_IRQHandler                /* External Line[9:5]s          */                          
  .word     TIM1_BRK_TIM9_IRQHandler          /* TIM1 Break and TIM9          */         
  .word     TIM1_UP_TIM10_IRQHandler          /* TIM1 Update and TIM10        */         
  .word     TIM1_TRG_COM_TIM11_IRQHandler     /* TIM1 Trigger and Commutation and TIM11 */
  .word     TIM1_CC_IRQHandler                /* TIM1 Capture Compare         */                          
  .word     TIM2_IRQHandler                   /* TIM2                         */                   
  .word     TIM3_IRQHandler                   /* TIM3                         */                   
  .word     TIM4_IRQHandler                   /* TIM4                         */                   
  .word     I2C1_EV_IRQHandler                /* I2C1 Event                   */                          
  .word     I2C1_ER_IRQHandler                /* I2C1 Error                   */                          
  .word     I2C2_EV_IRQHandler                /* I2C2 Event                   */                          
  .word     I2C2_ER_IRQHandler                /* I2C2 Error                   */                            
  .word     SPI1_IRQHandler                   /* SPI1                         */                   
  .word     SPI2_IRQHandler                   /* SPI2                         */                   
  .word     USART1_IRQHandler                 /* USART1                       */                   
  .word     USART2_IRQHandler                 /* USART2                       */                   
  .word     USART3_IRQHandler                 /* USART3                       */                   
  .word     EXTI15_10_IRQHandler              /* External Line[15:10]s        */                          
  .word     RTC_Alarm_IRQHandler              /* RTC Alarm (A and B) through EXTI Line */                 
  .word     OTG_FS_WKUP_IRQHandler            /* USB OTG FS Wakeup through EXTI line */                       
  .word     TIM8_BRK_TIM12_IRQHandler         /* TIM8 Break and TIM12         */         
  .word     TIM8_UP_TIM13_IRQHandler          /* TIM8 Update and TIM13        */         
  .word     TIM8_TRG_COM_TIM14_IRQHandler     /* TIM8 Trigger and Commutation and TIM14 */
  .word     TIM8_CC_IRQHandler                /* TIM8 Capture Compare         */                          
  .word     DMA1_Stream7_IRQHandler           /* DMA1 Stream7                 */                          
  .word     FSMC_IRQHandler                   /* FSMC                         */                   
  .word     SDIO_IRQHandler                   /* SDIO                         */                   
  .word     TIM5_IRQHandler                   /* TIM5                         */                   
  .word     SPI3_IRQHandler                   /* SPI3                         */                   
  .word     UART4_IRQHandler                  /* UART4                        */                   
  .word     UART5_IRQHandler                  /* UART5                        */                   
  .word     TIM6_DAC_IRQHandler               /* TIM6 and DAC1&2 underrun errors */                   
  .word     TIM7_IRQHandler                   /* TIM7                         */
  .word     DMA2_Stream0_IRQHandler           /* DMA2 Stream 0                */                   
  .word     DMA2_Stream1_IRQHandler           /* DMA2 Stream 1                */                   
  .word     DMA2_Stream2_IRQHandler           /* DMA2 Stream 2                */                   
  .word     DMA2_Stream3_IRQHandler           /* DMA2 Stream 3                */                   
  .word     DMA2_Stream4_IRQHandler           /* DMA2 Stream 4                */                   
  .word     ETH_IRQHandler                    /* Ethernet                     */                   
  .word     ETH_WKUP_IRQHandler               /* Ethernet Wakeup through EXTI line */                     
  .word     CAN2_TX_IRQHandler                /* CAN2 TX                      */                          
  .word     CAN2_RX0_IRQHandler               /* CAN2 RX0                     */                          
  .word     CAN2_RX1_IRQHandler               /* CAN2 RX1                     */                          
  .word     CAN2_SCE_IRQHandler               /* CAN2 SCE                     */                          
  .word     OTG_FS_IRQHandler                 /* USB OTG FS                   */                   
  .word     DMA2_Stream5_IRQHandler           /* DMA2 Stream 5                */                   
  .word     DMA2_Stream6_IRQHandler           /* DMA2 Stream 6                */                   
  .word     DMA2_Stream7_IRQHandler           /* DMA2 Stream 7                */                   
  .word     USART6_IRQHandler                 /* USART6                       */                    
  .word     I2C3_EV_IRQHandler                /* I2C3 event                   */                          
  .word     I2C3_ER_IRQHandler                /* I2C3 error                   */                          
  .word     OTG_HS_EP1_OUT_IRQHandler         /* USB OTG HS End Point 1 Out   */                   
  .word     OTG_HS_EP1_IN_IRQHandler          /* USB OTG HS End Point 1 In    */                   
  .word     OTG_HS_WKUP_IRQHandler            /* USB OTG HS Wakeup through EXTI */                         
  .word     OTG_HS_IRQHandler                 /* USB OTG HS                   */                   
  .word     DCMI_IRQHandler                   /* DCMI                         */                   
  .word     0                                 /* CRYP crypto                  */                   
  .word     HASH_RNG_IRQHandler               /* Hash and Rng                 */
  .word     FPU_IRQHandler                    /* FPU                          */
                         

The vector table was found in the startup file. But i couldn’t understand how it should be. I compared the startup file with the one used in a working FreeRTOS project, not much difference was found.

Looks good - it’s standard. The check was only to be sure that e.g. the symbol / ISR function SysTick_Handler is exactly the same in the table and in the code.
Using a debugger and breakpoint in this function and check that it’s hit is more easy to verify that the SysTick works :wink:
So does your FreeRTOSConfig.h contain the Handler defines mentioned before and is the CLOCK config fixed ? Then it should blink :slight_smile:

The clock configuration for the MCu was already proper. It has worked always. Even after changing the configCPU_CLOCK_HZ, it didn’t work. The name of handlers are also there in Config file as they should be.
So as a quicker solution, I had to create a new project with FreeRTOS using the IDE’s code generator (as it always gives working code). Then I manually added my own code elements one by one. Now it is working perfectly as if I made an empty project.
Though if this issue happens again in future, I might need to get into it deeper and also get the debugger running.
Thank you so much for your support.