Github Address
https://github.com/RT-Thread-packages/FreeRTOS-Wrapper
Looking Forward to Your⭐Star⭐
This project is part of the 2022 Summer of Open Source, RT-Thread community project. It was successfully completed in September 2022 by Tang Zhaozhou (Georgia Institute of Technology, senior). The FreeRTOS compatibility layer has now been implemented in RT-Thread’s compatibility projects for ESP32-IDF (Tang Zhaozhou) and core-v-mcu (Wang Shun).
1 Overview
This is a FreeRTOS compatibility layer for the domestic RT-Thread operating system, allowing existing projects based on FreeRTOS to migrate quickly and seamlessly to the RT-Thread operating system, enabling the use of FreeRTOS APIs without awareness while also utilizing the rich components of RT-Thread. The project is based on FreeRTOS version 10.4.6.
1.1 Other RTOS Compatibility Layers of RT-Thread
-
μCOS-III compatibility layer for RT-Thread operating system: https://github.com/mysterywolf/RT-Thread-wrapper-of-uCOS-III
-
μCOS-II compatibility layer for RT-Thread operating system: https://github.com/mysterywolf/RT-Thread-wrapper-of-uCOS-II
-
RTX (i.e., CMSIS-RTOS1) compatibility layer for RT-Thread operating system: https://github.com/RT-Thread-packages/CMSIS_RTOS1
-
RTX5 (i.e., CMSIS-RTOS2) compatibility layer for RT-Thread operating system: https://github.com/RT-Thread-packages/CMSIS_RTOS2
-
Arduino ecosystem compatibility layer for RT-Thread operating system: https://github.com/RTduino/RTduino
2 FreeRTOS API Support Status and Usage Notes
For detailed API support status, please refer to the readme link below:
https://github.com/RT-Thread-packages/FreeRTOS-Wrapper
(Please copy to an external browser to open)
The compatibility layer’s support for FreeRTOS is recorded in the issues. Some supported functions may have slight differences in functionality and usage compared to FreeRTOS, so care should be taken during migration.
2.1 Threads, Message Queues, and Mutexes
2.1.1 vTaskSuspend
vTaskSuspend
only supports suspending the currently running thread, and when used, the xTaskToSuspend
parameter must be NULL
. Otherwise, an assertion will be triggered.
2.1.2 xQueueSendToFront
xQueueSendToFront
does not support setting a timeout; the xTicksToWait
parameter will be ignored, and if there is no space in the message queue, it will return errQUEUE_FULL
immediately.
2.1.3 xQueueCreateStatic
Static message queues need to be created with the following example, ensuring that the memory allocated for the message queue is large enough:
1#define QUEUE_LENGTH 10
2#define ITEM_SIZE sizeof( uint32_t )
3
4/* The following is the method used in the original FreeRTOS to allocate memory, as the internal implementation of the RT-Thread message queue differs from FreeRTOS, this allocation is insufficient to hold ITEM_SIZE messages */
5//uint8_t ucQueueStorage[ QUEUE_LENGTH * ITEM_SIZE ];
6/* Use the QUEUE_BUFFER_SIZE macro to allocate memory */
7uint8_t ucQueueStorage[ QUEUE_BUFFER_SIZE(QUEUE_LENGTH, ITEM_SIZE)];
8StaticQueue_t xQueueBuffer;
9QueueHandle_t xQueue1;
10xQueue1 = xQueueCreate( QUEUE_LENGTH, ITEM_SIZE, &( ucQueueStorage[ 0 ] ), &xQueueBuffer );
2.1.4 Mutex and Recursive Mutex
FreeRTOS provides two types of mutexes, Mutex and Recursive Mutex. Recursive Mutex can be acquired repeatedly by the same thread, while Mutex cannot. The mutex provided by RT-Thread can be acquired repeatedly, so the compatibility layer does not distinguish between Mutex and Recursive Mutex.
Both mutexes created with xSemaphoreCreateMutex
and xSemaphoreCreateRecursiveMutex
can be acquired repeatedly.
2.2 Timers
Unlike FreeRTOS, RT-Thread does not use a message queue to pass commands to the timer thread. When using the compatibility layer, any timer function that needs to set a timeout, such as xTimerStart( xTimer, xTicksToWait )
, will ignore the xTicksToWait
parameter, and the function will complete the command immediately and return.
2.3 FromISR Functions
FreeRTOS provides FromISR versions for some functions that are used in interrupts; if these functions wake up a higher-priority thread, manual scheduling is required, as shown below:
1BaseType_t xHigherPrioritTaskWoken = pdFALSE;
2xQueueSendToFrontFromISR( xRxQueue, &cIn, &xHigherPriorityTaskWoken );
3if( xHigherPriorityTaskWoken )
4{
5 taskYIELD ();
6}
RT-Thread does not provide FromISR versions for functions; functions can be called in interrupts and complete scheduling internally. Therefore, after using FromISR functions in the compatibility layer, manual scheduling is not required, and xHigherPriorityTaskWoken
will always be set to pdFALSE
.
2.4 Memory Heap
The compatibility layer retains five memory allocation algorithms from FreeRTOS, with heap_3
being used by default. The internal calls to pvPortMalloc/vPortFree
use RT_KERNEL_MALLOC/RT_KERNEL_FREE
for memory allocation within RT-Thread. In this case, the size of the memory heap is determined by the RT-Thread BSP configuration and cannot be set in FreeRTOSConfig.h
via configTOTAL_HEAP_SIZE
. If using other algorithms, you need to modify FreeRTOS/sSConscript
to select the appropriate source file.
1# You can replace heap_3.c with heap_1.c, etc.
2src += Glob(os.path.join("portable", "MemMang", "heap_3.c"))
In FreeRTOS/portable/rt-thread/FreeRTOSConfig.h
, set the heap size using configTOTAL_HEAP_SIZE
. Application calls to pvPortMalloc/vPortFree
will allocate memory from a heap independent of RT-Thread, sized configTOTAL_HEAP_SIZE
, while the internal memory heap of RT-Thread still exists, and all memory allocation within compatibility layer functions is completed in the RT-Thread memory heap.
2.5 Thread Priority
In RT-Thread, the smaller the thread priority value, the higher the priority, while in FreeRTOS, the larger the thread priority value, the higher the priority. When using FreeRTOS APIs in the compatibility layer, such as xTaskCreate
, use FreeRTOS rules to specify thread priority. If RT-Thread and FreeRTOS APIs are mixed in the application, special attention should be paid when specifying thread priority. The following two macros can be used to convert between RT-Thread and FreeRTOS thread priorities:
1#define FREERTOS_PRIORITY_TO_RTTHREAD(priority) ( configMAX_PRIORITIES - 1 - ( priority ) )
2#define RTTHREAD_PRIORITY_TO_FREERTOS(priority) ( RT_THREAD_PRIORITY_MAX - 1 - ( priority ) )
2.6 Thread Stack Size
The unit for FreeRTOS thread stack size is sizeof(StackType_t)
, while for RT-Thread it is sizeof(rt_uint8_t)
. When creating threads using FreeRTOS API, be sure to follow FreeRTOS rules to avoid confusion.
2.7 vTaskStartScheduler
Due to differences in kernel startup processes between RT-Thread and FreeRTOS, when using the compatibility layer, the main
function runs in a thread with a priority of CONFIG_RT_MAIN_THREAD_PRIORITY
. (This option is configured via SCons; the smaller the value, the higher the priority.) At this point, the scheduler is already running. Typical FreeRTOS applications create threads as follows:
1xTaskCreate(pxTask1Code, ......);
2xTaskCreate(pxTask2Code, ......);
3......
4vTaskStartScheduler();
When using the compatibility layer, any thread created with xTaskCreate
that has a priority higher than CONFIG_RT_MAIN_THREAD_PRIORITY
will start executing immediately. vTaskStartScheduler
is only provided for application compatibility and has no practical effect. When using the compatibility layer, special attention should be paid when creating threads to ensure that all resources required by the thread are initialized and can run normally before calling xTaskCreate
.
3 Usage Method
Add the compatibility layer to the project using the Env tool:
1RT-Thread online packages
2 system packages --->
3 [*] FreeRTOS Wrapper --->
4 Version (latest)
Configure the RT-Thread kernel using scons --menuconfig
; the following options will affect the FreeRTOS compatibility layer:
1RT_USING_TIMER_SOFT /* Must be enabled when using FreeRTOS timer */
2RT_TIMER_THREAD_PRIO /* Timer thread priority. Opposite to FreeRTOS, the smaller the value, the higher the priority */
3RT_TIMER_THREAD_STACK_SIZE /* Timer thread stack size, unit is sizeof(rt_uint8_t) */
4RT_USING_MUTEX /* Must be enabled when using FreeRTOS mutex */
5RT_USING_SEMAPHORE /* Must be enabled when using FreeRTOS semaphore */
6RT_USING_HEAP /* Must be enabled when using FreeRTOS dynamic memory allocation */
7RT_TICK_PER_SECOND /* Equivalent to FreeRTOS configTICK_RATE_HZ */
8RT_THREAD_PRIORITY_MAX /* Equivalent to FreeRTOS configMAX_PRIORITIES */
9RT_NAME_MAX /* Equivalent to FreeRTOS configMAX_TASK_NAME_LEN */
The FreeRTOSConfig.h
template is provided in FreeRTOS/portable/rt-thread
. Most of the content cannot be modified or depends on RT-Thread kernel configuration; the following content can be manually modified:
1/* You can choose not to use recursive mutex */
2#ifdef RT_USING_MUTEX
3 #define configUSE_RECURSIVE_MUTEXES 1
4 #define configUSE_MUTEXES 1
5#endif
6
7/* You can choose not to use counting semaphore */
8#ifdef RT_USING_SEMAPHORE
9 #define configUSE_COUNTING_SEMAPHORES 1
10#endif
11
12/* If not using heap_3, you can configure the heap size via configTOTAL_HEAP_SIZE */
13#define configSUPPORT_STATIC_ALLOCATION 1
14#ifdef RT_USING_HEAP
15 #define configSUPPORT_DYNAMIC_ALLOCATION 1
16 #define configTOTAL_HEAP_SIZE 10240
17 #define configAPPLICATION_ALLOCATED_HEAP 0
18#endif
19
20#define configMINIMAL_STACK_SIZE 128
21
22/* Selectable functions and features */
23#define INCLUDE_vTaskPrioritySet 1
24#define INCLUDE_uxTaskPriorityGet 1
25#define INCLUDE_vTaskDelete 1
26#define INCLUDE_vTaskSuspend 1
27#define INCLUDE_xTaskDelayUntil 1
28#define INCLUDE_vTaskDelay 1
29#define INCLUDE_xTaskGetIdleTaskHandle 1
30#define INCLUDE_xTaskAbortDelay 1
31#define INCLUDE_xSemaphoreGetMutexHolder 1
32#define INCLUDE_xTaskGetHandle 1
33#define INCLUDE_uxTaskGetStackHighWaterMark 1
34#define INCLUDE_uxTaskGetStackHighWaterMark2 1
35#define INCLUDE_eTaskGetState 1
36#define INCLUDE_xTaskResumeFromISR 1
37#define INCLUDE_xTaskGetSchedulerState 1
38#define INCLUDE_xTaskGetCurrentTaskHandle 1
39#define configUSE_APPLICATION_TASK_TAG 1
40#define configUSE_TASK_NOTIFICATIONS 1
41#define configTASK_NOTIFICATION_ARRAY_ENTRIES 3
Some examples are provided in the test directory, which can be added to the applications folder under the BSP directory. After compiling and burning with SCons, you can connect to the serial port, input the corresponding msh commands, and observe the execution results of the examples:
1msh />queue_dynamic
2Task 1 receive data 0 from queue
3Task 1 receive data 1 from queue
4Task 1 receive data 2 from queue
5Task 1 receive data 3 from queue
6Task 1 receive data 4 from queue
7Task 1 receive data 5 from queue
8Task 1 receive data 6 from queue
9Task 1 receive data 7 from queue
10Task 1 receive data 8 from queue
11Task 1 receive data 9 from queue
12Task 1 receive data 10 from queue
4 References
RT-Thread Documentation
https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/README
FreeRTOS Documentation
https://www.freertos.org/a00106.html
Github Address
https://github.com/RT-Thread-packages/FreeRTOS-Wrapper
Looking Forward to Your⭐Star⭐
———————End———————
You can add WeChat:rtthread2020 as a friend, and note:Company + Name, to join the official RT-Thread WeChat group!
If you love me, please give me a thumbs up
👇ClickRead Original