历史上的今天
今天是:2024年12月23日(星期一)
2021年12月23日 | Tiny4412中断介绍
2021-12-23 来源:eefocus
Tiny4412中断介绍
通过几天裸板驱动开发,今天对ARM的中断做一些简单总结,前面我们已经了解了ARM的7种异常模式,中断是异常模式的一种,在ARM中异常事件发生将会触发中断,但是,所有的中断都不能直接访问cpu,而是都统一由GIC(中断管理器)来管理;下面是samsung提供的模式图:

其中GIC管理的中断有分为:

(1)SGI:一个cpu中断另一个cpu(cpu0 ->cpu1)
(2)PPI:一个中断只能中断一个cpu
(3)SPI:一个中断可以中断多个cpu
处理一个中断大致需要三步:
(1)cpu permit interrupt (cpu允许中断)
(2)GIC enable (启用GIC)
(3)SET Interrupt source (设置中断源)
下面是用SGI实现的一个程序:
头文件:
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 ICDIPR2_CPU0 (*(volatile unsigned long *)0x10490408)
8 #define ICDIPTR2_CPU0 (*(volatile unsigned long *)0x10490808)
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
14 #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, 0x1000);
13 enable_mmu();
14
15 *(unsigned long *)0x47000000 = do_irq;
16
17 //step 1: set cpu permit interrupt
18 __asm__ __volatile__(
19 "mrs r0, cpsrn"
20 "bic r0,r0, #0x80n"
21 "msr cpsr, r0n"
22 :::"r0"
23 );
24
25 //step 2: set GIC (cgi) enable
26 ICCICR_CPU0 = 1;//cpu接口控制寄存器(总开关)
27 ICCPMR_CPU0 =0xff;//中断总优先级(门槛)
28 ICDDCR = 1;//本中断开关
29 ICDIPR2_CPU0 = (3 << 9);//本中断优先级
30 ICDIPTR2_CPU0 = (1 << 9);//目标cpu
31 ICDISER0_CPU0 = (1 << 9);//启用本中断
32
33 //step 3: set interrupt source
34 ICDSGIR = 9 | (1 << 16);
35
36 printf("welcom backn");
37 }
38
39 void do_irq()
40 {
41 unsigned long ack_id = 0;
42 unsigned long cpu_id = 0;
43 unsigned long data = ICCIAR_CPU0;
44
45 /*clean interrupt*/
46 ack_id = data & 0x3ff;
47 cpu_id = data & (0x7 << 10);
48 ICCEOIR_CPU0 = ack_id | cpu_id;
49
50 printf("this is interruptn");
51 printf("cup_id is %dn", cpu_id >> 10);
52 printf("ack_id is %dn", ack_id);
53
54 }
55
56 void memcpy(unsigned char *dest, unsigned char *src, int len)
57 {
58 int i = 0;
59 for(i = 0; i < len; i++) {
60 dest[i] = src[i];
61 }
62 }
63
64 void enable_mmu()
65 {
66 /*构建表*/
67 unsigned long addr = 0x50000000;
68 init_table(addr);
69 /*打开mmu*/
70 unsigned long mmu = 0;
71 mmu = 1 | (1 << 1) | (1 << 3) | (1 << 8);
72 __asm__ __volatile__ (
73 "mov r0, #3n"
74 "MCR p15, 0, r0, c3, c0, 0n"//设置为管理员
75 "MCR p15, 0, %0, c2, c0, 0n"//设置表的地址
76 "MCR p15, 0, %1, c1, c0, 0n"//开启mmu
77 :
78 : "r" (addr), "r" (mmu)
79 :
80 );
81
82 }
83
84 __asm__(
85
86 "vector: n"
87 " b resetn"
88 " b undn"
89 " b swin"
90 " b pre_abtn"
91 " b data_abtn"
92 " .word 0x0n"
93 " b irqn"
94 " b fiqn"
95 "reset:n"
96 "und:n"
97 " mov sp, #0x47000000n"
98 " stmdb sp!, {r0-r12, lr}n"
99
100 " ldr r3, =0x47000004n"
101 " ldr r2, [r3]n"
102 " blx r2n"
103
104 " mov sp, #0x47000000n"
105 " ldmdb sp, {r0-r12, pc}^ n"
106
107 "swi:n"
108 " mov sp, #0x47000000n"
109 " stmdb sp!, {r0-r12, lr}^n"
110
111 " mov sp, #0x47000000n"
112 " ldmdb sp, {r0-r12, pc}^ n"
113
114 "pre_abt:n"
115
116 "data_abt:n"
117 " mov sp, #0x47000000n"
118 " sub lr, lr, #4n"
119 " stmdb sp!, {r0-r12, lr}n"
120
121 " ldr r3, =0x47000008n"
122 " ldr r2, [r3]n"
123 " blx r2n"
124
125 " mov sp, #0x47000000n"
126 " ldmdb sp, {r0-r12, pc}^ n"
127 "irq:n"
128
129 " mov sp, #0x47000000n"
130 " sub lr, lr, #4n"
131 " stmdb sp!, {r0-r12, lr}n"
132
133 " ldr r3, =0x47000000n"
134 " ldr r2, [r3]n"
135 " blx r2n"
136
137 " mov sp, #0x47000000n"
138 " ldmdb sp, {r0-r12, pc}^ n"
139
140 "fiq:n"
141
142 ".global vector_startn"
143 "vector_start: n"
144 ".word vector n "
145
146 );
147
148 void init_table(unsigned long *addr)
149 {
150 unsigned long va = 0;
151 unsigned long phys = 0;
152
153 //0x40000000-0x80000000 -> 0x40000000-0x80000000
154 for(va = 0x40000000; va < 0x80000000; va += 0x100000) {
155 phys = va;
156 addr[va >> 20] = phys | 2;
157 }
158
159 //0x10000000-0x14000000 -> 0x10000000-0x140000000
160 for(va = 0x10000000; va < 0x14000000; va += 0x100000) {
161 phys = va;
162 addr[va >> 20] = phys | 2;
163 }
164 //0x10000000-0x14000000 -> 0x10000000-0x140000000
165 for(va = 0x0; va < 0x10000000; va += 0x100000) {
166 phys = va + 0x70000000;
167 addr[va >> 20] = phys | 2;
168 }
169
170 }
运行结果如下:

