Introduction to FreeRTOS – Creating a Project

Recently, I found some free time and decided to review FreeRTOS. I am also posting this article for easy reference later. The following content will use the standard library for the STM32F407ZGT6 model as an example.(1) Download the Source CodeYou can directly search for “FreeRTOS” in your browser to download it, or you can access the shared file on Baidu Cloud: FreeRTOS source code.zip Link: https://pan.baidu.com/s/1Hb7zRlfu-UgXV2boZNSKGg?pwd=cvma Extraction code: cvmaIntroduction to FreeRTOS - Creating a Project(2) Create a Blank Template for STM32 Standard LibraryBy this point, you should have your own standard library template, so I won’t elaborate further.1. Create a new folder named freertos under your template.Introduction to FreeRTOS - Creating a Project2. Open the previously downloaded source code and navigate to the Source directory.Introduction to FreeRTOS - Creating a ProjectCopy all the contents into the newly createdfreertosfolder, rename the portable folder to port (personal preference), and create a new src folder under the freertos folder to store the source code files from the Source folder.Here are the .c files in the Source folder:Introduction to FreeRTOS - Creating a ProjectIntroduction to FreeRTOS - Creating a Project

croutine.c : Related to coroutines

event_groups.c : Related to event groups

list.c : List, a basic data structure in FreeRTOS

queue.c : Related to queues

tasks.c : Related to task creation, suspension, resumption, and scheduling

timers.c : Related to software timers

3. Enter the port folder,delete all folders except for Keil, MemMang, and RVDS.Introduction to FreeRTOS - Creating a ProjectIn the MemMang folder, only keep theheap_4.c file; delete the rest.Introduction to FreeRTOS - Creating a Project

Why choose heap_4.c? Here is the relevant introduction:

heap_1.c is suitable for tasks that do not delete tasks, queues, or semaphores, especially for simpler systems and those with high safety requirements. In fact, many systems will keep executing tasks once created without deleting them. Therefore, this file is applicable in many environments.

heap_2.c can allocate and free memory, but does not consider memory fragmentation during deallocation. It is suitable for situations where allocation and deallocation operations are not very frequent and do not involve large arrays. (Allocation and deallocation can cause memory fragmentation, and excessive operations may lead to a lack of large contiguous areas in memory.)

heap_3.c actually uses the C language’s malloc and free functions. It is not significantly related to the platform.

heap_4.c is suitable for systems where memory allocation and deallocation operations are frequent, such as when repeatedly creating and deleting tasks, queues, semaphores, etc.

heap_5.c is for systems that need to manage non-contiguous memory spaces, such as when connecting to external RAM.

In the RVDS folder, only keep the interfaces required for your chip. For the F407, it isARM_CM4F, so only keep theARM_CM4F folder.Introduction to FreeRTOS - Creating a ProjectAt this point, the file trimming is almost done. Next, open your standard library project and create the following groups.Introduction to FreeRTOS - Creating a Project4. Add the .c files from the previous src folder into the FreeRTOS_CORE group, and similarly add the .c files from the previous port folder under MemMang and RVDS\ARM_CM4F into the FreeRTOS_PORTABLE group. The final result is as shown in the image above. (I hope everyone knows how to create groups and modify group names.)5. Open the magic wand and include the file paths used in C/C++.Introduction to FreeRTOS - Creating a ProjectIntroduction to FreeRTOS - Creating a Project6. Then perform the first compilation, which will certainly result in errors.

......(omitted several lines)FreeRTOS\portable\RVDS\ARM_CM4F\port.c: 0 warnings, 1 errorcompiling heap_4.c....\FreeRTOS\include\FreeRTOS.h(98): error:  #5: cannot open source input file "FreeRTOSConfig.h": No such file or directory  #include "FreeRTOSConfig.h"FreeRTOS\portable\MemMang\heap_4.c: 0 warnings, 1 error".
\Objects\Template_FreeRTOS.axf" - 8 Error(s), 0 Warning(s).Target not created.Build Time Elapsed:  00:00:23

There is an error: “FreeRTOSConfig.h” cannot be found. This file is in the Demo folder of the FreeRTOS source code.

Place the “FreeRTOSConfig.h” file from the Demo into the include folder under the FreeRTOS folder. I believe everyone can do this, so I won’t provide detailed images.

Proceed to the second compilation, which will still have errors.

......(omitted several lines)compiling tasks.c...compiling timers.c...compiling port.c...FreeRTOS\portable\RVDS\ARM_CM4F\port.c(713): error:  #20: identifier "SystemCoreClock" is undefined
ortNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;FreeRTOS\portable\RVDS\ARM_CM4F\port.c: 0 warnings, 1 error

The error indicates that “SystemCoreClock” is undefined because it is used in “FreeRTOSConfig.h” to denote the MCU frequency, specifically in lines 87-95 of “FreeRTOSConfig.h”:

