0 回顾起初的目标
① 掌握裸机重定位(这有助于后续理解u-boot)
② 掌握裸机中断处理流程
③ 掌握Linux异常、中断处理体系
④ 编写Linux下的按键驱动程序
⑤ 掌握Linux中驱动和应用程序的交互方式:查询、中断-唤醒、poll、异步通知
下面我以这5点,概括梳理对应的知识点
1 知识梳理
对于前5个目标,我想以“思维导图”的方式展开,如下图
备注:忽略了一些知识点的展开,并概括总结了知识点
接着,提炼一些知识要点
1) 编写最基本的驱动程序框架(如LED/按键)如下
a. 编写驱动处理函数
b. 用file_operations结构体“关联”驱动处理函数
c. 在xxx_init 驱动程序入口函数用register_chrdev(设备号, 驱动名,&file_operations)注册
同理,在xxx_exit卸载函数里 unregister_chrdev(设备号, 驱动名)卸载驱动
d. 用module_init(xxx_init) 和 module_exit(xxx_exit) 进行模块初始化/卸载
e. 最后用MODULE_LICENSE(“GPL”) 声明模块的许可证为GPL
2)驱动程序的完善
a. 自动确定主设备号: major = register_chrdev(0, “led_drv”, &file_operations)
b. 自动创建设备节点
概括来说,在xxx_init驱动入口函数里class_create() 和 class_device_create()
在xxx_exit卸载函数里class_device_unregister() 和 class_destroy()
(备注:函数的具体用法可看内核或查阅博客,不需记住)
注意:上面是编写驱动程序的最基本的套路,除此之外,编写不同硬件的驱动程序,硬件操作不同
如对于按键中断驱动程序
在key_drv_open 里 需 request_irq(IRQ_EINT0,&key_irq,IRQT_BOTHEDGE,“s2”,&pins_desc[0]);
在key_drv_close 里 需 free_irq(IRQ_EINT0, &pins_desc[0]);
再如LED驱动程序
只需配置引脚用于输出,并操作引脚数据寄存器(GPFDAT等)即可
编写驱动程序的注意事项
1)驱动与用户程序之间数据交互用:copy_from_user 和 copy_to_user
2)驱动程序操作寄存器使用虚拟地址,需进行地址映射:即在xxx_init(…; ioremap(); …)
并在xxx_exit(…; iounmap(); …)
- 硬件中断处理
.text
.global _start
_start:
b reset
ldr pc, addr_und //设置 异常向量
ldr pc, addr_swi
.....
ldr pc, addr_irq
....
addr_und:
.word do_und
addr_swi:
.word do_swi
addr_irq:
.word do_irq
// 异常或中断的处理套路都一样
do_und/do_swi/do_irq/....
/* 执行到这里之前:
* 1. lr_xxx保存有被中断模式中的下一条即将执行的指令的地址
* 2. SPSR_xxx保存有被中断模式的CPSR
* 3. CPSR中的M4-M0被设置为XXX, 进入到xxx模式
* 4. 跳到XXX的地方执行程序
*/
/* sp_xxx未设置, 先设置它 */
ldr sp, =0xXXXX
>>> 1.保存现场
/* 在xxx异常处理函数中有可能会修改r0-r12, 所以先保存 */
/* lr是异常处理完后的返回地址, 也要保存 */
// sub lr, lr, #4 对于不同模式引发的异常,lr需相应减去某一值或不用减
stmdb sp!, {r0-r12, lr}
>>> 2.处理异常
bl xxxx(异常处理函数-->1.分辨中断源 2.调用对应处理函数 3.一些清理工作 4.中断返回)
>>> 3.恢复现场
ldmia sp!, {r0-r12, pc}^ /* ^会把spsr的值恢复到cpsr里 */
4)硬件操作
如UART、SDRAM、Timer等查看手册即可。
其实,硬件操作不同开发板的寄存器操作肯定不同,但是套路都是一样的
1)看原理图,确定操作对象
2)查手册,明确编程步骤
3)编写代码
4)测试 + 调试
下一阶段的目标:
目标:掌握输入子系统驱动开发、掌握Framebuffer驱动开发、掌握基本APP编程能力
① 学习裸机触摸屏编程(只要求理解原理,不要求能写出来)
② 编写Linux输入子系统驱动开发:按键、触摸屏
③ 学习裸机LCD编程(只要求理解原理,不要求能写出来)
④ 编写Linux下的LCD Framebuffer驱动
⑤ 练习Linux下APP编程