FreeRTOS v10.0.1 on STM32F4-discovery

Hi members & experitses,

My IDE is Ac6 Systemworkbech:
Eclipse IDE for C/C++ Developers
Version: Neon.3 Release (4.6.3)
Build id: 20170314-1500

My platform is STM32F4-Discovery.

I developed a FreeRTOS V10.0.1 four-thread program to blink the four LEDS on the platform. But those LEDs are not blinking at all, while the problem is able to be debugged.

Following are my source code and the debugging log. I wish you would like to view them and tell me what is wrong in my programming.

Thanks,
Tommy

Source

//******************************************************************************

include
include “stm32f4xx.h”
include “stm32f4_discovery.h” // LED3
include “stm32f4xx_hal_conf.h”
include “stm32f4xx_ll_utils.h”
//******************************************************************************

//******************************************************************************

include “FreeRTOS.h”
include “queue.h”
include “task.h”
include “croutine.h”
//******************************************************************************

void vLedBlinkBlue(void *pvParameters);
void vLedBlinkRed(void *pvParameters);
void vLedBlinkGreen(void *pvParameters);
void vLedBlinkOrange(void *pvParameters);

define STACK_SIZE_MIN 128 /* usStackDepth - the stack size DEFINED IN WORDS.*/

/**
* @brief System Clock Configuration
* The system Clock is configured as follow :
* System Clock source = PLL (HSE)
* SYSCLK(Hz) = 168000000
* HCLK(Hz) = 168000000
* AHB Prescaler = 1
* APB1 Prescaler = 4
* APB2 Prescaler = 2
* HSE Frequency(Hz) = 8000000
* PLL_M = 8
* PLL_N = 336
* PLL_P = 2
* PLL_Q = 7
* VDD(V) = 3.3
* Main regulator output voltage = Scale1 mode
* Flash Latency(WS) = 5
* @param None
* @retval None
*/
static void SystemClock_Config(void)
{
printf(“%s()@%u\n”, FUNCTION, LINE);
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;

/* Enable Power Control clock */
__HAL_RCC_PWR_CLK_ENABLE();

/* The voltage scaling allows optimizing the power consumption when the device is
clocked below the maximum system frequency, to update the voltage scaling value
regarding system frequency refer to product datasheet. */
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

/* Enable HSE Oscillator and activate PLL with HSE as source */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 7;
HAL_RCC_OscConfig(&RCC_OscInitStruct);

/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
clocks dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);

/* STM32F405x/407x/415x/417x Revision Z devices: prefetch is supported */
if (HAL_GetREVID() == 0x1001)
{
/* Enable the Flash prefetch */
__HAL_FLASH_PREFETCH_BUFFER_ENABLE();
}
}

extern void initialise_monitor_handles(void); // dec29tue20

//******************************************************************************
int main(void)
{
initialise_monitor_handles(); // dec29tue20
printf(“%s()@%u\n”, FUNCTION, LINE);
/* jan27wed21
* STM32F4xx HAL library initialization:
* Configure the Flash prefetch, instruction and Data caches
* Configure the Systick to generate an interrupt each 1 msec
* Set NVIC Group Priority to 4
* Global MSP (MCU Support Package) initialization
* jan27wed21 */
HAL_Init();

/* jan27wed21
* Configure the system clock to 168 MHz
* jan27wed21 */
SystemClock_Config();

/* jan27wed21
* HAL_Init() will call HAL_NVIC_SetPriorityGrouping() transparently.
* No need to call again.
* jan27wed21 */
// NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );
// HAL_NVIC_SetPriorityGrouping( NVIC_PriorityGroup_4 );
// HAL_NVIC_SetPriorityGrouping(4); // jan20wed21 temporary fix

BSP_LED_Init(LED3);
BSP_LED_Init(LED4);
BSP_LED_Init(LED5);
BSP_LED_Init(LED6);

xTaskCreate( vLedBlinkBlue, (const char* const)”Led Blink Task Blue”, STACK_SIZE_MIN, NULL, tskIDLE_PRIORITY, NULL );
xTaskCreate( vLedBlinkRed, (const char* const)”Led Blink Task Red”, STACK_SIZE_MIN, NULL, tskIDLE_PRIORITY, NULL );
xTaskCreate( vLedBlinkGreen, (const char* const)”Led Blink Task Green”, STACK_SIZE_MIN, NULL, tskIDLE_PRIORITY, NULL );
xTaskCreate( vLedBlinkOrange, (const char* const)”Led Blink Task Orange”, STACK_SIZE_MIN, NULL, tskIDLE_PRIORITY, NULL );

printf(“%s()@%u\n”, FUNCTION, LINE);
vTaskStartScheduler();
printf(“%s()@%u\n”, FUNCTION, LINE);
}
//******************************************************************************

