The SWI exception interrupt command allows an application to call code in system mode in user mode. in the operating system, the code is called by the system,
How can this process be implemented? Let's learn with questions!
The SWI command contains a 24-bit immediate number (call interrupt number), which indicates the specific call function to be requested by the user, therefore, you need to read the interrupt call number in the abnormal interrupt of SWI, and then call the corresponding processing program according to the interrupt number. This process can be divided into two steps:
1. SWI exception interrupt handling program
The exception interrupt handler must be compiled in assembly language because it is an underlying operation. The description is as follows:
Area top_swi code readonly
Export swi_headler
Swi_headler
Stmfd SP !, {R0-r12, LR}; Save the register value R0 to R12, LR
LDR r0, [LR, #-4]; obtain the address of the SWI instruction from the memory
Bic r0, R0, # ff000000; read 24-bit interrupt call number
MoV R1, SP
; ========================================================== ==========
BL swi_service_func; call functional service functions, see the following
The interrupt call number is passed in through the R0 register.
The parameter is passed in through the R1 register
; ========================================================== ==========
Ldmfd SP !, {R0-r12, PC} ^; resume R0 to R12 before calling and exit the interrupt handler
End
2. Functional service programs
Compile the interrupt call number obtained from the interrupt processing function. We can write the following service functions (for simplicity, we use the C language)
Void swi_service_func (unsigned int number, unsigned int * REG)
{
Unsigned int reg1, reg2, reg3, reg4;
// Obtain the parameters passed in before SWI
Reg1 = reg [0];
Reg2 = reg [1];
Reg3 = reg [2];
Reg4 = reg [3];
Switch (number ){
Case 0:
// Do something
Break;
Case 1:
// Do something
Break;
.
.
.
Case N:
// Do something
Break;
Default:
// Do something
}
}
// UPDATE results into r0-r3
Reg [0] = updata_reg1;
Reg [1] = updata_reg2;
Reg [2] = updata_reg3;
Reg [3] = updata_reg4;
}
In this way, different function calls can be implemented as long as the call break number is different, isn't it easy?