Getting Started with RTOS Configuration

Follow+Star PublicAccount, don’t miss wonderful content
Getting Started with RTOS Configuration
Author | strongerHuang
WeChat Public Account | strongerHuang
Recently, some friends asked: Where to start learning RTOS?
This question is simple and complicated, because everyone’s foundation is different, and naturally, where to start learning also varies.
I think, first you need to understand some basic knowledge related to RTOS, and then download the source code to practice and run it!Next, the first step to really get started, I think it still has to start from the “configuration” file, where the configuration can be understood as the “trimming system” and related configurations that everyone talks about.
For example, the “FreeRTOSConfig.h” configuration file in FreeRTOS:
Getting Started with RTOS Configuration
Of course, the configuration file is the content you need to master when you have a certain foundation and are getting started with the source code. Not only FreeRTOS, but also other μCOS, RT-Thread, and even Linux all start with configuration.
Some old friends may say that using STM32CubeMX to configure FreeRTOS, there is no need to modify (configure) the FreeRTOSConfig.h file?
Let’s put it this way, third-party tools for graphical configuration will also involve configuration files, and merely basic configurations will still require you to modify the configuration files for your projects.
Through third-party configuration tools, you will not truly master the underlying principles of RTOS, and you will find it very difficult to do projects later.

Common Contents of FreeRTOS Configuration Files

This article combines the process of FreeRTOS to talk about the contents of the configuration file.

The FreeRTOS configuration file looks a bit extensive, but it is categorized, and if you understand it better, you will find it is not very difficult.

Official website:
http://www.freertos.org/a00110.html
The official website has done some “localization”, making it more suitable for learning for Chinese people than before.

1

General Configuration

The basic configuration of general configuration is some configurations we need to define, which are also relatively important configurations.

1.configUSE_PREEMPTION

Scheduling Mode Configuration

Set to 0: Cooperative scheduling, i.e., time slices are executed alternately;

Set to 1: Preemptive scheduling, i.e., tasks with higher priorities are executed first;

Since we require real-time response, we set it to 1, using preemptive scheduling. Otherwise, it will not fulfill the role of a real-time operating system.

2.configCPU_CLOCK_HZ

CPU Clock, which is commonly referred to as the main frequency. Note: The unit is Hz.

For example: The main frequency of STM32F407 is 168M:

#define configCPU_CLOCK_HZ      (168000000)

3.configTICK_RATE_HZ

System Tick, which is the number of ticks per second for the system, can be said to be the heartbeat of the system, but it needs to be distinguished from the main frequency. The value of the system tick should be based on the CPU main frequency, generally, the higher the main frequency, the relatively larger the value, usually between 100 and 1000.

For example: The system tick determines vTaskDelay.

For example:

#define configTICK_RATE_HZ    (1000)

Then:

vTaskDelay(1000), indicates a delay of 1 second.

4.configMAX_PRIORITIES

Maximum Priority Value of the System

When we create tasks, the configured priority value cannot exceed this maximum value.

xTaskCreate(vAppTask1, “Task1”, TASK1_STACK_SIZE, NULL, TASK1_PRIORITY, NULL);

Tip:

a. System priority is similar to interrupt priority principles, high priority will preempt low priority, but it is necessary to distinguish the application scenarios of system and interrupt priorities.

b. In FreeRTOS, the higher the numerical value, the higher the priority. While in UCOS, it is the opposite.

5.configMINIMAL_STACK_SIZE

Minimum Stack Value

Generally used in system tasks such as idle and timer, of course, we can also use this defined stack value in some places.

Note the unit of the value, generally in ARM it is 4 bytes.

6.configTOTAL_HEAP_SIZE

Total Heap (Stack) Size of the System

We need to define this value based on the usage situation. It cannot be defined too small, as too small memory can easily overflow; it cannot be defined too large, as some chips have small RAM (some only have a few k), if too large, we cannot define too many global variables or allocate other stack space.

7.configMAX_TASK_NAME_LEN

Maximum Length of Task Name

Which is the string length of the task name defined when creating the task

xTaskCreate(vAppTask1, “Task1“, TASK1_STACK_SIZE, NULL, TASK1_PRIORITY, NULL);

Tip:

The terminating character ‘\0’ is also included.

8.configUSE_16_BIT_TICKS

Whether to use 16-bit tick count

Set to 0: Use 32-bit tick count, generally configured to 0 in 32-bit processors;

Set to 1: Use 16-bit tick count, generally configured to 1 in 8-bit or 16-bit processors.

9.configIDLE_SHOULD_YIELD

Whether to let idle tasks “yield” preemption

In other words, during the execution of tasks with the same priority as the idle task, whether the idle task has the opportunity to preempt.

Set to 0: Do not yield preemption;

Set to 1: Yield preemption;

10.configUSE_MUTEXES

Whether to use mutexes

