Integrating FreeRTOS and STM HAL Libraries
Keywords: Embedded systems, ARM, FreeRTOS, Tick Timer, HAL Libraries, STM32F4
Code Link: Tutorial Source Code Github – Keil
By the time i was writing FreeRTOS tutorials, I thought of making FreeRTOS tutorial (on STM32F4 Platform) by integrating FreeRTOS with Standard Peripheral Libraries provided by ST Microelectronics as part of their STMxx Microcontroller series. While downloading Standard Peripheral Library, there was an indication of cutting future MCUs support in Standard Peripheral Libraries. The ST Microelectronics itself is pushing hard the new HAL libraries to be considered for programming STM Microcontrollers. So in short I decided to switch to new HAL Libraries.
While creating simple tasks, that blinks LEDs, using FreeRTOS and HAL libraries, i found that both the FreeRTOS and HAL libraries uses ARM on Core 24-bits count down Timer called SysTick timer. FreeRTOS uses SysTick as tick timer on ARM Cortex-M cores for scheduling tasks while HAL libraries use Systick for generating fixed delay of 1msec (or multiple of 1msec) for various APIs operations.
The time requirements of both FreeRTOS and HAL Libraries converges when both freeRTOS Tick Timer and HAL Libraries delay timer needs to tick at the same rate of 1msec. In HAL libraries Systick interrupt is fixed at 1msec while in case of FreeRTOS, tick timer interrupt rate is not fixed and configurable via configTICK_RATE_HZ. So ultimately at some point there may be a conflict of interests for different tick rates and same timer may not be used to serve both. Thats the point where you have to consider to use separate independent timers to serve each. This tutorial is all about resolving this point of conflict. Let’s get started.
Steps:
1. The first step is to create a minimal project based on FreeRTOS and STM HAL Libraries. This is relatively easy step, still if you are stuck at some point, you can refer to the the following tutorial or use the example project provided with this tutorial at github.
2. Next is to initiate HAL libraries to be used ahead.
/* initialize HAL Library. This step is mandatory for HAL libraries to work properly. It configures SysTick etc. for its internal configurations. */ HAL_Init();
Once the HAL_Init() gets executed on STM32F4 MCU, the MCU exists in the following state:
* Configure the Flash prefetch, instruction and Data caches. * Configures the SysTick to generate an interrupt each 1 millisecond, * which is clocked by the HSI (at this stage, the clock is not yet * configured and thus the system is running from the internal HSI at 16 MHz). * Set NVIC Group Priority to 4. HAL Library Documentation
3. As documented, after HAL_Init, NVIC is set to Priority Group-4. FreeRTOS highly recommend to set the priority grouping to only 0 i.e. preempt priorities only. For further information on ARM Cortex-M priority and Priority Grouping, refer to the following tutorial.
So in accordance to FreeRTOS recommendation, let’s set the priority grouping to 0.
/* HAL_Init() sets the default priority grouping to 4U (3-premption, 1-sub priority). FreeRTOS highly recommend to set the priority grouping to only 0 i.e. preempt priorities only. webLink: https://www.freertos.org/RTOS-Cortex-M3-M4.html */ NVIC_SetPriorityGrouping(0U);
4. The next step is to decide and configure a general purpose timer (other than Systick Timer) to be used as a tick timer. In our case we have decided to use STM32 general purpose Timer-2 to be configured for FreeRTOS tick timer. The Tick timer configuration needs to use FreeRTOS specific APIs to be called by FreeRTOS kernel scheduler to start timer and catch its interrupt/tick. The following tutorial explains this very well. we will not repeat the same process here again. The main difference between the previous tutorial code and this is the use of HAL libraries. In this tutorial we will configure timer using STM HAL libraries.
/********************************************* From FreeRTOSConfig.h configTICK_RATE_HZ = 1000 So Timer-2 needs to be configured to generate 1msec delay that matches configTICK_RATE_HZ rate. *********************************************/ void vPortSetupTimerInterrupt (void) { /* Enable clock to Timer-2 NOTE: This is lagacy Macro. The better approach is the use of HAL_TIM_ConfigClockSource function. */ __HAL_RCC_TIM2_CLK_ENABLE(); /* From STM32F407 datasheet, Timer2 is clocked from APB1 bus (42Mhz max). In default configuration Timer-2 is receiving 16Mhz (HSI) bus clock. */ /*************************************************** Timer-2 Configuration: ****************************************************/ /* Select Timer-2 for further configuration */ TIM_InitStruct.Instance = TIM2; /* Divide the timer-2 input frequency (16Mhz) by a factor of 1000 (16,000,000/1,000 = 16,000 = 16Khz) */ TIM_InitStruct.Init.Prescaler = 1000; #if (UP_COUNTER) /* Up-Counter mode*/ TIM_InitStruct.Init.CounterMode = TIM_COUNTERMODE_UP; #else TIM_InitStruct.Init.CounterMode = TIM_COUNTERMODE_DOWN; #endif /* As configTICK_RATE_HZ = 1000, so tick timer need to generate interrupt at the rate of 1000/sec (1msec delay). As the input frequency is 16khz so the total counts required for 1msec delay: total counts = 1msec * f = 0.001 * 16,000 = 16 */ TIM_InitStruct.Init.Period = 16; /* Finally initialize Timer-2 */ while (HAL_TIM_Base_Init(&TIM_InitStruct)!= HAL_OK); /* Enable interrupt at IRQ-Level */ HAL_NVIC_EnableIRQ(TIM2_IRQn); /* Tick timer should have least priority In STM32F4, the lowest Prioirty is 0xf. */ NVIC_SetPriority(TIM2_IRQn,0x0fU); /* Start Timer and enable timer-2 IRQ interrupt */ HAL_TIM_Base_Start_IT(&TIM_InitStruct); }
5. Implement the timer ISR to be called on every timer interrupt. In our case as we are using Timer-2 so the default timer ISR in Keil is TIM2_IRQHandler. The ISR should do two things. First it should clear the interrupt flag so that next interrupt is generated. This is the first step that must be done in timer ISR to reduce ticks latency. Next is to call xPortSysTickHandler() function in timer ISR to inform scheduler for a timer tick. The following code snippet shows Timer-2 ISR implemented in HAL stm32f4xx_it.c file.
void TIM2_IRQHandler (void) { /* clear timer interrupt */ __HAL_TIM_CLEAR_IT(&TIM_InitStruct, TIM_IT_UPDATE); /* call the FreeRTOS kernel for a tick update*/ xPortSysTickHandler(); }
6. For demonstration purpose we will configure GPIOs connected (to which LEDs are connected on STM32F4-Discovery) and create two simple tasks, that will blink the LEDs. The detail of creating new tasks will be covered in other tutorials. For here just copy and ignore the details.
/* Configure onboard LEDs as output */ static void configureLEDs(void); /* Simple tasks to blink LEDs. */ void myTask1( void *pvParameters ); void myTask2( void *pvParameters ); void myTask1( void *pvParameters ) { volatile unsigned int i = 0; for (;;) { /* Toggle GPIOD Pin#14 --> RED LED on STM32F407-Discovery */ HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_14); for (i = 0 ; i<60000; i++); } } void myTask2( void *pvParameters ) { volatile unsigned int i = 0; for (;;) { /* Toggle GPIOD Pin#15 --> BLUE LED on STM32F407-Discovery */ HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_15); for (i = 0 ; i<80000; i++); } } static void configureLEDs(void) { GPIO_InitTypeDef GPIO_InitStruct; /* Enable clock to GPIO-D */ __HAL_RCC_GPIOD_CLK_ENABLE(); /* Set GPIOD Pin#14, Pin#15 Parameters */ GPIO_InitStruct.Pin = GPIO_PIN_14 | GPIO_PIN_15; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_PULLDOWN; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; /* Init GPIOD Pin#14,15 */ HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); } /***************************** Tasks creation in main *****************************/ xTaskCreate( myTask1, "Task1", 50, NULL, 1, NULL); xTaskCreate( myTask2, "Task2", 50, NULL, 1, NULL);
7. Now everything is set and in place, its time to start FreeRTOS scheduler.
/* Start FreeRTOS Kernel Scheduler */ vTaskStartScheduler();
That’s pretty much all the configuration you needed. Now grab the source code with link given a the start of this tutorial, match it with the steps, build it in Keil v5, burn it to STM32f4-discovery board and enjoy the beautiful blinking LEDs.
Video Demonstration:
References:
[1] – Reference manual-RM0090
Appreciate the recommendation. Let me try it out.
Hmm is anyone else experiencing problems with the pictures on this blog loading?
I’m trying to find out if its a problem on my end or if it’s the blog.
Any suggestions would be greatly appreciated.
Thanks for finally talking about > Integrating FreeRTOS and STM HAL Libraries –
EcoderLenz < Loved it!
What’s up friends, how is everything, and what you would like to say concerning this post, in my view
its truly remarkable for me.
This paragraph is genuinely a pleasant one it helps new net viewers,
who are wishing in favor of blogging.
Hey there would you mind stating which blog platform you’re working with?
I’m planning to start my own blog soon but I’m having a hard time choosing between BlogEngine/Wordpress/B2evolution and Drupal.
The reason I ask is because your design and style seems different then most blogs and I’m looking for something completely unique.
P.S Apologies for getting off-topic but I had to ask!
Keep on working, great job!
This website was… how do I say it? Relevant!! Finally I’ve found something which helped me.
Thanks a lot!
Wonderful, what a blog it is! This webpage presents helpful data to us, keep it up.
asmr https://app.gumroad.com/asmr2021/p/best-asmr-online asmr
Fantastic beat ! I would like to apprentice whilst you amend your
website, how could i subscribe for a weblog web site?
The account helped me a appropriate deal. I have been tiny
bit familiar of this your broadcast offered bright transparent concept quest
bars http://bit.ly/3C2tkMR quest bars
Hello! I just wanted to ask if you ever have any issues
with hackers? My last blog (wordpress) was hacked and I ended up losing a
few months of hard work due to no data backup. Do you
have any solutions to prevent hackers? ps4 https://bit.ly/3nkdKIi ps4
games
Aw, this was an incredibly good post. Spending some
time and actual effort to produce a superb article… but what
can I say… I procrastinate a lot and don’t manage to get anything done.
cheap flights http://1704milesapart.tumblr.com/ cheap flights
I do believe all of the ideas you’ve presented to your
post. They’re really convincing and will definitely work. Nonetheless,
the posts are very brief for novices. May you please extend them a bit from subsequent
time? Thank you for the post. scoliosis surgery https://0401mm.tumblr.com/ scoliosis surgery
Quality articles or reviews is the crucial to be a focus for the users to go to see
the web site, that’s what this website is
providing. scoliosis surgery https://coub.com/stories/962966-scoliosis-surgery scoliosis surgery
Good blog you have got here.. It’s difficult to find good
quality writing like yours these days. I really appreciate people like
you! Take care!! quest bars https://www.iherb.com/search?kw=quest%20bars quest bars
With havin so much content and articles do you ever run into any issues of plagorism or
copyright infringement? My site has a lot of exclusive content I’ve
either written myself or outsourced but it seems a lot of it is popping it up
all over the internet without my permission. Do you know any solutions to help reduce content
from being stolen? I’d truly appreciate it. part time jobs hired in 30 minutes https://parttimejobshiredin30minutes.wildapricot.org/
I’m extremely inspired along with your writing abilities and also with the format in your weblog.
Is this a paid subject matter or did you customize it your self?
Either way keep up the excellent high quality writing, it’s rare to see a nice blog like this one these days..
Heya! I’m at work surfing around your blog from my new iphone 4!
Just wanted to say I love reading through your blog and look forward to all your posts!
Carry on the superb work!