资源描述
课程设计
嵌入式系统
课程设计报告
题 目:
触摸屏设备驱动程 序设计
班 级:
姓 名:
学 号:
指导教师:
成 绩:
电子与信息工程学院
信息与通信工程系
目 录
引言 2
1 设备驱动程序简介 2
1.1 设备驱动程序的结构 2
1.2 设备驱动程序的功能 3
2 嵌入式系统开发平台构建 3
3 触摸屏设计流程 4
3.1 触摸屏设计流程图 4
3.2 触摸屏工作原理 4
4 触摸屏功能模块程序设计与交叉编译 5
4.1 功能模块驱动程序设计 5
4.1.1 触摸屏设备驱动中数据结构 5
4.1.2 触摸屏驱动模块加载和卸载函数 7
4.1.3 触摸屏设备驱动的读函数 7
4.1.4 触摸屏设备驱动的轮询与异步通知 8
4.1.5 应用程序的调试 8
4.2 触摸屏功能模块交叉编译 8
5 根文件系统建立与文件系统下载 9
5.1 Cramfs 根文件系统分析 9
5.2 文件系统映像文件生成 9
5.3 功能模块运行与调试 10
5.3.1 vivi的烧写 10
5.3.2 linux内核的烧写 10
5.3.3 cramfs文件系统的烧写 11
心得体会 11
引言
嵌入式Linux由于其可应用于多种硬件平台、内核高效稳定、源代码开放、软件丰富、网络通信和文件管理机制完善等优良特性,已经成为嵌入式操作系统的主力军,是整个嵌入式系统的重要组成部分。在嵌入式Linux系统中,由于内核的保护机制,用户一般不能直接访问硬件,而是要通过调用驱动程序来实现对硬件的控制。进行嵌入式系统的开发,很大的工作量是为各种设备编写驱动程序。设备驱动程序是Linux内核的重要组成部分,不同版本的内核,其主要区别也是体现在设备驱动程序的不同。
1 设备驱动程序简介
1.1 设备驱动程序的结构
1)Linux的设备驱动程序与外界的接口可以分成三部分:
a.驱动程序与操作系统内核的接口。
b.驱动程序与系统引导的接口。
c.驱动程序与设备的接口。
2)驱动程序的注册与注销:
向系统增加一个驱动程序意味着要赋予它一个主设备号,这可以通过在驱动程序的初始化过程中调用定义在fs/devices.c中的register_chrdev()函数或fs/block_dev.c中的register_blkdev()函数来完成。而在关闭字符设备或者块设备时,则要通过unregister_chrdev()或unregister_blkdev()函数从内核中注销设备,同时释放占用的主设备号。
3)设备的打开与释放:
a.打开设备是通过调用定义在include/linux/fs.h中的file_operations结构中的函数open()来完成。
b.释放设备是通过调用file_operations结构中的函数release()来完成。
4)设备的读写操作:
a.字符设备的读写操作相对比较简单,直接使用函数read()和write()就可以了。
b.块设备的话,则需要调用函数block_read()和block_write()来进行数据读写。
5)设备的控制操作:
通过设备驱动程序中的函数ioctl()来完成。
6)设备的轮询和中断处理:
a.设备执行某个命令时,如“将读取磁头移动到软盘的第42扇区上”,设备驱动可以从轮询方式和中断方式中选择一种以判断设备是否已经完成此命令。
b.不支持中断的硬件设备,读写时需要轮流查询设备状态。
1.2 设备驱动程序的功能
1)对设备的初始化和释放。
2)把数据从内核传送到硬件和从硬件读取数据到内核。
3)读取应用程序传送给设备文件的数据和回送应用程序请求的数据。这需要在用户空间,内核空间,总线以及外设之间传输数据。
4)检测和处理设备出现的错误。
2 嵌入式系统开发平台构建
开发嵌入式Linux系统,其实最方便的还是构建一个标准的Linux开发环境,大大地方便Linux开发中的编译调试等工作。同样地,EduKit2410的Linux开发也可以在标准Linux 环境下进行,比如选择Red Hat等优秀的系统。
3 触摸屏设计流程
3.1 触摸屏设计流程图
是
打开触摸屏设备
创建等待队列和缓冲区
初始化队列头
等待中断
使用中断子程序
更新X、Y
显示一个触摸点或坐标值
开始
结束
图3.1-1
3.2 触摸屏工作原理
1)普通转换模式
普通转换模式(AUTO_PST=0,XY_PST=0)是用作一般目的下的ADC转换。这个模式可以通过设置ADCCON和ADCTSC来进行对AD转换的初始化;而后读取ADCDAT0(ADC 数据寄存器0)的XPDATA域(普通ADC转换)的值来完成转换。
2)分离的X/Y轴坐标转换模式
X 轴坐标转换(AUTO_PST=0且XY_PST=1)将X轴坐标转换数值写入ADCDAT0寄存器的XPDATA域。转换后,触摸屏接口将产生中断源(INT_ADC)到中断控制器。
Y轴坐标转换(AUTO_PST=0且XY_PST=2)将Y轴坐标转换数值写入到ADCDAT1寄存器的YPDATA域。转换后,触摸屏接口将产生中断源(INT_ADC)到中断控制器。
3)自动(连续)X/Y轴坐标转换模式
自动(连续)X/Y轴坐标转换模式(AUTO_PST=1且XY_PST= 0)以下面的步骤工作:触摸屏控制器将自动地切换X轴坐标和Y轴坐标并读取两个坐标轴方向上的坐标。触摸屏控制器自动将测量得到的X轴数据写入到ADCDAT0寄存器的XPDATA域,然后将测量到的Y轴数据到ADCDAT1的YPDATA域。(连续)自动转换之后,触摸屏控制器产生中断源(INT_ADC)到中断控制器。
4)等待中断模式
当触摸屏控制器处于等待中断模式下时,它实际上是在等待触摸笔的点击。在触摸笔点击到触摸屏上时,控制器产生中断信号(INC_TC)。中断产生后,就可以通过设置适当的转换模式(分离的X/Y轴坐标转换模式或自动X/Y轴坐标转换模式)来读取X和Y的位置。
5)静态(Standby)模式
当ADCCON寄存器的STDBM位被设为1时,Standby模式被激活。在该模式下,A/D 转换操作停止,ADCDAT0寄存器的XPDATA域和ADCDAT1寄存器的YPDATA(正常 ADC)域保持着先前转换所得的值。
4 触摸屏功能模块程序设计与交叉编译
4.1 功能模块驱动程序设计
4.1.1 触摸屏设备驱动中数据结构
1)触摸屏的 file_operations
static struct file_operations s3c2410_fops={
owner: THIS_MODULE,
open: s3c2410_ts_open,
read: s3c2410_ts_read,
release: s3c2410_ts_release,
#ifdef USE_ASYNC
fasync: s3c2410_ts_fasync,//异步通知
#endif
poll: s3c2410_ts_poll,//轮询
};
2)触摸屏设备结构体的成员与按键设备结构体的成员类似,也包含一个缓冲区,同时包括自旋锁、等待队列和fasync_struct 指针。
typedef struct {
unsigned int penStatus; /* PEN_UP, PEN_DOWN, PEN_SAMPLE */
TS_RET buf[MAX_TS_BUF]; /* protect against overrun(环形缓冲区) */
unsigned int head, tail;/* head and tail for queued events (环形缓冲区的头尾)*/
wait_queue_head_t wq; //* 等待队列数据结构
spinlock_t lock; //* 自旋锁
#ifdef USE_ASYNC
struct fasync_struct *aq;
#endif
#ifdef CONFIG_PM
struct pm_dev *pm_dev;
#endif
} TS_DEV;
3)触摸屏结构体中包含的TS_RET值的类型定义,包X、Y坐标和状态(PEN_DOWN、PEN_UP)等信息,这个信息会在用户读取触摸信息时复制到用户空间。
typedef struct {
unsigned short pressure; //* 压力,这里可定义为笔按下,笔抬起,笔拖曳。
unsigned short x; //* 横坐标的采样值
unsigned short y; //* 纵坐标的采样值
unsigned short pad; //* 填充位
} TS_RET;
4)在触摸屏设备驱动中,将实现open()、release()、read()、fasync()和poll()函数,因此,其文件操作结构体定义:触摸屏驱动文件操作结构体:static struct file_operations s3c2410_fops={ }。
4.1.2 触摸屏驱动模块加载和卸载函数
1)在触摸屏设备驱动的模块加载函数中,要完成申请设备号、添加 cdev、 申请中断、设置触摸屏控制引脚(YPON、YMON、XPON、XMON)等多项工作。
2)可知触摸屏驱动中会产生两类中断,一类是触点中断(INT-TC),一类是X/Y位置转换中断(INT-ADC)。在前一类中断发生后,若之前处于PEN_UP状态,则应该启动X/Y位置转换。另外,将抬起中断也放在INT-TC处理程序中,它会调用tsEvent()完成等待队列和信号的释放触摸屏设备驱动的触点/抬起中断处理程序:static void s3c2410_isr_tc(int irq, void *dev_id, struct pt_regs *reg)
当X/Y位置转换中断发生后,应读取X、Y的坐标值,填入缓冲区触摸屏设备驱动X/Y位置转换中断处理程序:static void s3c2410_isr_adc(int irq, void *dev_id, struct pt_regs *reg) 。触摸屏设备驱动中获得X、Y坐标s3c2410_get_XY(void) 。
3)tsEvent最终为tsEvent_raw(),这个函数很关键,当处于PEN_DOWN状态时调用该函数,它会完成缓冲区的填充、等待队列的唤醒以及异步通知信号的释放;否则(处于 PEN_UP状态),将缓冲区头清0,也唤醒等待队列并释放信号。
4)在包含了对拖动轨迹支持的情况下,定时器会被启用,周期为10ms,在每次定时器处理函数被引发时,调用start_ts_adc()开始X/Y位置转换过程触摸屏设备驱动的定时器处理函数static void ts_timer_handler(unsigned long data) 。
5)在触摸屏设备驱动的打开函数中,应初始化缓冲区、penStatus和定期器、等待队列及tsEvent时间处理函数指针。触摸屏设备驱动的打开函数static int s3c2410_ts_open(struct inode *inode, struct file *filp)。
4.1.3 触摸屏设备驱动的读函数
触摸屏设备驱动的读函数实现缓冲区中信息向用户空间的复制,当缓冲区有内容时,直接复制;否则,如果用户阻塞访问触摸屏,则进程在等待队列上睡眠,否则,立即返回-EAGAIN。
4.1.4 触摸屏设备驱动的轮询与异步通知
在触摸屏设备驱动中,通过s3c2410_ts_poll()函数实现了轮询接口,这个函数的实现非常简单。它将等待队列添加到poll_table,当缓冲区有数据时,返回资源可读取标志,否则返回0。触摸屏设备驱动的poll()函数static unsigned int s3c2410_ts_poll(struct file *filp, struct poll_table_struct *wait)。而为了实现触摸屏设备驱动对应用程序的异步通知,设备驱动中要实现s3c2410_ts_fasync()函数,触摸屏设备驱动的fasync()函数static int s3c2410_ts_fasync(int fd, struct file *filp, int mode)。
4.1.5 应用程序的调试
使用s3c2410_ts.c 触摸屏驱动编写应用程序,读取触摸屏的触点坐标值及动作信息,并在串口中断打印出来对触摸屏设别的操作有打开设备,关闭设备,读操作等。编写应用程序读取触摸屏的触点坐标值及动作信息时,只需利用触摸屏驱动程序便可实现,先打开触摸屏设备,然后调用读函数即可。其中,触摸笔动作取值如下:
#define PEN_UP 0 /* 触摸笔抬笔,即触摸屏不被压下*/
#define PEN_DOWN 1 /* 触摸笔下笔,即触摸屏被压下 */
#define PEN_FLEETING 2 /* 触摸笔拖动 */
结构体定义如下:
typedef struct {
unsigned short pressure; /* 触摸笔动作 */
unsigned short x; /* 触点 x 座标值 */
unsigned short y; /* 触点 y 座标值 */
unsigned short pad;
}TS_RET;
4.2 触摸屏功能模块交叉编译
将编写好的源文件程序放在cygwin目录中。交叉编译生成文件。
5 根文件系统建立与文件系统下载
5.1 Cramfs 根文件系统分析
一个完整的根文件系统通常包含以下几个目录:
/bin应用程序存放目录。
/sbin系统管理员服务程序,其中最重要的就是供内核初始化之后执行的/sbin/init进程。
/lib存放程序运行所需要的动态库。
/proc系统状态文件目录。
/dev驱动程序存放目录。
/etc系统配置文件及用户数据存放目录。
/mnt用于设备安装的目录,通常包含etc子目录和为块设备安装保留目录。
/usr用于存放用户程序和配置文件的目录,可以根据需要进行设置。
一般情况下都要把已经规划好的目录结构转换成一个映象文件,即使用命令工具mkcram,把相应的cramfs目录树压缩为单一的映象文件。其命令格式为:mkcramfs [-h] [-e edition] [-i file] [-n name] dirname outfile。
5.2 文件系统映像文件生成
1)构建cramfs文件系统:
将\image\中的root.cramfs.tar.bz2拷贝到$SOURCEDIR目录,运行cygwin,执行以下命令解压安装。….root…. root 文件夹中就是我们想要的cramfs文件系统。在root目录中新建xx文件夹,用于存放应用程序。
2)编译应用程序将编写好的源文件ts.c程序放在cygwin目录中。
3)拷贝测试程序到文件系统中,并编译生成文件系统映象。
新文件系统的制作,把刚才编译输出的ts文件拷贝到文件系统所在的工作目录root/bin 目录下,执行以下命令生成新的文件系统映象。
5.3 功能模块运行与调试
5.3.1 vivi的烧写
1)首先把SW104短接(从Nand Flash启动),运行Embest online Flash Programmer for ARM(version 3.0 以上),点击菜单Settings选择Configure…项,配置当前使用的Embest JTAG仿真器型号为PowerICEARM9,并设置相应的参数。
2)点击菜单File选择Open打开烧写配置文件S3C2410&NandFLash_vivi.cfg,Flash Programmer的Program页中选择要烧写的文件:在vivi.bon&load.bin。
3)点击按钮Progarm开始烧写,直到烧写成功。
4)连接串口线到PC机COM1,运行光盘中提供的Windows 超级终端Hyper Terminal.ht。
5)把开发板重新加电,程序运行后,在超级终端上可以看到串口输出类似以下信息:
图 5.3.1-1
6)看到以上信息后,表示正在等待用户从超级终端下载文件。这时,请点击超级终端菜单"传送"选择Xmodem方式下载vivi.nand文件,点击OK后等待下载烧写结束即可。
5.3.2 linux内核的烧写
1)首先SW104设为短接(从Nand Flash启动)并确定已经烧写vivi.nand,加电。
2)在vivi启动等待中,敲入空格键进入vivi界面环境,并输入以下命令:vivi> load flash kernel x <回车> 烧写更新内核约4分钟即可烧写完毕。
3)点击超级终端菜单中的“传送”,选“发送文件”zImage,烧写结束,重起实验板,观测超级终端窗口提示信息就可以启动linux内核。
5.3.3 cramfs文件系统的烧写
1)首先SW104设为短接,确定已经成功烧写vivi和linux kernel,加电运行可以看到 vivi启动信息,输入空格进入命令状态;
2)双击运行Download.pjf工程文件,点击连接Remote connect,程序应该正在运行(此时命令按钮STOP为红色);在超级终端输入help看看有没有反应,如果没反应,点击IDE 按钮:Reset->Start(F5);再输入help测试,直到有反应为止;
3)如果超级终端可以输出一些信息,再点击IDE中的Stop,配置Debug的Download 地址为0x30000000,并点击IDE菜单Project选择Settings项,Download页下拉Category在到Download项,在Download File选择root.cramfs.new文件,点击确定后:
(1) 点击IDE菜单DEBUG选择Download下载文件系统映象约1-2分钟;
(2) 下载完毕后,点击Start(F5);
(3) 然后在超级终端里输入:load flash root j。
心得体会
这次课程设计,加深对触摸屏设备程序设计原理和基本性质的理解。对嵌入式有了新的认识,掌握了设计和编程思想,为以后深入的学习奠定了基础。这次课程设计,我觉得最有意义的就是掌握了一定的软件设计能力。同时也让我意识到平时的课程文化的学习的一些疏忽,所以在以后的学习生活中,我要努力学习,培养自己独立思考的能力,要加强理论学习,全面的提高自己。
参考文献
[1]王田苗,魏洪兴 嵌入式系统设计实例与开发,北京:清华大学出版社 2008
[2]李中奇,张冬波,罗文俊.嵌入式 Linux系统中触摸屏控制的研究与实现[J].工业控制计算机 2005
[3]张晓明,超声波触摸屏 PC 机接口驱动程序设计[J].计算机应用. 2004
11
展开阅读全文