- 论坛徽章:
- 0
|
在linuxdrivers.cn上发表过,转贴到这里问问.
这几天研究触摸板的Linux驱动。看了不少资料,发现主要的代码没有多少,关键倒是和Linux内核交互的东西高不明白。
拿内核源码的驱动改成自己的,硬是起不来,又不知道如何解决。
下面是我的源代码框架,贴在这里,顺便列出自己不明白的地方,请达人指教:
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/serio.h>
#include <linux/init.h>
#define DRIVER_DESC "Serial touchpad driver"
MODULE_AUTHOR("foobar<foobar@foobar.com>");
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
/**
* Per-touchpad data.
*/
struct sertp {
struct input_dev *dev; /**< input device */
struct serio *serio; /**< serio struct */
s32 id; /**< device id */
u8 buf[8]; /**< buffer to receive data */
u8 pre_cnt; /**< received byte pre_cnter */
s8 phys[32];
};
static irqreturn_t sertp_interrupt(struct serio *serio,
u8 data,
u32 flags,
struct pt_regs *regs)
{
struct sertp *sertp = serio_get_drvdata(serio);
printk (KERN_ALERT "sertp_interrupt\n");
sertp_process_data(sertp, data, regs); /* start processing data */
return IRQ_HANDLED;
}
static void sertp_disconnect(struct serio *serio)
{
struct sertp *sertp = serio_get_drvdata(serio);
printk (KERN_ALERT "sertp_disconnect\n");
input_unregister_device(sertp->dev);
serio_close(serio);
serio_set_drvdata(serio, NULL);
kfree(sertp);
}
static int sertp_connect(struct serio *serio, struct serio_driver *drv)
{
struct sertp *sertp;
struct input_dev *input_dev;
int err;
printk (KERN_ALERT "sertp_connect\n"); /* allocate our struct data and input device */
sertp = kzalloc(sizeof(struct sertp), GFP_KERNEL);
input_dev = input_allocate_device();
if (!sertp || !input_dev) {
err = -ENOMEM;
goto fail;
}
sertp->serio = serio;
sertp->id = serio->id.id;
sertp->dev = input_dev;
snprintf(sertp->phys, sizeof(sertp->phys), "%s/input0", serio->phys); /* Q0 */
input_dev->private = sertp;
input_dev->name = "Serial TouchPad";
input_dev->phys = sertp->phys; /* Q1 */
input_dev->id.bustype = BUS_RS232;
input_dev->id.vendor = SERIO_ANY; /* Q2 */
input_dev->id.product = sertp->id;
input_dev->id.version = 0x0100;
input_dev->cdev.dev = &serio->dev;
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y) | BIT(REL_WHEEL) | BIT(REL_HWHEEL);
serio_set_drvdata(serio, sertp);
err = serio_open(serio, drv);
if (err) goto fail;
input_register_device(sertp->dev);
return 0;
fail: serio_set_drvdata(serio, NULL);
input_free_device(input_dev);
kfree(sertp);
return err;
}
static struct serio_device_id sertp_serio_ids[] = {
{ .type = SERIO_RS232,
.proto = SERIO_ANY, /* Q3 */
.extra = SERIO_ANY,
.id = SERIO_ANY,
},
{ 0 }
};
MODULE_DEVICE_TABLE(serio, sertp_serio_ids);
static struct serio_driver sertp_drv = {
.driver = {
.name = "sertp",
},
.description = DRIVER_DESC,
.id_table = sertp_serio_ids,
.interrupt = sertp_interrupt,
.connect = sertp_connect,
.disconnect = sertp_disconnect,
};
static int __init sertp_init(void)
{
printk (KERN_ALERT "sertp_init\n");
serio_register_driver(&sertp_drv);
return 0;
}
static void __exit sertp_exit(void)
{
printk (KERN_ALERT "sertp_exit\n");
serio_unregister_driver(&sertp_drv);
}
/* Module interfaces */
module_init(sertp_init);
module_exit(sertp_exit); |
以上是基于串口的触摸板驱动。
我的设计流程大致如下:
1. 接好硬件设备,我的串口触摸板只接了Rx和Tx两根线,不知道这样能不能触发中断;
2. 编写如上代码,然后写了一个Makefile生成.ko模块文件;
3. 使用insmod指令加载驱动模块,发现加载的时候打印出"sertp_init"字符串,表明初始化函数成功调用;
4. 但是实际触摸触摸板时,发现connect函数和中断函数均为调用。但是硬件设备能够正常往串口发送数据的,我用moni调试过,能够确保硬件没问题;
5. 使用rmmod指令卸载模块,发现卸载时打印出"sertp_exit"字符串,表明退出函数成功调用。
我不清楚是哪一步有问题,导致设备发生事件时没有产生中断。请指教
对于上面的代码,标示为Q0~Q3的是我不太明白的地方:
Q0:这条语句的含义是什么?
Q1:serio->phys是做什么用的,需要驱动程序员自己手动填写的还是由input子系统事先预填的?
Q2:input_dev->id有四个字段,bustype、vendor、product和version,这四个字段是怎么确定的?当然了,我这个是串口驱动,bustype我想应该填写BUS_RS232,对不?
Q3:这里的serio_device_id又是4个字段,除了.type我参照touchscreen/elo.c的驱动填写成SERIO_RS232,其他的我真是丈二和尚摸不着头脑,望赐教。
最倒霉的是connect和中断函数不被调用,我连调试也不知道怎么入手
最后给所有进行串口调试的同仁推荐一个Linux下的很不错的串口监视器:Moni
http://www.rolf-schroedter.de/moni/
能够输出16进制数值。程序用Tcl/Tk编写的,使用了startkit封装。使用按主页提示先下载一个tclkit,然后运行。
那个minicom我搞了半天也不能显示16进制,根本无法进行串口调试,只好放弃。
[ 本帖最后由 shaohao 于 2009-3-19 22:17 编辑 ] |
|