μC/OS-II Compatibility Layer for RT-Thread OS

1 Overview

μC/OS-II Compatibility Layer for RT-Thread OS

This is a compatibility layer for the RT-Thread domestic operating system, designed to allow projects based on the μC/OS-II operating system from the American company Micriμm to migrate quickly and seamlessly to the RT-Thread operating system. The design and implementation of the compatibility layer respect the original μC/OS-II, ensuring its authenticity.

The design and implementation of the uCOS-II compatibility layer incorporate experience from the uCOS-III compatibility layer, while cross-checking with the uCOS-III compatibility layer to ensure the reliability of both layers.

Supported versions: All versions of μC/OS-II from 2.00 to 2.93

Code Repository:
https://github.com/mysterywolf/RT-Thread-wrapper-of-uCOS-II
Welcome to Star!

1.1 Other RTOS Compatibility Layers for RT-Thread

μC/OS-III Compatibility Layer for RT-Thread OS:https://github.com/mysterywolf/RT-Thread-wrapper-of-uCOS-III

1.2 This Compatibility Layer is Suitable for

  • Those who have previously learned the μC/OS-II operating system and intend to switch to learning the RT-Thread domestic operating system. This compatibility layer can help you quickly run your project using your existing μC/OS-II programming experience and habits, while gradually becoming familiar with the RT-Thread API functions over time, thus lowering your learning threshold and time cost.With this compatibility layer, unfamiliarity with RT-Thread API and programming style will no longer hinder your learning of RT-Thread!
  • Existing task (thread) modules written in μC/OS-II that need to be used in RT-Thread-based projects
  • Old projects that need to migrate from μC/OS-II to RT-Thread
  • When rapid product development based on RT-Thread is needed, but engineers have only used μC/OS and have no experience with RT-Thread development. This compatibility layer can help engineers quickly develop products based on their μC/OS-II experience, simplifying software reuse and shortening the learning process for new microcontroller developers, thereby reducing time to market for new devices.
  • Avoiding errors caused by fixed thinking due to μC/OS-II programming experience when migrating to RT-Thread, as these errors are often difficult to detect

For example:

  1. Different parameters for software timer

  2. Different data types for task stack

1.3 Version Details

μC/OS-II Compatibility Layer for RT-Thread OS

1.4 Official Website

RT-Thread:

https://www.rt-thread.org/

Documentation Center:

https://www.rt-thread.org/document/site/tutorial/nano/an0038-nano-introduction/

μC/OS-II:

https://www.micrium.com/ Documentation Center:

https://doc.micrium.com/pages/viewpage.action?pageId=10753158

2 Usage

2.1 Keil-MDK Simulation Project

This simulation project is based on the STM32F103 platform.

Keil project path: rt-thread-3.1.3/bsp/stm32f103/Project.uvprojx

Make sure to install the RT-Thread Nano-3.1.3 Keil support package in advance.

Note: The debugging serial port used is USART2, not USART1

μC/OS-II Compatibility Layer for RT-Thread OS

2.2 Migration Steps

(If using the RT-Thread Nano version, please refer to the following steps; if using the full version of RT-Thread, you can skip directly tothe section on automatically configuring Env tools into the project)
  1. Add all files from the uCOS-II folder to your project, keeping the original folder structure if possible. Compared to the original μC/OS-II, the file<span>os_rtwrap.c</span> has been added, which is responsible for supporting the conversion between RT-Thread and μC/OS-II.
  2. Configure<span>os_cfg.h</span> Each option’s configuration description is consistent with the original μC/OS-II; if there are differences, I have explained them in the comments. Original μC/OS-II configuration descriptions can be found in: a) “Embedded Real-Time Operating System μC/OS-II (Second Edition)” Beijing Aerospace University Press, translated by Shao Beibei et al. b) Micriμm company μCOS-II online documentation
  3. The original μCOS-II timer callback function is called in the timer thread, not in an interrupt; therefore, to use the software timer of the μCOS-II compatibility layer, you need to set the macro definition in rtconfig.h<span>RT_USING_TIMER_SOFT</span> to 1.
  4. Since the compatibility layer uses the memory allocation method provided by the RT-Thread kernel, it eliminates the need to configure the task and the size of memory pools for each kernel object in the original μC/OS-II, thus requiring the definition of<span>RT_USING_MEMHEAP</span> in rtconfig.h.

2.3 os_cfg.h Configuration File

