Linux驱动开发_输入子系统、触摸屏坐标上报
任务1: 输入子系统
按键设备、触摸屏设备、三轴加速计设备、鼠标设备、标准键盘设备……。
输入子系统: 统一形态各异的输入设备。
输入子系统使用步骤
1. 定义某一个结构体或者动态分配某一个结构体
2. 根据结构体成员,进行初始化赋值
3. 注册输入子系统
4. 当按键按下时,再根据输入子系统核心的层的标准函数进行按键值上报。
5. 驱动卸载时,再将输入子系统注销掉。
应用读取的输入子系统标准结构体:
输入子系统上报(重定向系统标准输入):
[root@tiny4412 code]#exec 0</dev/tty1 |
上报触摸屏标准坐标
触摸屏上报的值有哪些? X坐标值、Y坐标值、压力值(代表触摸屏按下或者松开)。
绝对坐标不只是触摸屏: 触摸屏驱动上报的时候,需要增加一些标志信息。
Tslib库运用
编译的步骤:
1. 解压…….
2. 生成配置文件: [root@wbyq tslib-master]# ./autogen.sh
3. 生成Makefile:
[root@wbyq tslib-master]# ./configure --host=arm-linux ac_cv_func_malloc_0_nonnull=yes --cache-file=arm-linux.cache -prefix=$PWD/tslib |
4. 编译并安装
[root@wbyq tslib-master]# make && make install |
5. 并将编译好的文件拷贝到开发板对应目录下
6. 修改etc/ts.conf文件 ,将第2行注释去掉,删除多余的空格(顶格)
7. 拷贝ts插件目录到开发板上
8. 设置tslib使用的环境变量
安装rpm后缀的安装包:
[root@wbyq Packages]# rpm -ivh <包名称>.rpm |
获取系统环境变量的函数
#include <stdlib.h> char *getenv(const char *name); |
参数: const char *name :环境的名称。
返回值: 获取到环境变量里的字符串数据。
#include <stdio.h> #include <stdlib.h> int main() { char *p=getenv("PATH"); printf("p=%s\n",p); return 0; } |
1. 按键输入子系统方式上报编写一次
2. 触摸屏也是用输入子系统方式编写一次
3. 移植tslib库。
4. 继续做: 数码相册。
动态库处理函数
#include <dlfcn.h> void *dlopen(const char *filename, int flag); char *dlerror(void); void *dlsym(void *handle, const char *symbol); int dlclose(void *handle); 用法示例: handle=dlopen("lib123.so", int flag); void (abc*)(int,int); abc=dlsym(handle,"abc"); abc(12,45); int main() { abc(12,45); } gcc 456.c -L/work -l123 |
触摸屏的驱动上报:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <linux/fb.h>
#include <linux/dma-mapping.h>
#include <linux/workqueue.h>
#include <linux/wait.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/fcntl.h>
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/delay.h>
#include <linux/workqueue.h>
#include <linux/gpio.h>
#include <mach/gpio.h>
#include <plat/gpio-cfg.h>
#include <linux/timer.h>
#include <linux/miscdevice.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/timer.h>
static struct i2c_client *touch_client=NULL;
static struct input_dev *ft5x06_touch_dev=NULL;
/*工作处理函数*/
static void tiny4412_work_func(struct work_struct *work)
{
/*读取触摸屏的坐标值*/
u8 buff[7];
u32 x,y;
i2c_smbus_read_i2c_block_data(touch_client,0,7,buff);/*读取第一个点*/
x=(buff[3]&0xF)<<8|buff[4];
y=(buff[5]&0xF)<<8|buff[6];
if(buff[2]&0xF) /*判断是否按下*/
{
input_report_abs(ft5x06_touch_dev,ABS_PRESSURE,1);
input_report_key(ft5x06_touch_dev,BTN_TOUCH,1);
printk("x=%d,y=%d,ABS_PRESSURE=%d\n",x,y,1);
}
else
{
input_report_abs(ft5x06_touch_dev,ABS_PRESSURE,0);
input_report_key(ft5x06_touch_dev,BTN_TOUCH,0);
printk("x=%d,y=%d,ABS_PRESSURE=%d\n",x,y,0);
}
input_report_abs(ft5x06_touch_dev,ABS_X,x);
input_report_abs(ft5x06_touch_dev,ABS_Y,y);
/*将输入的信息同步给事件层*/
input_sync(ft5x06_touch_dev);
}
/*静态声明工作队列*/
static DECLARE_WORK(touch_wq,tiny4412_work_func);
/*触摸屏的中断服务函数*/
static irqreturn_t tiny4412_touch_handler(int irq, void *dev)
{
schedule_work(&touch_wq); /*将工作加入到一个工作队列里去*/
return IRQ_HANDLED;
}
static int touch_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
u8 touch_id;
printk("触摸屏驱动端匹配成功:0x%X\n",client->addr);
touch_client=client;
/*IIC子系统标准的读函数*/
i2c_smbus_read_i2c_block_data(client,0xA3,1,&touch_id); /*读取厂家ID*/
printk("厂家ID=%d\n",touch_id);
/*动态分配一个输入子系统结构体*/
ft5x06_touch_dev=input_allocate_device();
/*设置输入子系统的功能(能力)*/
input_set_capability(ft5x06_touch_dev,EV_ABS,ABS_X);
input_set_capability(ft5x06_touch_dev,EV_ABS,ABS_Y);
input_set_capability(ft5x06_touch_dev,EV_ABS,ABS_PRESSURE);
input_set_capability(ft5x06_touch_dev,EV_KEY,BTN_TOUCH); /*代表当前输入子系统上报的是触摸屏坐标*/
/*设置绝对坐标参数*/
input_set_abs_params(ft5x06_touch_dev, ABS_X, 0,800-1, 0, 0);
input_set_abs_params(ft5x06_touch_dev, ABS_Y, 0,1280-1, 0, 0);
input_set_abs_params(ft5x06_touch_dev, ABS_PRESSURE,0,1,0,0);
/*注册输入子系统设备*/
input_register_device(ft5x06_touch_dev);
/*注册中断*/
printk("client->irq中断号:%d (430)\n",client->irq);
int err=request_irq(client->irq,tiny4412_touch_handler,IRQ_TYPE_EDGE_BOTH,client->name,NULL);
printk("中断注册状态:%d (0表示成功)\n",err);
return 0;
}
static int touch_remove(struct i2c_client *client)
{
printk("触摸屏驱动端卸载成功!\n");
/*释放中断号*/
free_irq(client->irq,NULL);
/*注销输入子系统设备*/
input_unregister_device(ft5x06_touch_dev);
/*注销动态分配的结构体*/
input_free_device(ft5x06_touch_dev);
return 0;
}
static struct i2c_device_id touch_id[]=
{
{"tiny4412_ft5x06",0},
{}
};
static struct i2c_driver touch_driver=
{
.probe=touch_probe,
.remove=touch_remove,
.driver=
{
.name="touch_drv",
},
.id_table=touch_id
};
static int __init tiny4412_touch_init(void)
{
/*1. 注册IIC子系统驱动端*/
i2c_add_driver(&touch_driver);
return 0;
}
static void __exit tiny4412_touch_exit(void)
{
/*2. 注销IIC子系统驱动端*/
i2c_del_driver(&touch_driver);
}
module_init(tiny4412_touch_init);
module_exit(tiny4412_touch_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("tiny4412 wbyq");
- 点赞
- 收藏
- 关注作者
评论(0)