Share this

Porting the real-time operating system µC/OS-II to C8051F120

2026-04-06 08:57:28 · · #1
Abstract This paper introduces the features of the real-time operating system µC/OS-II and discusses the necessity of porting it to the 51 series microcontrollers. The 8-bit microcontroller C8051F120 is selected as the porting target, and the specific porting process of µC/OS-II is analyzed. Finally, a routine is designed to verify the correctness of the porting. Keywords C8051F120; µC/OS-II; porting [align=center]The Porting of Real-Time Operation System µC/OS-II on C8051F120 Taiyuan University of Technology Tian Juan[/align] Abstract The paper introduces the characteristics of real-time operation system µC/OS-II, and discusses the necessity of porting µC/OS-II on 51 series MCU. Then the specific process of porting µC/OS-II on C8051F120, which is selected as porting target, is analyzed. The paper ends with designing test program to prove the success of the porting. Keywords C8051F120; µC/OS-II; porting Introduction Traditional embedded system design often adopts a foreground/background system. The application program is an infinite loop, in which the corresponding function is called to complete the corresponding operation. This part can be regarded as background behavior. The interrupt service routine handles asynchronous events. This part can be regarded as foreground behavior[1]. In most situations where real-time requirements are high, this system architecture cannot meet the application requirements, and real-time kernels have gradually become the mainstream of embedded system design. µC/OS-II is a complete, portable, solidified, and customizable preemptive real-time multitasking kernel. It is not only simple in structure and mostly uses C language, but also has good portability and can be easily ported to various microprocessors. During the porting process, only a small amount of modification work is required. Currently, µC/OS-II supports up to 64 tasks and always executes the highest priority task that is in the ready state. It has been widely used due to the complete openness of its source code and its superior performance. The 51 series microcontroller is a high-performance 8-bit microcontroller launched by Intel Corporation in 1980. It is still one of the most widely used microcontroller series in my country and has a very large application environment and prospect. If an operating system based on the 51 series microcontroller is developed, then the user only needs to write the program for each task and does not need to remember the various situations of all tasks running at the same time. This not only greatly reduces the workload of program writing, but also reduces the possibility of errors [2]. Therefore, it is necessary to port the real-time operating system µC/OS-II to the 51 series microcontroller. 1. Porting Requirements for µC/OS-II For µC/OS-II to function correctly after being ported to a processor, the processor must meet the following conditions: ● The processor's C compiler must be able to generate reentrant code. µC/OS-II is a preemptive kernel, always allowing high-priority ready tasks to run first. Interrupt service routines can preempt the CPU, so only a C compiler can generate reentrant code. Reentrant functions can be called by more than one task without data corruption. ● The processor's C compiler must be able to enable and disable interrupts in C. µC/OS-II must disable interrupts when handling critical sections and re-enable them afterward. ● The processor must support interrupts and be able to generate timer interrupts. µC/OS-II uses hardware interrupts to implement the system clock and handles time-related issues and task scheduling in the clock interrupt service routine. ● The processor must have a certain number of hardware stacks and instructions to read the stack pointer and other CPU register contents and store them on the stack or in memory. Because µC/OS-II allocates a task stack for each task, when switching tasks, it is necessary to save the current task stack content first, and then restore the highest priority task stack content. 2 Selection of CPU Chip With the development of modern communication technology, the demand for DSP in intelligent systems is constantly increasing the speed of single-chip microcomputers[3]. The C8051F series single-chip microcomputer was launched by Silabs under such circumstances. It is a fully integrated mixed-signal system-on-a-chip with a microcontroller core compatible with 8051. Without expanding the 8-bit data bus, it increases the single-cycle instruction speed to 12 times that of the original 8051. The C8051F120, as a high-end product in the C8051F series, was selected as the object of system porting. The internal resources of the C8051F120 include: 64 I/O pins, 5 16-bit general-purpose counters/timers, 6 capture/compare modules, hardware-implemented SPI, SMBus/IIC and two UART serial interfaces, on-chip watchdog timer, 2 comparators, a true 12-bit 100ksps 8-channel ADC, an 8-bit 500ksps 8-channel ADC, 128KB FLASH memory, and 8448B of internal data RAM[4]. Since the C8051F120 processor and the Keil compiler used can meet the above porting conditions well, µC/OS-II can be ported to the C8051F120. In the actual development system, an external crystal oscillator with a crystal frequency of 22.1184MHz is used, and 256KB of RAM is added externally. 3 Porting process The porting of µC/OS-II can be regarded as a modification of µC/OS-II code. µC/OS-II code is divided into processor-independent code, processor-dependent code and application-dependent code. In principle, processor-independent code can be added directly without modification. However, due to the special nature of the Keil compiler, the reentant keyword must be marked after the function declaration that needs to be reentrant, that is, the reentrant attribute must be added. Also, because pdata is both a Keil keyword and a parameter of some functions of µC/OS-II, it will cause compilation errors. Therefore, pdata is changed to pdat. The processor-related code includes three files: OS_CPU.H, OS_CPU_C.C, and OS_CPU_A.ASM. It requires a lot of modification before it can be added, which is the focus of the porting work. In addition, the application-related code includes two header files: INCLUDES.H and OS_CFG.H. INCLUDES.H is a main header file that appears as the first line of each .C file. The INCLUDES.H file makes it so that each .C file in the project does not need to consider which header files it actually needs. You can also add your own header files at the end of the header file list. OS_CFG.H is the system configuration file. The reduction process of µC/OS-II is completed by setting the relevant constants in OS_CFG.H[5]. This can be divided into: reducing task management functions to save code storage space; reducing data structures to save data storage space; and setting system clock frequency and task stack size. 3.1 OS_CPU.H OS_CPU.H includes processor-related constants, macros, and types defined using #define statements. Data type definitions are to ensure portability. Furthermore, the data type of the task stack must be told to µC/OS-II, which is achieved by declaring the appropriate C data type for OS_STK. The C8051F120's stack is 8 bits, so OS_STK is declared: typedef INT8U OS_STK; //The stack width is 8 bits. µC/OS-II must disable interrupts and re-enable them after processing critical code segments. Therefore, two macros are defined to disable and enable interrupts: OS_ENTER_CRITICAL() and OS_EXIT_CRITICAL(). These two macros can be implemented in three ways; the specific method used depends on the processor type and C compiler. The C8051F120 uses Method 1 to handle critical sections, which directly enables or disables interrupts. This definition reduces the number of program lines and avoids system crashes caused by disabling interrupts after exiting the critical section. Since bit 7 (EA) of the Interrupt Enable Register (IE) is the global interrupt enable control bit, EA=0 disables all interrupts, and EA=1 enables all interrupts. Therefore, the definition statements are: #define OS_ENTER_CRITICAL() EA=0 //disable interrupts #define OS_EXIT_CRITICAL() EA=1 //enable interrupts The C8051F120 stack grows from bottom to top (0=up, 1=down), and the stack direction is specified by the configuration constant OS_STK_GROWTH. Therefore, the definition statement is: #define OS_STK_GROWTH 0 // The stack grows from bottom to top, 1 = grows downwards. Task switching in µC/OS-II is accomplished by mimicking interrupt actions, but the C8051F120 does not have software interrupt instructions, so task switching is implemented using function calls. The definition statement is: #define OS_TASK_SW() OSCtxSw() // OSCtxSw() is the function used to implement task switching. 3.2 OS_CPU_C.C OS_CPU_C.C includes 10 C functions: OSTaskStkInit() and 9 Hook functions. The OSTaskStkInit() function is called when a task is created to initialize the task stack. Hook functions are used to extend the functionality of µC/OS-II; they can be empty of code but must be declared. Finally, the Timer0 initialization function is added, including selecting the working mode, setting the initial value, and enabling interrupts, because the C8051F120's Timer0 will be used to implement clock interrupts. Before modifying the `OSTaskStkInit()` function, it's necessary to understand the task stack structure. µC/OS-II allocates a task stack for each task, consisting of a system stack and a simulation stack. Since the C8051F120 requires the stack to be located in on-chip RAM, and on-chip RAM space is very limited, it's almost impossible to store all task stacks in on-chip RAM. The task stacks must be stored in off-chip RAM, with a shared stack (the system stack) set up in the on-chip RAM, with the stack base address `?STACK`. During task switching, the current task stack content must be saved first, and then the highest priority task stack content must be restored—that is, the task stack and system stack are copied. The simulation stack is used for parameter passing and storing local variables for reentrant functions. It is located in off-chip RAM, grows from top to bottom, and its stack pointer is `?C_XBP`. Therefore, task stack initialization can be viewed as the process of copying the task stack content of the highest priority task in the ready state to the system stack. First, the lowest address and length of the task stack must be obtained. Since 15 register contents need to be restored from the task stack to the system stack, the stack length is 15. Then, the register contents are copied sequentially from bottom to top: PCL, PCH, PSW, ACC, B, DPL, DPH, R0, R1, R2, R3, R4, R5, R6, R7. Finally, the simulation stack address is saved, and the lowest address of the task stack is returned. This completes the task stack initialization. 3.3 OS_CPU_A.ASM OS_CPU_A.ASM includes four assembly language functions, all of which are non-reentrant and define the system stack size. The OSStartHighRdy() function starts the highest priority task among the ready tasks. The OSCtxSw() function implements task switching during normal CPU operation, i.e., saving the current task stack and popping the highest priority task stack, allowing the highest priority task to gain CPU control. The OSIntCtxSw() function performs interrupt-level task switching within an interrupt service routine. Most of its code is the same as the OSCtxSw() function, the difference being that the interrupt service function has already saved the register contents, so it does not need to be saved again in the OSIntCtxSw() function. The OSTickISR() function is the interrupt service routine for the system clock. Its main function is to check if any tasks that were suspended due to delays have become ready tasks. If so, it calls the OSIntCtxSw() function to perform a task switch, thereby running the highest priority task. Because µC/OS-II checks for higher priority tasks waiting to be executed at every clock tick, and performs a task switch if found, the higher the clock tick rate, the heavier the additional load on the system. 4 System Testing Following the above porting steps, the authors implemented the specific porting of µC/OS-II to the C8051F120 in the Keil compilation environment. To prevent excessively large segmentation errors during compilation, the memory mode needs to be selected as large mode, and XBPSTACK=1 needs to be set accordingly in the STARTUP.A51 file. Two tasks were created to verify the successful porting of µC/OS-II: `OSTaskCreate (TaskLed, (void *)0, TaskStartStkLed,2); OSTaskCreate (TaskSmg, (void *)0, TaskStartStkSmg,3);` The program flowchart is shown in Figure 1. After TaskLed blinks once, it sends a message to TaskSmg and waits for a reply. TaskSmg receives the message, displays the blink count, and replies. The final effect is that when the LED connected to P4.0 blinks once, the digital tube connected to P5 increments the displayed number by 1, up to a maximum of 9, and then automatically resets to zero. After 4 hours of continuous experimentation, everything ran normally, verifying the correctness of the ported code. [align=center] Figure 1 Program Flowchart[/align] It should be noted that the use of C8051F120 involves the protection of SFRPAGR, because C8051F120 has too many analog and digital resources, all of which require corresponding SFR control. The SFR space reserved by the standard 8051 cannot meet the required SFR registers, so C8051F120 arranges SFRPAGE to expand more SFR register space. The same SFR address, combined with different SFRPAGE values, controls different resources. However, if a task switch occurs in a non-interrupt situation and SFRPAGE is changed in the new task, then after returning to the previous task, SFRPAGE may have changed, thus making it impossible to control the correct resources, and may even cause the program to crash. Because different resources often require different SFRPAGE, in order to solve this problem, critical code protection should be made in all places where SFRPAGE is assigned, so that problems caused by incorrect SFRPAGE values ​​can be completely avoided[6]. 5. Conclusion µC/OS-II is a multi-tasking real-time operating system with good real-time performance and small code size. It has excellent stability and reliability and can be widely ported to microprocessors with different architectures. This paper fully describes the porting process of µC/OS-II and implements dual-task synchronous communication on the C8051F120. This paper has general guiding significance for the porting of µC/OS-II to 51 series microcontrollers.
Read next

CATDOLL Charlotte Hard Silicone Head

The head made from hard silicone does not have a usable oral cavity. You can choose the skin tone, eye color, and wig, ...

Articles 2026-02-22