1. About the soft interrupt instruction The software interrupt instruction (SWI) can generate a software interrupt exception, which provides a mechanism for the application program to call the system routine.

Syntax: SWI {} SWI_number Register changes after SWI execution:

lr_svc = address of the instruction following the SWI instruction spsr_svc = cpsr pc = vectors + 0x08

cpsr mode = SVC cpsr I = 1 (masks IRQ interrupts)

When the processor executes the SWI instruction, the program counter pc is set to the 0x08 offset of the vector table, and the colleague switches the processor mode to SVC mode forcibly, so that the operating system routine can be called in the privileged mode.

Each SWI instruction has an associated SWI number (number) that represents a specific function call or feature.

[Example] An example of debugging SWI in ARM toolbox is a SWI call with SWI number 0x123456. Usually SWI instructions are executed in user mode.

Before SWI execution: cpsr = nzcVqft_USER pc = 0x00008000 lr = 0x003fffff ;lr = 4 r0 = 0x12

Execute command: 0x00008000 SWI 0x123456

After SWI execution: cpsr = nzcVqIft_SVC spsr = nzcVqift_USER pc = 0x00000008 lr = 0x00008004 r0 = 0x12

SWI is used to call routines of the operating system, usually need to pass some parameters, which can be done through registers.

In the above example, r0 is used to pass the parameter 0x12, and the return value is also passed through the register.

The code segment that handles software interrupt calls is called an interrupt handler (SWI Handler). The interrupt handler obtains the software interrupt number by executing the address of the instruction, which is calculated from lr.

The SWI number is determined by the following formula: SWI_number = AND NOT "0xff000000" where SWI instrucTIon is the 32-bit SWI instruction executed by the actual processor

The SWI instruction is encoded as: 31 - 28 27 - 24 23 - 0 cond 1 1 1 1 immed24

The bit23-bit0 of the binary code of the instruction is a 24-bit immediate number, that is, the interrupt number of the SWI instruction. The interrupt number can be obtained by masking the high 8 bits.

The lr register holds the address of the interrupt return instruction, so [lr - 4] is the execution code that executes the SWI.

Copy the entire SWI instruction to the register through the load instruction, and use the BIC to mask the upper 8 bits of the instruction to obtain the SWI interrupt number.

;read the SWI instrucTIon LDR r10, [lr, #-4] BIC r10, r10, #0xff000000 2. Zhou Ligong transplanted uC/OS-II to s3c2410's soft interrupt service level task switching uC/OS-II task scheduling The task-level scheduling of the function uC/OS-II is done by the function OS_Sched( ).

void OS_Sched (void)

{

#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */

OS_CPU_SR cpu_sr;

#endif

INT8U y;

OS_ENTER_CRITICAL();

if ((OSIntNesting == 0) && (OSLockNesting == 0)) { /* Sched. only if all ISRs done & not locked */

y = OSUnMapTbl[OSRdyGrp]; /* Get pointer to HPT ready to run */

OSPrioHighRdy = (INT8U)((y<<3) + OSUnMapTbl[OSRdyTbl[y]]);

if (OSPrioHighRdy != OSPrioCur) { /* No Ctx Sw if current task is highest rdy */

OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];

OSCtxSwCtr++; /* Increment context switch counter */

OS_TASK_SW(); /* Perform a context switch */

}

}

OS_EXIT_CRITICAL();

}

For a detailed explanation, please refer to "Embedded Real-Time Operating System uC/OS-II". The os_sched function performs task switching when it is determined that the highest priority of all ready tasks is higher than the current task priority, and is called through the OS_TASK_SW( ) macro.

The OS_TASK_SW( ) macro actually defines the SWI soft interrupt instruction. See the code in the OS_CPU.H file:

__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); /* open interrupt*/

__swi(0x40) void *GetOSFunctionAddr(int Index); /* Get system service function entry*/

__swi(0x41) void *GetUsrFunctionAddr(int Index);/* Get the entry of custom service function*/

__swi(0x42) void OSISRBegin(void); /* interrupt start processing */

__swi(0x43) int OSISRNeedSwap(void); /* Determine whether the interrupt needs to be switched*/

__swi(0x80) void ChangeToSYSMode(void); /* task switch to system mode */

__swi(0x81) void ChangeToUSRMode(void); /* task switch to user mode */

__swi(0x82) void TaskIsARM(INT8U prio); /* Task code is ARM code */

__swi(0x83) void TaskIsTHUMB(INT8U prio); /* Task code is THUMB */

__swi(0x00) void OS_TASK_SW(void); is the code related to ADS. It can be seen through disassembly that the call to OS_TASK_SW is actually replaced by the swi 0x00 soft interrupt instruction. Doing this execution, pc jumps to offset 0x08 of the vector table.

Interrupt vector table: (see Startup.s file)

CODE32

AREA vectors, CODE, READONLY

; exception vector table

Reset

LDR PC, ResetAddr

LDR PC, UndefinedAddr

LDR PC, SWI_Addr

LDR PC, PrefetchAddr

LDR PC, DataAbortAddr

DCD IRQ_Addr

LDR PC, IRQ_Addr

LDR PC, FIQ_Addr

ResetAddr DCD ResetInit

UndefinedAddr DCD Undefined

SWI_Addr DCD SoftwareInterrupt

PrefetchAddr DCD PrefetchAbort

DataAbortAddr DCD DataAbort

Nouse DCD 0

IRQ_Addr DCD IRQ_Handler

FIQ_Addr DCD FIQ_Handler

After executing the SWI 0x00 instruction, the pc will jump to the SoftwareInterrupt code to start execution:

See the SoftwareInterrupt function of the Os_cpu_a.s file:

SoftwareInterrupt

LDR SP, StackSvc ; reset the stack pointer

STMFD {R0-R3, R12, LR}

MOV R1, SP ; R1 points to parameter storage location

MRS R3, SPSR

TST R3, #T_bit ; Whether it is Thumb state before interrupt

LDRNEH R0, [LR, #-2] ; yes: get Thumb status SWI command

BICNE R0, R0, #0xff00

LDREQ R0, [LR, #-4] ; No: get arm state SWI command

BICEQ R0, R0, #0xFF000000 ; As mentioned above, the SWI number is obtained by masking the upper 8 bits of the SWI instruction, r0 = SWI number, and R1 points to the parameter storage location

CMP R0, #1

LDRLO PC, =OSIntCtxSw ; jump to the address of OSIntCtxSwdi when it is 0

LDREQ PC, =__OSStartHighRdy ; When it is 1, jump to the address of __OSStartHighRdy. SWI 0x01 is the first task switch

BL SWI_Exception ; Enter the interrupt number scatter function

LDMFD {R0-R3, R12, PC}^

StackSvc DCD (SvcStackSpace + SVC_STACK_LEGTH * 4 - 4)

The above is the realization of the task switching soft interrupt level service.

Low Frequency Transformer

Encapsulated Transformers are simply transformers in which one or more of the transformer's components are completely sealed. One example of a component is the transformer's coils. This process of encapsulation protects the transformer from dirt, dust, moisture, and any other contaminants.

Epoxy Encapsulated Transformer, PCB Transformer, Low Frequency Transformer, Encapsulated Unit, Electronic Components, Low Voltage Transformer

Shaanxi Magason-tech Electronics Co.,Ltd , https://www.magason-tech.com

Posted on