1#define  OS_TMR_CFG_TICKS_PER_SEC  10u   /* Rate at which timer management task runs (Hz) */
In the original μCOS-II, this macro defines the time base signal for software timers, which is fundamentally different from RT-Thread’s software timers; in RT-Thread, the time base signal for software timers is equal to OS Ticks. Therefore, to convert the μCOS-II software timer time parameters to RT-Thread software timer time parameters, this macro definition is needed. Please ensure this macro definition is consistent with the parameters used in the original project using μCOS-II. It is important to note that while the time base frequency for software timers is defined in the compatibility layer, the time base frequency of the RT-Thread software timer used internally in the compatibility layer is equivalent to OS Ticks, thus<span>OS_TMR</span> structure’s<span>.OSTmrMatch</span> member variable’s value is calculated based on OS Ticks frequency.
Since the compatibility layer uses the memory allocation method provided by the RT-Thread kernel, it eliminates the need to configure the task and the size of memory pools for each kernel object in the original μC/OS-II, thus all related macro definitions have been deleted in the compatibility layer.

2.4 Running

2.4.1 Manual Initialization Process
This compatibility layer is fully compatible with the standard initialization process provided by the official documentation; if you are compatible with old projects, no modifications are needed for the μCOS-II initialization part.

2.4.2 Automatic Initialization Process

