Based on the analysis of the real-time embedded system mC/OS-II and LPC2119 chip, this article analyzes and discusses the knowledge that needs to be understood and the preliminary preparation work that needs to be done before mC/OS-II is transplanted to the processor. Finally, it gives The specific work of transplantation has been carried out. The paper focuses on analyzing the transplantation of mC/OS-II.
μC/OS-II is a complete, portable, solidifiable, and scalable preemptive real-time multitasking kernel. It is powerful, supports 56 user tasks, and supports a variety of commonly used processes such as semaphores, mailboxes, and message queues. communication mechanism. The source code is open, the program is highly readable and portable, and it is available for free.
LPC2119 is a 32-bit ARM7TDMI-S microprocessor produced by PHILIPS. Its core is a high-performance 32-bit RISC architecture, with a high-density 16-bit instruction set and extremely low power consumption. With zero-wait 128K bytes of on-chip FLASH and 16K SRAM, there is no need to expand the memory, making the system simpler and more reliable.
Table 1
This article mainly discusses the transplantation of μC/OS-II on LPC2119. At the same time, it analyzes the basic knowledge that needs to be mastered before transplantation, especially the three files closely related to the transplantation. It also conducts a detailed analysis of the chips used. The remapping concept is explained in detail.
Introduction to LPC2119
In addition to the memory introduced above, the LPC2119 on-chip resources also include 2 UARTs, high-speed I2C interfaces, 2 SPI interfaces, 6 output PWM units, 4 10-bit AD converters, 2 32-bit timers, and 2 CAN Channel, real-time clock and watchdog, etc., the maximum CPU operating frequency of 60MHz can be achieved through the on-chip PLL.
Since the writing of the startup code below will use the concept of remapping, LPC2119 and other series of chips such as AT91 also have remapping functions, so the explanation here will serve as a reference for the study of other ARM chips.
In the memory of the ARM chip, the exception vector table is shown in Table 1.
When the system is powered on, the program will automatically start execution from address 0. Therefore, in the initial state of the system, the memory at address 0 is required to be non-volatile ROM or Flash. However, the access speed of ROM or Flash is relatively slow. After each interrupt occurs, it must start by reading the vector table on ROM or Flash, which affects the interrupt response speed. Therefore, LPC2119 provides a flexible address remapping method that can remap the address of the internal RAM to the 0x0 location. Before the system executes the remapping command, the interrupt vector code in Flash needs to be copied to the internal RAM. In this way, after the remapping command is executed, it is equivalent to finding the interrupt vector from the 0x0 position in the internal RAM, but in fact, the starting address of the RAM 0x40000000 is mapped to 0x0. In this way, when the interrupt is executed, it is equivalent to finding the corresponding interrupt vector in RAM to implement exception handling debugging.
Introduction to μC/OS-II
μC/OS-II is actually an embedded operating system kernel, and the basic service provided by the kernel is task switching. In μC/OS-II, dedicated stack space is allocated for each task. When μC/OS-II performs task switching, it will put the CPU registers of the current task into the stack of this task, then restore the original working registers from the stack of another task, and continue to run another task. Therefore, the pushing and popping of registers is the basis of μC/OS-II multi-task scheduling.
Figure 1 μC/OS-II hardware and software architecture
The structure of μC/OS-II is shown in Figure 1.
As shown in Figure 1, there are only three files related to the processor code. Generally, you only need to modify these three files during transplantation.
Write startup code
The startup code is a piece of code executed before entering the main() function of C language after the chip is reset. It mainly provides a basic operating environment for running C language programs, such as initializing peripheral components, memory systems, etc. Therefore, the function of the startup code is somewhat similar to the BIOS in the PC and the Bootloader in VxWorks. Since Philips does not provide the startup code for this chip, you need to write the startup code yourself.
The startup code can be divided into five files: STartup.s, IRQ.s, stack.s, heap.s and target.c. Startup.s contains the exception vector table and system initialization code mentioned earlier, which generally does not need to be modified; IRQ.s contains the interface code between the interrupt service program and the C program, which can be slightly modified according to the actual interrupt situation; stack.s and heap.s saves the starting position of the heap and stack used in C language; target.c contains special code for the target board, including exception handlers and target board initialization procedures, which can be modified according to the needs of the program.
Figure 2 Basic system initialization Tar get Peset1 ni t() flow chart
Since the writing of startup code is very long, and this article just wants to point out that writing startup code is a preparatory work that must be done before transplantation and briefly explain it, so I will not list all the codes here (for specific startup codes, see the reference [ 1]), and a flow chart of the function TargetReseTInit() in the target board initialization program is given, from which we can see the specific steps of the basic initialization work of the system before entering the main () function.
transplant
With the above knowledge and the preparatory work of writing startup code, you can enter the specific transplantation stage. Mainly complete the following work:
① In order to enhance the portability of the code, add the header file includes.h to all C files.
② Add config.h to the user program.
③ The main codes that need to be added or modified in the file OS_CPU.H are:
Define compiler-independent data types:
typedef unsigned char INT8U;
typedef unsigned short INT16U;
typedef unsigned int INT32U;
typedef INT32U OS_STK;
Use soft interrupt SWI as the underlying interface:
__swi(0x00) void OS_TASK_SW(void); /* Task-level task switching function*/
__swi(0x01) void _OSStartHighRdy(void); /* Run the task with the highest priority*/
__swi(0x02) void OS_ENteR_CRITICAL(void); /*Turn off interrupts*/
__swi(0x03) void OS_EXIT_CRITICAL(void); /* Enable interrupts*/
__swi(0x80) void ChangeToSYSMode(void); /* Switch the task to system mode*/
__swi(0x81) void ChangeToUSRMode(void); /* Switch the task to user mode*/
#define OS_STK_GROWTH 1 /* The stack grows from top to bottom*/
Define working mode:
#define USR32Mode 0x10 /* User mode*/
#define SYS32Mode 0x1f /* system mode*/
#define NoInt 0x80
#ifndef USER_USING_MODE
#define USER_USING_MODE USR32Mode /* Task default mode*/
#endif
Define the switch semaphore: extern OS_STK OsEnterSum
④ Code that needs to be added or modified in the file OS_CPU_C.C:
OS_ENTER_CRITICAL() code
__asm
{ MRS R0, SPSR
ORR R0, R0, #NoInt
MSR SPSR_c, R0
}
OsEnterSum++;
OS_EXIT_CRITICAL() code
if (--OsEnterSum == 0)
{__asm
{ MRS R0, SPSR
BIC R0, R0, #NoInt
MSR SPSR_c, R0
}
}
Write the initialization code for the task stack:
OS_STK *OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt)
{ OS_STK *stk;
opt = opt; /* 'opt' is not used. The function is to avoid compiler warnings*/
stk = ptos; /* Get the stack pointer*/
/* Establish the task environment and use the full decrementing stack */
*stk = (OS_STK) task; /* pc */
*--stk = (OS_STK) task; /* lr */
*--stk = 0; /* r12 */
?? /*r11?r2*/
*--stk = 0; /* r1 */
*--stk = (unsigned int) pdata; /* r0, the first parameter is passed using R0*/
*--stk = (USER_USING_MODE|0x00); /* spsr, enable IRQ, FIQ interrupts*/
*--stk = 0; /* Turn off the interrupt counter OsEnterSum; */
return (stk);
}
Write hook functions such as void OSInitHookBegin ( ), void OSInitHookEnd ( ), void OSTaskCreateHook ( ), void OSTaskDelHook ( ), etc. Users can add code as needed.
⑤ Code that needs to be added or modified in the file OS_CPU_A.S:
Write the __OSStartHighRdy code that is called by OSStartHighRdy(), the ready task function with the highest priority.
__OSStartHighRdy
MSR CPSR_c, #(NoInt | SYS32Mode)
LDR R4, =OSRunning
MOV R5, #1
STRB R5, [R4]
BLOSTaskSwHook
LDR R6, =OSTCBHighRdy
LDR R6, [R6]
B OSINTCtxSw_1
Write OSIntCtxSw code
Due to space limitations, the OSIntCtxSw function prototype is given here, from which the code can be written. For source code details, see reference [1].
void OSIntCtxSw(void)
{
Call user-defined OSTaskSwHook();
STCBCur=OSTCBHighRdy;
SPrioCur=OSPrioHighRdy;
Get the stack pointer of the task that needs to be restored;
Stack pointer=OSTCBHighRdy->OSTCBStkPtr;
Restore all processor registers from the new task's stack;
Execute interrupt return instruction;
}
Due to space limitations, the main codes in the three files related to the processor that need to be modified during transplantation are given above. Of course, more detailed transplantation instructions can be found in reference [1]. In order to verify whether the transplant is successful, you can write a simple user program (such as displaying characters on the PC interface through serial communication) and compile it with mC/OS-II and program it into the chip for verification. The author has successfully tested it.
Mistakes to avoid
Includes.h in the user program needs to be modified to config.h, because the latter includes the former and specific header files and configuration items.
The definition of data types cannot directly use short, int, long, etc. in C, because they are related to the processor type and imply non-portability, so data that is highly portable and does not depend on the compiler is defined in OS_CPU.H type.
The growth direction of the stack must be defined. 1 means the stack grows from top to bottom, 0 means the stack grows from bottom to top. The ARM processor supports both methods, but the ADS compiler used only supports the top-to-bottom method. Therefore it must be defined as 1, otherwise a register value push error will occur.
Previous article:Intelligent ultrasonic liquid level transmitter designed using LPC2119 chip CAN bus and DSl8B20
Next article:Briefly describe the tunnel lighting intelligent controller of ARM microprocessor
Recommended ReadingLatest update time:2024-11-15 07:55
- 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
- CGD and Qorvo to jointly revolutionize motor control solutions
- CGD and Qorvo to jointly revolutionize motor control solutions
- Keysight Technologies FieldFox handheld analyzer with VDI spread spectrum module to achieve millimeter wave analysis function
- Infineon's PASCO2V15 XENSIV PAS CO2 5V Sensor Now Available at Mouser for Accurate CO2 Level Measurement
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- A new chapter in Great Wall Motors R&D: solid-state battery technology leads the future
- Naxin Micro provides full-scenario GaN driver IC solutions
- Interpreting Huawei’s new solid-state battery patent, will it challenge CATL in 2030?
- Are pure electric/plug-in hybrid vehicles going crazy? A Chinese company has launched the world's first -40℃ dischargeable hybrid battery that is not afraid of cold
- [Discussion] I'm looking at a product recently, a 400x400 camera for car use
- DSP Power Budget Digital Output Voltage Regulation
- Detailed introduction to crystal oscillators and crystal parameters
- Timing Analysis of TB5128FTG’s Decay Action
- Wi-Fi sensor network forms and related typical applications
- msp430 button control LED light
- MATLAB simulation model for online parameter identification of permanent magnet synchronous motor based on MRAS
- It is said that noise spectral density is more useful than signal-to-noise ratio?
- Altium Designer 18 Schematic
- I am designing a transformer for a flyback switching power supply. Is my estimate of the maximum duty cycle correct?