Set to 0: Do not use

Set to 1: Use

Tip: Mutexes are also called mutex semaphores, which means “locking” resources. Their role is to achieve exclusive processing of shared resources among multiple tasks. In simple terms, a resource is allowed to be processed by only one task at a time, and only after processing is completed can other tasks process that resource.

For example: Task A has a high priority, Task B has a low priority; both tasks A and B will use a serial port to send command data (i.e., each time must be completed, cannot be interrupted midway).

When Task B is sending data, Task A is in a ready state (wanting to interrupt Task B). Then Task B needs to use a mutex to occupy that serial port (lock, occupy that resource), after sending the command, it releases that serial port (unlock, release that resource). Once that resource is released, Task A can use that serial port (resource).

11.configUSE_RECURSIVE_MUTEXES

Whether to use recursive mutexes

Set to 0: Do not use

Set to 1: Use

13.configQUEUE_REGISTRY_SIZE(*)

Number of queue names that can be added (or registered)

This configuration information is difficult to translate, it mainly works with vQueueAddToRegistry and vQueueUnregisterQueue functions.

Directly on the function interface:

void vQueueAddToRegistry(QueueHandle_t xQueue, const char *pcQueueName);
void vQueueUnregisterQueue(QueueHandle_t xQueue);
From the function interface, we can see that one function is used to register the name of an (already created) queue; one function is used to unregister the name of the queue;
In fact, the main purpose is to name (already created) queues for easier debugging and searching.

Tip: Many beginners misunderstand this as the “maximum number of queues that can be created”, this configuration parameter is completely different in concept.

14.configUSE_QUEUE_SETS(*)

Whether to use message queue “SET” function

Set to 0: Do not use

Set to 1: Use

This configuration information is also relatively difficult to understand.

Tip: Many explanations online say: enable/disable message queues. This understanding is too general, and there is a lot of information related to message queue configuration, I personally think it is incorrect.

15.configUSE_TIME_SLICING

Whether to use time slicing for scheduling

This parameter is used with the above configuration parameter configUSE_PREEMPTION.

This configuration parameter was added in later versions, it seems that there was no such configuration parameter before version V7. Therefore, it is not defined in the FreeRTOSConfig.h configuration file by default, but is defined in FreeRTOS.h.

#ifndef configUSE_TIME_SLICING
  #define configUSE_TIME_SLICING 1
#endif

2

HOOK Configuration

HOOKs are also called hooks, beginners can just understand them for now.
1.configUSE_IDLE_HOOK
Whether to define IDLE idle task HOOK function
Set to 0: Not defined
Set to 1: Defined
configUSE_IDLE_HOOK has been present since the system was designed and must be defined in “FreeRTOSConfig.h”. Unlike some macro definitions that can be omitted in “FreeRTOSConfig.h” because they are checked in “FreeRTOS.h” and have a default definition if not defined.
For example, the “configUSE_MUTEXES” mentioned in the previous article can be omitted in “FreeRTOSConfig.h” and can be found in “FreeRTOS.h” as follows:
#ifndef configUSE_MUTEXES#define configUSE_MUTEXES 0#endif
In other words, if not defined, it will give you a default definition.
Going back to configUSE_IDLE_HOOK, in the task.c file, there is the following code:
#if (configUSE_IDLE_HOOK == 1){  extern void vApplicationIdleHook(void);  vApplicationIdleHook();}#endif
This means: If you set configUSE_IDLE_HOOK to 1, then you must implement the function “vApplicationIdleHook()”; otherwise, the compilation will fail. Beginners generally do not define this function.
2.configUSE_TICK_HOOK
Whether to define TICK tick HOOK function
Set to 0: Not defined
Set to 1: Defined
In the task.c file under the xTaskIncrementTick function, you can see the following code:
#if (configUSE_TICK_HOOK == 1){  if(uxPendedTicks == (UBaseType_t) 0U)  {    vApplicationTickHook();  }  else  {    mtCOVERAGE_TEST_MARKER();  }}#endif
Tip: The xTaskIncrementTick function is called in the PendSV_Handler interrupt function. Therefore, the execution time of the vApplicationTickHook() function must be very short.
3.configCHECK_FOR_STACK_OVERFLOW
Whether to define stack overflow HOOK function
Set to 0: Not defined
Set to 1: Defined
This configuration is relatively critical and important, especially for complex system designs with large codebases. Using this function can help you analyze whether there are memory overflow situations.
4.configUSE_MALLOC_FAILED_HOOK
Whether to define memory allocation failure HOOK function
Set to 0: Not defined
Set to 1: Defined
Creating tasks, semaphores, queues, etc. all consume system heap. If we do not allocate enough heap in total, it is easy to fail when creating multiple tasks or queues, and this will serve as a prompt.
5.configUSE_DAEMON_TASK_STARTUP_HOOK
Whether to define daemon task HOOK function
Set to 0: Not defined
Set to 1: Defined
By analyzing the software source code, we can find that this HOOK function is implemented under the TIMER task, so it is necessary to configure configUSE_TIMERS to 1.

