首先在编写linux设备驱动程序的时候需要一些基本的技术基础如下:
1,编写驱动时首先自己需要对HW有个较好的认识,比如一些常见的SRAM, Flash,SDRAM,磁盘的读写方式,UART,i2c,USB等设备接口的通信原理,pulling,interrupt,DMA的原理,PCI的工作方式,以及cpu 里的MMU的工作方式等。
2,比较特别需要注意的也是最基本的,需要了解多任务时的并发控制与同步,比如自旋锁,互斥,信号量,等待队列等,关于这部分,我觉得如果对linux C lib中的多线程编程了解的话应该,比较好理解这块。
3,其实如果要希望能了解知道对应设备的具体配置信息,跟通信方式,还有点重要的要了解,关于这块子模块系统的连接方式,关于这部分还是需要自己多去看看source code。
驱动设计的硬件基础
首先来从Cpu大概的了解开始。
1.1什么叫通用处理器,也就是简单称为GPP.
GPP 是用来不针对特定领域进行体系结构跟指令集的优化,它具有一般通用的体系结构跟指令集,支持复杂的运算,并有利于对新功能的添加。
一般而言在嵌入式微控制器(MCU)和微处理器(MPU)中都会包含一个GPP。
1.2 什么叫微处理器,也就是简单称为MPU.
所谓的MPU通常都是代表一个CPU.
1.3 什么叫微处理器,也就是简单称为MCU.
MCU强调把一个cpu,存储器,跟外围电路集成在一个芯片中。早期把MCU都称其为单片机,MCU也有叫片上系统(SOC),含义是在片上设计了整个系统。
对于不同的产品可能有相同的CPU,但是集成的扩展电路不一样。以下是一般MCU的结构图。
目前比较主流的CPU如下:
1,Advanced RISC Machines 公司的ARM
ARM的功耗很低,正因为如此才在移动设备中应用的非常广泛。
2,Silicon Graphics 公司的MIPS
两个最重要的MIPS芯片厂商为PMC和IDT。PMC公司的MIPS处理器被CISCO公司大量采用在高端路由器上,IDT公司在MIPS上集成了PCI接口,广泛用于以太网交换。
3,IBM喝Motorola的PowerPC
ppc 处理器是通信和工控领域应用最广泛的处理器,国内包括华为中兴在内的通信公司都大量的使用PowerPC.
CPU的体系架构类别可分为两类:
1.1 冯若依曼结构,
也称为普林顿结构,是将程序指令存储器跟数据存储器合并在一起的存储结构,程序指令存储位置跟数据存储位置,指向在同个存储器的不同位置,因此带宽是相同的。
1.2 哈佛结构。
哈佛结构刚好是相反分开存储的,所有他们都有各自的带宽,采用了不同的程序总线跟数据总线,作为CPU与存储器之间的专用通道,有较高的执行效率。
如下图是两者之间的图表。
从指令集的角度划分,可分为RISC(精简指令集)和CISC(复杂指令集),目前ARM,MIPS,PowerPC都是用RISC。
数字信号处理器(DSP)
DSP 是专门针对通信,图像,视频和语音处理等算法而设计,它包含了独立的硬件乘法器,优化了诸多算法中的大量重复运算。
DSP 一般采用如下图所示的改进过的普林斯顿结构,它具有独立的数据跟地址总线,两条总线有程序存储器跟地址数据存储器分时共用,
DSP可分为两类:一类是定点DSP,一类是浮点DSP。浮点DSP的浮点运算用HW来实现,可以在单周期内完成,因此浮点DSP的速度要高于定点DSP,而定点DSP只能用定点运算来模拟浮点运算。
通用处理器也有跟DSP也有相互融合取长补短的趋势,如数字信号处理器(DSC)即为MCU+DSP,
关于之前提到的处理器相关的结构关系可以如下图所示:
关于存取器的有关介绍
存取器可以分为如下几种:
1.1 只读存取器(ROM)
1.2 闪存(Flash)
1.3 随即存取存取器(RAM)
1.4 光介质存取器
1.5 磁介质存取器
ROM可以分为,不可编程ROM,可编程ROM(PROM),可擦除可编程ROM(EPROM),电可擦除可编程ROM(E2PROM),E2PROM完全可以用软件来实现擦写已经非常方便了;目前ROM有被闪存(Flash)取代的趋势,目前NOR(或非)和NAND(与非)是市场上两个种主要的闪存技术。
NOR Flash跟CPU接口类SRAM接口,程序可以直接在NOR Flash 内执行,而NAND Flash 跟CPU 必须由一个Flash 控制器来进行转换,它不支持在芯片内执行程序。
典型的类SRAM的接口如下图所示:
首先在这里先大概的介绍下NAND Flash在下篇关于NAND Flash驱动我会对这部分做更详细的介绍。
Flash的主要接口包括如下:
1.1 I/O端口:地址,命令跟数据都要经过这几条总线传到Flash controler那里,一般有8条或者是16条。
1.2 chip enable (CE#)该端口用来设置IC是否处于待机模式。这里的‘#’一般表示为低有效,有些电路图上是用上划线来表低有效的。没标注的一般都是表示高有效。
1.3 Write enable (WE#)该gpio口是用来表示当前是写入状态可用。
1.4 Read enable (RE#)该口是用来便是当前是读出是否可用。拉低表示可以读取,但是一般都是要等待R/B这个位拉高后(也就是等Flash Controler 把RAM中的buffer写入到NAND flash之后再可以去读数据)
1.5 Command Latch enable(CLE)当CLE高时表示告诉 Flash Controler当前通过 I/O端口传过去的是命令数据。
1.6 Address Latch enable(ALE) 当ALE高时表示告诉 Flash Controler当前通过 I/O端口传过去的是列/行的地址数据。
1.7 Ready/Busy (R/B#) 如果为低,表示当前的设备都处于忙的状态,比如可能当前Flash Controler正接收到刚通过I/O口传过来的命令跟地址数据请求后,在从NAND Flash中拷贝数据到RAM中。等copy完之后controler自动会拉高,告诉主控来从RAM中取数据。
NAND flash每个快的擦写都有限制一般都是100W次,NAND Flash的擦除,编程速度远远大于NOR Flash。
NAND Flash的编程原理是,只能将1变成0,但是不能把每个单元里面的由0变成1,所以每次的擦除动作实际上都把所有的单元都编程为1即为0xFF。
许多嵌入式系统都提供了IDE(Integrated Driv Electronics)接口,以供连接硬盘控制器跟光盘。IDE的接口信号跟SRAM的类似。通常把IDE接口称为ATA(advanced technology attachment)。
以上所介绍的存取器都是属于非易失性存储器(NVM)掉电时信息并不会消失,但是RAM正好相反。
以下介绍RAM有关的信息。
RAM可以分为静态的RAM(SRAM)跟动态的RAM(DRAM).
DRAM是以电荷形式进行存储的,数据存储在电容器中,电容器会漏电,导致电荷会丢失,所以要定期的进行刷新。SRAM是静态的,只要供电它就会一直保存一个值,不需要进行刷新,DRAM由一个晶体管跟一个电容器组成,而SRAM由6个晶体管组成。
通常所讲的SDRAM ,DDR SDRAM都属于DRAM的范畴,他们采用跟CPU外存同步的时钟工作,不是CPU的工作频率。
同时DDR SDRAM同时利用时钟脉冲的上升沿跟下降沿来传输数据,因此在时钟频率不变的情况下,数据传输频率会加倍。
非易失性的RAM(NVRAM)
所谓的NVRAM其实也是RAM,只是借助了外界的一些条件,比如有备用电源的SRAM,或者借助E2PROM来帮忙记忆 SRAM中得一些信息。只是少了E2PROM跟Flash的擦除跟编程操作。
双端口RAM(DPRAM)
DPRAM的特点是同时可以有两个端口进行访问,具有两套完全独立的数据总线,地址总线,读写控制总线,通常是用于两个CPU之间的数据交互,当一端写入数据,另外一端CPU通过polling/interrupt去取数据,
由于访问数据的仲裁在HW内部已经完成了。
关于它的结构如下:
内容比较RAM(CRAM)
CRAM是按内容进行寻址的寄存器,主要的工作流程是,通过输入的数据项与之前存在CRAM中得数据项进行比较,判断该数据项是否与存入的CRAM数据项匹配,如果匹配则输出该匹配信息。
如下图所示,根据输入数据项进行匹配,然后输出匹配对应的数据地址跟标志。由于这部分是由HW来实现的所以比起软件来说可以极大的提供系统的性能。
先进先出队列存储器(FIFO)
FIFO的特点是先进先出,进出有序,FIFO多用于数据的缓存。跟DPRAM一样有连个访问端口,但是都不是对等的,在某一时刻只能设置某一端为输入,另外一端为输出。
如果FIFO的区域共有n个字节,那么只能在同个地址,循环读取n次才能把所有的数据读出,不能指定偏移地址。当这次读取m个字节,那么在下次就读取m+1个字节。
关于存储器的介绍大概就说到这里,以后会根据具体的设备做驱动时进行说明。下图是关于这部分的总结:
接口和总线。
ISA总线
ISA的信号可分为三组:
1.1总线的基本信号:包含了总线要工作的基本的信号,比如reset,vdd,gnd还有clock等。
1.2 总线的访问信号:用于访问ISA总线设备的地址线,数据线以及相应的应答信号。
1.3 总线的控制信号:中断跟DMA请求。
如下图的详细的信号线介绍如下:
1.1 RESET,BCLK 复位跟基本的clock ,BCLOCK一般都是8MHZ
1.2 SA19~SA0 存储器及I/O空间的20位地址,带锁存。
1.3 LA23~LA17 存储器及I/O空间的20位地址,不带锁存。
1.4 BALE 总线地址锁存。
1.5 AEN 地址允许,表明CPU退出总线,DMA开始。
1.6 SMEMR#~ SMEMW# 8位ISA存储器读写控制。
1.7 MEMR#~MEMW# 16为ISA存储器读写控制。
1.8 SD15~SD0 数据总线,访问8位ISA卡时,高八位自动通过SD7~SD0来传输。
1.9 SBHE# 高字节允许,打开SD15~SD8数据通路
2.0 MEMCS16#,IOCS16#:ISA 卡发送次信号确认可以进行16位传输了。
2.1 I/OCHRDY :ISA准备信号,可控制插入等待周期。
2.3 NOWS有效暗示不用插入等待周期。
2.4 I/OCHCK ISA卡奇偶校验错误。
2.5 IRQ15,IRQ14,IRQ12~IRQ9,IRQ7~IRQ3:中断请求。
2.6 DRQ7~DRQ0 ISA DMA请求信号。
2.7 DACK7~DACK0 DMA请求响应信号。
2.8 MASTER# ISA 住模块确定信号,ISA通过发送次信号 与主机内的DMA 控制器,配合使ISA卡成为主模块。
PCI和cPCI
PCI 具有如下的特点:
1.1数据总线32位,可扩充到64位。
1.2 可进行突发(burst)模式传输(突发模式表示取得总线控制权之后,连续发送多个数据的传输,只需要给出目的的首地址,访问第一数据后,第2~n个数据会在首地址的基础上按一定规则自动被寻址传输,与之相反的就是单周期模式,一个周期传输一个数据)。
1.3总线时钟频率一般为33MHZ和66MHZ,最高传输达528MHZ/s
1.4中央集中式总线仲裁。
1.5 支持全自动配置,自动分配资源,PCI卡内有设备信息寄存器组,为系统提供卡的基本信息。可实现即插即用。
1.6 PCI总线规范独立于微处理器,通用性好。
1.7 PCI设备可以完全作为主控设备控制总线。
下图是个比较完典型的PCI总线的逻辑图表,
系统的各个不叫通过PCI总线跟PCI-PCI桥连接在一起,RAM跟CPU通过PCI桥来连接PCI总线0即主PCI总线,有相应的PCI接口的设备可以直接接到PCI总线上,
两个PCI总线通过PCI-PCI桥来连接在一起,PCI总线0称为上游,其他的称为下游,为了兼容之前的ISA总线标准,PCI总线还可以通过PCI-ISA桥来连接ISA总线或ISA接口设备。
PCI卡在加电的时候,卡上只有配置空间是可以访问的,因而开始时不能由驱动或者用户进程访问,ISA卡正好相反,其中ISA卡的配置空间保存了,该卡工作所需的所有信息,如厂家,卡功能,资源要求,处理能力等。通过对该卡的这个配置空间信息的读取跟编程,可以完成对PCI卡的配置。
该配置空间的共为256个字节,主要包括如下信息:
1.1 制造商标识(Vendor ID):由PCI组织分配给厂家。
1.2 设备标识(device id):按产品分类给本卡的编号。
1.3 分类码(Class code):本卡功能的分类码,如图卡,显示卡,解压 卡等。
1.4申请存储器空间:PCI卡内有存储器或有基于存储器编址的寄存器和I/O空间,为使驱动访问他们,需要在CPU的一段存储区域进行定位。配置空间的基地址寄存器就是用于次目的。
1.5 申请I/O空间:配置寄存器的基地址寄存器也用来进行系统I/O空间的申请。
1.6 中断资源申请:配置空间的中断pin用来向系统分配中断资源。
PCI总线上得信号大体可分为如下几组:
系统接口信息:
地址跟数据接口信息:
接口控制信息:
仲裁信息:
中断接口信息:
其他接口信息:
以上信息的详细定义如下:
CLK:系统时钟。
AD31~AD0:地址跟数据复用信号线信号
C/BE3~C/BE0:总线命令和地址使能命令
PAR:奇偶校验信息
FRAME#:帧周期信号,指示总线操作起始跟终止。
IRDY#:主设备准备好信息。
TRDY#:目标设备准备好信号
STOP#:目标设备要求终止当前数据传输信号。
DEVSEL#:目标设备选中信号。
IDSEL:配置空间读写时的片选信号。
LOCK#:总线锁定信号。
RST:复位信号
INTA#INTB#INTC#INTD#:中断请求
REQ#,GNT#:PCI总线请求与仲裁后的授权。
AD63~AD32,C/BE7~C/BE4等,用于扩展64位总线。