//******************************************************************************
void vLedBlinkRed(void *pvParameters)
{
// printf(“%s()@%u\n”, FUNCTION, LINE);
for(;;)
{
BSP_LED_Toggle(LED6);
vTaskDelay( 750 / portTICK_RATE_MS );
}
}

void vLedBlinkGreen(void *pvParameters)
{
// printf(“%s()@%u\n”, FUNCTION, LINE);
for(;;)
{
BSP_LED_Toggle(LED4);
vTaskDelay( 250 / portTICK_RATE_MS );
}
}

void vLedBlinkOrange(void *pvParameters)
{
// printf(“%s()@%u\n”, FUNCTION, LINE);
for(;;)
{
BSP_LED_Toggle(LED5);
vTaskDelay( 900 / portTICK_RATE_MS );
}
}

//******************************************************************************
void vLedBlinkBlue(void *pvParameters)
{
// printf(“%s()@%u\n”, FUNCTION, LINE);
for(;;)
{
BSP_LED_Toggle(LED3);
vTaskDelay( 500 / portTICK_RATE_MS );
}
}

Console

main()@91
SystemClock_Config()@45
main()@124

Info : halted: PC: 0x08002ba2

Info : halted: PC: 0x08002ba2

Info : halted: PC: 0x08002ba2

Info : halted: PC: 0x08002ba2

Temporary breakpoint 8, main () at …/src/main.c:90
90 initialise_monitor_handles(); // dec29tue20

