通过几天裸板驱动开发,今天对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实现的一个程序:

  头文件:

 #ifndef __BUNFLY_H
#define __BUNFLY_H #define ICCICR_CPU0 (*(volatile unsigned long *)0x10480000)
#define ICCPMR_CPU0 (*(volatile unsigned long *)0x10480004)
#define ICDDCR (*(volatile unsigned long *)0x10490000)
#define ICDIPR2_CPU0 (*(volatile unsigned long *)0x10490408)
#define ICDIPTR2_CPU0 (*(volatile unsigned long *)0x10490808)
#define ICDISER0_CPU0 (*(volatile unsigned long *)0x10490100)
#define ICDSGIR (*(volatile unsigned long *)0x10490f00)
#define ICCEOIR_CPU0 (*(volatile unsigned long *)0x10480010)
#define ICCIAR_CPU0 (*(volatile unsigned long *)0x1048000c) #endif //__BUNFLY_H
 #include "bunfly.h"

 int (*printf)(char *, ...) = 0xc3e114d8;
void enable_mmu();
void init_table(unsigned long *addr);
void memcpy(unsigned char *dest, unsigned char *src, int len);
extern unsigned long vector_start;
void do_irq(); int main()
{
memcpy(0x70000000, vector_start, 0x1000);
enable_mmu(); *(unsigned long *)0x47000000 = do_irq; //step 1: set cpu permit interrupt
__asm__ __volatile__(
"mrs r0, cpsr\n"
"bic r0,r0, #0x80\n"
"msr cpsr, r0\n"
:::"r0"
); //step 2: set GIC (cgi) enable
ICCICR_CPU0 = ;//cpu接口控制寄存器(总开关)
ICCPMR_CPU0 =0xff;//中断总优先级(门槛)
ICDDCR = ;//本中断开关
ICDIPR2_CPU0 = ( << );//本中断优先级
ICDIPTR2_CPU0 = ( << );//目标cpu
ICDISER0_CPU0 = ( << );//启用本中断 //step 3: set interrupt source
ICDSGIR = | ( << ); printf("welcom back\n");
} void do_irq()
{
unsigned long ack_id = ;
unsigned long cpu_id = ;
unsigned long data = ICCIAR_CPU0; /*clean interrupt*/
ack_id = data & 0x3ff;
cpu_id = data & (0x7 << );
ICCEOIR_CPU0 = ack_id | cpu_id; printf("this is interrupt\n");
printf("cup_id is %d\n", cpu_id >> );
printf("ack_id is %d\n", ack_id); } void memcpy(unsigned char *dest, unsigned char *src, int len)
{
int i = ;
for(i = ; i < len; i++) {
dest[i] = src[i];
}
} void enable_mmu()
{
/*构建表*/
unsigned long addr = 0x50000000;
init_table(addr);
/*打开mmu*/
unsigned long mmu = ;
mmu = | ( << ) | ( << ) | ( << );
__asm__ __volatile__ (
"mov r0, #3\n"
"MCR p15, 0, r0, c3, c0, 0\n"//设置为管理员
"MCR p15, 0, %0, c2, c0, 0\n"//设置表的地址
"MCR p15, 0, %1, c1, c0, 0\n"//开启mmu
:
: "r" (addr), "r" (mmu)
:
); } __asm__( "vector: \n"
" b reset\n"
" b und\n"
" b swi\n"
" b pre_abt\n"
" b data_abt\n"
" .word 0x0\n"
" b irq\n"
" b fiq\n"
"reset:\n"
"und:\n"
" mov sp, #0x47000000\n"
" stmdb sp!, {r0-r12, lr}\n" " ldr r3, =0x47000004\n"
" ldr r2, [r3]\n"
" blx r2\n" " mov sp, #0x47000000\n"
" ldmdb sp, {r0-r12, pc}^ \n" "swi:\n"
" mov sp, #0x47000000\n"
" stmdb sp!, {r0-r12, lr}^\n" " mov sp, #0x47000000\n"
" ldmdb sp, {r0-r12, pc}^ \n" "pre_abt:\n" "data_abt:\n"
" mov sp, #0x47000000\n"
" sub lr, lr, #4\n"
" stmdb sp!, {r0-r12, lr}\n" " ldr r3, =0x47000008\n"
" ldr r2, [r3]\n"
" blx r2\n" " mov sp, #0x47000000\n"
" ldmdb sp, {r0-r12, pc}^ \n"
"irq:\n" " mov sp, #0x47000000\n"
" sub lr, lr, #4\n"
" stmdb sp!, {r0-r12, lr}\n" " ldr r3, =0x47000000\n"
" ldr r2, [r3]\n"
" blx r2\n" " mov sp, #0x47000000\n"
" ldmdb sp, {r0-r12, pc}^ \n" "fiq:\n" ".global vector_start\n"
"vector_start: \n"
".word vector \n " ); void init_table(unsigned long *addr)
{
unsigned long va = ;
unsigned long phys = ; //0x40000000-0x80000000 -> 0x40000000-0x80000000
for(va = 0x40000000; va < 0x80000000; va += 0x100000) {
phys = va;
addr[va >> ] = phys | ;
} //0x10000000-0x14000000 -> 0x10000000-0x140000000
for(va = 0x10000000; va < 0x14000000; va += 0x100000) {
phys = va;
addr[va >> ] = phys | ;
}
//0x10000000-0x14000000 -> 0x10000000-0x140000000
for(va = 0x0; va < 0x10000000; va += 0x100000) {
phys = va + 0x70000000;
addr[va >> ] = phys | ;
} }

运行结果如下:

最新文章

  1. org.jboss.deployment.DeploymentException: Trying to install an already registered mbean: jboss.jca:service=LocalTxCM,name=egmasDS
  2. mysql删除开放用户权限
  3. 1215课后练习----indexOf的用法
  4. Seven-Segment LED Display Example Design an 8-to-1 multiplexer.
  5. Hive的JDBC使用&amp;并把JDBC放置后台运行
  6. [学习笔记]设计模式之Command
  7. MaterialEditText
  8. HDU 1853Cyclic Tour(网络流之最小费用流)
  9. asp.net 页面跳转的方法
  10. 读书笔记之MERGE 语句使用
  11. 如何在Linux上检查SSH的版本(转)
  12. ubuntu 14.04中文分词 结巴分词
  13. Nginx1.8.0版本平滑升级新版本1.9.7
  14. Asp.net mvc 知多少(九)
  15. java基础(Fundamental)
  16. Linux一键安装宝塔控制面板
  17. day16-(listener&amp;filter)
  18. android camera(一):camera模组CMM介绍【转】
  19. Ubuntu下在Apache中运行Keystone
  20. 大数据自学2-Hue集成环境中使用Sqoop组件从Sql Server导数据到Hive/HDFS

热门文章

  1. FFMPEG结构体分析:AVCodec
  2. Unity3D学习笔记(二)Unity的JavaScript基础
  3. iOS关于蓝牙连接的简单介绍与使用
  4. 【Matlab编程】生日快乐歌(显示歌词)—matlab版
  5. Git错误一例
  6. 【1】mac下面iTerm配置oh-my-zsh教程
  7. android studio JNI使用
  8. OpenCV分通道显示图片,灰度,融合,直方图,彩色直方图
  9. bash编程语法自我总结
  10. linux下让irb实现代码自动补全的功能