If you do not wish to manually initialize this compatibility layer in the application layer, you can define the macro<span>PKG_USING_UCOSII_WRAPPER_AUTOINIT</span> in the<span>rtconfig.h</span> file. Please refer to [4.2.1 section](#4.2.1 Enable uCOS-II wrapper automatically init) (unless otherwise specified, it is recommended to use this method).

2.5 Notes

1. The task stack size of μCOS-II is measured in<span>sizeof(CPU_STK)</span>, while the thread stack size of RT-Thread is measured in<span>sizeof(rt_uint8_t)</span><span>, although the compatibility layer has made the conversion, it is crucial to ensure that all API calls and macro definitions related to μCOS-II adhere to μCOS-II standards, i.e., the stack size is</span><code><span>sizeof(CPU_STK)</span><span><span>, </span><strong>do not mix types</strong><span>! Such errors are extremely subtle and must be noted!</span></span>
 1ALIGN(RT_ALIGN_SIZE)
 2static rt_uint8_t thread2_stack[1024];//Error: Mixing RT-Thread data type with thread stack
 3
 4OSTaskCreateExt(task,
 5               0,
 6               &amp;task_stack[TASK_SIZE-1],
 7               TASK_PRIO,
 8               0,
 9               &amp;task_stack[0],
10               sizeof(thread2_stack),//Task stack size (Error: this parameter is in sizeof(CPU_STK))
11               0,
12               OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR);

Below is the correct way:

 1#define THREAD_STACK_SIZE       256 //Correct, stack size defined separately using macro, unit is sizeof(CPU_STK)
 2ALIGN(RT_ALIGN_SIZE)
 3   static CPU_STK thread2_stack[THREAD_STACK_SIZE];//Correct, using μCOS-II's own data type to define task stack
 4
 5OSTaskCreateExt(task,
 6               0,
 7               &amp;task_stack[TASK_SIZE-1],
 8               TASK_PRIO,
 9               0,
10               &amp;task_stack[0],
11               THREAD_STACK_SIZE,//Task stack size (Correct)
12               0,
13               OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR);
2. This compatibility layer file contains Chinese comments, encoded in ANSI – GB2312, not UTF-8 encoding.

3 Interfaces

3.1 New APIs Added

Extra implementation of<span>OSMutexCreateEx()</span><span> function, which is not present in the original μCOS-II functions. The first parameter of</span><code><span>OSMutexCreate()</span><span> in the compatibility layer has no significance and is thus omitted for user convenience. This is because the implementation of μCOS-II is outdated and does not support the same task at the same priority. Users are recommended to use this API:</span>
1OS_EVENT  *OSMutexCreateEx (INT8U  *perr);
Extra implementation of<span>OSQCreateEx()</span><span> function, which is not present in the original μCOS-II functions. The first parameter of</span><code><span>OSQCreateEx()</span><span> in the compatibility layer has no significance and is thus omitted for user convenience. Users are recommended to use this API:</span>
1OS_EVENT  *OSQCreateEx (INT16U    size);

3.2 APIs Not Implemented (Only 2)

 1INT8U         OSTaskCreate            (void           (*task)(void *p_arg),
 2                                       void            *p_arg,
 3                                       OS_STK          *ptos,
 4                                       INT8U            prio);
 5
 6INT16U        OSEventPendMulti        (OS_EVENT       **pevents_pend,
 7                                       OS_EVENT       **pevents_rdy,
 8                                       void           **pmsgs_rdy,
 9                                       INT32U           timeout,
10                                       INT8U           *perr);

3.3 Hook Functions

The hook functions of μCOS-II are only responsible for the μCOS-II compatibility layer. If you register the<span>OSTaskDelHook</span><span> function, it will only be called when the OSTaskDel function is invoked, and not when the</span><code><span>rt_thread_detach</span><span> function is called (this is handled by RTT's hook functions). This is to maintain clarity and prevent the μCOS-II compatibility layer from interfering with RT-Thread internal affairs.</span>
The hook functions for μCOS-II are implemented in two files:<span>os_cpu_c.c</span> and <span>app_hooks.c</span><code> . Following μCOS-II's philosophy,<code><span>os_cpu_c.c</span> provides the original hook functions (i.e., these hook functions are called directly by the respective functions), and this file, along with its internal hook functions, is intended for use by porting engineers; application engineers should not modify the content of this file. The hook functions in the<span>os_cpu_c.c</span> file provide function pointers for the hook functions in the<span>app_hooks.c</span> file to register and use, which can be manipulated by application engineers. In other words, any functions that need to be called in the hook functions should be placed in the<span>app_hooks.c</span> file.
The following original μCOS-II hook functions will be canceled, and RT-Thread will take over the related hook functions:
1void          OSTaskReturnHook          (OS_TCB *p_tcb);
2void          OSTaskSwHook              (void);
3void          OSTimeTickHook            (void);

At the same time, the corresponding application-level hook functions for the above hook functions have also been canceled:

1void  App_TaskReturnHook (OS_TCB  *p_tcb);
2void  App_TaskSwHook (void);
3void  App_TimeTickHook (void);

3.4 Statistical Task (OS_TaskStat())

In μCOS-II, the statistical task is a system task, determined by the<span>OS_TASK_STAT_EN</span><span> macro. It can perform statistical tasks during system runtime. The CPU utilization is represented as an integer between 0-100 (corresponding to 0% - 100%).</span>
However, RT-Thread does not have a statistical task, so a task needs to be created to be compatible with the original μCOS-II statistical task and fulfill the above functions. This statistical task will be automatically created during the compatibility layer initialization, and users do not need to intervene. Users only need to callOSCPUUsage global variable to obtain the current CPU usage, which is calculated in the same way as the original μCOS-II.

3.5 Task Control Blocks, Kernel Object Control Blocks (Structures)

This compatibility layer aims to be as compatible as possible with each member variable of the task and kernel object control blocks (structures), ensuring that old programs migrated over can run directly without modification (even though directly accessing the member variables of structures is not recommended by μCOS-II).
For example, the member variables of the<span>OS_TCB</span> structure are as follows, showing that it includes most member variables of the original version. If you do not need to maintain compatibility with the original member variables, you can define the macro<span>PKG_USING_UCOSII_WRAPPER_TINY</span>, which will significantly reduce the<span>OS_TCB</span> structure. You can also disable<span>OS_TASK_PROFILE_EN</span>, <span>OS_TASK_NAME_EN</span>, <span>OS_CFG_TASK_REG_TBL_SIZE</span> to further trim.
 1typedef struct os_tcb {
 2    struct rt_thread OSTask;
 3    OS_STK          *OSTCBStkPtr;           /* Pointer to current top of stack                         */
 4
 5#if OS_TASK_CREATE_EXT_EN &gt; 0u
 6    void            *OSTCBExtPtr;           /* Pointer to user definable data for TCB extension        */
 7    OS_STK          *OSTCBStkBottom;        /* Pointer to bottom of stack                              */
 8    INT32U           OSTCBStkSize;          /* Size of task stack (in number of stack elements)        */
 9    INT16U           OSTCBOpt;              /* Task options as passed by OSTaskCreateExt()             */
10    INT16U           OSTCBId;               /* Task ID (0..65535)                                      */
11#endif
12
13    struct os_tcb   *OSTCBNext;             /* Pointer to next     TCB in the TCB list                 */
14    struct os_tcb   *OSTCBPrev;             /* Pointer to previous TCB in the TCB list                 */
15
16#if OS_TASK_CREATE_EXT_EN &gt; 0u
17#if defined(OS_TLS_TBL_SIZE) &amp;&amp; (OS_TLS_TBL_SIZE &gt; 0u)
18    OS_TLS           OSTCBTLSTbl[OS_TLS_TBL_SIZE];
19#endif
20#endif
21
22#ifndef PKG_USING_UCOSII_WRAPPER_TINY
23#if (OS_EVENT_EN)
24    OS_EVENT        *OSTCBEventPtr;         /* Pointer to           event control block                */
25#endif
26#if (OS_FLAG_EN &gt; 0u)
27    OS_FLAGS         OSTCBFlagsRdy;         /* Event flags that made task ready to run                 */
28#endif
29    INT32U           OSTCBDly;              /* Nbr ticks to delay task or, timeout waiting for event   */
30#endif
31    INT8U            OSTCBStat;             /* Task      status                                        */
32    INT8U            OSTCBStatPend;         /* Task PEND status                                        */
33    INT8U            OSTCBPrio;             /* Task priority (0 == highest)                            */
34
35#if OS_TASK_DEL_EN &gt; 0u
36    INT8U            OSTCBDelReq;           /* Indicates whether a task needs to delete itself         */
37#endif
38
39#if OS_TASK_PROFILE_EN &gt; 0u
40    OS_STK          *OSTCBStkBase;          /* Pointer to the beginning of the task stack              */
41    INT32U           OSTCBStkUsed;          /* Number of bytes used from the stack                     */
42#endif
43
44#if OS_TASK_NAME_EN &gt; 0u
45    INT8U           *OSTCBTaskName;
46#endif
47
48#if OS_TASK_REG_TBL_SIZE &gt; 0u
49    INT32U           OSTCBRegTbl[OS_TASK_REG_TBL_SIZE];
50#endif
51} OS_TCB;

3.6 Global Variables

Currently, this compatibility layer can use the following original μCOS-II global variables (located in<span>ucos_ii.h</span><span>). The specific meanings of these global variables can be found in the reference materials listed in [2.2 section](#2.2 迁移步骤).</span>
 1#if OS_TASK_STAT_EN &gt; 0u
 2OS_EXT  INT8U             OSCPUUsage;               /* Percentage of CPU used                          */
 3OS_EXT  INT32U            OSIdleCtrMax;             /* Max. value that idle ctr can take in 1 sec.     */
 4OS_EXT  INT32U            OSIdleCtrRun;             /* Val. reached by idle ctr at run time in 1 sec.  */
 5OS_EXT  BOOLEAN           OSStatRdy;                /* Flag indicating that the statistic task is rdy  */
 6OS_EXT  OS_STK            OSTaskStatStk[OS_TASK_STAT_STK_SIZE];      /* Statistics task stack          */
 7#endif
 8
 9#define OSIntNesting      rt_interrupt_get_nest()   /* Interrupt nesting level                         */
10
11#define OSLockNesting     rt_critical_level()       /* Multitasking lock nesting level                 */
12
13#define OSPrioCur rt_thread_self()-&gt;current_priority       /* Priority of current task                 */
14
15OS_EXT  BOOLEAN           OSRunning;                       /* Flag indicating that kernel is running   */
16
17OS_EXT  INT8U             OSTaskCtr;                       /* Number of tasks created                  */
18
19#if OS_TASK_STAT_EN &gt; 0u
20OS_EXT  volatile  INT32U  OSIdleCtr;                       /* Idle counter                             */
21#endif
22
23#ifdef OS_SAFETY_CRITICAL_IEC61508
24OS_EXT  BOOLEAN           OSSafetyCriticalStartFlag;
25#endif
26
27#define OSTCBCur         ((OS_TCB*)rt_thread_self())       /* Pointer to currently running TCB         */
28OS_EXT  OS_TCB           *OSTCBFreeList;                   /* Pointer to list of free TCBs             */
29OS_EXT  OS_TCB           *OSTCBList;                       /* Pointer to doubly linked list of TCBs    */
30OS_EXT  OS_TCB           *OSTCBPrioTbl[OS_LOWEST_PRIO + 1u];    /* Table of pointers to created TCBs   */
31OS_EXT  OS_TCB            OSTCBTbl[OS_MAX_TASKS + OS_N_SYS_TASKS];   /* Table of TCBs                  */
32
33#if (OS_MEM_EN &gt; 0u) &amp;&& (OS_MAX_MEM_PART &gt; 0u)
34OS_EXT  OS_MEM           *OSMemFreeList;            /* Pointer to free list of memory partitions       */
35OS_EXT  OS_MEM            OSMemTbl[OS_MAX_MEM_PART];/* Storage for memory partition manager            */
36#endif
37
38#if OS_TASK_REG_TBL_SIZE &gt; 0u
39OS_EXT  INT8U             OSTaskRegNextAvailID;     /* Next available Task register ID                 */
40#endif
41
42#if OS_TIME_GET_SET_EN &gt; 0u
43#define   OSTime          rt_tick_get()             /* Current value of system time (in ticks)         */
44#endif
45
46#if OS_TMR_EN &gt; 0u
47#define   OSTmrTime       rt_tick_get()             /* Current timer time                              */
48#endif

4 Automating Env Tool Configuration into the Project

4.1 Configuration Method

The uCOS-II compatibility layer needs to be manually added to the project in the RT-Thread Nano version, but if using the full version of RT-Thread, it can be automatically added to the project via the Env tool. The method is as follows:
1RT-Thread online packages
2    system packages ---&gt;
3        [*] Micrium: Micrium software products porting for RT-Thread ---&gt;
4            [*] uCOS-II Wrapper ---&gt;
5                [*]   Enable uCOS-II wrapper automatically init
6                [*]   Enable uCOS-II wrapper tiny mode
7                Version (latest)  ---&gt;
8

4.2 Optional Function Descriptions

4.2.1 Enable uCOS-II wrapper automatically init

The uCOS-II compatibility layer supports initialization according to the original μCOS-II initialization steps; however, in some cases, users may not want to manually initialize the uCOS-II compatibility layer and wish to run application-level tasks or modules directly. In this case, after defining this macro in<span>rtconfig.h</span><span>, the uCOS-II compatibility layer will be automatically initialized before RT-Thread completes its initialization and enters the main thread, allowing users to focus solely on the application-level tasks of uCOS-II.</span>

If this feature is enabled, the macro<span>PKG_USING_UCOSII_WRAPPER_AUTOINIT</span> will be defined in the<span>rtconfig.h</span> file. The following functions in the<span>os_rtwrap.c</span> file will be enabled and automatically executed during RT-Thread initialization.

If you want to use this feature without using the full version (i.e., the nano version), you can manually add the macro definition<span>PKG_USING_UCOSII_WRAPPER_AUTOINIT</span> in<span>rtconfig.h</span>.

 1/**
 2 * Automatic initialization
 3 * The uCOS-II compatibility layer supports initialization according to the original μCOS-II initialization steps; however, in some cases,
 4 * users may not want to manually initialize the uCOS-II compatibility layer and wish to run application-level tasks or modules directly. This
 5 * macro definition can be used. After defining this macro in rtconfig.h, the uCOS-II compatibility layer will be automatically initialized
 6 * before RT-Thread completes its initialization and enters the main thread, allowing users to focus solely on the application-level tasks of uCOS-II.
 7 * The wrapper supports uCOS-II standard startup procedure. Alternatively,
 8 * if you want to run uCOS-II apps directly and ignore the startup procedure, 
 9 * you can choose this option.
10 */
11#ifdef PKG_USING_UCOSII_WRAPPER_AUTOINIT
12static int rt_ucosii_autoinit(void)
13{
14    OSInit();                                       /* Initialize the μCOS-II operating system */
15    OSStart();                                      /* Start running the μCOS-II operating system */
16
17#if OS_TASK_STAT_EN &gt; 0u
18    OSStatInit();
19#endif
20    return 0;
21}
22INIT_PREV_EXPORT(rt_ucosii_autoinit);
23#endif

4.2.2 Enable uCOS-II wrapper tiny mode

If you do not need to maintain compatibility with the member variables of task/kernel object structures during use, you can enable this option. The ENV will automatically define the macro<span>PKG_USING_UCOSII_WRAPPER_TINY</span> in the<span>rtconfig.h</span> file. This mode meets basic compatibility requirements for all APIs, and it is recommended to select this option.

5 Others

5.1 Contact Information

Maintenance:Meco Man

Contact method:[email protected]

5.1.2 Personal GitHub Page

https://github.com/mysterywolf/RT-Thread-wrapper-of-uCOS-II

μC/OS-II Compatibility Layer for RT-Thread OS

RT-Thread

Making the development of IoT terminals simple and fast, maximizing the value of chips. Apache2.0 license, can be used for free in commercial products without disclosing source code, no potential business risks.

Long press the QR code to follow us

👇👇👇 Click to read the original text and enter the RT-Thread official website

Leave a Comment