驱动应该是在/lib/modules/内核版本/kernel/drives/usb下,
当然另外还要mousedev模块吧。
我只是提供个思路,也没有试过安装
#include <linux/miscdevice.h>#include <linux/delay.h>
#include <asm/irq.h>
#include <mach/hardware.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/string.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <asm/unistd.h>
#include <mach/map.h>
#include <mach/regs-clock.h>
#include <mach/regs-gpio.h>
#include <plat/gpio-cfg.h>
#include <mach/gpio-bank-e.h>
#include <mach/gpio-bank-m.h>
#define DEVICE_NAME "s3c6410_keys" //定义设备名字
static int major //定义按键设备的主设备号变量
volatile unsigned long *gpncon
volatile unsigned long *gpndat
static struct class *keys_class //使用mdev机制让内核自动创建对应的设备节点文件
static struct class_device *keys_class_devs
//key驱动程序的open函数,用来初始化key设备 对应应用程序里面的open函数
static long s3c6410_keys_open(struct inode *inode, struct file *file)
{
//OK6410A的key1-6连接到gpn0-5
//gpn0-5 input mode
*gpncon &=~((0x3<<(0*2))|(0x3<<(1*2))|(0x3<<(2*2))|(0x3<<(3*2))|(0x3<<(4*2))|(0x3<<(5*2)))
return 0
}
//key驱动程序的读函数
static long s3c6410_keys_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
{
/*返回6个引脚的电平状态*/
unsigned char key_vals[6]
int regzhi,i
if(size!=sizeof(key_vals))
return -EINVAL
regzhi=*gpndat
for (i=0i<6i++)
key_vals[i]=(regzhi &(1<<i)) ? 1 : 0
copy_to_user(buf,key_vals,sizeof(key_vals)) //将内核空间的数据key_vals复制到用户空间buf指向的内存空间
return sizeof(key_vals)
}
//定义file_operations类型的结构体,当应用程序 *** 作设备文件时使用的read . write .open等系统调用,
//最终会调用该结构体中的对应函数
static struct file_operations OK6410A_keys_fops={
.owner = THIS_MODULE,
.open = s3c6410_keys_open,
.read = s3c6410_keys_read,
}
//当执行insmod 命令安装key驱动程序时会调用该函数,该函数实现将该驱动注册进内核
static int __init ok6410a_key_init(void)
{
major = register_chrdev(0, DEVICE_NAME, &OK6410A_keys_fops) //由内核自动分配key的主设备号,将key的主设备号与设备 *** 作结构体OK6410A_keys_fops关联起来
if (major <0) { //分配失败
printk(DEVICE_NAME " can't register major number\n")
return major}
keys_class = class_create(THIS_MODULE, "ok6410_keys") //创建一个类,在根文件系统的/sys/class/目录下会创建对应的类(ok6410_keys)目录
if (IS_ERR(keys_class))
return PTR_ERR(keys_class)
keys_class_devs = device_create(keys_class, NULL, MKDEV(major, 0), NULL, DEVICE_NAME)//创建该类的一个设备
if (unlikely(IS_ERR(keys_class_devs))) //创建设备节点文件/dev/DEVICE_NAME (s3c6410_keys)
return PTR_ERR(keys_class_devs)
gpncon=(volatile unsigned long *)ioremap(0x7f008830,12)
gpndat=gpncon+1
printk(DEVICE_NAME " initialized\n")
return 0
}
//执行rmmod 命令时卸载key驱动是调用的函数
static void __exit ok6410a_key_exit(void)
{
/* 卸载驱动程序 */
unregister_chrdev(major, DEVICE_NAME)
device_unregister(keys_class_devs)
iounmap(gpncon)
class_destroy(keys_class) //删除创建的类
}
//以下两行指定驱动程序的初始化函数和卸载函数
module_init(ok6410a_key_init)
module_exit(ok6410a_key_exit)
MODULE_LICENSE("GPL") //遵循的协议
测试程序:
/***********************************************************************************************************
key驱动程序的应用测试程序
命令格式: key_teston
key_testoff
************************************************************************************************************/
//包含进内核中有的头文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//一个应用程序有一个main函数,为该应用程序的入口处
int main(int argc, char **argv) //argc为使用key_test 命令时传入的参数个数,argv为具体的参数
{
int fd,cnt=0
unsigned char key_vals[6]
fd = open("/dev/s3c6410_keys", O_RDWR) //打开key设备对应的设备文件,前提是必须存在
if (fd <0)
{
printf("can't open /dev/key\n")
return -1
}
while
(1)
{read(fd,key_vals,sizeof(key_vals))
if(!key_vals[0] || !key_vals[1] || !key_vals[2] || !key_vals[3] || !key_vals[4] || !key_vals[5])
printf("%04d key pressed: %d %d %d %d %d %d\n",cnt++,key_vals[0],key_vals[1],key_vals[2],key_vals[3],key_vals[4],key_vals[5])
}
return 0
}
ps:这是采用查询方式设计的按键驱动程序,望采纳!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)