字符设备驱动笔记——中断方式按键驱动之linux异常处理结构(四)
1.中断方式获取按键值单片机: 1)按键按下 2)cup发生中断,跳转到异常向量入口执行 3)b 函数a.保存被中断的现场b.执行中断处理函数c.恢复 linux: 1)trap_init()函数构造异常向量 2)vector_irq + stubs_offset 跳转,vector_irq用宏来实现a.保存寄存器的值b.asm_do_IRQc.恢复2.linux异常处理结构分析 --------------------------------------------- trap_init()函数构造了异常向量 把__vectors_start代码复制到vectors这个地址中去 ---------------------------------------------1)/arch/arm/kernel/traps.ctrap_init(){memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start); ......}vectors ====> CONFIG_VECTORS_BASE 异常向量的地址,可配置项 2) /arch/arm/kernel/entry-armv.S__vectors_start分析:-------------------------------------------__vectors_start: ARM( swi SYS_ERROR0 )THUMB( svc #0 )THUMB( nop )W(b) vector_und + stubs_offset @这些都是异常向量W(ldr) pc, .LCvswi + stubs_offsetW(b) vector_pabt + stubs_offsetW(b) vector_dabt + stubs_offsetW(b) vector_addrexcptn + stubs_offsetW(b) vector_irq + stubs_offsetW(b) vector_fiq + stubs_offset...... ----------------------------------------------3)分析vector_undvector_und由vector_stub宏定义而来vector_stub und, UND_MODE ---------------------------------------------------------//宏定义.macro vector_stub, name, mode, correction=0.align 5vector_\name:.if \correctionsub lr, lr, #\correction.endif ...... //替换后 .macro vector_stub, name, mode, correction=0.align 5vector_und: @定义了一个标号@@ Save r0, lr_<exception> (parent PC) and spsr_<exception>@ (parent CPSR)@stmia sp, {r0, lr} @ save r0, lrmrs lr, spsrstr lr, [sp, #8] @ save spsr@@ Prepare for SVC32 mode. IRQs remain disabled.@mrs r0, cpsreor r0, r0, #(\mode ^ SVC_MODE | PSR_ISETSTATE)msr spsr_cxsf, r0....... .endm------------------------------------------------------------- 4).long __und_usr @ 0 (USR_26 / USR_32) //作用:保存寄存器,做处理,恢复寄存器.long __und_invalid @ 1 (FIQ_26 / FIQ_32).long __und_invalid @ 2 (IRQ_26 / IRQ_32).long __und_svc @ 3 (SVC_26 / SVC_32).long __und_invalid @ 4.long __und_invalid @ 5.long __und_invalid @ 6.long __und_invalid @ 7.long __und_invalid @ 8.long __und_invalid @ 9.long __und_invalid @ a.long __und_invalid @ b.long __und_invalid @ c.long __und_invalid @ d.long __und_invalid @ e.long __und_invalid @ f.align 5 ----------------------------------------------------------------- ========================================================================== 分析vector_irq 1)W(b) vector_irq + stubs_offset ----------------------------------------------------------------- 2)vector_stub irq, IRQ_MODE, 4 替换后.macro vector_stub, name, mode, correction=0.align 5vector_irq://计算返回地址 sub lr, lr, #\correction@@ Save r0, lr_<exception> (parent PC) and spsr_<exception>@ (parent CPSR)@stmia sp, {r0, lr} @ save r0, lrmrs lr, spsrstr lr, [sp, #8] @ save spsr@@ Prepare for SVC32 mode. IRQs remain disabled.@mrs r0, cpsreor r0, r0, #(\mode ^ SVC_MODE | PSR_ISETSTATE)msr spsr_cxsf, r0@@ the branch table must immediately follow this code@and lr, lr, #0x0fTHUMB( adr r0, 1f )THUMB( ldr lr, [r0, lr, lsl #2] )mov r0, spARM( ldr lr, [pc, lr, lsl #2] )movs pc, lr @ branch to handler in SVC mode ENDPROC(vector_\name).align 2@ handler addresses follow this label 1:.endm ----------------------------------------------------------- 3).long __irq_usr @ 0 (USR_26 / USR_32).long __irq_invalid @ 1 (FIQ_26 / FIQ_32).long __irq_invalid @ 2 (IRQ_26 / IRQ_32).long __irq_svc @ 3 (SVC_26 / SVC_32).long __irq_invalid @ 4.long __irq_invalid @ 5.long __irq_invalid @ 6.long __irq_invalid @ 7.long __irq_invalid @ 8.long __irq_invalid @ 9.long __irq_invalid @ a.long __irq_invalid @ b.long __irq_invalid @ c.long __irq_invalid @ d.long __irq_invalid @ e.long __irq_invalid @ f------------------------------------------------------ 4)__irq_usr分析: __irq_usr: usr_entry @入口kuser_cmpxchg_checkget_thread_info tsk #ifdef CONFIG_PREEMPTldr r8, [tsk, #TI_PREEMPT] @ get preempt countadd r7, r8, #1 @ increment itstr r7, [tsk, #TI_PREEMPT] #endifirq_handler @处理函数 #ifdef CONFIG_PREEMPTldr r0, [tsk, #TI_PREEMPT]str r8, [tsk, #TI_PREEMPT]teq r0, r7ARM( strne r0, [r0, -r0] )THUMB( movne r0, #0 )THUMB( strne r0, [r0] ) #endif #ifdef CONFIG_TRACE_IRQFLAGSbl trace_hardirqs_on #endifmov why, #0b ret_to_userUNWIND(.fnend ) ENDPROC(__irq_usr).ltorg.align 5 ------------------------------------------------------ usr_entry分析:.macro usr_entryUNWIND(.fnstart )UNWIND(.cantunwind ) @ don't unwind the user space sub sp, sp, #S_FRAME_SIZE ARM( stmib sp, {r1 - r12} ) @保存寄存器THUMB( stmia sp, {r0 - r12} )ldmia r0, {r1 - r3}add r0, sp, #S_PC @ here for interlock avoidancemov r4, #-1 @ "" "" "" ""str r1, [sp] @ save the "real" r0 copied@ from the exception stack.......endm ------------------------------------------------------------ irq_handler分析:.macro irq_handlerget_irqnr_preamble r5, lr 1: get_irqnr_and_base r0, r6, r5, lrmovne r1, sp@@ routine called with r0 = irq number, r1 = struct pt_regs *@adrne lr, BSYM(1b)bne asm_do_IRQ @跳转到C程序里面处理.......endm5) 调用asm_do_IRQ C处理程序
转载于:https://www.cnblogs.com/liulipeng/p/3330866.html
字符设备驱动笔记——中断方式按键驱动之linux异常处理结构(四)相关推荐
- 字符设备驱动笔记——中断方式按键驱动之linux中断处理结构(五)
一.单片机下的中断处理1)分辨是哪一个中断2)调用处理函数3)清中断 二.linux下的中断处理1)/arch/arm/kernel/irq.c asmlinkage void __exception ...
- linux 按键驱动中断 rockchip_7.自己写中断方式按键驱动程序(详解)
request_irq()和free_irq()分析完毕后,接下来开始编写上升沿中断的按键驱动 如下图,需要设置4个按键的EINT0, EINT2, EINT11, EINT19的模式为双边沿,且设置 ...
- 第12课第3节 字符设备驱动程序之查询方式的按键驱动程序
第12课第3节 字符设备驱动程序之查询方式的按键驱动程序 cat /proc/devices //查询主设备号 insmod ./second_drv.ko ls /dev/button -l pos ...
- chrdev字符设备几种注册方式的差异
数据结构 #define CHRDEV_MAJOR_HASH_SIZE 255static struct char_device_struct {struct char_device_struct * ...
- linux驱动的中断函数,嵌入式Linux驱动开发(四)——字符设备驱动之中断方式以及中断方式获取按键值...
之前我们完成了关于通过查询的方式获取按键键值的驱动程序,可以参考:嵌入式Linux开发--裸板程序之中断控制器. 虽然读取键值没有什么问题,但是测试程序占用CPU过高,一直在不断的查询,资源消耗过大, ...
- 全志V3S裸机串口驱动(中断方式接收,DMA接收有问题,小于32字节数据无法触发DMA传输)
调试DMA接收遇到了个很奇怪的问题,就是DMA发送没问题,DMA接收的时候,如果数据小于32字节,数据被DMA从串口接收FIFO中取走了,但是并不会传输到指定的buff中,这个就没法用于接收未知长度的 ...
- 4412驱动-sixth_drv 同步互斥按键驱动
并发-信号量 阻塞与非阻塞 1. 原子操作 原子操作指的是在执行过程中不会被别的代码路径所中断的操作. 常用原子操作函数举例: atomic_t v = ATOMIC_INIT(0); //定 ...
- 【Linux驱动】input子系统与按键驱动
input子系统架构总览 在网上能找到一些关于input子系统架构相关的示意图,大体表达的意思都差不多. linux输入子系统(linux input subsystem)从上到下由三层实现,分别为: ...
- Linux之字符设备驱动框架
目录 一.驱动介绍 1.内核模块 2.日志级别 3.模块符号的导出 4.内核模块参数 二.字符设备驱动(一) 1.模块加载 2.注册字符设备驱动 3.内存映射 三.字符设备驱动(二) 1.模块加载 2 ...
最新文章
- LVS负载均衡群集的了解与基本配置(一)
- python 异步io_python之同步IO和异步IO
- 看完Andoird9.0 Pie的隐藏特性,我买了SSL证书
- 引导滤波的opencv实现以及解释
- java职业发展路线图_软开(Java),该如何规划职业路线?
- html快捷键_Mac进阶:掌握这 5 个冷门快捷键,让Mac更好用
- 5G 基站功耗,到底有多可怕?
- python 2 与 python 3 —— 转义及编码(\u, \x)
- EMNLP'21中预训练模型最新研究进展
- 上海黑马python培训
- 模拟停车场管理系统(栈和队列的应用)
- 小米VR一体机、Oculus Go投屏到PC、TV教程
- 瑞萨开发板编译和烧录
- python中用turtle画爱心表白
- js选中html的数字设置倒计时,JS实现的网页倒计时数字时钟效果
- 软件测试Selenium-API 操作(上机练习文档)分享
- sqlserver 下载地址(SQL Server 2008 R2 中英文 开发版/企业版/标准版 下载)
- php球鞋,行家啊?!这些球鞋外号你必须要知道!
- 网易云课堂Python数据分析实战前两章(跟小蚊子老师学数据分析)
- 人脸验证与二分类(Face verification and binary classification)
热门文章
- mysql出现1499错误_连接MySQL时出现1449与1045异常解决办法
- oracle 大页配置,ORACLE 启用大页内存
- 杭州中国移动java待遇_【中国移动杭州研发中心Java面试】移动杭研社招java中级面试-看准网...
- Python知识点4——if分支与while循环
- MFC创建属性表单“所需资源不存在”错误解决方法
- 两个不同网段的局域网如何互通_多台路由器,不同网段的设备之间如何互访?...
- bartlett方差齐性检验_R语言实用教程-数据正态性以及方差齐性检验
- 结对第2次作业——WordCount进阶需求
- SCCM2016 集成WSUS提供补丁服务(一)
- Visual Studio 2008 可扩展性开发(九):总结篇