3

TIMERS Configuration

TIMER refers to a timer, and in RTOS, TIMER belongs to software timing. The precision of FreeRTOS timers is not high and changes with the increase of timing, especially when the TIMER task priority is low and high priority occupies resources.
If you want to use high-precision timing, it is still better to use hardware timers (most processors now have multiple hardware TIMERS).

1.configUSE_TIMERS

Whether to use software timers

Set to 0: Do not use

Set to 1: Use

Many other related functions need to be used in conjunction with this configuration, so it is important to pay attention to whether they are related.

2.configTIMER_TASK_PRIORITY

Software Timer Task Priority

A software timer actually needs to create a task, and the creation method is the same as our conventional one, except that it is completed by the system kernel, and we do not need to write the task creation code ourselves.

This priority is the priority of the timer task.

3.configTIMER_QUEUE_LENGTH

Software Timer Command Queue Length

The knowledge related to the TIMER command queue is relatively complex, and will be discussed further later; see the figure below:

Getting Started with RTOS Configuration

4.configTIMER_TASK_STACK_DEPTH

Stack Space Allocated for Software Timer

4

CO_ROUTINES Configuration

CO_ROUTINES are difficult to translate, and are commonly referred to as cooperative programs or collaborative programs. They can be understood as programs that work together, and will be discussed in conjunction with applications later.
1.configUSE_CO_ROUTINES
Whether to use CO_ROUTINES
Set to 0: Do not use
Set to 1: Use
2.configMAX_CO_ROUTINE_PRIORITIES
CO_ROUTINE Priority

5

MEMORY Configuration

Memory allocation related configuration, these configurations are related to heap_x.c, and will be discussed again later.

1.configSUPPORT_STATIC_ALLOCATION

Whether to support static allocation

Set to 0: Do not support

Set to 1: Support

2.configSUPPORT_DYNAMIC_ALLOCATION

Whether to support dynamic allocation

Set to 0: Do not support

Set to 1: Support

3.configTOTAL_HEAP_SIZE

Heap allocated for the system

Creating tasks, stacks, both static and dynamic allocations come from here.

4.configAPPLICATION_ALLOCATED_HEAP

Where the APP uses allocated heap

Set to 0: Use system allocated heap

Set to 1: Use externally allocated heap

By default, it uses the system allocated heap, see the definition below:

#if(configAPPLICATION_ALLOCATED_HEAP == 1 )
  extern uint8_t ucHeap[configTOTAL_HEAP_SIZE];
#else
  static uint8_t ucHeap[configTOTAL_HEAP_SIZE];
#endif

6

RUN_TIME_STATS Configuration

Runtime information statistics configuration

1.configGENERATE_RUN_TIME_STATS

Whether to generate statistical information

Set to 0: No

Set to 1: Yes

2.configUSE_TRACE_FACILITY

Whether to assist in visualization and tracing

Set to 0: No

Set to 1: Yes

Additional structures will be added to achieve this.

3.configUSE_STATS_FORMATTING_FUNCTIONS

Whether to provide statistical related functions

Set to 0: No

Set to 1: Yes

Setting macros configUSE_TRACE_FACILITY and configUSE_STATS_FORMATTING_FUNCTIONS to 1 will compile the functions vTaskList() and vTaskGetRunTimeStats(). If either of these two macros is set to 0, the above two functions will not be compiled.

7

Other Configurations

Here is a brief overview of various configurations

1.configASSERT

Assertion Configuration

2.Interrupt Related

  • configKERNEL_INTERRUPT_PRIORITY: Kernel Interrupt Priority

  • configMAX_SYSCALL_INTERRUPT_PRIORITY: Maximum Priority for System Calls

  • configMAX_API_CALL_INTERRUPT_PRIORITY: Maximum Priority for API Calls

This section is related to (Cortex) kernel hardware interrupts.

3.INCLUDE Configuration

#define INCLUDE_vTaskPrioritySet   1
#define INCLUDE_uxTaskPriorityGet  1
#define INCLUDE_vTaskDelete       1

Here we have shared some common configuration contents, to deeply understand and master them, it is still necessary to modify the code and verify it yourself.

———— END ————

Getting Started with RTOS Configuration

● Column “Embedded Tools

● Column “Embedded Development”

● Column “Keil Tutorial”

● Selected Tutorials in the Embedded Column

Follow the public account reply “Join Group” to join the technical exchange group according to the rules, reply “1024” to see more content.

Getting Started with RTOS Configuration

Getting Started with RTOS Configuration

Click “Read the Original” to see more shares.

Leave a Comment

Your email address will not be published. Required fields are marked *