




已阅读5页,还剩1页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第二十六篇 SWI软件中断1.SWI修改CPSR前面学中断的时候曾经说过,如果CPSR得I位为1,则中断被禁止,如果CPSR得F位为1,则快速中断被禁止,还好利用KEIL的启动代码进入main函数后,CPSR的I和F都为0。但是有的启动代码不这样,或者我们就是要去修改CPSR该怎么办。进入main函数中,由于处于用户模式下,CPSR是不允许修改的,只能利用SWI来解决这个问题。运行指令SWI后,系统进入管理模式,这时候就有修改CPSR和SPSR的特权了,注意我们要修改的是SPSR而不是CPSR,这是因为:进入管理模式后,CPSR的值被系统自动拷贝到管理模式的SPSR(即SPSR_svc),离开管理模式后,我们会用SPSR_svc去还原CPSR,所以对CPSR的修改时无效的(当然我们可以修改CPSR而不去使它还原,不过这样有悖原则),如果修改SPSR,然后还原给CPSR,这样就行了。下面做个程序,在用户模式下使I=1,F=0:主函数这样写,很简单:/*/软件中断修改CPSR#includeint main(void) _asmSWI 0 /内嵌汇编,调用SWI,这里立即数任意取while(1);/*然后在启动代码中写该SWI的例程将SWI_Handler B SWI_Handler 该为:SWI_Handler MRS R0,SPSR ;SPSR的值为SWI之前的CPSR的值,将其取出 BIC R0,#0X40 ;F位清零,允许fiq ORR R0,#0X80 ;I位置一,禁止irq MSR SPSR_C,R0 ;修改过的值给SPSR的c域 MOVS PC,LR ;返回,S表示用SPSR恢复CPSR仿真如下图:可见CPSR的I和F位被顺利修改2.SWI立即数作为参数使用上例中用的是SWI 0,立即数为0,这个立即数可以设定为24位任意值,这个立即数就会存在于这条指令之中,提取出这个立即数即可以实现不同功能的调用。SWI的立即数使用可以这样做:SWI_Handler STMFD SP!,R0-R12,LR ;寄存器入栈 MRS R0,SPSR ;读取SPSR TST R0,#0X20 ;测试软件中断之前,CPU是Thumb状态还是ARM状态 LDRNEH R0,LR,#-2 ;如果是Thumb状态,读取该SWI指令 BICNE R0,#0XFF00 ;提取出SWI指令中的立即数 LDREQ R0,LR,#-4 ;如果是ARM状态,读取该SWI指令 BICEQ R0,R0,#0XFF000000 ;提取出SWI指令中的立即数 CMP R0,#2 ;立即数是否超出范围 LDRLS LR,=OUT ;如果未超出范围,保存返回地址 LDRLS PC,PC,R0,LSL#2 ;从地址向量表中选择相应的地址,进行跳转 B OUT ;如果超出范围,直接返回 DCD fun0 ;地址向量表 DCD fun1 DCD fun2OUTLDMFD SP!,R0-R12,pc ;寄存器出栈,LR复制到PC表示返回,“ ”表示用SPSR恢复CPSR主程序测试一下:/*/软件中断测试/测试SWI中的立即数功能/“SWI 0”使LED0闪烁,“SWI 1”使LED1闪烁,“SWI 2”使LED2闪烁#include#define LED0 116#define LED1 117#define LED2 118int main(void) unsigned int i; IODIR=LED0|LED1|LED2; /三个引脚作为输出用 while(1) _asmSWI 1 /内嵌汇编,调用SWI,立即数对应灯的号 for(i=0;i100000;i+); /延时 void fun0() /“SWI 0”使LED0闪烁 if(IOSET&LED0) IOCLR=LED0; else IOSET=LED0;void fun1() /“SWI 1”使LED1闪烁 if(IOSET&LED1) IOCLR=LED1; else IOSET=LED1;void fun2() /“SWI 2”使LED2闪烁 if(IOSET&LED2) IOCLR=LED2; else IOSET=LED2;/*仿真如下图:可见不同的立即数会使相应的灯闪烁3.R0作为参数其实不光SWI立即数可以传递参数,R0也可以,使用C语言形式的软件中断时(函数声明加 _swi(立即数)),参数被自动编译为R0,如果有两个参数, 则被编译为R0、R1,以此类推主程序如下:/*/SWI软件中断测试/测试用R0作为参数的调用功能/x=0使LED0闪烁,x=1使LED1闪烁,x=2使LED2闪烁#include#define LED0 116#define LED1 117#define LED2 118/声明是软件中断例程(立即数固定为0),x被自动编译为R0,如果有两个参数, 则被编译为R0、R1,以此类推_swi(0) ruanjian(int x);int main(void) unsigned int i; IODIR=LED0|LED1|LED2; /输出功能 while(1) ruanjian(2); /调用软件中断例程,参数默认用R0传递 for(i=0;i100000;i+); /延时 void fun0() /R0=0使LED0闪烁 if(IOSET&LED0) IOCLR=LED0; else IOSET=LED0;void fun1() /R0=1使LED1闪烁 if(IOSET&LED1) IOCLR=LED1; else IOSET=LED1;void fun2() /R0=2使LED2闪烁 if(IOSET&LED2) IOCLR=LED2; else IOSET=LED2;/*SWI的例程可以这样写:SWI_Handler STMFD SP!,R0-R12,LR ;寄存器入栈 CMP R0,#2 ;立即数是否超出范围 LDRLS LR,=OUT ;如果未超出范围,保存返回地址 LDRLS PC,PC,R0,LSL#2 ;从地址向量表中选择相应的地址,进行跳转 B OUT ;如果超出范围,直接返回 DCD fun0
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 社工线上活动创意方案策划(3篇)
- 水喷砂施工方案(3篇)
- 阜阳团建活动策划方案模板(3篇)
- 铜仁支座砂浆施工方案(3篇)
- 战略解码考试题库及答案
- 电气考试题库及答案合集
- 心理咨询考点题目及答案
- 心理测试题目及答案爱情
- 小学消防测试题目及答案
- 工业厂房设备维修保养合同
- 合资研发中心管理制度
- CJ/T 242-2007城市客车外置式制动间隙自动调整臂
- T/CSPSTC 106-2022水工建筑物表面位移机器视觉在线监测技术规程
- 2024年中级统计师《统计工作实务》真题及答案解析
- 小学2024-2025学年度第二学期道德与法治课程计划
- 河北省唐山市路北区2025届八年级数学第二学期期末达标检测模拟试题含解析
- 缴纳社保免责协议书
- 平面广告设计基本原则试题及答案
- 《癫痫持续状态》课件
- 患者十大安全目标(2025) 2
- 《钓鱼的艺术教学》课件
评论
0/150
提交评论