4412 驱动认识总结
一、QQ聊天记录总结
- 对于所有的驱动设备Linux看来都是文件,这些文件都有固定的接口,read、write、open、ioctl、close等,包含在struct fileoptions中。
- 通过设备文件的主设备号和次设备号,让应用程序调用。驱动写的是主设备号的功能,置于类似功能的设备用次设备号区分。
- 然后函数接口和设备文件通过,linux特定的函数注册。如字符设备是register_chrdev等等。
- 桥接之后,应用层可以用open调用内核的open函数
二、Linux驱动程序的基本认识
Linux驱动包含三种:字符设备驱动、块设备驱动、网络设备驱动。理解和掌握字符设备驱动是更重要的
Linux驱动程序讲解的步骤 :
- GPIO(General Purpose Input Output Port),通用输入输出口
- 内存管理单元(MMU)
- Linux把设备看成了文件( open, read, write, ioctrl,close)
- Linux字符设备驱动的编程思想:做一组设备对应的驱动函数
- 设备节点(设备文件)
- 举例说明上层应用程序如何对某个外设进行操作
- 举例说明底层驱动的编写方式以及如何注册到系统(register_chrdev())
- MISC杂项设备(混杂设备)
- 模块(module)
学习编写驱动需要:
• 学会查看开发板原理图
• 学会查看处理器的数据手册(datasheet)
• 对外部设备操作的步骤(三部曲)
– 通过原理图找到设备连接的PIN脚
– 根据该PIN脚找到控制这个引脚的相关寄存器,并找到寄存器对应的物理地址
– 最后,通过编写程序来实现对该设备的操作
比如led0的管脚在底板中叫KP_COL0,对应到核心板管脚叫KP_COL0,对应带4412管脚是AA4(GPL2_0)
然后相关的寄存器有GPL2CON、GPL2DAT、GPL2PUD、GPL2DRV、GPL2CONPDN、GPL2PUDPDN。了解了寄存器功能,就可以写函数对此控制了
嵌入式控制芯片地址的方式:
0x11000104 ----比方说有一个地址 unsigned int *pintx; ----定义一个32位的指针地址 pintx = 0x11000104; ----给地址指针赋值 *pintx = 0; ----对地址的内容吸入数据 *((unsigned int *)0x11000104) = 0; ----同样的可以直接这样写
- RISC(精简指令集)/CiSC(复杂指令集)
精简指令集的指令长度和运行时间都是一样的。
- RISC便于实现指令流水线
可以使一些需要计算机处理的多项操作在时间上重叠进行,便于提高电路的工作频率
• Memory Management Unit(MMU)
• 虚拟地址到物理地址的转换
– 如何通过物理地址找到虚拟地址呢?(ioremap)
• 辅助实现虚拟内存
• 辅助实现多任务管理
虚拟内存
处理器有了MMU,那么就有了虚拟内存的概念
虚拟存储器的空间大小取决于计算机的访存能力而不是实际外存的大小。 - 32位 2^32 = 4G
使存储系统既具有相当于外存的容量又有接近于主存的访问速度。 - 硬盘 EMMC FLASH
如何评价处理器
• 频率
• 性能 (MIPS/MHz)
– ARM7 处理速度为0.9MIPS/MHz,常见的主时钟一般为20MHz-133MHz
– ARM9 处理速度为1.1MIPS/MHz,常见的主时钟一般为100MHz-233MHz
– CORTEX-A9处理速度2.5 MIPS/MHz,主时钟一般为1000MHz-1600MHz
• 功耗
• 面积(成本)
三、Linux内核基础
Linux体系结构
• 从程序员的角度分析
– 将linux底层和应用分开,做应用的做应用,做底层的做底层,各干各的。经济学的原理是,分工产生效率
• 从安全性的角度分析,为了保护内核。现代CPU通常都实现了不同的
工作模式。以ARM为例:ARM实现了7种工作模式,不同模式下CPU可以执行的指令或者访问的寄存器不同:
– (1)用户模式 usr (2)系统模式 sys(3)管理模式 svc(4)快速中断 fiq(5)外部中断 irq(6)数据访问终止 abt(7)未定义指令异常
– 以(2)X86为例:X86实现了4个不同级别的权限,Ring0—Ring3 ;Ring0下可以执行特权指令,可以访问IO设备;Ring3则有很多的限制
– 以Android为例:将应用放到Java虚拟机上面运行,应用更加远离底层
• 用户空间和内核空间是程序执行的两种不同状态,我们可以通过“系统调用”和“硬件中断“来完成用户空间到内核空间的转移
Linux内核结构
• System Call Interface (SCI层)
– 为用户空间提供了一套标准的系统调用函数来访问Linux内核。
• Procees Management(PM)
– 进程管理是创建进程(fork、exec),停止进程(kill、exit),并控制他们之间的通信(signal等)。还包括进程调度,控制活动进程如何共享CPU
• Memory Management(MM)
– 内存管理的主要作用是控制多个进程安全的共享内存区域
• Virtual File Systems(VFS)
– 虚拟文件系统,隐藏各种文件系统的具体细节,为文件操作提供统一的接口
– Linux提供了一个大的通用模型,使这个模型包含了所有文件系统功能的集合(一切皆文件)
• Device Drivers设备驱动
– Linux内核中有大量的代码在设备驱动程序部分,用于控制特定的硬件设备。
– Linux驱动一般分为网络设备、块设备、字符设备、杂项设备
• 网络协议栈
– 内核网络协议栈为Linux提供了丰富的网络协议实现。
Linux内核源码目录结构
• arch目录
– arch目录是平台目录。内核支持的所有CPU架构,在该目录下都有对应的子目录。每个CPU的子目录,又进一步分解为boot,mm,kernel等子目录,分别控制系统引导,内存管理,系统调用。还有动态调频,主频率设置部分等
• Linux很复杂,很强大。
– 内核源码解压编译后有1.3G,通过裁减编译出的linux镜像zImage不到4M
– 4M源码镜像中,还有大部分不用我们关心
– 我们只需要了解对写代码有帮助的部分,掌握我们需要掌握的代码
– 前面Linux代码中只有红色标记的一部分是需要了解或者掌握的
• 作为开发者只需要学会使用它,我们要重点学习只是其中很小的一部分。
– 对架构有一定的了解即可
– 学习的重点是驱动开发相关的知识、函数的调用、驱动的协议、简单的硬件知识