简单字符设备驱动——LED驱动

来源:互联网 发布:西安移动网络怎么样 编辑:程序博客网 时间:2024/06/06 00:00

驱动程序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  0static 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  0static 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