驱动程序ledkey_drv.c
#include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #include <linux/init.h> #include <linux/miscdevice.h> #include <linux/delay.h> #include <asm/irq.h> #include <mach/hardware.h> #include <linux/cdev.h> #include <linux/device.h> #include <linux/gpio.h> #include <plat/gpio-cfg.h> #include <mach/regs-gpio.h> #include <linux/delay.h> #define DEVICE_NAME "ledkey" #define LEDKEY_MAJOR 241 /*棰勮鐨刟dc鐨勪富璁惧鍙?/ static int ledkey_MAJOR=LEDKEY_MAJOR; #define Led_ON 1 #define Led_OFF 0 static struct cdev cdev_ledkey; struct class *ledkey_class; static long s3c6410_ledkey_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { unsigned char k; switch(cmd) { case 0: gpio_set_value(S3C64XX_GPP(0),0); k=gpio_get_value(S3C64XX_GPP(0)); printk("<0>\n Led is OFF,GPP0= %d\n",k); break; case 1: gpio_set_value(S3C64XX_GPP(0),1); k=gpio_get_value(S3C64XX_GPP(0)); printk("<0>\n Led is ON,GPP0= %d\n",k); break; default: printk("fail\n"); printk("<0>\n please enter the cmd again!\n"); return -EINVAL; } } static int s3c6410_ledkey_open(struct inode *inode, struct file *filp) { s3c_gpio_cfgpin(S3C64XX_GPP(0), 0x01); /*閰嶇疆寮曡剼GPP0锛岃緭鍑烘柟寮?姝や负杈撳嚭*/ // printk("<0>閰嶇疆寮曡剼GPP0涓鸿緭鍑?\n"); return 0; } static struct file_operations s3c6410_ledkey_fops = { .owner = THIS_MODULE, .unlocked_ioctl = s3c6410_ledkey_ioctl, .open = s3c6410_ledkey_open, }; static int __init s3c6410_ledkey_init(void) { int result; dev_t devno = MKDEV(ledkey_MAJOR,0); // result = register_chrdev_region(devno,1,DEVICE_NAME); /* 闈欐€佺敵璇疯澶囧彿 */ result = alloc_chrdev_region(&devno,0,1,DEVICE_NAME); /* 鍔ㄦ€佺敵璇疯澶囧彿 */ ledkey_MAJOR=MAJOR(devno); if(result) { printk(KERN_NOTICE "Error %d register ledkey",result); return result; } cdev_init(&cdev_ledkey,&s3c6410_ledkey_fops); /*鍒濆鍖栧苟娉ㄥ唽cdev*/ result = cdev_add(&cdev_ledkey,devno,1); if(result) { printk(KERN_NOTICE "Error %d adding ledkey",result); return result; } ledkey_class = class_create(THIS_MODULE, "ledkey_class"); /*鍦╯ys涓嬪垱寤虹被鐩綍/sys/class/ledkey_class*/ device_create(ledkey_class, NULL, MKDEV(ledkey_MAJOR,0), "NULL","ledkey"); /*鑷姩鍒涘缓璁惧鏂囦欢*/ return 0; } static void __exit s3c6410_ledkey_exit(void) { cdev_del(&cdev_ledkey); /*娉ㄩ攢cdev*/ unregister_chrdev_region(MKDEV(ledkey_MAJOR,0),1); /*閲婃斁璁惧鍙?/ device_destroy(ledkey_class,MKDEV(ledkey_MAJOR,0)); class_destroy(ledkey_class); } module_init(s3c6410_ledkey_init); module_exit(s3c6410_ledkey_exit); MODULE_LICENSE("GPL");
测试程序ledkey_test.c
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/ioctl.h> #include <string.h> #define Led_ON 1 #define Led_OFF 0 static int fd; int main(int argc, char *argv[]) { fd = open("/dev/ledkey", 0); if (fd < 0) { perror("Failed to open ledkey"); exit(1); } printf("opend ledkey success!\n"); if(strcmp("Led_ON", argv[1])==0) { printf("Led is ON!\n"); ioctl(fd, Led_ON); } else if(strcmp("Led_OFF", argv[1])==0) { printf("Led is OFF!\n"); ioctl(fd, Led_OFF); } else { printf("please input Led_ON or Led_OFF!\n"); } close(fd); return 0; }
Makefile
ifneq ($(KERNELRELEASE),) obj-m := ledkey_drv.o else KDIR := /home/ok6410/linux3.0.1/linux-3.0.1 all: make -C $(KDIR) M=$(PWD) ARCH=arm CROSS_COMPILE=arm-linux- clean: rm -f *.ko *.o *.mod.o *.mod.c *.symvers endif