1: External interrupt
When we studied key drivers before, we detected whether the key was pressed by round-robin (that is, what we call an infinite loop). Although this can detect the key press, it wastes too much system resources. Regardless of whether our key interrupt occurs, the CPU must keep detecting; in this way, the operating system cannot do other things, so this is definitely not possible, so we can solve it through external interrupts;
To handle an interrupt, we need to understand the mode, and to understand the mode, we need to understand MMU; after learning these, we can return to deal with the problems left when we drove the key;
Through the previous push-to-drive, we have learned the position of the push-to-drive on the board, the circuit diagram of the button, and the function of its pins. Now let's take a look at the steps to implement this program:
We know that the registers that control the buttons are:
The external interrupts correspond to:
0xf = EXT_INT43[2]
In EXT_INT43[2] we select edge trigger mode:
Through the key on the core board pin diagram we can know that the external interrupt source is 26 and the interrupt number is 64
Registers that we need to configure:
(1) EXT_INT43PEND (2) EXT_INT43MASK (3) EXT_INT43CON
It should be noted that: interrupt status: EXT_INT43_PEND[2], especially to clear the interrupt, set the value to 1.
Implementing an external interrupt generally requires five steps:
(1) CPU allows interrupts
(2) Enable GIC
(3) Configure external interrupt register (xeint)
(4) Configure GPIO (General Purpose Input Output, referred to as GPIO. Each GPIO port can be configured as input or output through software)
(5) External interrupt source
The following is the specific code for implementation:
1 #ifndef __BUNFLY_H
2 #define __BUNFLY_H
3
4 #define ICCICR_CPU0 (*(volatile unsigned long *)0x10480000)
5 #define ICCPMR_CPU0 (*(volatile unsigned long *)0x10480004)
6 #define ICDDCR (*(volatile unsigned long *)0x10490000)
7 #define ICDIPR0_CPU0 (*(volatile unsigned long *)0x10490400)
8 #define ICDIPTR0_CPU0 (*(volatile unsigned long *)0x10490800)
9 #define ICDISER0_CPU0 (*(volatile unsigned long *)0x10490100)
10 #define ICDSGIR (*(volatile unsigned long *)0x10490f00)
11 #define ICCEOIR_CPU0 (*(volatile unsigned long *)0x10480010)
12 #define ICCIAR_CPU0 (*(volatile unsigned long *)0x1048000c)
13 #define ICDIPR2_CPU0 (*(volatile unsigned long *)0x10490408)
14 #define ICDIPTR2_CPU0 (*(volatile unsigned long *)0x10490808)
15 #define ICDIPR3_CPU0 (*(volatile unsigned long *)0x1049040c)
16 #define ICDIPTR3_CPU0 (*(volatile unsigned long *)0x1049080c)
17 #define ICDIPR16_CPU0 (*(volatile unsigned long *)0x10490440)
18 #define ICDIPTR16_CPU0 (*(volatile unsigned long *)0x10490840)
19 #define ICDIPR18_CPU0 (*(volatile unsigned long *)0x10490448)
20 #define ICDIPTR18_CPU0 (*(volatile unsigned long *)0x10490848)
21 #define ICDISER2_CPU0 (*(volatile unsigned long *)0x10490108)
twenty two
23 #define WTCON (*(volatile unsigned long *)0x10060000)
24 #define WTDAT (*(volatile unsigned long *)0x10060004)
25 #define WTCNT (*(volatile unsigned long *)0x10060008)
26 #define WTCLRINT (*(volatile unsigned long *)0x1006000C)
27
28 #define EXT_INT43_CON (*(volatile unsigned long *)0x11000e0c)
29 #define EXT_INT43_MASK (*(volatile unsigned long *)0x11000f0c)
30 #define EXT_INT43_PEND (*(volatile unsigned long *)0x11000f4c)
31 #define GPX3CON (*(volatile unsigned long *)0x11000c60)
32
33 #define GPM4CON (*(volatile unsigned long *)0x110002e0)
34 #define GPM4DAT (*(volatile unsigned long *)0x110002e4)
35
36 #endif //__BUNFLY_H
1 #include "bunfly.h"
2
3 int (*printf)(char *, ...) = 0xc3e114d8;
4 void enable_mmu();
5 void init_table(unsigned long *addr);
6 void memcpy(unsigned char *dest, unsigned char *src, int len);
7 extern unsigned long vector_start;
8 void do_irq();
9
10 int main()
11 {
12 memcpy(0x70000000, vector_start, 0x10000);
13 enable_mmu();
14
15 *(unsigned long *)0x47000000 = do_irq;
16
17 //step 1: cpu permit interrupt
18 __asm__ __volatile__ (
19 "mrs r0, cpsrn"
20 "bic r0, r0, #0x80n"
21 "msr cpsr, r0n"
22 ::: "r0"
twenty three );
twenty four
25 //step 2: GIC (cgi) enable
26 ICCICR_CPU0 = 1; // Main switch
27 ICCPMR_CPU0 = 0xff; //Total priority (threshold)
28 ICDDCR = 1; //Interrupt switch
29
30 ICDIPR16_CPU0 = (0 << 0); //This interrupt priority
31 ICDIPTR16_CPU0 = (1 << 0); //target cpu
32 ICDISER2_CPU0 = (1 << 0); // Enable this interrupt
33
34 //step 3: Xeint
35 EXT_INT43_CON = (4 << 8); //Triggers Both edge (set to edge trigger)
36 EXT_INT43_MASK = 0; // Enable interrupt
37
38 //step 4: set gpio
39 GPX3CON = (0xf << 8); //0xF = EXT_INT43[2] (gpio configured as external interrupt)
40
41 //step 5: interrupt source
42
43 printf("welcome back");
44 }
45
46 void do_irq()
47 {
48 unsigned long data = ICCIAR_CPU0;
49 int irq = data & 0x3ff; //Get the interrupt number
50 int cpu = (data >> 10) & 0x7; //Get the target cpu
51 ICCEOIR_CPU0 = irq | (cpu << 10); // Clear interrupt
52 EXT_INT43_PEND |= (1 << 2); // Clear interrupt
53 printf("key 1 down, cpu is %d, irq is %dn", cpu, irq);
54 }
55
56 void enable_mmu()
57 {
58 unsigned long addr = 0x50000000;
59 init_table(addr);
60 unsigned long mmu = 0;
61 mmu = 1 | (1 << 1) | (1 << 3) | (1 << 8);
62
63 __asm__ __volatile__ (
64 "mov r0, #3n"
65 "MCR p15, 0, r0, c3, c0, 0n"
66 "MCR p15, 0, %0, c2, c0, 0n"
67 "MCR p15, 0, %1, c1, c0, 0n"
68 :
69 : "r" (addr), "r" (mmu)
70 :
71 );
72 }
73
74 void init_table(unsigned long *addr)
75 {
76 unsigned long va = 0;
77 unsigned long phys = 0;
78
79 for(va = 0x40000000; va < 0x80000000; va+=0x100000)
80 {
81 phys = va;
82 addr[va >> 20] = phys | 2;
83 }
84
85 for(va = 0x10000000; va < 0x14000000; va+=0x100000)
86 {
87 phys = va;
88 addr[va >> 20] = phys | 2;
89 }
90
91 for(va = 0x0; va < 0x10000000; va+=0x100000)
92 {
93 phys = va + 0x70000000;
94 addr[va >> 20] = phys | 2;
95 }
96 }
97
98 __asm__ (
99 "vector:n"
100 "b reset"
101 "b undefinedn"
102 " b swin"
103 "b pre_abtn"
104 "b data_abtn"
105 ".word 0x0n"
106 "b irqn"
107 "b fiqn"
108
109 "reset:n"
110 "undefined:n"
111 "mov sp, #0x47000000n"
112 "stmdb sp!, {r0-r12, lr}n"
113
114 "ldr r3, =0x47000004n"
115 "ldr r2, [r3]n"
116 "blx r2n"
117
118 "mov sp, #0x47000000n"
119 "ldmdb sp, {r0-r12, pc}^n"
120 "swi:n"
121 "mov sp, #0x47000000n"
122 "stmdb sp!, {r0-r12, lr}n"
123
124 "mov sp, #0x47000000n"
125 "ldmdb sp, {r0-r12, pc}^n"
126 "pre_abt:n"
127 "data_abt:n"
128 "mov sp, #0x47000000n"
129 "sub lr, lr, #4n"
130 "stmdb sp!, {r0-r12, lr}n"
131
132 "ldr r3, =0x47000008n"
133 "ldr r2, [r3]n"
134 "blx r2n"
135
136 "mov sp, #0x47000000n"
137 "ldmdb sp, {r0-r12, pc}^n"
138 "irq:n"
139 "mov sp, #0x47000000n"
140 "sub lr, lr, #4n"
141 "stmdb sp!, {r0-r12, lr}n"
142
143 "mov r3, #0x47000000n"
144 "ldr r2, [r3]n"
145 "blx r2n"
146
147 "mov sp, #0x47000000n"
148 "ldmdb sp, {r0-r12, pc}^n"
149 "fiq:n"
150
151 ".global vector_startn"
152 "vector_start:n"
153 ".word vectorn"
154 );
155
156 void memcpy(unsigned char *dest, unsigned char *src, int len)
157 {
158 int i = 0;
159 for(i = 0; i < len; i++)
160 dest[i] = src[i];
161 }
Next, we control the watchdog through the external interrupt (KEY1), and then control the LED light through the watchdog. When key1 is pressed, the LED light starts flashing, and press it again to stop flashing:
The code is posted below:
1 #ifndef __BUNFLY_H
2 #define __BUNFLY_H
3
4 #define ICCICR_CPU0 (*(volatile unsigned long *)0x10480000)
5 #define ICCPMR_CPU0 (*(volatile unsigned long *)0x10480004)
6 #define ICDDCR (*(volatile unsigned long *)0x10490000)
7 #define ICDIPR0_CPU0 (*(volatile unsigned long *)0x10490400)
8 #define ICDIPTR0_CPU0 (*(volatile unsigned long *)0x10490800)
9 #define ICDISER0_CPU0 (*(volatile unsigned long *)0x10490100)
10 #define ICDSGIR (*(volatile unsigned long *)0x10490f00)
11 #define ICCEOIR_CPU0 (*(volatile unsigned long *)0x10480010)
12 #define ICCIAR_CPU0 (*(volatile unsigned long *)0x1048000c)
13 #define ICDIPR2_CPU0 (*(volatile unsigned long *)0x10490408)
14 #define ICDIPTR2_CPU0 (*(volatile unsigned long *)0x10490808)
15 #define ICDIPR3_CPU0 (*(volatile unsigned long *)0x1049040c)
16 #define ICDIPTR3_CPU0 (*(volatile unsigned long *)0x1049080c)
17 #define ICDIPR16_CPU0 (*(volatile unsigned long *)0x10490440)
18 #define ICDIPTR16_CPU0 (*(volatile unsigned long *)0x10490840)
19 #define ICDIPR18_CPU0 (*(volatile unsigned long *)0x10490448)
20 #define ICDIPTR18_CPU0 (*(volatile unsigned long *)0x10490848)
21 #define ICDISER2_CPU0 (*(volatile unsigned long *)0x10490108)
twenty two
23 #define WTCON (*(volatile unsigned long *)0x10060000)
24 #define WTDAT (*(volatile unsigned long *)0x10060004)
25 #define WTCNT (*(volatile unsigned long *)0x10060008)
26 #define WTCLRINT (*(volatile unsigned long *)0x1006000C)
27
28 #define EXT_INT43_CON (*(volatile unsigned long *)0x11000e0c)
29 #define EXT_INT43_MASK (*(volatile unsigned long *)0x11000f0c)
30 #define EXT_INT43_PEND (*(volatile unsigned long *)0x11000f4c)
31 #define GPX3CON (*(volatile unsigned long *)0x11000c60)
32
33 #define GPM4CON (*(volatile unsigned long *)0x110002e0)
34 #define GPM4DAT (*(volatile unsigned long *)0x110002e4)
35
36 #endif //__BUNFLY_H
1 #include "bunfly.h"
2
3 void (*udelay)(int) = 0xc3e25f90;
4 int (*printf)(char *, ...) = 0xc3e114d8;
5 void enable_mmu();
6 void init_table(unsigned long *addr);
7 void memcpy(unsigned char *dest, unsigned char *src, int len);
8 extern unsigned long vector_start;
9 void do_irq();
10 void led_on();
11 void led_off();
12 void wdt_on();
13 void wdt_off();
14
15 int main()
16 {
17 memcpy(0x70000000, vector_start, 0x1000);
18 enable_mmu();
19
20 *(unsigned long *)0x47000000 = do_irq;
twenty one
22 //step 1: cpu permit interrupt
23 __asm__ __volatile__(
24 "mrs r0, cpsrn"
25 "bic r0,r0, #0x80n"
26 "msr cpsr, r0n"
27 :::"r0"
28 );
29
30 //step 2: GIC (cgi) enable
31 ICCICR_CPU0 = 1; // Main switch
32 ICCPMR_CPU0 =0xff; //Total priority
Previous article:S3C6410 board transplanted Android2.2
Next article:Tiny4412 interrupt watchdog
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Why software-defined vehicles transform cars from tools into living spaces
- How Lucid is overtaking Tesla with smaller motors
- Wi-Fi 8 specification is on the way: 2.4/5/6GHz triple-band operation
- Wi-Fi 8 specification is on the way: 2.4/5/6GHz triple-band operation
- Vietnam's chip packaging and testing business is growing, and supply-side fragmentation is splitting the market
- Vietnam's chip packaging and testing business is growing, and supply-side fragmentation is splitting the market
- Three steps to govern hybrid multicloud environments
- Three steps to govern hybrid multicloud environments
- Microchip Accelerates Real-Time Edge AI Deployment with NVIDIA Holoscan Platform
- Microchip Accelerates Real-Time Edge AI Deployment with NVIDIA Holoscan Platform
- Low-cost MCU options
- 5G millimeter wave antenna
- Design of Switching Power Supply Using MSP430 Microcontroller
- LCD screen problem
- Using 18f2550 as PWM sine generator
- TI CCS MAP File Description
- Approximate power functions using the extremum method
- 【Experimental Case】Application of Power Amplifier in Microfluidic Chip Testing
- 【IoT Smart Home System】---Temperature and humidity data collection and upload (2)
- How to turn off the basic timer of STM32 HAL library