s3c2410触摸屏在linux下的驱动分析 一

发布者:sunyouz1最新更新时间:2016-12-02 来源: eefocus关键字:s3c2410  触摸屏  linux 手机看文章 扫描二维码
随时随地手机看文章

触摸屏驱动在/kernel/drivers/char/s3c2410-ts.c 文件中。
该驱动总要有以下重要数据结构:
 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.全局变量TS_DEV结构体,用来保存触摸屏的相关参数、等待处理的消息队列、当前采样数据、上一次采样数据等信息
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;
其中TS_RET在/kernel/include/asm-arm/linuette_ioctl.h 文件中:
typedef struct {
   unsigned short pressure; //* 压力,这里可定义为笔按下,笔抬起,笔拖曳
   unsigned short x; //* 横坐标的采样值
   unsigned short y; //* 纵坐标的采样值
   unsigned short pad; //* 填充位
} TS_RET; 
结构体wait_queue_head_t在/kernel/include/linux/wait.h 文件中:
struct __wait_queue_head {
   wq_lock_t lock;
   struct list_head task_list;
#if WAITQUEUE_DEBUG
   long __magic;
   long __creator;
#endif
};
typedef struct __wait_queue_head wait_queue_head_t;
 
    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_ts_init 函数来实现的,主要完成触摸屏设备的内核模块加载、初始化系统I/O、中断注册、设备注册,为设备文件系统创建入口等标准的字符设备初始化工作。
static int __init s3c2410_ts_init(void)
   ret = register_chrdev(0, DEVICE_NAME, &s3c2410_fops);
   tsMajor = ret;
这里首先对字符设备进行注册,将触摸屏的file_operations 结构中的函数接口传入内核,注册成功后获得系统自动分配的主设备号。
set_gpio_ctrl(GPIO_YPON); 
set_gpio_ctrl(GPIO_YMON);
set_gpio_ctrl(GPIO_XPON);
set_gpio_ctrl(GPIO_XMON);
在/kernel/include/asm-arm/arch-s3c2410/smdk.h 文件中:
#define GPIO_YPON (GPIO_MODE_nYPON | GPIO_PULLUP_DIS | GPIO_G15)
#define GPIO_YMON (GPIO_MODE_YMON | GPIO_PULLUP_EN | GPIO_G14)
#define GPIO_XPON (GPIO_MODE_nXPON | GPIO_PULLUP_DIS | GPIO_G13)
#define GPIO_XMON (GPIO_MODE_XMON | GPIO_PULLUP_EN | GPIO_G12)
GPIO 口的Port G 端口有4个管脚对应触摸屏的控制接口,分别是:
GPG15 --- nYPON Y+ 控制信号
GPG14 --- YMON Y- 控制信号
GPG13 --- nXPON X+ 控制信号
GPG12 --- XMON X- 控制信号
需要通过配置GPGCON 寄存器来设定该端口管脚的输出模式,对应位如下:
[31:30] [29:28] [27:26] [25:24]
GPG15 GPG14 GPG13 GPG12 ... 
参考S3C2410 芯片datasheet 的I/O口章节,都要设为11(二进制)。
ADCDLY = 30000;
配置ADCDLY 寄存器,对自动转换模式来说是设定ADC 开始转换时的延时时间,以及对X轴和Y轴转换的时间间隔,对正常模式来说仅设定对X轴和Y轴转换的时间间隔。注意该值不能为0。
  ret = request_irq(IRQ_ADC_DONE, s3c2410_isr_adc, SA_INTERRUPT, 
             DEVICE_NAME, s3c2410_isr_adc);
  if (ret) goto adc_failed;
  ret = request_irq(IRQ_TC, s3c2410_isr_tc, SA_INTERRUPT, 
             DEVICE_NAME, s3c2410_isr_tc);
 if (ret) goto tc_failed;
 /* Wait for touch screen interrupts */
 wait_down_int();
 
     函数request_irq 是Linux 系统中驱动程序注册中断的方法。irq 为所要申请的硬件中断号,handler 为系统所注册的中断处理子程序,irq_flags 为申请时的选项,devname 为指向设备名称的字符指针,dev_id 为申请时告诉系统的设备标识。若中断申请成功则返回0,失败则返回负值。
