Application of M16C62 in uC/OS-II Embedded Systems
2026-04-06 06:02:56··#1
[Abstract] μC/OS-II is an open-source real-time embedded operating system. Its features include open source code, strong portability, preemptive multitasking, separate stacks for each task, interrupt management, and high stability and reliability. It is increasingly attracting the attention of real-time embedded system designers. This paper details how to port the μC/OS-II operating system to the M16C62 microcontroller and presents a design scheme for a real-time multitasking system based on the M16C62 microcontroller as the core processor. [Keywords] Embedded operating system, uC/OS-II, M16C62 microcontroller, real-time, multitasking Introduction With the development of microelectronics technology and networks, people's understanding of networks has deepened. Network terminal products are receiving increasing attention, and the application of embedded operating systems has experienced unprecedented development. Research on embedded systems has also made significant progress. The design and application of real-time, multitasking systems based on a specific operating system has become a new development trend in microcontroller applications. uC/OS is an open-source embedded operating system. uC/OS-II is an upgrade from uC/OS V1.1. Based on the original version, uC/OS-II has many new features, such as: memory management; allowing users to call custom functions during task creation, deletion, task switching, and clock tick switching; supporting Task Control Block (TCB) function extension; verifying the usage of each stack; and some other new features [2]. The M16C62 microcontroller is a new generation of 16-bit microcontroller launched by Mitsubishi in the late 1990s. It is one of the most widely used 16-bit microcontrollers. The M16C family of microcontrollers combines the advantages of register-based and memory-based structures, thus achieving high-speed processing performance similar to RISC. The M16C62 microcontroller has ultra-low power consumption, strong anti-interference ability, and high C language programming efficiency. It integrates a 10-bit A/D converter, DMA controller, asynchronous communication channel, timer, and other rich peripheral function circuit modules, making it very suitable for application in small real-time, multi-tasking, embedded systems [1]. By porting uC/OS-II to the M16C62 microcontroller, a real-time multitasking application system can be constructed. The following discusses how to port uC/OS-II to the M16C62 microcontroller and design a real-time multitasking system based on this. 1. Porting uC/OS-II: uC/OS-II uses a fully preemptive real-time kernel, capable of managing up to 56 tasks, each with a different priority. Therefore, the uC/OS-II operating system does not support time-slice round-robin scheduling. However, the execution time of all function calls and services in uC/OS-II is predictable; that is, the execution time of uC/OS-II system services does not depend on the number of application tasks. In addition, each task in uC/OS-II has its own separate stack, and the size of each stack can be allocated according to the needs of the application, thus reducing the system's RAM requirements. In terms of interrupt management, interrupts in uC/OS-II can suspend the currently executing task. If a higher priority task is woken up by an interrupt, the higher priority task will be executed immediately after all interrupt nesting is exited. The interrupt nesting of uC/OS-II can reach 255 levels. Most of the source code of uC/OS-II is written in the highly portable ANSI C. Only a small part of the code related to the microprocessor is written in assembly, which makes it relatively easy to port uC/OS-II to MC16C62. The main thing is to modify the processor-related code, such as: OS-CPU.H, OS-CPU-A.ASM, OS-CPU-CC. (1) OS-CUP.H header file The OS_CUP.H header file mainly defines the data types related to the processor. The data types in M16C62 include unsigned integer, signed integer, unsigned character, signed character, etc. Therefore, the OS_CPU.H header file defines these types entirely new. In addition to the data type definitions related to the processor, OS-CUP.H also defines some simple macros related to interrupt disable, interrupt enable, stack growth direction, etc. (2) The OS-CPU-A.ASM file contains four assembly language functions: OSStartHighRdy(), OSCtxsw(), OSIntCtxsw(), and OSTickISR(). The stack structure of a task in the ready state in uC/OS-II looks the same as the case when it is interrupted. To run the highest priority task, the porting process is to restore all processor registers from the task stack in sequence and switch tasks through an interrupt return statement. Therefore, OSStartHighRdy() makes the task stack pointer to be restored point to the memory unit at offset 0 of the task control block. That is, the data stored in the task stack and the CPU registers, such as R0, R1, R2, R3, A0, A1, SB and FB, should be returned to the current system registers, and the current stack pointer should be set to the position of the PC pointer. In uC/OS-II, task switching is accomplished by sending a software interrupt command or by relying on the processor to execute a trap instruction. However, the vector address of the interrupt service routine, trap or exception handling routine must point to OSCtxSw() [1]. In the M16C62 microcontroller, task switching can be accomplished by defining software interrupt 0. Therefore, the address of software interrupt 0 in the interrupt vector table of M16C62 points to OSCtxSW(). The corresponding interrupt number is 0. OSInCtxSw() is used to perform the switching function in the ISR. Since this function itself is called in the interrupt, the state of the registers has been correctly saved during interrupt handling. Stack cleanup is performed in the OSInCtxSw() function, only in this way can the stack contents of the interrupted task be returned correctly. The OSTickISR() function is the clock reference required by UC/OS-II, i.e., the clock tick. The clock tick frequency of UC/OS-II is between 10 and 100, and is usually set to an integer for ease of calculation. There are multiple timers and counters in M16C62 that can be used as the system clock reference. In this system, clock timer A0 is used to generate a clock tick with a frequency of 100. OSTickISR() is an interrupt response function, so it must be assigned to OSTickISR() in the interrupt vector table of M16C62. The corresponding interrupt vector number is 21 [4]. (3) OS_CPU_C.C file This C file contains 6 simple C functions, and among these 6 functions, the OSTaskInit() function is most closely related to porting. This function is used to create a task stack. OSTaskCreat() and OSTaskExt() initialize the task stack structure by calling this function. Therefore, OSTaskInit() is the key to porting. In the previous OS_CPU_A.ASM file, task switching is achieved by calling a software interrupt 0. The interrupt return instruction returns the data in the stack to the CPU register, allowing the highest priority task to occupy the CPU. Therefore, the OSTaskInit() function simulates the process of the processor pushing the CPU register contents onto the task stack when an interrupt occurs. In the M16C62 microcontroller, the system is divided into two stacks: the user stack and the interrupt stack. In uC/OS-II, task switching is achieved through software interrupt 0. Therefore, the uC/OS-II task stack is the interrupt stack in the M16C62 [1]. In the M16C62, the stack state after responding to an interrupt is shown in Figure (I): [align=center] Figure (I): Stack state after responding to an interrupt[/align] The interrupt stack stores the contents of the program counter PC and the flag register FLG in sequence. Therefore, the OSTaskStkInit() function simulates such a stack pushing process. First, push the high four bits of FLAG and the high four bits of PC pointer, then push the low bits of FLAG, the middle eight bits of PC, and the low eight bits of PC. After saving the PC and FLAG bits, the corresponding storage space should be allocated for the CPU registers FB, SB, A1, A0, R3, R2, R1, and R0 [3]. The OSTaskInit() function returns a pointer to the task stack. 2. Multitasking System Design The multitasking system is designed with the M16C62 microcontroller as the CPU and uC/OS-II as the operating system to form a real-time multitasking system. The system includes a temperature sensor (DS1722) based on the SPI bus, a real-time clock (X1226) based on the I2C bus, an LCD (JM202A), and a keyboard. The M16C62 works in microprocessor mode, with an external 32K×16-bit RAM (Cy7c1021b) and a memory consisting of two EEPROMs (EEP29010-90). The design of a multi-task system mainly includes two aspects: microcontroller resource allocation and multi-task design. (1) M16C62 microcontroller resource allocation The M16C62 microcontroller is a 16-bit microcontroller with a linear address space of 1M, but the on-chip RAM size is only 3Kbyte. Therefore, in order for the multi-task system to work normally and stably, resources must be allocated reasonably. All kernel code in uC/OS-II must be in the RAM area, while the system stack area is allocated outside the 3K RAM area. By configuring the two M16C62 configuration files Ncrt0.a30 and Secret30.inc, the microcontroller's resource allocation can be completed. The NC30 compiler will compile the two files Ncrt0.a30 and Secret30.inc at the beginning to complete the CPU initialization and resource allocation, mainly including: memory space, RAM area allocation, interrupt vector allocation, stack area division, etc. [5][4][6]. (2) Multitasking Design In addition to the uC/OS-II idle task, this system also includes a real-time clock task, a temperature acquisition task, a keyboard interrupt task, and a data storage task. The real-time clock mainly records the system date accurately, with a task priority of 10, and is always in operation. The temperature acquisition task has a priority of 20 and mainly collects temperature data. The data storage task records the time and temperature when the temperature changes significantly, with a task priority of 30. Under normal circumstances, this task is in a suspended state. Once the temperature change exceeds the preset range, the temperature acquisition task will send a valid signal to make the suspended data storage task ready. The keyboard interrupt task sets parameters through the keyboard interrupt of the M16C62, and this task is completed in the form of an interrupt handling function. The system flowchart is shown in Figure (II). 3. Conclusion Porting uC/OS-II to the M16C62 microcontroller and using the M16C62 as the microprocessor to construct a real-time multitasking system not only results in a simpler system design and hardware structure compared to the 51 series microcontrollers, but also provides stronger anti-interference capabilities and system stability. A multitasking system using the M16C62 as the microprocessor and uC/OS-II as the real-time operating system can be widely applied in small-scale real-time multitasking systems and has good application prospects. [align=center] Figure (II): System Main Program Flowchart[/align] 4. References (1) Lu Yanfeng, Chang Qingpu, Zhu Xuan, eds., Mitsubishi M16C62 Microcontroller Principles and Applications, Beijing University of Aeronautics and Astronautics Press (2) uC/OS-II - Open Source Real-Time Embedded Operating System, JEAN J. LABROSSE, translated by Shao Beibei, China Electric Power Press (3) Yi Yanzhi, ed., Advanced Practical Tutorial of C Language, Tsinghua University Press (4) MITSUBISHI ELECTRIC M16C/62 Group manual (5) MITSUBISHI ELECTRIC NC30 Compile User Manual (6) MITSUBISHI ELECTRIC AS30 Assembler User Manual