网站建设公司走进深圳易百讯,服装网站开发项目计划书,网站的程序和数据库怎么做,新网站建设总结加粗样式本文所作内容#xff1a; 基于S5PV210芯片实现按键的外部中断处理程序#xff0c;搭建中断处理流程框架
S5PV210对于中断处理的操作流程
1 外部中断得到触发#xff1a;
1#xff09;外部中断在初始化阶段得到使能 2#xff09;外界达到了外部中断的触发条件
…加粗样式本文所作内容 基于S5PV210芯片实现按键的外部中断处理程序搭建中断处理流程框架
S5PV210对于中断处理的操作流程
1 外部中断得到触发
1外部中断在初始化阶段得到使能 2外界达到了外部中断的触发条件
2 跳转到向量表
1异常向量表在初始化阶段进行了配置ISR处理程序 2ISR处理程序包含了保护现场和回复现场的功能 3ISR处理程序能够跳转到中断总ISR_handel程序
3 跳转到对应中断号的中断处理程序
1对应中断号的中断得到初始化使能 2在ISR_handel中找到对应出现的中断号 3在ISR_handel中跳转到对应该中断号的isr中
S5PV210实现外部中断处理的程序流
初始化阶段
1首先初始化异常向量表 //初始化异常向量表r_exception_reset (unsigned int)reset_exception;r_exception_undef (unsigned int)undef_exception;r_exception_sotf_int (unsigned int)sotf_int_exception;r_exception_prefetch (unsigned int)prefetch_exception;r_exception_data (unsigned int)data_exception;r_exception_irq (unsigned int)IRQ_handle;r_exception_fiq (unsigned int)IRQ_handle;2然后初始化芯片的中断系统先全部中断号禁止中断然后中断工作模式为IRQ然后清除中断跳转寄存器 //禁止所有中断VIC0INTENCLEAR 0xFFFFFFFF;VIC1INTENCLEAR 0xFFFFFFFF;VIC2INTENCLEAR 0xFFFFFFFF;VIC3INTENCLEAR 0xFFFFFFFF;//配置中断类型 (默认全部为IRQ工作模式)VIC0INTSELECT 0x0;VIC1INTSELECT 0x0;VIC2INTSELECT 0x0;VIC3INTSELECT 0x0;//清除中断跳转寄存器VIC0ADDR 0;VIC1ADDR 0;VIC2ADDR 0;VIC3ADDR 0;3设置想要调试的外部中断设置对应GPIO的工作模式外外部中断模式使能对应的外部中断设置外部中断的触发方式
//配置IO引脚为外部中断工作模式rGPH0CON | (0xFF8); rGPH2CON | (0xFFFF0);//配置对应外部中断号下中断触发形式下降沿触发rEXT_INT_0_CON ~(0xFF8); rEXT_INT_0_CON | ((28)|(212)); rEXT_INT_2_CON ~(0xFFFF0);rEXT_INT_2_CON | ((20)|(24)|(28)|(212)); /*设置为0表示使能中断*/rEXT_INT_0_MASK ~(32); rEXT_INT_2_MASK ~(0x0f0);/*软件写1 表示清除flag*/rEXT_INT_0_PEND | (32);rEXT_INT_2_PEND | (0x0F0);实现中断处理流程
1实现第一阶段的异常向量表跳转程序汇编实现保存现场-跳转IRQ处理程序-现场恢复
IRQ_handle:// 设置IRQ模式下的栈指针ldr sp, IRQ_STACK// 保存现场// 保存LR寄存器 lr寄存器先减去4ARM的流水线机制sub lr, lr, #4// 保存R0-R12寄存器stmfd sp!, {r0-r12, lr}// 跳转到真正的中断处理程序bl irq_handler// 回复现场ldmfd sp!, {r0-r12, pc}^2实现中断处理第二阶段寻找中断编号寻找中断编号对应的isr
/*1-根据状态寄存器 找到对应的中断控制器位置VIC0/1/2/3*/unsigned long vicaddr[4] {VIC0ADDR,VIC1ADDR,VIC2ADDR,VIC3ADDR};void (*isr)(void) NULL;unsigned int i 0;for(i0; i3 ; i){if(intc_getvicirqstatus(i)){/*2-根据中断控制器位置跳转到对应中断控制器的vectaddr中拿到对应的中断isr*/isr (void (*)(void)) vicaddr[i];break; }}(*isr)(); 3使能对应外部中断的中断编号配置对应该中断编号的isr程序
//根据中断号 将对应的中断回调函数绑定在VECTADDR寄存器中
void intc_setvectaddr(unsigned long intnum, void (*handler)(void))
{if(intnum 32){( *((volatile unsigned long *)(VIC0VECTADDR 4*(intnum - 0))) ) (unsigned)handler;}else if(intnum 64){( *((volatile unsigned long *)(VIC0VECTADDR 4*(intnum - 32))) ) (unsigned)handler;}else if(intnum 96){( *((volatile unsigned long *)(VIC0VECTADDR 4*(intnum - 64))) ) (unsigned)handler;}else if(intnum 128){( *((volatile unsigned long *)(VIC0VECTADDR 4*(intnum - 96))) ) (unsigned)handler;}else{printf(ERR!:intc_setvectaddr err: intnum out of max of SOC\n);}return;
}//根据中断号将对应中断使能
void intc_enable(unsigned long intnum)
{unsigned int sTemp 0;if(intnum 32){sTemp VIC0INTENABLE;sTemp | (1(intnum - 0));VIC0INTENABLE sTemp;}else if(intnum 64){sTemp VIC1INTENABLE;sTemp | (1(intnum - 32));VIC1INTENABLE sTemp;}else if(intnum 96){sTemp VIC2INTENABLE;sTemp | (1(intnum - 64));VIC2INTENABLE sTemp;}else if(intnum 128){sTemp VIC3INTENABLE;sTemp | (1(intnum - 96));VIC3INTENABLE sTemp;}else{VIC0INTENABLE 0xFFFFFFFF;VIC1INTENABLE 0xFFFFFFFF;VIC2INTENABLE 0xFFFFFFFF;VIC3INTENABLE 0xFFFFFFFF;printf(ERR!:intc_enable err: intnum out of max of SOC\n);}
}在功能调试时遇到的问题
问题一按下按键后程序没有跳转到中断处理程序
1分析1结合没有心跳信息打印怀疑程序跑飞需要调试出程序具体在哪一行飞了 2行动1在main函数中加入串口打印信息看看程序在哪一行之后不能正常打印信息了 3结果1发现程序在配置中断向量表的第一行飞了
4分析2检查该行还行的目的是将函数指针以地址的形式填充到中断向量表中但是中断向量表只有一个首地址需要根据中断号计算地址。明显偏移地址计算出错地址是以字节形式递增的应该×4 5行动2 6结果2问题解决
问题二中断只能触发一次之后就不能触发了同时心跳信息消失
1分析1怀疑是中断返回时候现场恢复有问题但是检查现场恢复程序为标准处理过程问题出现在异常向量表的处理阶段检查初始化代码的流程看是否缺少异常向量表初始化 2行动1检查初始化程序流发现缺少了一步异常向量表初始化加入异常向量表初始化 3结果1问题解决