上一篇:Tiny4412中断之看门狗
下一篇:Tiny4412模式跳转
史海拾趣
|
我对嵌入式软件开发的时间也不是很长,仅仅只有5年,算不上高手,也不是老手只能算是5岁的老菜鸟 ,在前面的3年里没有高人指点,靠着自己摸索也写了不少的程序吧,那时侯我没有想过要写出容易理解 和维护以及移植的问题,仅仅想着如何把这个功能 ...… 查看全部问答> |
|
单片机教程【1】LED $(\'swf_nhN\').innerHTML=AC_FL_RunContent(\'width\', \'550\', \'height\', \'400\', \'allowNetworking\', \'internal\', \'allowScriptAccess\', \'never\', \'src\', encodeURI(\'http://player.youku.com/player.php/si ...… 查看全部问答> |
|
今天去电子市场买了一个U盘,上次买了一个清华紫光的,没用几天就坏了!今天没有贪图便宜买了一个金士顿的。进电子市场前发现联想的乐PHONE在搞宣传,价格为2899,感觉价格还算便宜,就上去试了一把。   ...… 查看全部问答> |
|
Protel Synchronization report ========================================================================= Date : 17-Jun-2010 Time : 17:23:33 Reference document: Documents\\Previous Backup of PREVIO~1.SCH Target document: ...… 查看全部问答> |
|
谁有CH452芯片代码给我看看 CH452主要是对单片机上的数码管和按键控制的 我现在想让数码管亮起来 不知道怎样去写, 急~~~~~~~~~,赶紧帮帮我 谢谢 给点代码 邮箱:dfyl_2006@163.com … 查看全部问答> |
|
IAR 6.3中intrinsics.h与core_cm3.h 中的兼容错误解决方法 解决办法1: 用IAR6.3打开IAR6.0 的工程,编译的时候出现提示错误: extern uint32_t __get_PSP(void); 已经在C:\\Program Files\\IAR Systems\\Embedded Workbench 6.0\\arm\\inc\\c\\intrinsics.h文件中定义 extern uint32_t __get_MSP(void); ...… 查看全部问答> |
|
在上一个帖子里,从回帖里,我提取了两个比较关键的问题。 1.losingamong 提到 总的来说,zigbee不面向控制应用,无线本身不稳定,容易有丢包和网络延时,控制应用不能接受。 2.Error_Dan 提到 zigbee真正的价值在于那套自组网和具有路由能力 ...… 查看全部问答> |
|
很惭愧的说瑞萨开发板也就刚起了个头,由于各种原因(省略1万字)搁浅了,瑞萨的单片机以前没有接触过非常不熟悉,后来做着做着也就没信心了。活动要结束了,小车还没结束,在线下的时间里不用着急赶进度了,有空搞搞,至少没压力了哈。看到有的坛 ...… 查看全部问答> |
|
(1)物品名称:MSP430G2 LaunchPad(带触摸板); (2)新旧状况:板子只上过2次电,触摸板附带的MSP430G2452剪开袋子了但是没有用过; (3)转让价格:50不包邮; (4)联系方式:QQ673186827 … 查看全部问答> |




