




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
uClinux功能扩充和应用Wax526@163.com设备驱动管理添加新设备扩展LCD做系统输出T6963Clcd
控制器介绍T6963C与目标板的连接与工作原理部分源代码分析主要内容设备驱动管理Linuxdevicedriver的概念驱动driver司机ApplicationsInvokeEOSHardwaredriverLinuxdevicedriver的概念系统调用是操作系统内核和应用程序之间的接口,设备驱动程序是操作系统内核和机器硬件之间的接口,设备驱动程序为应用程序屏蔽了硬件的细节,这样在应用程序看来,硬件设备只是一个设备文件,应用程序可以象操作普通文件一样对硬件设备进行操作.Linuxdevicedriver的概念Linux设备字符设备串口显示器打印机…硬盘磁盘光盘…块设备网络设备各种网络接口…Linuxdevicedriver的概念设备号主设备号:从设备号:
唯一标识了设备类型,即设备驱动程序类型
标识使用同一个设备驱动程序的不同硬件例如:主设备号是3的块设备是IDE磁盘驱动程序,而主设备号为8的块设备是SCSI磁盘驱动程序。303132Linuxdevicedriver的概念字符设备和块设备的主要区别是:
在对字符设备发出读/写请求时,实际的硬件I/O一般就紧接着发生了,块设备则不然,它利用一块系统内存作缓冲区,当用户进程对设备请求能满足用户的要求,就返回请求的数据.Linuxdevicedriver的概念块设备是主要针对磁盘等慢速设备设计的,以免耗费过多的CPU时间来等待.
用户进程是通过设备文件来与实际的硬件打交道.每个设备文件都有其文件属性(c/b),表示是字符设备还是块设备Linuxdevicedriver的概念设备文件的的主设备号必须与设备驱动程序在登记时申请的主设备号一致,否则用户进程将无法访问到驱动程序.Linuxdevicedriver的概念设备驱动程序是内核的一部分,它完成以下的功能:1.对设备初始化和释放.2.把数据从内核传送到硬件和从硬件读取数据.3.读取应用程序传送给设备文件的数据和回送应用程序请求的数据.4.检测和处理设备出现的错误.设备驱动程序的框架LINUX的设备驱动的接口可分为三部分与内核接口:通过file_operations来完成。与系统启动代码的接口:对设备进行初始化。与设备的接口:即对设备的读写等操作。Linux设备驱动的开发为LINUX内核编写驱动程序,所要做的只是为相应的设备编写几个基本函数并进行注册即可。当上层应用要使用该设备时,就会调用相应的设备函数。设备驱动多数是基于中断的(安装中断处理函数,即注册对应中断向量表,使用LINUX提供的注册函数request_irq);但也有基于轮询方式的。
Linux设备驱动的开发外设I/O空间编址根据内存空间是否独立,可以将I/O空间的配置分为两种情况:一种是I/O空间与内存空间相互独立,这样I/O空间的访问需要使用专门的I/O语句。另一种是将I/O寄存器作为内存的一部分,这样使用普通的内存访问语句就可以读写I/O寄存器。Linux设备驱动的开发模块支持标准PC上的LINUX可以以模块的形式加载各种类型的设备。要求在设备驱动中编制两个入口点:Module
init();Module
exit();Linux设备驱动的开发内核空间与用户空间设备驱动编程实际就是对LINUX内核编程,设备驱动都是以内核态在内核空间运行。若驱动代码编制不良,就会导致整个系统死掉设备驱动程序接口LINUX把每一个设备都当作一个特殊文件对待,存放在/dev/目录下。输入输出子系统向内核其它部分提供了一个统一的标准设备接口。这是通过数据结构file_operation(include/linux/fs.h)。Linux设备驱动的开发设备驱动程序接口(include/linux/fs.h)struct
file_operations{ …ssize_t(*read)(structfile*,char__user*,size_t,loff_t*); ssize_t(*write)(structfile*,constchar__user*,size_t,loff_t*); int(*readdir)(structfile*,void*,filldir_t); int(*open)(struct
inode*,structfile*); int(*flush)(structfile*); int(*release)(struct
inode*,structfile*);…….};Linux设备驱动的开发每个字符设备用结构char_device_struct来描述,所有的字符设备组成数组chrdevs:staticstruct
char_device_struct{ struct
char_device_struct*next; unsignedintmajor; unsignedint
baseminor; …… charname[64]; struct
file_operations*fops; ……}*chrdevs[CHRDEV_MAJOR_HASH_SIZE];数组chrdev[]在字符设备管理中处于核心地位。Linux通过该数组组织起MAX_CHRDEV个char_device_struct结构,主要功能就是记录相关设备的名称以及对应的设备操作函数接口,major编号就是对应结构的数组下标。初始化注册一个字符设备register_chrdev()(fs/char_dev.c)register_chrdev(unsigned
int
major,constchar*name,struct
file_operations*fops)int
register_chrdev(unsigned
intmajor,constchar*name,conststruct
file_operations*fops){ struct
char_device_struct*cd;
struct
cdev*cdev; char*s;
interr=-ENOMEM;
cd=__register_chrdev_region(major,0,256,name); if(IS_ERR(cd)) returnPTR_ERR(cd);
cdev=cdev_alloc(); //分配一个cdev对象空间 if(!cdev)
gotoout2;
cdev->owner=fops->owner;
cdev->ops=fops;
kobject_set_name(&cdev->kobj,"%s",name); for(s=strchr(kobject_name(&cdev->kobj),'/'); s; s=strchr(s,'/')) *s='!'; err=cdev_add(cdev,MKDEV(cd->major,0),256); if(err) gotoout;
cd->cdev=cdev; returnmajor?0:cd->major;out: kobject_put(&cdev->kobj);out2:
kfree(__unregister_chrdev_region(cd->major,0,256)); returnerr;}staticstruct
char_device_struct*__register_chrdev_region(unsignedintmajor,unsignedint
baseminor,int
minorct,constchar*name){ struct
char_device_struct*cd,**cp; intret=0; inti; cd=kzalloc(sizeof(struct
char_device_struct),GFP_KERNEL); if(cd==NULL) returnERR_PTR(-ENOMEM); mutex_lock(&chrdevs_lock); /*temporary*/ if(major==0){ //如果参数major为0动态分配一个major for(i=ARRAY_SIZE(chrdevs)-1;i>0;i--){ if(chrdevs[i]==NULL) break;} if(i==0){ ret=-EBUSY;
gotoout; } major=i; ret=major; } cd->major=major; cd->baseminor=baseminor; cd->minorct=minorct; strncpy(cd->name,name,64); i=major_to_index(major);
for(cp=&chrdevs[i];*cp;cp=&(*cp)->next) if((*cp)->major>major||((*cp)->major==major&&(*cp)->baseminor>=baseminor)) break; if(*cp&&(*cp)->major==major&&(*cp)->baseminor<baseminor+minorct){ret=-EBUSY;gotoout; } cd->next=*cp; *cp=cd; //将设备加入chrdev数组mutex_unlock(&chrdevs_lock); returncd;out: mutex_unlock(&chrdevs_lock);kfree(cd); returnERR_PTR(ret);}Linux下添加设备驱动Linux下添加字符设备基本步骤1确定设备的设备名和主设备号2确定编写需要的初始化函数和退出函数3确定并编写需要的file_operations中的操作函数4修改drivers/char/Makefile5将该设备私有的*.c,*.h复制到目录drivers/char下6重新编译内核7用mknod命令在目录/dev下建立相应主设备号用于读写的特殊文件所以添加设备驱动的工作为:设备初始化函数,一般为xxx_init
,在这些初始化函数中要完成如下工作:填充file_operations数据结构,指定要实现向上提供的接口操作。实现file_operations指定的接口操作函数。并以此为参数,用register_chrdev
和register_blkdev
向操作系统注册。实际上就是向内核注册一个设备文件(主设备号/次设备号)及其一系列标准操作接口。注册的工作就是向LINUX管理的设备链表中加入一个节点。构建设备驱动程序的大部分代码,即通常要实现的操作,如open,read,write,ioctl
等设备驱动的开发设备驱动编程注意事项库函数使用由于内核是个自我封闭的系统,无法使用libc
中提供的标准库函数,内核重新封装实现了一些常用的库函数,如字符串操作,memcpy
等,这都是经过多人高度优化的代码,可读性不是很强,但性能却是最佳,这也正是内核所追求的。内存分配内核态下编程也要使用栈,即内核栈,只有8K大小。且一旦栈溢出,就可能会导致内核崩溃。因此使用栈一定要小心。对于大数组使用,应该用静态变量或分配到堆上。设备驱动的开发I/O空间检查在为设备分配要使用的I/O地址时,需要检查该地址空间是否已经被其它设备所占用。设备驱动的开发
睡眠唤醒队列interruptible_sleep_on在设备驱动代码中经常遇到要等待数据到达的情况,如DMA操作,但内核态不能陷入死循环等待,它必须要处于这样一种状态:等待但又不占用CPU。LINUX支持这种工作模式,驱动程序处于睡眠状态并交出CPU,这时该进程被放入一个睡眠等待唤醒队列。在中断处理程序中有数据到达时,就从队列中找到该进程并唤醒之。设备驱动的开发设备的中断轮询方式要做在应用程序层,只有采用中断方式的设备驱动才需要在内核中完成。一般的,可以在打开设备或初始化设备时调用request_irq注册一个中断,在关闭设备时调用free_irq
注销这个中断。实现file_operations指定的接口操作函数。初始化、注册等操作完成后,才开始真正构建设备驱动程序的大部分代码,即通常要实现的操作,如open,read,write,ioctl
等。设备驱动的开发最后必须提到的是,在用户进程调用驱动程序时,系统进入核心态,如果你的驱动程序陷入死循环,不幸的是你只有重新启动机器了实例剖析我们来写一个最简单的字符设备驱动程序.虽然它什么也不做,但是通过它可以了解Linux的设备驱动程序的工作原理.实例剖析(1)建立驱动主程序,存为test.ctest.c实例剖析 (2)makefile文件:
Makefile实例剖析
在命令行输入make编译驱动程序,现在把它安装到系统中去。
$insmod
test.ko
如果安装成功,在/proc/devices文件中就可以看到设备test,并可以看到它的主设备号。要卸载的话,运行
$rmmodtest当一个模块设备驱动被加载到内核时,通常要做的事情包括:设备复位,初始化RAM,初始化中断,初始化输入/输出端口,等。
这些动作在内核空间进行,通过module_init
和module_exit进行;它们和用户空间的用于安装和卸载模块的命令insmod
和rmmod对应。也可以说,用户空间的命令insmod
和rmmod使用内核空间的函数module_init和module_exit进行。实例剖析
下一步要创建设备文件。
mknod/dev/testcmajorminor
其中c是指字符设备,major是主设备号,就是在/proc/devices里看到的。
minor是从设备号,设置成0就可以了。如:mknod/dev/testc470实例剖析我们现在可以通过设备文件来访问我们的驱动程序。写一个小小的测试程序。testAccess.cuClinux驱动移植下面我们将上述的驱动实例移植到uClinux中:1将模块方式改为静态链接方式mydev.cuClinux驱动移植2在drivers/char/mem.c
中添加相应语句;在chr_dev_init函数之前添加mydev_init的原型说明:
voidmydev_init(void);(2)在chr_dev_init函数的return语句之前添加以下语句:
mydev_init();uClinux驱动移植3修改drivers/char/Makefile;
找到“L_OBJS:=tty_io.o
n_tty.o
console.o”
将mydev.o
加入其中uClinux驱动移植4将设备私有的*.c,*.h复制到目录drivers/char/下。5重新编译内核;uClinux驱动移植6.在目录/dev下建立相应的设备文件。
mknod
mydevcmajorminor重温uClinux应用程序开发mydevtest.c练习GPIO控制的LED驱动扩展LCD做系统输出T6963Clcd
控制器介绍T6963Clcd
控制器介绍T6963C的基本特点:T6963C是点阵式液晶图形显示控制器T6963C可以显示四种字体:5×8点阵,6×8点阵,7×8点阵和8×8点阵T6963C占空比为1/16-1/128T6963Clcd
控制器介绍T6963C可以图形方式、文本方式及图形和文本合成方式进行显示,以及文本方式下的特征显示,还可以实现图形拷贝操作T6963C具有128字符的内部发生器CGROM,并可以管理64k显示缓冲区及字符发生器CGRAMT6963Clcd
控制器介绍内置T6963C的图形液晶显示模块有两种连接方式:直接访问方式间接控制方式T6963Clcd
控制器介绍引脚名引脚号状态描述T6963C与MPU接口的引脚D0-D710-17三态T6963C与MPU接口的数据总线/WR,/RD18,19输入写、读选通信号,低电平有效/CE20输入T6963C的片选信号,低电平有效C/D21输入通道选择信号:1为指令通道,0为数据通道T6963Clcd
控制器介绍功能描述地址指针计数器 地址计数器是一个16位的计数器。作为当前选择的显示存储器的地址寄存器。该计数器具有自动增一和自动减一功能图形地址计数器图形地址计数器是一个16位的计数器。作为显示扫描时图形显示区的扫描地址。该计数器具有自动增一和自动减一的功能。T6963Clcd
控制器介绍文本地址计数器文本地址计数器是一个16位的计数器。作为显示扫描时文本显示区的扫描地址。该计数器具有自动增一和自动减一的功能。CGRAM偏置地址寄存器
CGRAM偏置地址寄存器是一个5位的寄存器。作为自定义字符库的高5位地址指针指定自定义字符在显示存储器中的区域。T6963Clcd
控制器介绍T6963C的指令有的带一个参数、有的带两个参数,也有的不带参数。每条指令的执行都是先传送参数,在传送命令代码,并且每次操作之前都要检测状态字。T6963Clcd
控制器介绍指令名控制信号指令代码
CD/RD/WRd7d6d5d4d3d2d1d0读状态字
101S7S6S5S4S3S2S1S0设置寄存器
11000100N2N1N0设置控制字
110010000N1N0设置显示模式
1101000CGN2N1N0设置显示状态
1101001N3N2N1N0选择光标形状
11010100N2N1N0设置数据自动读写
110101100N1N0设置数据读写
11011000N2N1N0位操作
1101111N3N2N1N0数据写操作
010数据数据读操作
001数据T6963Clcd
控制器介绍CDRDWRd7d6d5d4d3d2d1d0101S7S6S5S4S3S2S1S0读状态字(STATUSREAD)T6963Clcd
控制器介绍T6963C的状态字由七个标志位组成,它们是:S0(STA0) 指令读写状态 1:准备好0:忙S1(STA1) 数据读写状态 1:准备好0:忙S2(STA2) 数据自动读状态 1:准备好0:忙S3(STA3) 数据自动写状态 1:准备好0:忙S4(STA4) 未用 S5(STA5) 控制器运行检测可能性 1:可能0:不能S6(STA6) 屏读/屏拷贝出错状态 1:出错0:正确S7(STA7) 闪烁状态检测 1:显示0:关显示T6963Clcd
控制器介绍在读写数据前必须要检测状态。这七个标志位的意义不同,应用的场合也不同,它们并非同时有效。在计算机写指令或一次读/写数据时,要求S0和S1同时有效,即“准备好”状态;当计算机使用自动读/写功能时,计算机要判别S2和S3是否有效;设置寄存器D1,D2CDRDWRd7d6d5d4d3d2d1d011000100N2N1N0D1D2指令代码十六进制功能水平方向位置垂直方向位置0010000121H设置光标指针数据00H0010001022H设置偏移地址寄存器低地址高地址0010010024H设置地址指针T6963Clcd
控制器介绍设置控制字(CONTROLWORDSET)CDRDWRd7d6d5d4d3d2d1d0110010000N1N0该指令是双参数指令,它将在显示存储器内划分出各显示区域的范围。它是由设定显示区域的首地址和宽度来确定该显示区域的范围,同时也确定了显示存储器单元与显示屏上各点像素的对应关系。
T6963Clcd
控制器介绍D1D2N1N0指令码功能低字节高字节0040H设置文本显示区首地址字节数00H0141H设置文本显示区宽度低字节高字节1042H设置图形显示区首地址字节数00H1143H设置图形显示区宽度T6963Clcd
控制器介绍⑴设置文本显示区首地址D1-D2-40H
该指令设置文本显示区在外部显示存储器中的起始地址。该地址对应显示屏上左上角的第一个字符位(home)。定时定间隔地修改该地址会产生显示画面的平滑滚动。参数D1为该地址的低8位,D2为该地址的高8位。T6963Clcd
控制器介绍⑵设置文本显示区宽度D1-00H-41H
该指令规定在文本显示区中一行显示数据所占的单元(字节)数。该数据与文本显示首地址一起确定了显示单元与显示屏上各点像素的对应关系。T6963Clcd
控制器介绍⑶设置图形显示区首地址该指令设置图形显示区在显示存储器中的起始地址。该地址对应显示屏左上角的第一个8点列像素。一个水平8点像素作为一个像素组由一个字节表示。定时定间隔地修改该地址将会产生显示画面的平滑滚动。参数Dl为该地址的低8位,D2为该地址的高8位。T6963Clcd
控制器介绍⑷设置图形显示区宽度该指令规定图形显示区中每行显示所占的单元(字节)数。该数据与图形显示首地址一起确定显示单元与显示屏上各像素组(字节)的对应关系。T6963Clcd
控制器介绍设置显示模式(MODESET)CDRDWRd7d6d5d4d3d2d1d01101000CGN2N1N0该指令设置显示方式,无参数。直到再发送此命令,才能修改显示模式。显示方式可以是文本、图形显示的逻辑或、异或和与。T6963Clcd
控制器介绍设置位功能如下:CG—字符发生器选择位。内部字符发生器模式下,字符代码OOH-7FHF分配给内部内部字符发生器CGROM。字符代码8OH-FFH自动分配给外部字符发生器CGRAM。
CG=0,启用内部字符发生器CGROM;同时可以建立128种8×8点阵的自定义字符发生器CGRAM,其字符代码规定在8OH-FFH范围内;T6963Clcd
控制器介绍
CG=1,禁止内部CGROM,字符显示完全取自自定义字符发生器CGRAM,该字符库为2K字节容量,字符代码为OOH-FFH。
注意:文本属性只能应用在文本显示中,因为属性数据放在图形显示RAM中。T6963Clcd
控制器介绍N2N1N0显示方式000文本与图形以逻辑“或”的关系合成显示001文本与图形以逻辑“异或”的关系合成显示011文本与图形以逻辑“与”的关系合成显示100文本属性—文本显示特征以双字节表示N2,N1,N0—显示方式设置位,它们的组合所产生的显示方式如下表所示。设置显示状态CDRDWRd7d6d5d4d3d2d1d01101001N3N2N1N0代码功能1001000关显示1001xx10启用光标显示,禁止光标闪烁1001xx11启用光标显示,启用光标闪烁100101xx启用文本显示,禁止图形显示100110xx禁止文本显示,启用图形显示100111xx启用文本显示,启用图形显示选择光标形状
CDRDWRd7d6d5d4d3d2d1d011010100N2N1N0代码功能101000001行光标101000012行光标101000103行光标101000114行光标101001005行光标101001016行光标101001107行光标101001118行光标T6963Clcd
控制器介绍设置数据自动读写(DATAAUTOREADWRITE)CDRDWRd7d6d5d4d3d2d1d0110101100N1N0T6963Clcd
控制器介绍该指令设置进入或退出数据的自动读或自动写方式。它为从外部显示RAM发送整屏数据提供了方便。设置了自动读(
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 地理-2025年中考考前最后一卷试题押题猜想(陕西卷)
- 中国古代文学作品选笔记
- 初中数学九年级下册统编教案 8.2货比三家
- DeepSeek+AI大模型在工程造价领域的智能化解决方案
- 内蒙古自治区锡林郭勒盟三县联考2025届九年级下学期中考三模数学试卷(含详解)
- 洗胃试题及答案
- 五官考试题及答案
- 河南省商丘市夏邑县2025年九年级下学期模拟考试英语试卷(文字版含答案)
- 2025年四川省泸州市江阳区初中学业水平适应性考试生物学试题 (含解析)
- 2025个人汽车贷款合同常用版
- T-ISEAA 001-2020 网络安全等级保护测评高风险判定指引
- 护理查房慢性肾脏病5期护理查房
- 钻越保阜高速公路施工方案
- GMS基础知识的教案
- 第5章 钢梁计算原理
- 中医药法试题及答案
- 篮球规则简介课件PPT模板下载
- GB/T 3452.4-2020液压气动用O形橡胶密封圈第4部分:抗挤压环(挡环)
- GB/T 20523-2006企业物流成本构成与计算
- GA 44-2015消防头盔
- 西南科技大学机械原理期末考试复习题及答案
评论
0/150
提交评论