linux字符设备驱动-LED驱动

2019-07-12 18:16发布

字符设备驱动-LED驱动 嵌入式Linux版本:linux2.6.24 驱动源码: //================================================= //version: linux2.6.24 //led_pin:GB5/GB6/GB8/GB10 //================================================= #include #include #include #include #include #include #include #include #include #include #include #include #include   #define DEVICE_NAME      "leds"    //定义设备名 #define LED_MAJOR        231       //手动定义主设备号 #define LED_MINOR        0   //定义要操作的设备,把每一个led作为结构体的一个成员 static unsigned long led_table [] = {                  S3C2410_GPB5,         S3C2410_GPB6,         S3C2410_GPB8,         S3C2410_GPB10, }; //对设备进行设置,结构体的每一个成员是对对应led的设置 static unsigned int led_cfg_table [] = {         S3C2410_GPB5_OUTP,                         //0x01<<10 defined in  refg-gpio.h         S3C2410_GPB6_OUTP,         S3C2410_GPB8_OUTP,         S3C2410_GPB10_OUTP, }; //设备驱动程序中对设备的I/O通道进行管理的函数,用来实现对led的操作 static int s3c2410_leds_ioctl(struct inode *inode,        struct file *file, unsigned int cmd, unsigned long arg) {     switch(cmd) {         case 0:         case 1:             if (arg > 4)                 return -EINVAL;             s3c2410_gpio_setpin(led_table[arg], !cmd);             return 0;         default:             return -EINVAL;     } } // static struct file_operations s3c2410_leds_fops = {     .owner    =    THIS_MODULE,     .ioctl    =    s3c2410_leds_ioctl, }; /**  *  * struct cdev of 'led_dev'  *   */ struct cdev *my_cdev; struct class *my_class; //========================================= //            模块加载函数 //======================================== static int __init s3c2410_leds_init(void) {     int err, i;     int devno = MKDEV(LED_MAJOR, LED_MINOR);//Get device number .       /* register the 'dummy_dev' char device */     my_cdev = cdev_alloc();     cdev_init(my_cdev, &s3c2410_leds_fops);     my_cdev->owner = THIS_MODULE;     err = cdev_add(my_cdev, devno, 1);     if (err != 0)         printk("led device register failed! ");     /* creating your own class */     my_class = class_create(THIS_MODULE, "led_class");     if(IS_ERR(my_class)) {         printk("Err: failed in creating class. ");         return -1;      }     /* register your own device in sysfs, and this will cause udevd to create corresponding device node */     class_device_create(my_class, NULL, devno, NULL, DEVICE_NAME "%d", LED_MINOR );     //======led端口配置,数组不要超长,否则会导致insmodsegment fault========     for (i = 0; i < 4; i++) {         s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);         s3c2410_gpio_setpin(led_table[i], 1);     }     printk("Led_Driver insmod success! ");     return 0; } //======================================== //            模块卸载函数 //======================================= static void __exit s3c2410_leds_exit(void) {     cdev_del(my_cdev);     class_device_destroy(my_class, MKDEV(LED_MAJOR, LED_MINOR));     class_destroy(my_class);     printk("Led_Driver removed success! "); }   module_init(s3c2410_leds_init); module_exit(s3c2410_leds_exit); MODULE_LICENSE("GPL");
工程管理Makefile: #Makefile for s3c2440_leds.c obj-m :=led_driver.o KERNELDIR ?=/home/zhw123/linux-2.6.24 PWD := $(shell pwd) default:         $(MAKE) -C $(KERNELDIR) M=$(PWD) modules clean:         rm -r led_driver.mod.c led_driver.mod.o led_driver.o Module.symvers disclean:         rm -r led_driver.mod.c led_driver.mod.o led_driver.o led_driver.ko Module.symvers
测试函数: #include "stdio.h" #include "unistd.h" #include "sys/types.h" #include "sys/ioctl.h" #include "stdlib.h" #include "termios.h" #include "sys/stat.h" #include "fcntl.h" #include "sys/time.h"
 
  int main(void) {             int on=1;        int led;        int fd;        fd=open("/dev/leds",0); //打开设备文件        if(fd<0)        {               perror("open device leds");               exit(1);        }        printf("leds test show,press ctrl+c to exit ");        while(1)        {               for(led=0;led<4;led++)               {                      ioctl(fd,on,led); //反转LED                      usleep(50000);               }               on=!on;        }        close(fd);        return 0; }
测试: 1.Makefile和驱动文件放在同一目录下,make产生insmod led_driver.ko文件。 2.开发板上:insmod led_driver.ko 打印出:Led_Driver insmod success!   lsmod查看设备驱动安装情况 3.开发板上:在/mnt/dev下面mknod leds c 231 0 创建设备节点 4.开发板上:./led       LED开始依次闪烁 5.开发板上:rmmod led_driver.ko卸载模块  打印出:Led_Driver removed success!