ret = request_irq(IRQ_ADC_DONE, s3c2410_isr_adc, SA_INTERRUPT, 
           DEVICE_NAME, s3c2410_isr_adc);
    调用该函数来进行A/D转换的中断注册,所要申请的硬件中断号为IRQ_ADC_DONE(62),在arch/irq s.h中定义;系统所注册的中断处理子程序为s3c2410_isr_adc 函数;申请中断选项为SA_INTERRUPT,表示中断处理程序是快速处理程序,即快速处理程序运行时,所有中断都被屏蔽;设备名称定义为DEVICE_NAME,即"s3c2410-ts";而设备标识仍然用中断处理子程序代替。
 
ret = request_irq(IRQ_TC, s3c2410_isr_tc, SA_INTERRUPT, 
          DEVICE_NAME, s3c2410_isr_tc);
    接着继续调用该函数来进行触摸屏触摸的中断注册,所要申请的硬件中断号为IRQ_TC(61);系统所注册的中断处理子程序为s3c2410_isr_tc 函数;申请中断选项为SA_INTERRUPT,表示中断处理程序是快速处理程序,即快速处理程序运行时,所有中断都被屏蔽;设备名称定义为DEVICE_NAME,即"s3c2410-ts";而设备标识仍然用中断处理子程序代替。
wait_down_int();
    调用该宏函数来设置触摸屏为等待中断模式【笔按下产生中断】,具体定义如下:
#define wait_down_int() { ADCTSC = DOWN_INT | XP_PULL_UP_EN | /
    XP_AIN | XM_HIZ | YP_AIN | YM_GND | /
    XP_PST(WAIT_INT_MODE); }
    用该宏函数来设置ADC 触摸屏控制寄存器,参考S3C2410 芯片datasheet 中关于触摸屏的章节,具体设置参数如下:
DOWN_INT = 1<<8 * 0 该位保留且应该设为0 【笔按下或笔抬起中断信号控制位,设为0 表示笔按下产生中断信号】
XP_PULL_UP_EN = 1<<3 * 0 上拉开关使能,设为0 表示XP 引脚上拉使能
XP_AIN = 1<<4 * 1 选择nXPON 引脚输出值,设为1 表示nXPON 引脚输出1,则XP 引脚连接AIN[7] 引脚
XM_HIZ = 1<<5 * 0 选择XMON 引脚输出值,设为0 表示XMON 引脚输出0,则XM 引脚为高阻态
YP_AIN = 1<<6 * 1 选择nYPON 引脚输出值,设为1 表示nYPON 引脚输出1,则YP 引脚连接AIN[5] 引脚
YM_GND = 1<<7 * 1 选择YMON 引脚输出值,设为1 表示YMON 引脚输出1,则YM 引脚为接地
XP_PST(WAIT_INT_MODE); = 3 X坐标Y坐标手动测量设置,设为3 表示等待中断模式
 
#ifdef CONFIG_DEVFS_FS
devfs_ts_dir = devfs_mk_dir(NULL, "touchscreen", NULL);
devfs_tsraw = devfs_register(devfs_ts_dir, "0raw", DEVFS_FL_DEFAULT,
       tsMajor, TSRAW_MINOR, S_IFCHR | S_IRUSR | S_IWUSR,
       &s3c2410_fops, NULL);
#endif
   这里调用了devfs_mk_dir 函数,在设备文件系统中创建了一个名为touchscreen 的目录,并返回一个带有目录结构的数据结构变量devfs_ts_dir。将该变量作为下一步devfs_register 函数的参数,该参数在调用设备文件系统注册清除函数devfs_unregister 时也要作为参数传入。
    调用devfs_register 函数后,会在刚才创建的touchscreen 目录下再创建一个名为0raw 的设备文件节点。该函数的参数中,DEVFS_FL_DEFAULT 为该函数的标志选项,tsMajor 为注册字符设备时系统自动分配的主设备号,TSRAW_MINOR(1)为次设备号,S_IFCHR | S_IRUSR | S_IWUSR 为默认的文件模式,&s3c2410_fops 为传入内核的触摸屏file_operations 结构中的函数接口,私有数据指针为空。返回一个devfs_handle_t 数据结构的变量devfs_tsraw,这会在调用设备文件系统注册清除函数devfs_unregister 时作为参数传入。
 
   模块的退出函数为s3c2410_ts_exit,该函数的工作就是清除已注册的字符设备,中断以及设备文件系统。
