0 Preface
When developing embedded systems, embedded development platforms based on ARM and uC/OS-II are generally chosen because ARM microprocessors have the advantages of fast processing speed, ultra-low power consumption, low price, and wide application prospects [1]. After porting uC/OS-II to the ARM system, the advantages of both can be fully combined. If a program can work in one environment, we often hope to port it to another compilation system, processor or operating system. This is the porting technology. Porting technology can make a specific technology used in a wider range, making the use of software more flexible and not limited to a certain condition. uC/OS-II is a complete, portable, solidified, and tailored preemptive real-time multitasking kernel written by Mr. Jean J. Labrosse. The source code of uC/OS-II is completely open, which is unmatched by other commercial real-time kernels [2]. It is designed for embedded applications and portability is fully considered at the beginning of the design. Most of its source code is written in highly portable ANSI C [3]. uC/OS-II can be ported to systems ranging from 8-bit to 64-bit. It can be used to develop embedded systems of different types and sizes, and can run on most 8-bit, 16-bit, 32-bit, and even 64-bit microprocessors and DSPs. Since uC/OS-II is a real-time operating system, if it is embedded in an ARM processor, it can further simplify the development of ARM systems.
1 uC/ OS-II porting
The file system structure of uC/OS-II includes the core code part, the setting code part, and the processor-related porting code part[4]. The structure is shown in Figure 1. The top software application layer is the code on uC/OS-II. The core code part includes 7 source code files and 1 header file. The functions are kernel management, event management, message queue management, storage management, message management, semaphore processing, task scheduling and timing management. The setting code part includes 2 header files, which are used to configure the number of event control blocks and whether to include message management related code. The processor-related porting code part is the part that needs to be changed during the porting process, including 1 header file OS CPU.H, 1 assembly file OS CPU A.S and 1 C code file. In fact, to port uC/OS-II to ARM processor, the work that needs to be completed is mainly the following three architecture-related files: OS CPU.H, OS CPU.C and OS CPU A.S[5].
1. 1 OS CPU. H porting
The file OS CPU.H includes constants, macros and types related to the processor defined by the #define statement. The main modifications during porting include: the setting of data types related to the compiler; the definition of 2 macro switch interrupts by the #define statement; the definition of OS STK GROWTH according to the direction of the stack, etc.
When porting uC/OS-II to the ARM processor, the first step is to perform basic configuration and data type definition. Redefining data types is to increase the portability of the code, because different compilers provide different data lengths for the same data type. For example, the int type is 16 bits in some compilers and 32 bits in others. Therefore, in order to facilitate porting, it is necessary to redefine the data type, such as INT32U represents an unsigned 32-bit integer. typedefunsigned int INT8U is to define an 8-bit unsigned integer data type. The second step is to define ARM processor-related macros, such as the macro definitions of exiting the critical section and entering the critical section in the ARM processor. The macro definition of exiting the critical section [5]: #define OS EXITCRITICAL () ARMDisable Int () //Disable interrupts, enter the critical section macro definition #define OS ENTER CRITICAL () AR2MEnableInt () //Enable interrupts. Finally, the stack growth direction is set. When a function is called, the entry parameters and return address are generally saved in the stack of the current task. The compiler options and the stack instructions generated by them determine the growth direction of the stack [6], defined as #define OS STK GROWTH 1.
1. 2 OS CPU. C porting
OS CPU. C porting includes task stack initialization and corresponding function implementation. Here, there are 6 functions: OSTaskStkInit(), OSSTaskCreateHook(), OSTaskDelHook(), OS2TaskSwHook(), OSTaskStatHook(), OSTimeTickHook(). The latter 5 HOOK functions are also called hook functions, which are mainly used to expand the functions of uC/OS-II. These functions are user-defined functions, which are executed by the operating system calling the corresponding HOOK functions. In general, they have no code, so they can be implemented as empty functions. The function OSTaskStkInit() initializes the stack. In the ARM system, the task stack space is PC, LR, R12, R11, ⋯, R1, R0, CPSR, SPSR from high to low. After the stack is initialized, OSTaskStkInit() returns the new stack top pointer.
1.3 OS CPU A.S Porting
The porting of OS CPU A.S files requires the operation of processor registers, so they must be written in assembly language. The implementation of this file embodies the architecture of the processor to be ported and the porting principle of uC/OS-II [6]. It includes four sub-functions: OSStartHighRdy(), OSCtxSw(), OSIntCtxSw(), and OSTick2ISR(). The difficulty lies in the implementation of OSIntCtxSw() and OSTickISR() functions, because the implementation of these two functions is related to the porter's porting ideas and the settings of related hardware timers and interrupt registers. In actual porting work, these two places are also prone to errors.
The OSIntCtxSw() function is called by the OSIntExit() function, which in turn is called by OSTickISR(). The most important function of the OSIntCtxSw() function is that it performs task switching directly in the interrupt ISR, thereby improving the speed of real-time response. It occurs when the ISR executes to OSIntExit(). If a high-priority task is found to have obtained the conditions for execution due to waiting for the arrival of the time tick, it can be scheduled for execution immediately without returning to the interrupted task and then performing task switching. There are roughly two ways to implement OSIntCtxSw() [7]: One is to adjust the SP stack pointer. According to the compiler's processing of function nesting, the SP position that needs to be adjusted is accurately calculated so that the work of protecting the scene when entering the interrupt can be reused. The second method is to set the flag that needs to be switched. In OSIntCtxSw(), no switching occurs, but a flag that needs to be switched is set. After the function is nested and exits from OSIntExit() => OS ENTER CRITI2CAL() => OSIntCtxSw() => OS EXIT CRITICAL() => OSIntExit(), the flag is used to determine whether interrupt-level task switching is required.
The second is to modify OSTickISR(). OSTickISR() first saves the value of the CPU register in the interrupted task stack, and then calls OSIntEnter(). Then it calls OSTimeTick() to check all tasks in the delayed waiting state to determine whether there is a task that is ready after the delay. Finally, OSIntExit() is called. If there is a higher priority task ready in the interrupt (or other nested interrupts), and the current interrupt is the last layer of interrupt nesting, OSIntExit() will schedule the task. If the task is scheduled, OSIntExit() will no longer return to the caller, but will restore the CPU scene with the register value in the stack of the new task, and then implement task switching. If the current interrupt is not the last layer of interrupt nesting, or the ready state of the task is not changed in the interrupt, OSIntExit() will return to the caller OSTickISR(), and OSTickISR() will return to the interrupted task. Finally, there are the functions of exiting and entering the critical section. When entering the critical section, the interrupt must be turned off, which is implemented using the ARMDisableInt() function. When exiting the critical section, the original interrupt status is restored through the ARMEnableInt() function [7]. As for the task-level context switch, it is implemented by the assembly subroutine OSCtxSw.
2 Implementation on ARM system
Taking the marquee and digital tube as examples, the transplantation process of uC/OS-II is explained: the marquee is a system where four small lights turn bright and dark in turn, which makes it very easy to see the effect. Marquees are widely used in daily life, such as status bar marquees, text marquees, image marquees, microcontroller marquees, etc. [8]. This article uses a microcontroller marquee. In the program that implements the microcontroller marquee, the light-emitting diode will only light up when the address port is at a low level (grounded). Therefore, as long as the level of each pin of the address port is cyclically controlled, the LED can be lit up cyclically: first, all lights are off, then the first light is on, the second light is on, the third light is on, the fourth light is on, the fifth light is on, and finally all lights are on together.
The author uses 6 common anode LED digital tubes to realize the cyclic display of 0~9, A~F characters on the 7-segment digital tube. The segment selection line of each display bit is connected to an 8-bit parallel port line. As long as the segment code level on the segment selection line of the display bit remains unchanged, the bit can maintain the corresponding display character. The 8-bit parallel port here can directly use the parallel I/O port, or it can use a serial input/parallel output shift register or other latches with three-state functions. When using a dynamic display interface, in multi-bit LED display, in order to simplify the circuit and reduce costs, the segment selection lines of all bits are connected in parallel and controlled by an 8-bit I/O port. The common end of the common cathode (or common anode) pole is controlled by the corresponding I/O line to realize the time-sharing selection of each bit. Since each digital tube shares the same segment code output port and is powered in turn in time, the hardware circuit is greatly simplified and the cost is reduced.
Previous article:Electronic system design using ARM
Next article:Design of LED large screen control system based on MCU+FPGA
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Wi-Fi 8 specification is on the way: 2.4/5/6GHz triple-band operation
- Wi-Fi 8 specification is on the way: 2.4/5/6GHz triple-band operation
- Vietnam's chip packaging and testing business is growing, and supply-side fragmentation is splitting the market
- Vietnam's chip packaging and testing business is growing, and supply-side fragmentation is splitting the market
- Three steps to govern hybrid multicloud environments
- Three steps to govern hybrid multicloud environments
- Microchip Accelerates Real-Time Edge AI Deployment with NVIDIA Holoscan Platform
- Microchip Accelerates Real-Time Edge AI Deployment with NVIDIA Holoscan Platform
- Melexis launches ultra-low power automotive contactless micro-power switch chip
- Melexis launches ultra-low power automotive contactless micro-power switch chip
- Msp430F5438A interrupt initial
- EEWORLD University - Teach you how to use emWin graphical interface
- Chuanglong TMS320C6748 development board——timer/counter learning
- The Android software has been unable to successfully upload the example to the board. Is this a bug?
- 【RT-Thread】Reading Notes (3) Critical Section Protection, Objects, and Containers
- I'm planning to buy a current probe.
- How to solve the chip shortage dilemma? Find out from Yunhan Chip City!
- Three ways to write fennel beans
- My own DIY download website, a small website placed on the router, please support
- CSR8670 - What are ANC, CVC, and DSP noise reduction?