arm中断控制led
2015-08-16 11:24
405 查看
board/keyled_intr.c
cpu/board.c
/cpu/start.S
makefile
这里用到框架
通常要修改这几个文件
说明:
GPD0CON是模式设置
GPD0DAT是数据寄存器
GPD0PUD是推挽选择
推挽了之后带负载能力会强一点
其实推挽输出就是输出电阻小一点
第一阶段:外部中断初始化
1. io控制器初始化
GPH2CON[3:0]=1111
2. 外部中断控制器初始化
EXT_INT_2_CON[2:0]=010
EXT_INT_2_MASK[0] = 1
EXT_INT_PEND[0] = 1 // clear 0
EXT_INT_CON2[3:0] = 1111 = 0XF
3. 向量中断控制器初始化
4. 状态寄存器的中断使能
第二阶段:中断响应过程
1)保护现场
a.模式切换
CPSR -> SPSR_irq 硬件做
CPSR_svc <- CPSR_irq
硬件做
b. PC跳转
pc -> lr 硬件做
pc <- 0x18
硬件做
c. 保存通用寄存器r0-r12 用户做
r0-r12 -> sp
2)真正的中断处理
3)恢复现场
a. r0-r12 <- sp
b. lr -> pc
c. SPSR_irq -> CPSR
按键有不同模式,输入模式,就不需要中断,中断模式就需要中断。
使用中断的话一定是要设置异常表的。
不是中断处理器调用中断处理函数。是cpu自己调用中断处理函数。这个pc指针所指向的中断私服程序就是中断控制器在接受到硬件中断后强制设置的。这个和硬件有关的。
arm的异常向量表位置是可调整的,这个在协处理器cp15中设置
另外,如果是在操作系统下跑的程序,只需向系统注册中断处理函数就可以了。异常向量表是不会让用户程序动的
http://bbs.csdn.net/topics/390333297
参考:
http://blog.csdn.net/u012990532/article/details/47458701 http://blog.csdn.net/a158337/article/details/40043417 http://www.qrszxp.com/luojibiancheng/17.html http://www.bubuko.com/infodetail-529486.html
#include "stdio.h" #include "s5pv210.h" void Eint16_isr() { if(rEXT_INT_2_PEND==0x1) { printf("key2 put down\n"); rEXT_INT_2_PEND |=(0x1<<0); //清除中断标志位 rVIC0ADDRESS = 0x0; //清除中断处理子程序地址 rGPJ2DAT ^=(0x1<<0); } else if(rEXT_INT_2_PEND==0x2) { printf("key3 put down\n"); rEXT_INT_2_PEND |=(0x1<<1); rVIC0ADDRESS = 0x0; rGPJ2DAT ^=(0x1<<1); } else if(rEXT_INT_2_PEND==0x4){ printf("key4 put down\n"); rEXT_INT_2_PEND |=(0x1<<2); rVIC0ADDRESS = 0x0; // rGPJ2DAT ^=(0x4<<0);或用下面的移位 rGPJ2DAT ^=(0x1<<2); } else { printf("key5 put down\n"); rEXT_INT_2_PEND |=(0x1<<3); rVIC0ADDRESS = 0x0; rGPJ2DAT ^=(0x1<<3); } } void led_init() { //GPJ2CON[3:0] = 0B0001 rGPJ2CON &=~(0xffff<<0); rGPJ2CON |=(0x1111<<0); //GPJ2DAT[0] = 0/1 rGPJ2DAT |=(0xf<<0); } void key_init() { // GPH2CON[3:0] = 0B1111 -> intr mode rGPH2CON |=(0xffff<<0); } void ext_init() { /*//EXT_INT_2_CON[2:0]= 010 rEXT_INT_2_CON &=~(0x7<<0); rEXT_INT_2_CON |=(0x2<<0); //EXT_INT_2_MASK[0] = 0 rEXT_INT_2_MASK &=~(0x1<<0); //EXT_INT_2_PEND[0] = 0 rEXT_INT_2_PEND |=(0x1<<0);*/ //如果是1个按键就是0x7,就是上面的,初始化led和key时都要注意 // 下面是4个按键的中断初始化 rEXT_INT_2_CON &=~(0x7777<<0); rEXT_INT_2_CON |=(0x2222<<0); rEXT_INT_2_MASK &=~(0xf<<0); rEXT_INT_2_PEND |=(0xf<<0); } void vic0_init() { //VIC0INTENCLEAR[16] = 0 rVIC0INTENCLEAR &=~(0x1<<16); //VIC0INTSELECT[16] = 0 -> EINT16 IRQ rVIC0INTSELECT &=~(0x1<<16); //VIC0INTENABLE[16] = 1 -> EINT16 ENABLE *((unsigned int *)0xf2000140) = (unsigned int)Eint16_isr; rVIC0ADDRESS = 0x0; rVIC0INTENABLE |=(0x1<<16); } void keyled_intr() { led_init(); key_init(); ext_init(); vic0_init(); printf("while....\n"); while(1); }
cpu/board.c
#include "stdio.h" #include "api.h" int start_armboot() { printf(">>>>> welcome to c <<<<<<<\n"); keyled_intr(); return 0; }
/cpu/start.S
.text .extern uart_init .extern printf .extern start_armboot .global _start _start: mov r5,lr bl uart_init ldr r0,=fmt bl printf bl exc_vectable bl cpsr_init bl start_armboot return_uboot: mov lr,r5 bx lr cpsr_init:@标志位初始化 mrs r0,cpsr bic r0,r0,#0xc0 msr cpsr,r0 bx lr exc_vectable: ldr r0,=Handler_IRQ ldr r1,=0xd0037418 @iram里的地址 str r0,[r1] bx lr Handler_IRQ:@中断处理程序 sub lr,lr,#4 stmfd sp!,{r0-r12,lr} ldr lr,=return_irq ldr r0,=0xf2000000 @vic0地址 ldr r1,[r0] cmp r1,#0 beq return_irq ldr r0,=0xf2000f00 @VIC0ADDRESS地址 ldr pc,[r0] return_irq: ldmfd sp!,{r0-r12,pc}^ fmt: .asciz ">>>>> welcome to arm <<<<<<<\n" .end
makefile
CC = arm-linux-gcc LD = arm-linux-ld OBJCOPY = arm-linux-objcopy INCLUDEDIR := $(shell pwd)/include/ CPPFLAGS := -nostdinc -nostdlib -I$(INCLUDEDIR) CFLAGS := -fno-builtin -Wall -O2 export CC LD OBJCOPY CPPFLAGS CFLAGS OBJS := cpu/start.o cpu/board.o board/keyled_intr.o lib/uart.o lib/libc.a all:start.bin clean start.bin:$(OBJS) $(LD) -Ttext=0x40000000 $(OBJS) -o start.elf $(OBJCOPY) -O binary -S start.elf $@ %.o:%.S $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ %.o:%.c $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ clean: rm -rf ./start.elf make clean -C cpu make clean -C board
这里用到框架
通常要修改这几个文件
说明:
GPD0CON是模式设置
GPD0DAT是数据寄存器
GPD0PUD是推挽选择
推挽了之后带负载能力会强一点
其实推挽输出就是输出电阻小一点
第一阶段:外部中断初始化
1. io控制器初始化
GPH2CON[3:0]=1111
2. 外部中断控制器初始化
EXT_INT_2_CON[2:0]=010
EXT_INT_2_MASK[0] = 1
EXT_INT_PEND[0] = 1 // clear 0
EXT_INT_CON2[3:0] = 1111 = 0XF
3. 向量中断控制器初始化
4. 状态寄存器的中断使能
第二阶段:中断响应过程
1)保护现场
a.模式切换
CPSR -> SPSR_irq 硬件做
CPSR_svc <- CPSR_irq
硬件做
b. PC跳转
pc -> lr 硬件做
pc <- 0x18
硬件做
c. 保存通用寄存器r0-r12 用户做
r0-r12 -> sp
2)真正的中断处理
3)恢复现场
a. r0-r12 <- sp
b. lr -> pc
c. SPSR_irq -> CPSR
按键有不同模式,输入模式,就不需要中断,中断模式就需要中断。
使用中断的话一定是要设置异常表的。
不是中断处理器调用中断处理函数。是cpu自己调用中断处理函数。这个pc指针所指向的中断私服程序就是中断控制器在接受到硬件中断后强制设置的。这个和硬件有关的。
arm的异常向量表位置是可调整的,这个在协处理器cp15中设置
另外,如果是在操作系统下跑的程序,只需向系统注册中断处理函数就可以了。异常向量表是不会让用户程序动的
http://bbs.csdn.net/topics/390333297
参考:
http://blog.csdn.net/u012990532/article/details/47458701 http://blog.csdn.net/a158337/article/details/40043417 http://www.qrszxp.com/luojibiancheng/17.html http://www.bubuko.com/infodetail-529486.html
相关文章推荐
- LayoutInflater.inflate源码分析
- Andriod Studio科普文章——3.大约gradle常见问题插头
- USACO:2.2.2 Subset Sums 集合和
- 取石子游戏
- for循环
- struts2学习笔记(十一)文件上传
- 如何设置eclipse的自动补齐功能
- 数据结构读书笔记1
- IOS拉伸之底盖设置
- 关于Cocos2d-x的CC_SYNTHESIZE 和 CC_SYNTHESIZE_READONLY 宏的作用
- Android ADB工具-管理设备/取设备硬件信息(一)
- POJ 2001 Shortest Prefixes(字典树)
- UVA 10294 Arif in Dhaka (置换polya)
- Android之assets资源
- codeforces 570 c
- 我开发的第一个Android软件
- AC算法初探
- POJ1915 Knight Moves(宽搜经典题目)
- Android Resources
- 电脑显示U盘,但是读取不了