The concept of exception in the microcontroller has also been exposed, it means that the CPU can pause the current thing, jump to the exception handler to execute. Previously written MCU bare metal program belongs to the front and rear program, the foreground refers to the Mian function in the while (1) cycle, backstage refers to the processing program after the exception. ARM9 has the following exception modes:
The address of the exception vector for the ARM architecture can be 0x00000000, or it can be 0xffff0000,linux using address 0xffff0000. At initialization time, the interrupt vector table is placed at the 0xffff0000, in the main function of Init/main.c trap_init (); The specific code in the function is:
718 void__init Early_trap_init (void)719 { ... ... /*Copy the interrupt vector table to vectors*/732memcpy ((void*) vectors, __vectors_start, __vectors_end-__vectors_start);//vectors=config_vectors_base=0xffff0000 generated when configuring the kernel //located in Include\linux\autoconf.h /*Copy the processing code of the jump address of the interrupt vector table to vectors+0x200*/733memcpy ((void*) Vectors +0x200, __stubs_start, __stubs_end-__stubs_start); ... ...745}
The complete exception-handling process is described below as an example of IRQ exception handling
1, IRQ exception handling process, this exception is usually generated by the hardware configuration, s3c2440 interrupt structure will eventually be reflected in the IRQ exception
Continuing to see the exception vector table, we take an IRQ exception as an example: it is located in ARCH\ARM\KERNEL\ENTRY-ARMV. s, you can see that it jumps to the VECTOR_IRQ + stubs_offset Place
. equ Stubs_offset, __vectors_start +0x200-__stubs_start//calculate the offset of a jump address. Globl __vectors_start__vectors_start:swi sys_error0//Reset Exception Handlersb Vector_und +Stubs_offset Ldr pc,. Lcvswi+ Stubs_offset//software interrupt Exception handlersb Vector_pabt +Stubs_offset b vector_dabt+Stubs_offset b vector_addrexcptn+Stubs_offset b VECTOR_IRQ+ Stubs_offset//jump to the exception handler for the IRQ, B is the location independent code, where VECTOR_IRQ calls the VECTOR_STUB macrob Vector_fiq + Stubs_offset
Search Vector_irq found no search, it is actually called VECTOR_STUB macro generated. This macro is introduced later, see Vector_stub IRQ First, it eventually generates VECTOR_IRQ
. Globl __stubs_start//call the start address of the variable defined by the VECTOR_STUB macro__stubs_start:/** Interrupt Dispatcher*/vector_stub IRQ, Irq_mode,4//calling the Vector_stub macro defines the VECTOR_IRQ variable, and the IRQ exception jumps here to start execution. .Long__IRQ_USR @0(Usr_26/usr_32).Long__irq_invalid @1(Fiq_26/fiq_32).Long__irq_invalid @2(Irq_26/irq_32).Long__irq_svc @3(Svc_26/svc_32).Long__irq_invalid @4 .Long__irq_invalid @5 .Long__irq_invalid @6 .Long__irq_invalid @7 .Long__irq_invalid @8 .Long__irq_invalid @9 .Long__irq_invalid @ A.Long__irq_invalid @ B.Long__irq_invalid @ C.Long__irq_invalid @ d.Long__irq_invalid @ E.Long__irq_invalid @ F
Then we introduce the procedure of Vector_stub call.
VECTOR_IRQ:.if 4Sub LR, LR,4//lr = lr-4. endif @ Save r0, Lr_<exception> (parent PC) and spsr_<exception>@ (parent CPSR) @ Stmia sp, {r0, LR} @ Save R0, LR//saving r0 and LR registers to the IRQ pattern stackMrs LR, SPSR//assigning SPSR to LRstr LR, [SP, #8] @ Save SPSR//put LR into the stack, i.e. SPSR into the stack@ @ Prepare forSVC32 mode. IRQs remain disabled. @ Mrs R0, CPSR Eor r0, R0, # (\mode^svc_mode) MSR spsr_cxsf, R0//assigns the value of R0 to spsr_cxsf, at which point the status is still in IRQ mode@ The branch table must immediately follow Thiscode @ and LR, LR, #0x0f //The LR=LR&0X0F,LR start is the value of the SPSR, it holds the CPU mode before entering the IRQ mode, is actually 5-bit control, here only 4 bits, used to jump to different processing functionsmov r0, SP//give R0 the value of the SP that manages the modeLdr LR, [PC, LR, LSL #2]//lr = * (pc+lr<<2). If user mode is entered from the application layer before the IRQ is entered, then lr = PC = __irq_usr. Otherwise, an IRQ exception occurs when the management mode is in the kernel layer LR = pc+12=__irq_svcMovs pc, LR @ branch to HandlerinchSVC mode//The value of LR is given to the PC, and the value of SPSR is assigned to CPSR, at which point the management mode is entered.. endm
When the macro executes, it enters the SVC mode and then calls __IRQ_USR or __irq_svc. Take __IRQ_USR as an example to continue to explain the exception function call procedure
__irq_usr: usr_entry // ingress of some processing, save register to Stack get_thread_info tsk // Get thread information irq_handler // Real exception handling b ret_to_user / / Switch back to the state before the exception, and stack the register out of the stack
You can see that this function shows saving some register data and then calling Irq_handler the real exception handler, Irq_handler finally called the C function. Finally, the register reverts to the state before the exception. IRQ Exception handling ended
. Macro Irq_handler get_irqnr_preamble R5, LR1: get_irqnr_and_base r0, R6, R5 , LR movne R1, sp @ struct pt_regs * @ Adrne LR, 1b BNE ASM_DO_IRQ // Finally, ASM_DO_IRQ is called. This is the C function .
A brief analysis of the architecture of Linux-driven exception handling system