废话少说,直接贴代码吧:
<span style="font-size:18px;">#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <linux/irq.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <linux/interrupt.h>
#include <asm/uaccess.h>
#include <mach/hardware.h>
#include <linux/platform_device.h>
#include <linux/cdev.h>
#include <linux/miscdevice.h>
#include <mach/map.h>
#include <mach/regs-clock.h>
#include <mach/regs-gpio.h>
#include <plat/gpio-cfg.h>
#include <mach/gpio-bank-n.h>
#include <mach/gpio-bank-l.h>
static unsigned button_major;
static dev_t button_id; /*设备号*/
static struct cdev button_cdev;
static struct class *button_class;
static struct device *button_device;
static int myButton_open(struct inode * inode, struct file * file)
{
return 0;
}
static int myButton_write(struct file *filp,const char __user *buf,size_t count,loff_t *f_pos)
{
return 0;
}
static int myButton_read(struct file *file, char __user *userbuf, size_t bytes, loff_t *off)
{
char temp[10];
temp[0] = readl(S3C64XX_GPNDAT)&(0xf); /*GPN0~3对应于按键K1~K4*/
if(copy_to_user(userbuf, temp, bytes)) /*成功时返回0,失败时返回没有成功拷贝的字符个数*/
{
printk("copy_to_user error\n");
return -1;
}
//printk("myButton_read succeed\n");
return 0;
}
struct file_operations button_fiops=
{
.owner = THIS_MODULE,
.open = myButton_open,
.write = myButton_write,
.read = myButton_read,
};
static int myButton_init(void)
{
alloc_chrdev_region(&button_id, 0, 2,"myButton_drv" );
button_major = MAJOR(button_id);
cdev_init(&button_cdev, &button_fiops);
cdev_add(&button_cdev, button_id, 2);
button_class = class_create(THIS_MODULE, "myButton");
button_device = device_create(button_class, NULL, MKDEV(button_major , 0), NULL, "myButton0"); /*创建设备节点/dev/myButton0*/
button_device = device_create(button_class, NULL, MKDEV(button_major , 1), NULL, "myButton1"); /*创建设备节点/dev/myButton1*/
printk("myButton init succeed\n");
return 0;
}
static void myButton_exit(void)
{
device_destroy(button_class, MKDEV(button_major , 0));
device_destroy(button_class, MKDEV(button_major , 1));
class_destroy(button_class);
cdev_del(&button_cdev);
unregister_chrdev_region(button_id, 2);
printk("myButton exit succeed\n");
}
module_init(myButton_init);
module_exit(myButton_exit);
MODULE_LICENSE("GPL");</span>
Makefile文件如下:
<span style="font-size:18px;">obj-m := mybutton_drv2.o
KDIR :=/home/lijunliang/windows-files/linux-tiny6410
all :
make -C $(KDIR) M=$(PWD) modules CROSS_COMPILE=arm-linux- ARCH=arm
clean :
rm -f *.ko *.o *.mod.o *.mod.c *.symvers *.bak *.order
</span>
测试程序:
<span style="font-size:18px;">#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define bufferSize 10
int main(void)
{
int fd;
char userbuffer[bufferSize];
fd = open("/dev/myButton0",O_RDWR);
while(1)
{
read(fd ,userbuffer,bufferSize);
switch(userbuffer[0])
{
case 0xe: printf("K1 按下\n");
break;
case 0xd: printf("K2 按下\n");
break;
case 0xb: printf("K3 按下\n");
break;
case 0x7: printf("K4 按下\n");
break;
default : break;
}
}
//printf("%x\n",userbuffer0[0]);
return 0;
}
</span>