1. Overview of vectored INTERRUPT Controller (Overview vector interrupt Controllers)
There are 4 main vic,4 Tzic and a very special arm Primecell PL192. the main Vic and Tzic can support 93 interrupt sources . Tzic is designed for TrustZone technology, and ARM trustzone® technology is a system-wide security approach for a wide range of applications on high-performance computing platforms, including secure payments, digital rights Management (DRM), Enterprise Services, and WEB-based services (citing official introductions). The Tzic provides security-controlled Nfiq interrupts and allows such interrupts to be shielded from the traditional unsafe interrupt Vic, thus achieving the security and confidentiality of the application in data transmission.
2,key FEATURES of vectored INTERRUPT CONTROLLER
supports vectored IRQ interrupts
fixed hardware interrupts priority levels (fixed hardware interrupt prioritization)
Programmable interrupt priority levels (programmable interrupt precedence)
supports Hardware interrupt priority level masking (supports hardware interrupt precedence masking)
programmable interrupt Priority level masking
generates IRQ and FIQ (generating IRQ and FIQ)
generates software interrupt
Test Registers
Raw Interrupt status (original interrupt state, that is, set enable, mask the interrupt state before the register)
Interrupt Request Status
supports privileged mode for restricted access (supports restricted access privilege mode)
3. When user clears interrupt pending, user must write 0 to all the vicaddress registers (vic0address,
Vic1address, vic2address, and vic3address).
4. Please refer to the s5pv320 User manual for each interrupt register.
Interrupt Reference Program:
. Global _start.global irq_handle_start://off watchdog Ldrr0, =0XE2700000MOVR1, #0strr1, [r0]//set stack to call C function LDRSP, =0x40000000/ /on interrupt mov r0, #0x53msr cpsr_cxsf, r0//assembly initialize clock BL clock_init//call main function BL mainirq_handle://set interrupt mode stack Ldr SP, =0xd0037f80//Save Field Sub LR, LR, #4stmfd sp!, {r0-r12, lr}//jump to interrupt handler function blirq_handler//Restore site Ldmfd sp!, {r0-r12, pc}^
First, turn off the watchdog, set the stack, open interrupts, set the clock, and when an interrupt source (not an interrupt) occurs, execute the Interrupt service program Irq_handle, set the interrupt mode stack, save the scene, and jump to the interrupt processing letter (irq_ Handler), the interrupt handler function first determines which interrupt group is interrupted and then enters the corresponding interrupt handler (IRQ_XXX), in advance we want to set interrupt handler irq_xxx (such as Irq_key) In address Vicxvectaddrx, when an interrupt occurs, the interrupt handler of the current interrupt is automatically copied from the register VICXVECTADDXR to the register vicaddr in the hardware, so we'll call it in the Irq_handler () function. The interrupt handler function in the VICDDR.
(An interrupt group has 32 interrupt sources, why can we run the interrupt group directly vicxintaddr the specified function without knowing which interrupt source triggered the interrupt?) This is because the interrupt source in the interrupt group after the interrupt is triggered, the hardware will automatically assign the address of the corresponding interrupt source to the vicaddr of the owning group, so that we can save the time to retrieve the interrupt source and jump to the corresponding interrupt function entry, of course, if we want to "break the key" The Service Program entry address is assigned to a corresponding register (assuming the Vic0intaddr12, the owning group is the VIC0 group, the corresponding entry is vic0intaddr)).
This section is really a bit hard to understand, it takes some time
#include "stdio.h" #include "int.h" #define GPH2CON (* (volatile unsigned long) 0xe0200c40) #define GPH2DAT (* (volatile unsigned long *) 0xe0200c44) #define GPH2_0_EINT16 (0xf<< (0*4)) #define GPH2_1_EINT17 (0xf<< (1*4)) #define gph2_2_eint18 (0xf<< (2*4)) #define GPH2_3_EINT19 (0xf<< (3*4)) #defineEXT_INT_0_CON (* (Volatile unsigned long *) 0xe0200e00) #defineEXT_INT_1_CON (* (volatile unsigned long *) 0xe0200e04) #defineEXT_INT_2_CON (* (Volatile U nsigned long *) (0XE0200E08)) #defineEXT_INT_3_CON (* (volatile unsigned long *) 0xe0200e0c) #defineEXT_INT_0_MASK (* ( Volatile unsigned long *) (0XE0200F00)) #defineEXT_INT_1_MASK (* (volatile unsigned long *) 0xe0200f04) #defineEXT_INT_2_ MASK (* (volatile unsigned long *) 0xe0200f08) #defineEXT_INT_3_MASK (* (volatile unsigned long *) 0xe0200f0c) #defi Neext_int_0_pend (* (volatile unsigned long *) 0xe0200f40) #defineEXT_INT_1_PEND (* (volatile unsigned long *) 0xe020 0F44)) #defineEXT_INT_2_PEND (* (VolaTile unsigned long *) (0XE0200F48)) #defineEXT_INT_3_PEND (* (volatile unsigned long *) 0xe0200f4c) void Uart_init ();//delay Time function void delay (unsigned long count) {volatile unsigned long i = Count;while (i--);} void Isr_key (void) {printf ("We get company:eint16_31\r\n");//clear vic0addrintc_clearvectaddr ();/clear Pending Bitext_int_2_pend |= 1<<0;} int main (void) {int c = 0;//initializes the serial port Uart_init ();//Interrupt related initialization system_initexception ();p rintf ("**************int test ********* \ r \ n ")///external interrupt Related Settings//1111 = ext_int[16] Gph2con |= 0xf;//010 = falling edge Triggeredext_int_2_con |= 1<<1; Unmaskedext_int_2_mask &= ~ (1<<0);//Set Interrupt eint16_31 processing function intc_setvectaddr (num_eint16_31, Isr_key);// Enable interrupt eint16_31intc_enable (NUM_EINT16_31), while (1) {printf ("%d\r\n", C + +);d Elay (0x100000);}}
#include "int.h" #include "stdio.h"////interrupt#define vic0_base (0xf2000000) #define VIC1_BASE (0xf2100000) #define Vic2_base (0xf2200000) #define VIC3_BASE (0xf2300000)//Vic0#definevic0irqstatus (* (volatile unsigned long *) (vic0_ BASE + 0x00)) #defineVIC0FIQSTATUS (* (volatile unsigned long *) (vic0_base + 0x04)) #defineVIC0RAWINTR (* (Volatile unsi gned long *) (vic0_base + 0x08)) #defineVIC0INTSELECT (* (volatile unsigned long *) (vic0_base + 0x0c)) #defineVIC0INTENAB LE (* (volatile unsigned long *) (vic0_base + 0x10)) #defineVIC0INTENCLEAR (* (volatile unsigned long *) (Vic0_base + 0x14) )) #defineVIC0SOFTINT (* (volatile unsigned long *) (vic0_base + 0x18)) #defineVIC0SOFTINTCLEAR (* (Volatile unsigned lon G *) (Vic0_base + 0x1c)) #defineVIC0PROTECTION (* (volatile unsigned long *) (vic0_base + 0x20)) #defineVIC0SWPRIORITYMAS K (* (volatile unsigned long *) (vic0_base + 0x24)) #defineVIC0PRIORITYDAISY (* (volatile unsigned long *) (Vic0_base + 0x2 8))) #define VIC0VECTADDR (Vic0_base + 0x100) #define VIC0VECPRIORITY (* (volatile unsigned long *) (vic0_base + 0x200)) #define VIC0ADDR (* (volatile unsigned long *) (Vic0_base + 0xf00)) ) #define VIC0PERID0 (* (volatile unsigned long *) (vic0_base + 0xfe0)) #define VIC0PERID1 (* (volatile unsigned long *) (VI C0_base + 0xfe4)) #define VIC0PERID2 (* (volatile unsigned long *) (vic0_base + 0xfe8)) #define VIC0PERID3 (* (Volatile U nsigned long *) (vic0_base + 0xfec)) #define VIC0PCELLID0 (* (volatile unsigned long *) (vic0_base + 0xff0)) #define VIC0P CELLID1 (* (volatile unsigned long *) (vic0_base + 0xff4)) #define VIC0PCELLID2 (* (volatile unsigned long *) (Vic0_base + 0XFF8))) #define VIC0PCELLID3 (* (volatile unsigned long *) (vic0_base + 0XFFC))//Vic1#definevic1irqstatus (* (volatile unsigned long *) (vic1_base + 0x00)) #defineVIC1FIQSTATUS (* (volatile unsigned long *) (vic1_base + 0x04)) #defineVIC1RA WINTR (* (volatile unsigned long *) (vic1_base + 0x08)) #defineVIC1INTSELECT (* (volatile unsigned long *) (Vic1_base + 0x0 c))) #defineVIC1INTENABLE (* (volatile unsigned long *) (vic1_base + 0x10)) #defineVIC1INTENCLEAR (* (volatile unsigned long *) (vic1_base + 0x14)) #defineVIC1SOFTINT (* (volatile unsigned long *) (vic1_base + 0x18)) #defineVIC1SOFTINTCLEAR (* (v Olatile unsigned long *) (vic1_base + 0x1c)) #defineVIC1PROTECTION (* (volatile unsigned long *) (vic1_base + 0x20)) #defi Nevic1swprioritymask (* (volatile unsigned long *) (vic1_base + 0x24)) #defineVIC1PRIORITYDAISY (* (Volatile unsigned Long *) (vic1_base + 0x28)) #define VIC1VECTADDR (vic1_base + 0x100) #define VIC1VECPRIORITY (* (volatile unsigned long *) (V Ic1_base + 0x200)) #define VIC1ADDR (* (volatile unsigned long *) (vic1_base + 0xf00)) #define VIC1PERID0 (* (Volatile UN Signed long *) (vic1_base + 0xfe0)) #define VIC1PERID1 (* (volatile unsigned long *) (vic1_base + 0xfe4)) #define Vic1peri D2 (* (volatile unsigned long *) (vic1_base + 0xfe8)) #define VIC1PERID3 (* (volatile unsigned long *) (vic1_base + 0xfec)) ) #define VIC1PCELLID0 (* ((volAtile unsigned long *) (vic1_base + 0xff0)) #define VIC1PCELLID1 (* (volatile unsigned long *) (vic1_base + 0xff4)) #defin E Vic1pcellid2 (* (volatile unsigned long *) (vic1_base + 0xff8)) #define VIC1PCELLID3 (* (volatile unsigned long *) (vic1_ BASE + 0XFFC))//Vic2#definevic2irqstatus (* (volatile unsigned long *) (vic2_base + 0x00)) #defineVIC2FIQSTATUS (* ((vol Atile unsigned long *) (vic2_base + 0x04)) #defineVIC2RAWINTR (* (volatile unsigned long *) (vic2_base + 0x08)) #defineVIC 2INTSELECT (* (volatile unsigned long *) (vic2_base + 0x0c)) #defineVIC2INTENABLE (* (volatile unsigned long *) (vic2_base + 0x10)) #defineVIC2INTENCLEAR (* (volatile unsigned long *) (vic2_base + 0x14)) #defineVIC2SOFTINT (* (Volatile Unsigne D long *) (vic2_base + 0x18)) #defineVIC2SOFTINTCLEAR (* (volatile unsigned long *) (vic2_base + 0x1c)) #defineVIC2PROTECT ION (* (volatile unsigned long *) (vic2_base + 0x20)) #defineVIC2SWPRIORITYMASK (* (volatile unsigned long *) (Vic2_base + 0x24)) #defineVIC2PRIORITydaisy (* (volatile unsigned long *) (vic2_base + 0x28)) #define VIC2VECTADDR (vic2_base + 0x100) #define Vic2vecpriority ( * (volatile unsigned long *) (vic2_base + 0x200)) #define VIC2ADDR (* (volatile unsigned long *) (vic2_base + 0xf00)) #de Fine vic2perid0 (* (volatile unsigned long *) (vic2_base + 0xfe0)) #define VIC2PERID1 (* (volatile unsigned long *) (vic2_b ASE + 0xfe4)) #define VIC2PERID2 (* (volatile unsigned long *) (vic2_base + 0xfe8)) #define VIC2PERID3 (* (Volatile Unsig Ned long *) (vic2_base + 0xfec)) #define VIC2PCELLID0 (* (volatile unsigned long *) (vic2_base + 0xff0)) #define Vic2pcell ID1 (* (volatile unsigned long *) (vic2_base + 0xff4)) #define VIC2PCELLID2 (* (volatile unsigned long *) (Vic2_base + 0xFF 8))) #define VIC2PCELLID3 (* (volatile unsigned long *) (vic2_base + 0XFFC))//Vic3#definevic3irqstatus (* (Volatile unsi gned long *) (vic3_base + 0x00)) #define VIC3FIQSTATUS (* (volatile unsigned long *) (vic3_base + 0x04)) #define Vic3rawin TR (* (Volatile unsignedLong *) (vic3_base + 0x08)) #define VIC3INTSELECT (* (volatile unsigned long *) (vic3_base + 0x0c)) #define VIC3INTENABLE ( * (volatile unsigned long *) (vic3_base + 0x10)) #define VIC3INTENCLEAR (* (volatile unsigned long *) (vic3_base + 0x14)) ) #define VIC3SOFTINT (* (volatile unsigned long *) (vic3_base + 0x18)) #define VIC3SOFTINTCLEAR (* (volatile unsigned long *) (vic3_base + 0x1c))) #define Vic3protection (* (volatile unsigned long *) (vic3_base + 0x20)) #define Vic3swprioritymas K (* (volatile unsigned long *) (vic3_base + 0x24)) #define VIC3PRIORITYDAISY (* (volatile unsigned long *) (Vic3_base + 0x )) #define VIC3VECTADDR (vic3_base + 0x100) #define Vic3vecpriority (* ((volatile unsigned long *) (vic3_base + 0x200)) #d Efine vic3addr (* (volatile unsigned long *) (vic3_base + 0xf00)) #define VIC3PERID0 (* (volatile unsigned long *) (VIC3_BA SE + 0xfe0)) #define VIC3PERID1 (* (volatile unsigned long *) (vic3_base + 0xfe4)) #define VIC3PERID2 (* (Volatile unsign Ed long *) (vic3_base + 0Xfe8)) #define VIC3PERID3 (* (volatile unsigned long *) (vic3_base + 0xfec)) #define VIC3PCELLID0 (* (volatile unsigned L Ong *) (vic3_base + 0xff0))) #define VIC3PCELLID1 (* (volatile unsigned long *) (vic3_base + 0xff4)) #define VIC3PCELLID2 ( * (volatile unsigned long *) (vic3_base + 0xff8))) #define VIC3PCELLID3 (* ((volatile unsigned long *) (vic3_base + 0XFFC)) #define_Exception_Vector0xD0037400 # define Pexceptionreset (* (volatile unsigned long *) (_exception_vector + 0x0)) # Define PEXCEPTIONUNDEF (* (volatile unsigned long *) (_exception_vector + 0x4)) #define PEXCEPTIONSWI (* (Volatile unsign Ed long *) (_exception_vector + 0x8)) #define PEXCEPTIONPABORT (* (volatile unsigned long *) (_exception_vector + 0xc)) #d Efine Pexceptiondabort (* (volatile unsigned long *) (_exception_vector + 0x10)) #define PEXCEPTIONRESERVED (* (volatile unsigned long *) (_exception_vector + 0x14)) #define PEXCEPTIONIRQ (* (volatile unsigned long *) (_exception_vector + 0x18) )) #define PEXCEPTIONFIQ (* ((volAtile unsigned long *) (_exception_vector + 0x1c)) void Exceptionundef (void) {printf ("Undefined instruction exception.\ n "); while (1);} void Exceptionswi (void) {printf ("Swi exception.\n"); while (1);} void Exceptionpabort (void) {printf ("Pabort exception.\n"); while (1);} void Exceptiondabort (void) {printf ("Dabort exception.\n"); while (1);} Interrupt correlation initialization void system_initexception (void) {//Set interrupt vector table Pexceptionundef = (unsigned long) exceptionundef; PEXCEPTIONSWI = (unsigned long) exceptionswi; Pexceptionpabort = (unsigned long) exceptionpabort; Pexceptiondabort = (unsigned long) exceptiondabort; PEXCEPTIONIRQ = (unsigned long) irq_handle; Pexceptionfiq = (unsigned long) irq_handle; Initialize Interrupt controller intc_init ();} Initialize Interrupt controller void Intc_init (void) {//disable all interrupts vic0intenclear = 0xFFFFFFFF; Vic1intenclear = 0xFFFFFFFF; Vic2intenclear = 0xFFFFFFFF; Vic3intenclear = 0xFFFFFFFF; Select the interrupt type as IRQ Vic0intselect = 0x0; Vic1intselect = 0x0; Vic2intselect = 0x0; Vic3intselect = 0x0; Qing vicxaddr intc_clearvectaddr ();} Save address void intc_setvectaddr (unsigned long intnum, void (*handler) (void)) {//vic0 if (intnum<32) for interrupt handling function that needs to be processed {* (volatile unsigned long *) (vic0vectaddr + 4*intnum)) = (unsigned) handler; }//vic1 else if (intnum<64) {* (volatile unsigned long *) (vic1vectaddr + (intnum-32))) = (unsigned ) handler; }//vic2 else if (intnum<96) {* (volatile unsigned long *) (vic2vectaddr + (intnum-64))) = (unsigned ) handler; }//vic3 Else {* (volatile unsigned long *) (vic3vectaddr + intnum-96)) = (unsigned) handler; } return; address void intc_clearvectaddr (void) {////VICXADDR: The address of the interrupt handler function for the interrupt that is currently being processed vic0addr = 0; vic1addr = 0; vic2addr = 0; vic3addr = 0;} Enable interrupt void intc_enable (unsigned long intnum) {unsigned long temp; if (intnum<32) {temp = vic0intenable; Temp |= (1<<intNUM); vic0intenable = temp; } else if (intnum<64) {temp = vic1intenable; Temp |= (1<< (intnum-32)); vic1intenable = temp; } else if (intnum<96) {temp = vic2intenable; Temp |= (1<< (intnum-64)); vic2intenable = temp; } else if (intnum<num_all) {temp = vic3intenable; Temp |= (1<< (intnum-96)); vic3intenable = temp; }//Num_all:enable all interrupt else {vic0intenable = 0xFFFFFFFF; vic1intenable = 0xFFFFFFFF; vic2intenable = 0xFFFFFFFF; vic3intenable = 0xFFFFFFFF; }}//disables the interrupt void intc_disable (unsigned long intnum) {unsigned long temp; if (intnum<32) {temp = Vic0intenclear; Temp |= (1<<intnum); Vic0intenclear = temp; } else if (intnum<64) {temp = Vic1intenclear; Temp |= (1<< (intnum-32)); Vic1intenclear = temp; } else if (intnum<96) { temp = vic2intenclear; Temp |= (1<< (intnum-64)); Vic2intenclear = temp; } else if (intnum<num_all) {temp = Vic3intenclear; Temp |= (1<< (intnum-96)); Vic3intenclear = temp; }//Num_all:disable all interrupt else {vic0intenclear = 0xFFFFFFFF; Vic1intenclear = 0xFFFFFFFF; Vic2intenclear = 0xFFFFFFFF; Vic3intenclear = 0xFFFFFFFF; } return; Read interrupt status unsigned long intc_getvicirqstatus (unsigned long Ucontroller) {if (Ucontroller = = 0) returnvic0irqstatus; else if (Ucontroller = = 1) return vic1irqstatus; else if (Ucontroller = = 2) return vic2irqstatus; else if (Ucontroller = = 3) return vic3irqstatus; else {} return 0;} Universal Interrupt handling function void Irq_handler (void) {unsigned long vicaddr[4] = {VIC0ADDR,VIC1ADDR,VIC2ADDR,VIC3ADDR}; int i=0; void (*ISR) (void) = NULL; for (; i<4; i++) {if (intc_getvicirqstatus (i) = 0) { ISR = (void (*) (void)) vicaddr[i]; Break }} (*isr) ();}
SMART210 Learning Record-----Interruption