Nowadays, among embedded processor chips, the processor with ARM7 as the core is the most widely used one. It has multiple working modes and supports two different instruction sets (standard 32-bit ARM instruction set and 16-bit Thumb instruction set). μC/OSII is a preemptive, multi-tasking real-time operating system designed for embedded applications. It can be used for various 8-bit, 16-bit and 32-bit microcontrollers or DSPs. The transplantation of μC/OSII to ARM7 has unique advantages, so "μC/OSII+ARM7" has become a widely used platform.
Regardless of the type of ARM processor, or whether the embedded system has an operating system, interrupt technology is a key technology in the real-time interaction between the computer and the outside world. When an external event occurs, the CPU must respond to the interrupt in time to process the corresponding event. Therefore, whether interrupts can be nested is the main factor affecting the real-time performance of embedded systems.
1 ARM7 interrupt processing
There are two main types of interrupts in the ARM7 processor. This article mainly discusses the response mechanism of the IRQ interrupt exception. When the interrupt request IRQ arrives and the CPU enters the interrupt response, the CPU will automatically complete the following tasks: first, store the current values of PC and CPSR in the LR and SPSR of the interrupt mode; then, operate the running status bit in the CPSR to make the CPU enter the interrupt mode and turn off the interrupt; finally, change the value of PC to 0x00000018, so that the CPU execution jumps to the IRQ interrupt entry 0x00000018. At 0x00000018 in the exception vector table, an "LDR PC, [PC, #0xff0]" instruction is used. This instruction used at the IRQ is different from other vectors. When the CPU executes this instruction but has not jumped yet, the value of PC is 0x00000020 (because the ARM7TDMI core is a three-stage pipeline structure), 0x00000020 minus 0x00000FF0 is 0xFFFFF030, which is the address unit of the special register VICVectAddr of VIC. This register stores the entry of the interrupt service program of the IRQ to be serviced, so read the value of the VICVectAddr register and then put it into the PC program pointer, that is, jump to the corresponding interrupt service program, so that the CPU starts to execute the interrupt service program.
2 Handler macro analysis
In the "μC/OSII+ARM7" system, only the ARM7 IRQ interrupt is used. Since the interrupt systems of different ARM chips are not exactly the same, it is impossible to write interrupt and clock beat porting code that is common to all processors using the ARM core. However, in order to allow users to write interrupt service programs in C language without being troubled by the hardware differences of the processor, here, according to the requirements of μC/OSII for interrupt service programs and the characteristics of the ARM7 architecture and ADS compiler, an assembly macro-Handler suitable for all ARM7 core processors is written. This macro implements the general interface between the assembly language code and the C language function code of the "μC/OSII+ARM7" interrupt service program. Its function is to package the user's C language interrupt handler. Only after this packaging can the system execute the user's interrupt handler.
The interrupt service program flow is shown in Figure 1. When entering the Handler macro, first save the values of LR, SPSR and related registers in the stack in interrupt mode to facilitate breakpoint recovery. Then add 1 to the global variable OSIntNeSTIng that records the number of system interrupts, turn off the interrupt and switch to system mode, and call the C language interrupt handler. After executing the interrupt handler, call the interrupt function to obtain the task control block pointer and task priority of the highest priority ready task. After returning to the interrupt mode, by comparing the priority of the current task with the task to be switched, determine whether to switch tasks, and finally return to the breakpoint.
Figure 1 Interrupt service program flow
The assembly part of the IRQ exception handling code --Handler macro:
MACRO
$IRQ_Label HANDLER $IRQ_Excep TI ON_Func TI ON
EXPORT $IRQ_Label; Output label
IMPORT $IRQ_Excep TI on_Function; referenced external label
$IRQ_Label
SUB LR, LR, #4; Calculate return address
STMFD SP!, {R0R3, R12, LR}; save task environment
MRS R3, SPSR; save status
STMFD SP, {R3, SP, LR}^; R3, SP, LR that saves user status
;OSIntNesting++
LDR R2, =OSIntNesting
LDRB R1,[R2]
ADD R1,R1,#1
STRB R1, [R2]
SUB SP,SP,#4*3
MSR CPSR_c, #(NoInt | SYS32Mode)
;Switch to system mode to operate related registers
CMP R1, #1
LDREQ SP, =StackUsr
;When the first interrupt occurs, a new variable is created to store the variables used in the interrupt to avoid storage space conflicts
BL $IRQ_Exception_Function ;Call the C language interrupt handler
MSR CPSR_c, #(NoInt | SYS32Mode); Switch to system mode
LDR R2, =OsEnterSum
;OsEnterSum, disable interrupts when OSIntExit exits
MOV R1, #1
STR R1, [R2]
BL OSIntExit
LDR R2, =OsEnterSum
; The interrupt service routine needs to exit, so OsEnterSum=0
MOV R1, #0
STR R1, [R2]
MSR CPSR_c, #(NoInt | IRQ32Mode); switch back to interrupt mode
LDMFD SP, {R3, SP, LR}^; Restore user status R3, SP, LR
LDR R0, =OSTCBHighRdy
LDR R0, [R0]
LDR R1, =OSTCBCur
LDR R1, [R1]
CMP R0, R1
ADD SP,SP,#4*3
MSR SPSR_cxsf, R3
LDMEQFD SP! , {R0R3, R12, PC}^ ; Do not switch tasks
LDR PC, =OSINTCtxSw; perform task switching
MEND
END
Through the analysis of the Handler macro, we know that the user's C language interrupt handler runs in the privileged mode - system mode, and the interrupt is turned off when the CPU executes the interrupt service program, so this system adopts the simplest non-nested interrupt method. The advantage of this method is that the context data will not be destroyed by any order of interrupts; the disadvantage is that when the interrupt service program is executed, the interrupt cannot be nested according to the interrupt priority, the delay time is long, and the interrupt is only accepted again when an ISR is completely completed and exits the interrupt, which reduces the real-time characteristics of the system. In order to improve the real-time performance of the system, its interrupts need to be optimized.
3 Interrupt Optimization
Rewriting the HANDLER macro in the μC/OSII kernel can realize ARM interrupt nesting. Although this improves the real-time performance of the system, it damages the stability and portability of the system operation. Through the analysis of the interrupt process, a template for writing an interrupt service program is given below, which makes full use of the feature that ISR is executed in the privileged mode - system mode to realize the interrupt nesting conditions. The interrupt service program template is as follows:
void ISR(void) {
OS_ENTER_CRITICAL(); //Disable interrupt in interrupt service routine Clear interrupt flag; //Prevent interrupt from entering low priority multiple times without clearing interrupt flag; //Disable low priority interrupt
S_EXIT_CRITICAL(); //Open the user's C language code in the interrupt service routine; //Perform the work that the user needs to do in the interrupt
VICVectAddr=0; //Set the entry address of the interrupt service program to 0
}
Since the Handler macro has saved registers such as LR, SPSR, return address, and stack pointer before the interrupt, the only thing left to do is to turn on and off the interrupt. Since the interrupt-disabled system mode is entered before entering the C interrupt handler, the interrupt must be reopened in the C language, and the C language cannot perform register operations, so the soft interrupt OS_EXIT_CRITICAL() must be called to reopen the interrupt. Before turning on the interrupt, it is necessary to determine whether the global variable OsEnterSum is 0 after decrementing 1, so the soft interrupt OS_ENTER_CRITICAL() must be called before calling the interrupt to turn OsEnterSum to 1. Some processing can be performed in the critical section, such as clearing the interrupt flag, turning off low-priority interrupts, etc. After executing the C language interrupt service program, VICVectAddr must be set to 0. This is a requirement of the ARM7 processor core and must be written in this way, otherwise some errors will occur (such as failure to enter the interrupt for the second time, etc.).
Conclusion
"μC/OSII+ ARM7" is a platform widely used in current embedded systems, suitable for small and medium-sized embedded systems with low complexity. Based on an in-depth analysis of the "μC/OSII+ ARM7" interrupt mechanism, this paper improves the IRQ interrupt response mechanism and proposes an optimization scheme. Experiments have shown that this method can achieve interrupt nesting and improve system real-time performance, and has certain application value.
Previous article:Analysis of abnormal interrupt mechanism of ARM S3C4510B system
Next article:How to use the combination of ASIC and ARM to achieve powerful functions
Recommended ReadingLatest update time:2024-11-16 13:45
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- PCB copper plating problem
- [Project source code] Using scripts in Quartus II to convert sof to rbf files
- [Flower carving DIY] Interesting and fun music visualization series of small projects (07) --- large square spectrum light
- stm32 and dht11
- Looking for a solution that can achieve high-speed USB communication with Android phones
- [NXP Rapid IoT Review] + A dazzling first experience
- What kind of long distance wireless transmission equipment is there?
- 【Tuya BK7231N】In-depth analysis of sample code
- The sipeed team will provide developers with free MAXI development boards
- CircuitPython-enabled electronic cat (MeowMeow)