Breakpoint 2, vTaskDelay (xTicksToDelay=500) at …/Middlewares/Third_Party/FreeRTOS/Source/tasks.c:1320
1320 if( xAlreadyYielded == pdFALSE ) {

Breakpoint 2, vTaskDelay (xTicksToDelay=750) at …/Middlewares/Third_Party/FreeRTOS/Source/tasks.c:1320
1320 if( xAlreadyYielded == pdFALSE ) {

Breakpoint 2, vTaskDelay (xTicksToDelay=250) at …/Middlewares/Third_Party/FreeRTOS/Source/tasks.c:1320
1320 if( xAlreadyYielded == pdFALSE ) {

Breakpoint 2, vTaskDelay (xTicksToDelay=900) at …/Middlewares/Third_Party/FreeRTOS/Source/tasks.c:1320
1320 if( xAlreadyYielded == pdFALSE ) {

Program received signal SIGINT, Interrupt.
prvIdleTask (pvParameters=0x0) at …/Middlewares/Third_Party/FreeRTOS/Source/tasks.c:3264
3264 if( listCURRENT_LIST_LENGTH( &( pxReadyTasksLists tskIDLE_PRIORITY ) ) > ( UBaseType_t ) 1 )


Program received signal SIGINT, Interrupt.
prvIdleTask (pvParameters=0x0) at …/Middlewares/Third_Party/FreeRTOS/Source/tasks.c:3241
3241 prvCheckTasksWaitingTermination();


Program received signal SIGINT, Interrupt.
0x080030c4 in prvCheckTasksWaitingTermination () at …/Middlewares/Third_Party/FreeRTOS/Source/tasks.c:3479
3479 while( uxDeletedTasksWaitingCleanUp > ( UBaseType_t ) 0U )

Can you single step through one of the task loops ?
What happens e.g. when breaking at BSP_LED_Toggle(LED6); in vLedBlinkRed and step over (and repeat) ? Is the LED toggled ?
Then is stepping over vTaskDelay( 750 / portTICK_RATE_MS ); working ?
If not is the (sys)tick interrupt executing ? You can tell that by putting a break point in xTaskIncrementTick(), or checking the value of xTickCount in the debugger.
Have a look at the FreeRTOS FAQ – My application does not run, what could be wrong?. It contains valuable hints to avoid common pitfalls.
Another hint: Start with a reasonable stack size and optimize later if needed. The minimal stack size is indeed the bare minimum and might get quickly too small when adding some code.

Hartmut,
thanks for your comment. My schedule for FreeRTOS is tomorrow. I will update the post then.
Tommy

hs2 - Can you single step through one of the task loops ?
tommyclee -
Every task can be single-stepped through, but their for(;:wink: loops listed below, only executes once:
void vLedBlinkBlue(void *pvParameters)
{
// printf("%s()@%u\n", FUNCTION, LINE);
for(;:wink: {
BSP_LED_Toggle(LED6);
vTaskDelay( 750 / portTICK_RATE_MS );
}
}
hs2 -
What happens e.g. when breaking at BSP_LED_Toggle(LED6); in vLedBlinkRed and step over (and repeat) ? Is the LED toggled ?
Then is stepping over vTaskDelay( 750 / portTICK_RATE_MS ); working ?
What happens e.g. when breaking at BSP_LED_Toggle(LED6); in vLedBlinkRed and step over (and repeat) ? Is the LED toggled ?
Then is stepping over vTaskDelay( 750 / portTICK_RATE_MS ); working ?
tommyclee -
It works but only once - no occurrence of repeation as stated above.
hr2 -If not is the (sys)tick interrupt executing ? You can tell that by putting a break point in xTaskIncrementTick(), or checking the value of xTickCount in the debugger.
tommyclee
When the last task was single-stepped through, the execution is going on. The hit on the Suspend botton shows the Debug window shown as below:

FreeRTOS Debug [Ac6 STM32 Debugging]
FreeRTOS.elf
Thread #1 (Suspended : Signal : SIGINT:Interrupt)
prvCheckTasksWaitingTermination() at tasks.c:3,479 0x80030c4
prvIdleTask() at tasks.c:3,241 0x8002fe0
pxPortInitialiseStack() at port.c:214 0x800327c
openocd
gdb
I need to investigate the above calling stack to find out the cause of the SIGINT interruption.
Also, the xTaskCreate() needs to be evaluated.

I wish more comments on this post.

Have a look at the FreeRTOS FAQ – My application does not run, what could be wrong?. It contains valuable hints to avoid common pitfalls.
Another hint: Start with a reasonable stack size and optimize later if needed. The minimal stack size is indeed the bare minimum and might get quickly too small when adding some code.

Do your LEDs work at all?

If you wrote your own startup code, it’s reasonably common to forget to turn on the clock to the GPIO ports. If you use CubeMX to generate the startup code, it tends to work a whole lot better.

I wouldn’t assume that your use of an RTOS is a problem yet. Start at the start, put an infinite loop into main() before you start the scheduler, and just blink the LEDs. HAL GPIO toggle with a HAL Delay in an infinite loop.

Also, when you get this going, download a more recent version of FreeRTOS. 10.0.1 was released 3 years ago. I’m sure you don’t want to be debugging issues that were fixed already.

andrei -
If you wrote your own startup code, it’s reasonably common to forget to turn on the clock to the GPIO ports. If you use CubeMX to generate the startup code, it tends to work a whole lot better.
tommyclee -
I wrote my own startup code. The HAL_Init() and SystemClock_Config() are the only two pieces of of code I borrowed from the STM32F4-DISCO project. I need to check whether the clock to the GPIO ports has been turned on.
andrei -
I wouldn’t assume that your use of an RTOS is a problem yet. Start at the start, put an infinite loop into main() before you start the scheduler, and just blink the LEDs. HAL GPIO toggle with a HAL Delay in an infinite loop.
tommyclee -
I have used the project at STM32Cube_FW_F4_V1.24.0/Projects/STM32F4-Discovery/Demonstrations/SW4STM32/STM32F4-DISCO and verified the functinality of four LEDs on my STM32F4-Discovery platform. Based on that success, I created a FreeRTOS v10.0.1 project to try to blink that four LEDs. But these LEDs cannot blink, though the ELF of that project is still running, actually SIGINT interrpted.
andrei -Also, when you get this going, download a more recent version of FreeRTOS. 10.0.1 was released 3 years ago. I’m sure you don’t want to be debugging issues that were fixed already.
tommyclee -
Of course, I won’t debugging the issues that were fixed already. Replacing v10.0.1 with the latest stable verion might resolve my problem.

Using a newer/the latest FreeRTOS is recommended, but I think I’ll not solve your issue.
If the loop code runs just once it seems to me that the tasks are not woken up after the expected delay. So either the FreeRTOS systick isn’t running or the correct Systick_Handler isn’t installed properly or the clock related FreeRTOS config (configCPU_CLOCK_HZ/configTICK_RATE_HZ) is broken.
As far as I know on STM32 using HAL the Systick might be used by HAL and another TIMer interrupt is needed as FreeRTOS systick…

hs2 - Using a newer/the latest FreeRTOS is recommended, but I think I’ll not solve your issue.
tclee -
I think so. I am still trying to resolve my problem using v10.0.1.
hs2 - If the loop code runs just once it seems to me that the tasks are not woken up after the expected delay. So either the FreeRTOS systick isn’t running
tclee -
The FreeRTOS systick is running. My run-time investigation shows that HAL_InitTick() is called
twice with TickPriority == 15, e.g. The time source is configured to have 1ms
time base with a dedicated tick interrupt priority (#define TICK_INT_PRIORITY
(0x0FU). I have commented out the bare HAL_Iit(); used my SystemClock_Config() which initializes the system clock at 168MHz and calls HAL_Init(), to avoid the duplication.
hs2 - or the correct Systick_Handler isn’t installed properly
tclee -
I uncommented "comment-out “#define xPortSysTickHandler SysTick_Handler;” in my FreeRTOSConfig.h and encountered double Systick_Handler() definitions. I commented out “void SysTick_Handler(void)” in my stm32f4xx_it.c and used “void xPortSysTickHandler( void )” in my port.c.

The Debug windows shows the occurrence of the SysTick_Handler() but the infinitive loop of Default_Handler() happened as below:
FreeRTOS Debug [Ac6 STM32 Debugging]
FreeRTOS.elf
Thread #1 (Suspended : Signal : SIGINT:Interrupt)
WWDG_IRQHandler() at startup_stm32f407xx.s:127 0x8003dbc
() at 0xfffffff1
xTaskIncrementTick() at tasks.c:2,643 0x8002e54
SysTick_Handler() at port.c:500 0x80035a4
0xffffffe8
openocd
gdb
I am trying to find out the cause of the unexpected calling to Default_Handler(). Please comment on the above Debug window.

hs2 - or the clock related FreeRTOS config (configCPU_CLOCK_HZ/configTICK_RATE_HZ ) is broken.
tclee -
I ahve not got chance to work on this clue.
As far as I know on STM32 using HAL the Systick might be used by HAL and another TIMer interrupt is needed as FreeRTOS systick…

Just to be clear, in your FreeRTOSConfig.h you have these handlers defined ?

#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler

and you are using the provided FreeRTOS handlers, right ?

When using SysTick for FreeRTOS and also HAL ensure that SysTick it’s not (longer) used as HAL tick and use another TIMer for HAL instead. Or vice versa.

In case you want to re-generate an FreeRTOS example project with CubeMX maybe have a look at this post:

-----hs2-feb19fri21
Just to be clear, in your FreeRTOSConfig.h you have these handlers defined ?

#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler
and you are using the provided FreeRTOS handlers, right ?

-----tclee-feb23tue21
Yes, I am using the provided FreeRTOS handlers as below (in my inc/FreeRTOSConfig.h):

#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler // feb18thu21
#endif /* FREERTOS_CONFIG_H */

-----hs2-feb19fri21
When using SysTick for FreeRTOS and also HAL ensure that SysTick it’s not (longer) used as HAL tick and use another TIMer for HAL instead. Or vice versa.

----tclee-feb23tue21
With my SystemClock_Config(void) in my src/main.c commented out, the four LEDs are blinking at one frequency. I need to do the run-time investigation to see my four LED threads’ behavior.