#ifdef __ICCARM__#include <stdint.h>extern uint32_t SystemCoreClock;#endif#define configUSE_PREEMPTION				1#define configUSE_IDLE_HOOK				1#define configUSE_TICK_HOOK				1#define configCPU_CLOCK_HZ				( SystemCoreClock )

Modify the conditional compilation

#ifdef __ICCARM__

to

#if defined(__ICCARM__)||defined(__CC_ARM)||defined(__GNU__)

Proceed to the third compilation, which will still have errors:

......(omitted several lines)compiling port.c...compiling heap_4.c...linking....\Objects\Template_FreeRTOS.axf: Error: L6200E: Symbol SVC_Handler multiply defined (by port.o and stm32f4xx_it.o)..\Objects\Template_FreeRTOS.axf: Error: L6200E: Symbol PendSV_Handler multiply defined (by port.o and stm32f4xx_it.o)..\Objects\Template_FreeRTOS.axf: Error: L6200E: Symbol SysTick_Handler multiply defined (by port.o and stm32f4xx_it.o).Not enough information to list image symbols.Not enough information to list the image map.Finished: 2 information, 0 warning and 3 error messages."\Objects\Template_FreeRTOS.axf" - 3 Error(s), 0 Warning(s).Target not created.Build Time Elapsed:  00:00:02

The error indicates that port.o and stm32f4xx_it.o have duplicate definitions (.o files are compiled target files, which means there is an issue with the corresponding .c files). Comment out the SVC_Handler(), PendSV_Handler(), and SysTick_Handler() in stm32f4xx_it.c to resolve this. The modified stm32f4xx_it.c lines 110-145 are as follows:

/** 
 * @brief This function handles SVCall exception. 
 * @param None 
 * @retval None 
 */
//void SVC_Handler(void)//{
//}
/** 
 * @brief This function handles Debug Monitor exception. 
 * @param None 
 * @retval None 
 */
void DebugMon_Handler(void){}
/** 
 * @brief This function handles PendSVC exception. 
 * @param None 
 * @retval None 
 */
//void PendSV_Handler(void)//{
//}
/** 
 * @brief This function handles SysTick Handler. 
 * @param None 
 * @retval None 
 */
//void SysTick_Handler(void)//{
//}

After that, perform the fourth compilation, and there are still errors:

......(omitted several lines)linking....\Objects\Template_FreeRTOS.axf: Error: L6218E: Undefined symbol vApplicationIdleHook (referred from tasks.o)..\Objects\Template_FreeRTOS.axf: Error: L6218E: Undefined symbol vApplicationStackOverflowHook (referred from tasks.o)..\Objects\Template_FreeRTOS.axf: Error: L6218E: Undefined symbol vApplicationTickHook (referred from tasks.o)..\Objects\Template_FreeRTOS.axf: Error: L6218E: Undefined symbol vApplicationMallocFailedHook (referred from heap_4.o).Not enough information to list image symbols.Finished: 1 information, 0 warning and 4 error messages."\Objects\Template_FreeRTOS.axf" - 4 Error(s), 0 Warning(s).

The error indicates that four hook functions are undefined because they are defined in “FreeRTOSConfig.h” but their definitions are not found. We can comment out these definitions by setting the macros like configUSE_IDLE_HOOK to 0. Check lines 93-108 of “FreeRTOSConfig.h”:

#define configUSE_IDLE_HOOK				1#define configUSE_TICK_HOOK				1#define configCPU_CLOCK_HZ				( SystemCoreClock )#define configTICK_RATE_HZ				( ( TickType_t ) 1000 )#define configMAX_PRIORITIES				( 5 )#define configMINIMAL_STACK_SIZE			( ( unsigned short ) 130 )#define configTOTAL_HEAP_SIZE				( ( size_t ) ( 75 * 1024 ) )#define configMAX_TASK_NAME_LEN			( 10 )#define configUSE_TRACE_FACILITY			1#define configUSE_16_BIT_TICKS				0#define configIDLE_SHOULD_YIELD				1#define configUSE_MUTEXES				1#define configQUEUE_REGISTRY_SIZE			8#define configCHECK_FOR_STACK_OVERFLOW		2#define configUSE_RECURSIVE_MUTEXES			1#define configUSE_MALLOC_FAILED_HOOK		1

Modify lines 93, 94, 106, and 108 to 0, specifically:

#define configUSE_IDLE_HOOK				0#define configUSE_TICK_HOOK				0......(omitted 11 lines)#define configCHECK_FOR_STACK_OVERFLOW		0......(omitted 1 line)#define configUSE_MALLOC_FAILED_HOOK		0

Proceed to the fifth compilation:

......(omitted several lines)compiling port.c...compiling heap_4.c...linking...Program Size: Code=1880 RO-data=424 RW-data=68 ZI-data=2036  ".\Objects\Template_FreeRTOS.axf" - 0 Error(s), 0 Warning(s).Build Time Elapsed:  00:00:01

Finally, there are no errors. Thus, our porting is complete. The reason for not fixing everything at once and compiling five times is to train the ability to find and correct errors.In the next section, I will update how to create tasks.

Leave a Comment