首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

基于S3C2410的触摸屏驱动程序设计2

基于S3C2410的触摸屏驱动程序设计2

触摸屏驱动程序设计

触摸屏驱动程序中重要数据结构

typedef struct {
unsigned short pressure;
unsigned short x;
unsigned short y;
unsigned short pad;
} TS_RET;
typedef struct {
unsigned int PenStatus;
TS_RET buf[MAX_TS_BUF];
unsigned int head, tail;
wait_queue_head_t wq;
spinlock_t lock;
} TS_DEV;
static struct file_operations s3c2410_fops = {
owner: THIS_MODULE,
open: s3c2410_ts_open,
read: s3c2410_ts_read, release: s3c2410_ts_release,
poll: s3c2410_ts_poll, };

在程序中有三个重要的数据结构:用于表示笔触点数据信息的结构TS_RET,表示ADS7843中有关触摸屏控制器信息的结构TS_DEV,以及驱动程序与应用程序的接口file_operations结构的s3c2410_fops。

TS_RET结构体中的信息就是驱动程序提供给上层应用程序使用的信息,用来存储触摸屏的返回值。上层应用程序通过读接口,从底层驱动中读取信息,并根据得到的值进行其他方面的操作。

TS_DEV结构用于记录触摸屏运行的各种状态,PenStatus包括PEN_UP、PEN_DOWN和PEN_FLEETING。buf[MAX_TS_BUF]是用来存放数据信息的事件队列,head、tail分别指向事件队列的头和尾。程序中的笔事件队列是一个环形结构,当有事件加入时,队列头加一,当有事件被取走时,队列尾加一,当头尾位置指针一致时读取笔事件的信息,进程会被安排进入睡眠。wq等待队列,包含一个锁变量和一个正在睡眠进程链表。当有好几个进程都在等待某件事时,Linux会把这些进程记录到这个等待队列。它的作用是当没有笔触事件发生时,阻塞上层的读操作,直到有笔触事件发生。lock使用自旋锁,自旋锁是基于共享变量来工作的,函数可以通过给某个变量设置一个特殊值来获得锁。而其他需要锁的函数则会循环查询锁是否可用。MAX_TS_BUF的值为16,即在没有被读取之前,系统缓冲区中最多可以存放16个笔触数据信息。

s3c2410_fops就是内核对驱动的调用接口,完成了将驱动函数映射为标准接口。上面的这种特殊表示方法不是标准C的语法,而是GNU编译器的一种特殊扩展,它使用名字进行结构字段的初始化,它的好处体现在结构清晰,易于理解,并且避免了结构发生变化带来的许多问题。

init_module函数

这是模块的入口函数。在函数内部通过s3c2410_ts_init( )实现模块的初始化工作。在本设计中设备与系统之间以中断方式进行数据交换。整个触摸屏的驱动程序处理比较复杂,而且耗时较长,因而触摸屏驱动程序不可能在中断服务程序中完成。在Linux操作系统中一般把中断处理切为两个部分或两半。中断处理程序是上半部——接收到一个中断,它就立即开始执行,但只做有严格时限的工作,例如对接收的中断进行应答或复位硬件。这些工作都是在所有中断被禁止的情况下完成的,能够被允许稍后完成的工作会推迟到下半部去。在Linux中下半部的实现有多种机制。按触摸屏时,从ADS7843输出的数值有一个抖动过程,即从ADS7846输出的数值有一个不稳定时期,这个过程大约为10ms。所以中断处理程序的下半部处理函数采用内核定时器机制,使下半部在中断发生50ms后再作处理。这样有效地避开了ADS7843输出值的不稳定时期,使中断服务程序和中断处理任务串行化,达到了处理时间较长的触摸屏事件的目的。驱动程序通过request_irq函数注册并激活一个中断处理程序,以便处理中断。



图2 设备驱动在内核中的挂接、卸载和系统调用过程


int reguest_irq(unsigned int irq, void(*handler)(int, void *, struct pt_regs *), unsigned long irq_flags, const char *dev_name, void *dev_id)
参数irq表示所要申请的中断号;handler为向系统登记的中断处理子程序,中断产生时由系统来调用;dev_name为设备名;dev_id为申请时告诉系统的设备标识符;irq_flags是申请时的选项,它决定中断处理程序的一些特性,其中最重要的是中断处理程序是快速处理程序还是慢速处理程序。

本设计中触摸屏控制器ADS7843的中断输出通过外部中断5接在中断控制器上,当触摸屏上有触摸事件发生时,会引发中断号为IRQ_EINT5的中断服务程序s3c2410_isr_tc()。图3所示为该中断处理程序的流程图。



图3 触摸屏硬件中断处理程序流程图
返回列表