static void __exit s3c2410_ts_exit(void)
{
#ifdef CONFIG_DEVFS_FS 
   devfs_unregister(devfs_tsraw);
   devfs_unregister(devfs_ts_dir);
#endif 
   unregister_chrdev(tsMajor, DEVICE_NAME);
#ifdef CONFIG_PM
   pm_unregister(tsdev.pm_dev);
#endif
   free_irq(IRQ_ADC_DONE, s3c2410_isr_adc);
   free_irq(IRQ_TC, s3c2410_isr_tc);
#ifdef CONFIG_DEVFS_FS 
devfs_unregister(devfs_tsraw);
devfs_unregister(devfs_ts_dir);
#endif 
    这里首先清除原先后一步创建设备文件节点0raw 的结构变量devfs_tsraw,然后再清除创建touchscreen 目录的结构变量devfs_ts_dir。
unregister_chrdev(tsMajor, DEVICE_NAME);
   接下来删除字符设备的注册信息。
void free_irq(unsigned int irq, void *dev_id)
    函数free_irq 与函数request_irq 相对应,通常在模块被卸载时调用,负责注销一个已经申请的中断。
 
free_irq(IRQ_ADC_DONE, s3c2410_isr_adc);
free_irq(IRQ_TC, s3c2410_isr_tc);
    最后依次注销A/D转换和定时器这两个已经申请的中断。

关键字:s3c2410  触摸屏  linux 引用地址:s3c2410触摸屏在linux下的驱动分析 一

上一篇:s3c2410与s3c2440的全方位对比
下一篇:基于s3c2410 2.6.25内核cs8900网卡驱动的移植

推荐阅读最新更新时间:2024-03-16 15:22

S3C2410网卡CS8900A驱动程序的移植及问题解析
硬件环境:SBC-2410X开发板(CPU:S3C2410X) 内核版本:2.6.11.1 运行环境:Debian2.6.8 交叉编译环境:gcc-3.3.4-glibc-2.3.3 第一部分 网卡CS8900A驱动程序的移植 一、从网上将Linux内核源代码下载到本机上,并将其解压: #tar jxf linux-2.6.11.1.tar.bz2 二、打开内核顶层目录中的Makefile文件,这个文件中需要修改的内容包括以下两个方面。 (1)指定目标平台。 移植前: ARCH?= $(SUBARCH) 移植后: ARCH :=arm (2)指定交叉编译器。 移植前: CROSS_COMPILE ?= 移植后:
[单片机]
Linux 移植 】——4、移植 u-boot-2012.04.01 之 支持NAND启动
三、移植 u-boot-2012.04.01 之 支持NAND启动 需要进行修改和添加的文件: 1、添加的文件:init.c 包含NAND Flash 的相关配置 board/samsung/smdk2440目录, 修改Makefile 2、需要修改的文件: a、去掉-pie选项,修改arch/arm/config.mk b、start.S c、smdk2440.h d、common.h e、board.c f、arch/arm/cpu/u-boot.lds 1、添加的文件:init.c init.c 代码如下: /* NAND FLASH控制器 */ #define N
[单片机]
基于RT-Linux机器人控制系统实时性的研究
  实时系统是能够在确定的时间内执行计算或处理事务并对外部事件作出响应的计算机系统。对工业机器人控制来说,实时性是一个相当重要的内容,尤其是在远程机器人控制中,如果不能很好地满足系统所需的实时性要求,就失去了研究的基础和意义。当前专用的实时操作系统很多,但是遗憾的是它们的价格高昂,增加了开发成本。在考虑实时操作系统核心的性能之外,更应该对开发工具、编译器、调试器之类的开发环境进行全面考虑,尤其是随着应用的不断升级,要求实时操作系统支持各类网络协议和编程语言,系统的通用性和可移植性也应当列入考虑的范围内。于是力求寻找一种高性能的、低价的甚至是免费的实时操作系统,且功能必须完备,通用性必须强。RT—Linux与Linux的结合是一项比
[嵌入式]
arm-Linux中断处理体系结构与处理流程分析
异常,就是可以打断CPU正常运行流程的一些事情,比如外部中断、未定义指令、试图修改只读的数据、执行swi指令(Software Interrupt Instruction ,软件中断指令)等。当这些事情发生时,CPU暂停当前的程序,先处理异常事件,然后再继续执行被中断的程序。操作系统中经常通过异常来完成一些特定的功能。其中的中断也占有很大的一部分。例如下面的这几种情况: * 当CPU执行未定义的机器指令时将触发 未定义指令异常 ,操作系统可以利用这个特点使用一些自定义的机器指令,它们在异常处理函数中实现。 * 当用户程序试图读写的数据或执行的指令不在内存中时,也会触发一个 数据访问中止异常 或 指令预取中止异常 ,在异
[单片机]
arm-<font color='red'>Linux</font>中断处理体系结构与处理流程分析
基于ADS7846的在线动态签名认证的数据采集和预处理
  由于触摸屏输入方便,轻薄便于携带等优点,现在越来越多的电子产品用触摸屏作为人机界面的输入设备。在动态签名认证中,亦采用触摸屏作为输入设备对笔迹进行数据采集。本文主要从触摸屏工作原理、ADS7846的工作方式以及单片机89S51对ADS7846的控制等方面来分析如何实现三维数据的采集。   系统主要由四线电阻式触摸屏,触摸屏控制器ADS7846,单片机89S51以及相应软件程序组成。系统框图如图所示:   图1. 系统电路框图   一、四线电阻式触摸屏   电阻触摸屏是采用是使用电阻模拟量技术。它以一层玻璃作为基层,上面涂有一层透明氧化金属(ITO氧化铟)导电层,上面在盖有一层玻璃或是外表面硬化处理的光滑的塑料层,
[模拟电子]
用户关注实时性性,Linux使用率仍然偏低
日前在美国硅谷举办的嵌入式系统研讨会(Embedded Systems Conference)上,一份针对嵌入式操作系统的调查显示,目前(美国)只有17%的嵌入式系统设计工程师采用嵌入式Linux,而66%的人表示他们要么对此没有兴趣,要么就是今后也不会用。 EE Times及其姊妹出版物Embedded Systems Design的“2006年嵌入式系统设计状况调查报告”发现,34%的受调查表示对Linux不感兴趣,2/3的受调查对象说他们对Linux有兴趣,但是,最近不会使用;而17%的人则说他们可能很快就会采用。相比之下,2005年有24%的受调查者表示他们正在使用嵌入式Linux。 在考虑使用嵌入式Linux
[嵌入式]
STM32也能轻松跑Linux了 !STM32MP135核心板开发板评测
上个月, 意法半导体推出了新一代64位Cortex-A35内核,主频高达1.5GHz的STM32MP2x系列微处理器(MPU) ,这让STM32MP系列处理器又上了一个新的台阶。 最近,收到了一套米尔基于STM32MP135核心板及开发板,首次接触STM32MPx处理器,体验了一下,感觉还不错。 STM32MP135与普通STM32单片机在性能、价格、应用场景等各方面都有差异。同时,STM32MP135并非局限于裸机、RTOS,而是定位于更高的Linux操作系统平台。 下面就结合【米尔基于STM32MP135核心板及开发板】给大家讲解一下STM32MP135强悍的性能以及开发入门等相关的内容。 硬件平台介绍
[单片机]
STM32也能轻松跑<font color='red'>Linux</font>了 !STM32MP135核心板开发板评测
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved