Linux驱动之触摸屏程序编写

本篇博客分以下几部分讲解

1、介绍电阻式触摸屏的原理

2、介绍触摸屏驱动的框架(输入子系统)

3、介绍程序用到的结构体

4、介绍程序用到的函数

5、编写程序

6、测试程序

1、介绍电阻式触摸屏的原理

所谓的电阻式触摸屏,只不过是在LCD屏幕上贴了一层膜,这层膜的大小与LCD的尺寸刚好相同,它分为上下两层膜(假设上层为X膜,下层为Y膜),按下膜的不同位置,会产生不同的电压值,这样根据不同的电压值可以确定触点的位置,这就是触摸屏的基本原理。其实是利用了最简单的电阻分压原理。

下面的图是四线式电阻触摸屏的原理图,它的四根线都接到芯片的IO口上

1、如图14.4是什么都不设置的触摸屏的情况,其中S1、S2、S3、S4是由芯片内部寄存器控制的,四线电阻的四根线其实等效于接到了这个四个开关上了。

2、如图14.5是将触摸屏设置为等待中断的情况,可以看到只要触摸板被按下,Y_ADC点的电压就会发生变化,然后就会产生一个中断事件报告CPU有按键按下待处理。

3、确定按键被按下后,通过设置触摸屏ADC相关寄存器,设置为自动测量坐标模式,首先会进入测量X坐标模式,如图14.6可以将Y_ADC的值测量出来

4、接着进入测量Y坐标模式,如图14.7可以将X_ADC的值测量出来。x,y坐标测量出来后会存放在相应寄存中,然后又会产生一个中断,等待CPU读取x,y的坐标值

5、CPU确认读取玩x,y坐标的值之后就进入等待松开模式,当Y_ADC的电压为VCC时就认为松开,并进入相应中断。等待CPU处理。

2、介绍触摸屏驱动的框架(输入子系统)

触摸对于linux内核来说也是一个输入的器件,与按键一样,只不过比按键的值丰富了许多。在Linux驱动之输入子系统简析已经介绍过了输入子系统的框架,这里再简单回顾一下。

输入子系统按框架可以分为设备驱动层、事件层、以及核心层。

整个调用过程如下:

app_read->evdev_read->kbtab_irq->input_report_key->input_event->evdev_event->evdev_read

应用层           事件层          设备层         核心层                   核心层            事件层          事件层

如果要自己添加一个输入子系统的设备,只需要添加设备层的文件即可。

1、在里面添加设备层input_dev结构并初始化

2、编写中断处理程序

3、介绍程序用到的结构体

其实编写触摸屏的驱动程序就是编写一个输入子系统的设备层。它需要用的结构体有

1、struct input_dev结构体

struct input_dev {

    void *private;

    const char *name;//设备名字
    const char *phys;//文件路径,比如 input/buttons
    const char *uniq;
    struct input_id id;

    unsigned long evbit[NBITS(EV_MAX)];//表示支持哪类事件,常用于以下几种事件(可以多选)
    //EV_SYN      同步事件,当使用input_event()函数后,就要使用这个上报个同步事件
    //EV_KEY       键盘事件
    //EV_REL       (relative)相对坐标事件,比如鼠标
    //EV_ABS       (absolute)绝对坐标事件,比如摇杆、触摸屏感应

    unsigned long keybit[NBITS(KEY_MAX)];//存放支持的键盘按键值
    //键盘变量定义在:include/linux/input.h, 比如: KEY_L(按键L)、BTN_TOUCH(触摸屏的按键)

    unsigned long relbit[NBITS(REL_MAX)];//存放支持的相对坐标值
    unsigned long absbit[NBITS(ABS_MAX)];//存放支持的绝对坐标值
    unsigned long mscbit[NBITS(MSC_MAX)];
    unsigned long ledbit[NBITS(LED_MAX)];
    unsigned long sndbit[NBITS(SND_MAX)];
    unsigned long ffbit[NBITS(FF_MAX)];
    unsigned long swbit[NBITS(SW_MAX)];

    ...
    ...

    int absmax[ABS_MAX + 1];//绝对坐标的最大值
    int absmin[ABS_MAX + 1];//绝对坐标的最小值
    int absfuzz[ABS_MAX + 1];//绝对坐标的干扰值,默认为0,
    int absflat[ABS_MAX + 1];//绝对坐标的平焊位置,默认为0

    ...
    ...
};

2、struct timer_list结构体(用于触摸屏的长按处理)

struct timer_list {
    struct list_head entry;
    unsigned long expires;//期望定时器执行的jiffies值,假设需要定时10ms,那么应该设置expires = jiffies + HZ/100(10ms为100hz)

    void (*function)(unsigned long);//定时器定时时间到了之后的回调函数
    unsigned long data;//回调函数传入的数据

    struct tvec_t_base_s *base;
#ifdef CONFIG_TIMER_STATS
    void *start_site;
    char start_comm[16];
    int start_pid;
#endif
};

4、介绍程序用到的函数

触摸屏程序用到的函数众多大致分为以下几类:

1、输入子系统相关的函数

struct input_dev *input_allocate_device(void);//分配一个struct input_dev结构体,返回的是struct input_dev *
inline void set_bit(int nr, volatile unsigned long *addr);//这是一个内联函数,在调用的时候展开,功能为设置*addr的nr位为1
inline void input_set_abs_params(struct input_dev *dev, int axis, int min, int max, int fuzz, int flat);//设置绝对位移的参数
//struct input_dev *dev表示哪个输入子系统设备的绝对位移参数
//axis表示哪个坐标的绝对位移参数,可以设置为ABS_X、ABS_Y、ABS_PRESSURE等,位于include/linux/input.h中
//min绝对位移坐标的最小值
//max绝对位移坐标的最大值
//fuzz绝对位移坐标的干扰值,默认为0
//flat绝对位移坐标的平焊位置,默认为0
int input_register_device(struct input_dev *dev);//注册输入子系统设备驱动,输入参数为struct input_dev *
void input_unregister_device(struct input_dev *dev);//反注册输入子系统的设备驱动,输入参数为struct input_dev *
void input_free_device(s3c_ts_input);//释放分配的input_dev结构,,输入参数为struct input_dev *
static inline void input_report_abs(struct input_dev *dev, unsigned int code, int value);//上传绝对位移事件
//struct input_dev *dev表示哪个输入子系统设备的事件上传
//code表示绝对位移事件的哪类事件,可以取值ABS_PRESSURE、ABS_X、ABS_Y
//value表示事件的按键值
static inline void input_report_key(struct input_dev *dev, unsigned int code, int value);//上传按键事件
//struct input_dev *dev表示哪个输入子系统设备的事件上传
//code表示按键事件的哪类事件,可以取值BTN_TOUCH等
//value表示事件的按键值
static inline void input_sync(struct input_dev *dev);//上传同步事件,表示这次事件数据已经传送完成了

2、中断相关的函数

int request_irq(unsigned int irq, irq_handler_t handler,unsigned long irqflags, const char *devname, void *dev_id);//注册一个中断
//返回0表示注册成功,反之注册失败
//irq表示注册的中断号:有IRQ_TC、IRQ_ADC等等,位于include\asm-arm\arch-s3c2410irqs.h
//handler表示中断出现后的回调函数,函数原型为typedef irqreturn_t (*irq_handler_t)(int, void *);
//irqflags表示中断类型,可以设置为IRQF_SHARED、IRQF_DISABLED、IRQF_SAMPLE_RANDOM。位于include\linux\interrupt.h
//char *devname表示中断的名称
//void *dev_id传给中断回调函数的参数
void free_irq(unsigned int irq, void *dev_id);//释放中断
//irq表示中断号
//void *dev_id为传给中断回调函数的参数

3、定时器相关的函数

void fastcall init_timer(struct timer_list *timer);//初始化一个定时器*timer
inline void add_timer(struct timer_list *timer);//将定时器*timer将入内核
int mod_timer(struct timer_list *timer, unsigned long expires);//更改定时器*timer的定时值

5、编写程序

程序的大致思路为:

1、分配一个input_dev结构体

2、设置input_dev结构体

3、注册input_dev结构体

4、硬件相关的操作

  a、使能ADC时钟  

  b、设置S3C2440的ADC/TS寄存器

  c、注册INT_TC中断

  d、注册INT_ADC中断

  f、设置一个定时器用于长按处理

程序流程:

1、首先触摸屏位于等待按下状态;

2、待按键按下后,进入INTC_TC中断,在中断里面设置为INT_ADC中断等待ADC转换完成;

3、转换完成后进入INT_ADC中断:在里面上报X、Y坐标值;改变定时器值,使得10ms后调用定时器处理函数;设置为等待松开模式。

4、若按键在10ms内还未松开,定时器处理函数里面将触摸屏设置为INT_ADC中断模式,继续转到第3步。

5、若在10ms内松开,则进入INTC_TC中断,在中断里面设置为等待按键模式

下面是完整程序

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <asm/io.h>        //含有iomap函数iounmap函数
#include <asm/uaccess.h>//含有copy_from_user函数
#include <linux/device.h>//含有类相关的处理函数
#include <linux/fb.h>      //含有fb_info结构体定义
//#include <asm/dma-mapping.h> //含有dma_free_writecombine宏定义
//#include <linux/dma-mapping.h>  //含有dma_free_writecombine宏定义
#include <linux/platform_device.h>//含有平台设备总线模型相关变量
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/clk.h>
#include <asm-generic/errno-base.h>  //含有各种错误返回值
#include <linux/input.h>                    //含有输入子系统相关的类型
#include <linux/irq.h>    //含有IRQ_HANDLED\IRQ_TYPE_EDGE_RISING
#include <asm/irq.h>   //含有IRQT_BOTHEDGE触发类型
#include <linux/interrupt.h> //含有request_irq、free_irq函数

struct ts_regs
{
    unsigned long adccon;
    unsigned long adctsc;
    unsigned long adcdly;
    unsigned long adcdat0;
    unsigned long adcdat1;
    unsigned long adcupdn;
};

static struct input_dev *s3c_ts_input;     //新建一个输入子系统的设备层结构
static struct ts_regs *ts_reg;                  //分配一个adc触摸相关的寄存器
static struct timer_list ts_timer;                       //定义一个定时器处理长按的情况

static void enter_wait_pen_down_mode(void)//进入等待触摸笔按下的模式
{
    ts_reg->adctsc = 0xd3;//设置等待按下 模式中断
}

static void enter_wait_pen_up_mode(void)//进入等待触摸笔松开的模式
{
    ts_reg->adctsc = 0x1d3;//设置等待松开 模式中断
}

static void enter_measure_xy_mode(void)
{
    ts_reg->adctsc  = ((1<<2) | (1<<3));//设置自动测量adc模式,上拉电阻必须去掉
    ts_reg->adccon |= (1<<0);//启动adc转换
}

static irqreturn_t pen_up_down_irq(int irq, void *dev_id)
{
    if (ts_reg->adcdat0 & (1<<15))//如果是释放中断
    {
    //    printk("pen up\n");
        enter_wait_pen_down_mode();//进入等待按下模式
    }
    else//如果是按下中断
    {
    //    printk("pen down\n");
        //enter_wait_pen_up_mode();
        enter_measure_xy_mode();//进入自动转换adc模式等待ADC转换完成进入ADC中断
    }
//    if (ts_reg->adcdat1 & (1<<15))
//    {
//        printk("pen up\n");
//        enter_wait_pen_down_mode();
//    }
//    else
//    {
//        printk("pen down\n");
//        enter_wait_pen_up_mode();
//    }
    return IRQ_HANDLED;
}

static int s3c_filter_ts(int x[], int y[])//adc软件滤波
{
#define ERR_LIMIT 10

    int avr_x, avr_y;
    int det_x, det_y;

    avr_x = (x[0] + x[1])/2;
    avr_y=  (y[0] + y[1])/2;

    det_x = (avr_x > x[2])?(avr_x - x[2]):(x[2] - avr_x);
    det_y = (avr_y > y[2])?(avr_y - y[2]):(y[2] - avr_y);

    if((det_x >ERR_LIMIT) || (det_y >ERR_LIMIT))
        return 0;

    avr_x = (x[1] + x[2])/2;
    avr_y=  (y[1] + y[2])/2;

    det_x = (avr_x > x[3])?(avr_x - x[3]):(x[3] - avr_x);
    det_y = (avr_y > y[3])?(avr_y - y[3]):(y[3] - avr_y);

    if((det_x >ERR_LIMIT) || (det_y >ERR_LIMIT))
        return 0;

    return 1;

}

static irqreturn_t adc_irq(int irq, void *dev_id)
{
    static int x[4],y[4];
    static int cnt=0;

    int xvalue;
    int yvalue;
    int i;

    /*优化措施2,如果ADC完成时,发现触摸笔已经松开,则丢弃此次结果*/
    if (ts_reg->adcdat0 & (1<<15))//如果已经松开了
    {
        cnt = 0;//不能漏
        input_report_abs(s3c_ts_input,ABS_PRESSURE,0);  //压力为0
        input_report_key(s3c_ts_input,BTN_TOUCH,0);      //0表示松开
        input_sync(s3c_ts_input);                                    //事件已经处理完
        enter_wait_pen_down_mode();//直接进入等待按下模式
    }
    else
    {
          /*优化措施3:多次测量求平均值*/
        x[cnt] = ts_reg->adcdat0&0x3ff;
        y[cnt] = ts_reg->adcdat1&0x3ff;
        if(++cnt==4)//先++,再判断
        {
            if(s3c_filter_ts(x,y))//如果差值小于10
            {
                xvalue = 0;
                yvalue = 0;
                for(i=0;i<4;i++)
                {
                    xvalue = x[i] + xvalue;
                    yvalue = y[i] + yvalue;
                }
                xvalue /= 4;
                yvalue /= 4;
                input_report_abs(s3c_ts_input,ABS_X,xvalue);
                input_report_abs(s3c_ts_input,ABS_Y,yvalue);
                input_report_abs(s3c_ts_input,ABS_PRESSURE,1);//压力值为1
                input_report_key(s3c_ts_input,BTN_TOUCH,1);     //1表示按下
                input_sync(s3c_ts_input);//事件已经处理完毕

                //printk("x = %d ,y = %d\n",xvalue,yvalue);
                mod_timer(&ts_timer,jiffies+HZ/100);//

                //enter_wait_pen_up_mode();//进入等待松开模式
            }
            //else//如果差值大于10则丢弃
            //{
                enter_wait_pen_up_mode();//进入等待松开模式
            //}
            cnt = 0;
        }
        else
        {
            enter_measure_xy_mode();//继续进入自动测量模式
        }
    }

    return IRQ_HANDLED;
}

static void s3c_ts_timer_funcitin(unsigned long t)
{
    if (ts_reg->adcdat0 & (1<<15))//如果已经松开了
    {
        input_report_abs(s3c_ts_input,ABS_PRESSURE,0);  //压力为0
        input_report_key(s3c_ts_input,BTN_TOUCH,0);      //0表示松开
        input_sync(s3c_ts_input);                                    //事件已经处理完毕

        enter_wait_pen_down_mode();//直接进入等待按下模式
    }
    else
    {
        enter_measure_xy_mode();//继续进入自动测量模式
    }
}

static int s3c_ts_init(void)
{
    struct clk    *adc_clock;
    int ret;
    /* 1、分配一个input_dev结构体 */
    s3c_ts_input = input_allocate_device();//在设备层分配一个input_dev结构
    if (!s3c_ts_input)
        return -ENOMEM;

    /* 2、设置它 */
        /* 2.1 能产生哪些事件 */
    set_bit(EV_KEY, s3c_ts_input->evbit); //按键事件
    set_bit(EV_ABS, s3c_ts_input->evbit);//绝对位移事件

        /* 2.2 能产生这类事件里的哪些事件 */
       set_bit(BTN_TOUCH, s3c_ts_input->keybit);//按键事件里的BTN_TOUCH事件

       input_set_abs_params(s3c_ts_input, ABS_X, 0, 0x3FF, 0, 0);
    input_set_abs_params(s3c_ts_input, ABS_Y, 0, 0x3FF, 0, 0);
    input_set_abs_params(s3c_ts_input, ABS_PRESSURE, 0, 1, 0, 0);

    /* 3、注册 */
    input_register_device(s3c_ts_input);//注册设备驱动    

    /* 4、硬件相关的操作 */
   /* 4.1 使能时钟(CLKCON[15])*/ //为了省电,内核将不相关的外设时钟关掉 用的是PCLK时钟
    adc_clock = clk_get(NULL, "adc");
    clk_enable(adc_clock);//使能ACD时钟

   /* 4.2 设置S3C2440的ADC/TS寄存器 */
   ts_reg = ioremap(0x58000000, sizeof(struct ts_regs));//将ADC相关的寄存器的物理地址转换为虚拟地址

   /*预分配使能、预分配系数=49+1;所以ADC时钟为1M*/
   ts_reg->adccon = (1<<14) | (49<<6);

   /*优化措施1,设置ADCDLY为最大值,这使得电压稳定后再发出IRQ_TC中断*/
   ts_reg->adcdly = 0xffffffff;    //设置adc延时值,等待数值稳定后再读取相应的值

   /*注册INT_TC中断*/
  ret = request_irq(IRQ_TC, pen_up_down_irq, IRQF_SAMPLE_RANDOM,  "ts_pen", NULL);

  if(ret)
      return -1;

   /*注册INT_ADC中断*/
  ret = request_irq(IRQ_ADC,adc_irq,IRQF_SAMPLE_RANDOM,"adc",NULL);

  if(ret)
      return -1;

   /*优化措施4:使用定时器处理长按滑动的情况*/
 init_timer(&ts_timer);
 ts_timer.function = s3c_ts_timer_funcitin;
 add_timer(&ts_timer);

   /*进入等待中断模式*/
  enter_wait_pen_down_mode();//等待进入按下中断

   return 0;

}

static void s3c_ts_exit(void)
{
    input_unregister_device(s3c_ts_input);//反注册
    input_free_device(s3c_ts_input);//释放分配的input_dev结构
    iounmap(ts_reg);
    free_irq(IRQ_TC, NULL);//释放触摸中断
    free_irq(IRQ_ADC, NULL);//释放adc中断
}

module_init(s3c_ts_init);
module_exit(s3c_ts_exit);

MODULE_LICENSE("GPL");

6、测试程序

1、make menuconfog 去掉原来的触摸屏驱动程序

  Device Drives
    Input device supoport
      Generic input layer
        Touchscreens
          <>S3c2410/s3c2440 touchscreens
2、make uImage

3、重启开发版,进入UBOOT,下载编译完成的uImage_nots文件到0x30000000地址处:nfs 30000000 192.168.1.5:/work/nfs_root/uImage_nolcd。然后bootm 30000000进入此内核

4、进入系统后挂接网络文件系统mount 0t nfs -o nolock,vers=2 192.168.1.5:/work/nfs_root/first_fs /mnt

5、切换到/mnt目录。操作的就是服务器上的目录

6、制作tslib库,tslib库是介于触摸屏驱动程序与应用程序之间的接口。

  a、从网上下载tslib-1.4.tar.gz安装包

  b、tar xzf tslib-1.4.tar.gz解压

  c、cd tslib切换到tslib目录

  d、./autogen.sh运行

  e、mkdir tmp新建一个temp目录

  f、echo "ac_cv_func_malloc_0_nonnull=yes" >arm-linux.cache

  g、./configure --host=arm-linux --cache-file=arm-linux.cache --prefix=$(pwd)/tmp将安装目录设置为新建的tmp目录

  h、make编译;make install安装

  i、cd tmp切换到安装目录;cp * -rf /work/nfs_root/first_fs将当前所有文件都拷贝到网络文件系统下

7、使用tslib库,tslib库已经拷贝到了/mnt目录下

8、先安装10th_ts_drv.ko

9、修改 /etc/ts.conf第1行(去掉#号和第一个空格):

# module_raw input
    改为:
     module_raw input

10、配置环境变量

export TSLIB_TSDEVICE=/dev/event0    //使用的输入设备
export TSLIB_CALIBFILE=/etc/pointercal
export TSLIB_CONFFILE=/etc/ts.conf
export TSLIB_PLUGINDIR=/lib/ts
export TSLIB_CONSOLEDEVICE=none
export TSLIB_FBDEVICE=/dev/fb0          //使用的显示设备

11、运行ts_calibrate程序进行触摸屏校验

12、运行ts_test可以进行写字、画图等操作。

原文地址:https://www.cnblogs.com/andyfly/p/9566692.html

时间: 2024-10-08 00:21:16

Linux驱动之触摸屏程序编写的相关文章

第1个linux驱动___应用程序才是大Boss

我们的驱动模块已经可以被自动分配主设备号了,可以说到目前为止,一个驱动模块所具备的一些"基础设施"它都具备了,就像是养兵前日,用兵一时,已经可以让first_drv这个驱动模块出去打仗了. 那么说是出去打仗,总得有个发号施令的首长吧,在linux系统中,这位调兵遣将的首长就是应用程序,应用程序才是大Boss,我们"一直精雕细琢的驱动模块"说白了只是个跑腿的. 这就是为什么我们的专题是第1个linux驱动却要讲应用程序的原因,因为应用程序是让驱动程序能够被应用的,而驱

linux驱动之触摸屏驱动程序

触摸屏归纳为输入子系统,这里主要是针对电阻屏,其使用过程如下 :当用触摸笔按下时,产生中断.在中断处理函数处理函数中启动ADC转换x,y坐标.ADC结束,产生ADC中断,在ADC中断处理函数里上报(input_event)启动定时器,再次启动定时器(可以处理滑动.长按),松开按键.其驱动程序的写法和之前写输入子系统的写法基本上一致.写出入口函数,出口函数并加以修饰,加入相关头文件,然后开始完善各函数,在入口函数中分配input_dev结构体,设置(能产生哪类事件,能产生这类事件中的哪些事件),注

linux驱动系列之程序反汇编

摘抄网页:http://www.169it.com/article/330129798173630299.html 参考网页:http://www.cppblog.com/liu1061/articles/53762.html linux下objdump命令常见用法举例: objdump -x obj:以某种分类信息的形式把目标文件的数据组成输出:<可查到该文件的的所有动态库> objdump -t obj:输出目标文件的符号表() objdump -h obj:输出目标文件的所有段概括()

linux驱动之中断处理过程C程序部分

当发生中断之后,linux系统在汇编阶段经过一系列跳转,最终跳转到asm_do_irq()函数,开始C程序阶段的处理.在汇编阶段,程序已经计算出发生中断的中断号irq,这个关键参数最终传递给asm_do_irq().linux驱动中断处理C程序部分,主要涉及linux中断系统数据结构的初始化和C程序的具体执行跳转. 一.中断处理数据结构 linux内核将所有的中断统一编号,使用一个irq_desc[NR_IRQS]的结构体数组来描述这些中断:每个数组项对应着一个中断源(可能是一个中断,也可能是一

编写Linux驱动与统计单词个数

一.编写Linux驱动程序的步骤 1.建立Linux驱动骨架:也就是装载和卸载Linux驱动.在Linux驱动程序中需要提供两个函数来分别处理驱动初始化和退出的工作.这两个函数分别是module_init和module_exit宏指定. 2.注册和销毁设备文件:任何一个Linux驱动都需要一个设备文件,因为在Linux中设备都以文件的形式来存在.用misc_register和misc_deregiter函数创建和移除设备文件. 3.指定与驱动相关的信息:驱动程序是自描述的.驱动程序的作者姓名.使

迅为4412开发板Linux驱动教程——编写简单应用调用驱动

Linux驱动教程:http://pan.baidu.com/s/1c0hljUS 编写简单应用调用驱动--头文件 ? 打印头文件 – include <stdio.h>调用打印函数printf ? 应用中调用文件需要的头文件 – #include <sys/types.h>基本系统数据类型.系统的基本数据类型在32 编译 环境中保持为32 位值,并会在64 编译环境中增长为64 位值. – #include <sys/stat.h>系统调用函数头文件.可以调用普通文件

编写一个陌生的linux驱动的技巧

编写一个陌生的linux驱动的技巧 当你要写一个陌生的linux子系统的驱动时,例如v4l2的camera sensor驱动.首先你得去google.百度搜索一些关于这个子系统****框架的介绍,由于网上文章往往有错误,所以你要多看几篇好的文章,从而有一定了解.然后需要看linux相关的子系统的代码,特别是子系统的api,从而更深入的了解.然后你找一个使用该子系统的应用层和驱动代码例子,进一步理解.然后你基于已有的demo硬件和该子系统设备的驱动,例如camera sensor驱动ov5640_

Linux/Android——usb触摸屏驱动 - usbtouchscreen

最近需要往TV上装一个触摸屏设备,现在比较常见的就是使用usb接口的触摸框,适用于各种平台,这里大体记录一下在android上kernel中的usbtouchscreen驱动. 撰写不易,转载需注明出处:http://blog.csdn.net/jscese/article/details/41827495 驱动编译: 目前的kernel中都是自带了usbtouchscreen驱动的,我的版本3.1.10 源码位于:/kernel/drivers/input/touchscreen/usbtou

disk磁盘管理与Linux驱动编写

磁盘管理 一.关于硬盘接口 安装linux red hat系统,到分区时发现硬盘驱动器设备 /dev/sda             #sata接口设备名 /dev/sda1 #sda对应的物理分区 /dev/sda2 /dev/sda3 而又的安装时硬盘驱动设备名为 /dev/hda #IDE接口设备目录 /dev/hda1 sda和hda有什么区别那? HDA是使用了ide接口的硬盘的名称.SDA是sata接口的硬盘的名称.在最新的2.6.19内核里,所有的硬盘都叫SDA了. GERUB里填