zoukankan      html  css  js  c++  java
  • Linux驱动设计——字符杂项设备

    杂项设备

    linux里面的misc杂项设备是主设备号为10的驱动设备,misc设备其实也就是特殊的字符设备,可自动生成设备节点。
    定义头文件<linux/miscdevice.h>
     
    杂项设备的结构体:
    struct miscdevice{
        int minor; //杂项设备的此设备号(如果设置为MISC_DYNAMIC_MINOR,表示系统自动分配未使用的minor)
        const char *name;
        const stuct file_operations *fops;//驱动主题函数入口指针
        struct list_head list;
        struct device *parent;
        struct device *this device;
        const char *nodename;(在/dev下面创建的设备驱动节点)
        mode_t mode;
    }; 
    注册和释放
    注册:int misc_register(struct miscdevice *misc)
    释放:int misc_deregister(struct miscdevice *misc)
     
    misc_device是特殊字符设备。注册驱动程序时采用misc_register函数注册,此函数中会自动创建设备节点,即设备文件。无需mknod指令创建设备文件。因为misc_register()会调用class_device_creat或者device_creat().
    杂项字符设备和一般字符设备的区别:
    1.一般字符设备首先申请设备号。  但是杂项字符设备的主设备号为10次设备号通过结构体struct miscdevice中的minor来设置。
    2.一般字符设备要创建设备文件。 但是杂项字符设备在注册时会自动创建。
    3.一般字符设备要分配一个cdev(字符设备)。  但是杂项字符设备只要创建struct miscdevice结构即可。
    4.一般字符设备需要初始化cdev(即给字符设备设置对应的操作函数集struct file_operation). 但是杂项字符设备在结构体truct miscdevice中定义。
    5.一般字符设备使用注册函数 int cdev_add struct (cdev *p,devt_t dev, unsigned)(第一个参数为之前初始化的字符设备,第二个参数为设备号,第三个参数为要添加设备的个数) 而杂项字符设备使用int misc_register(struct miscdevice *misc)来注册
     
    驱动调用的实质:
    就是通过 设备文件找到与之对应设备号的设备,再通过设备初始化时绑定的操作函数硬件进行控制
     
      1 #include <linux/miscdevice.h>
      2 #include <linux/delay.h>
      3 #include <asm/irq.h>
      4 #include <mach/regs-gpio.h>
      5 #include <mach/hardware.h>
      6 #include <linux/kernel.h>
      7 #include <linux/module.h>
      8 #include <linux/init.h>
      9 #include <linux/mm.h>
     10 #include <linux/fs.h>
     11 #include <linux/types.h>
     12 #include <linux/delay.h>
     13 #include <linux/moduleparam.h>
     14 #include <linux/slab.h>
     15 #include <linux/errno.h>
     16 #include <linux/ioctl.h>
     17 #include <linux/cdev.h>
     18 #include <linux/string.h>
     19 #include <linux/list.h>
     20 #include <linux/pci.h>
     21 #include <linux/gpio.h>
     22 #include <asm/uaccess.h>
     23 #include <asm/atomic.h>
     24 #include <asm/unistd.h>
     25  
     26  
     27 #define DEVICE_NAME "leds"
     28  
     29 #define IOCTL_LED_ON 1
     30 #define IOCTL_LED_OFF 0
     31  
     32 static unsigned long led_table [] =
     33 {
     34 S3C2410_GPB(5),
     35 S3C2410_GPB(6),
     36 S3C2410_GPB(7),
     37 S3C2410_GPB(8),
     38 };
     39  
     40 static unsigned int led_cfg_table [] =
     41 {
     42 S3C2410_GPIO_OUTPUT,
     43 S3C2410_GPIO_OUTPUT,
     44 S3C2410_GPIO_OUTPUT,
     45 S3C2410_GPIO_OUTPUT,
     46 };
     47  
     48 static int gt2440_leds_ioctl(
     49 // struct inode *inode, 
     50 struct file *file, 
     51 unsigned int cmd, 
     52 unsigned long arg)
     53 {
     54 if (arg > 4)
     55 {
     56 return -EINVAL;
     57 }
     58  
     59 switch(cmd)
     60 {
     61 case IOCTL_LED_ON:
     62 // 设置指定引脚的输出电平为0
     63 s3c2410_gpio_setpin(led_table[arg], 0);
     64 return 0;
     65  
     66 case IOCTL_LED_OFF:
     67 // 设置指定引脚的输出电平为1
     68 s3c2410_gpio_setpin(led_table[arg], 1);
     69 return 0;
     70  
     71 default:
     72 return -EINVAL;
     73 }
     74 }
     75  
     76 static struct file_operations dev_fops = {
     77 .owner = THIS_MODULE,
     78 .unlocked_ioctl =  gt2440_leds_ioctl,
     79 };
     80  
     81 static struct miscdevice misc = {
     82 .minor = MISC_DYNAMIC_MINOR,
     83 .name = DEVICE_NAME,
     84 .fops = &dev_fops,
     85 };
     86  
     87 static int __init dev_init(void)
     88 {
     89 int ret;
     90  
     91 int i;
     92 for (i = 0; i < 4; i++)
     93 {
     94 s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);
     95 s3c2410_gpio_setpin(led_table[i], 0);
     96 }
     97  
     98 ret = misc_register(&misc);
     99  
    100 printk (DEVICE_NAME" initialized
    ");
    101  
    102 return ret;
    103 }
    104  
    105 static void __exit dev_exit(void)
    106 {
    107 misc_deregister(&misc);
    108 }
    109  
    110 module_init(dev_init);
    111 module_exit(dev_exit);
    112  
    113 MODULE_LICENSE("GPL");
    114 MODULE_AUTHOR("www.e-online.cc");
    115 MODULE_DESCRIPTION("LEDS control for GT2440 Board");
    View Code
     
     
  • 相关阅读:
    信息安全系统设计基础学习总结第二周
    一维数组求和2
    求一维数组的最大子数组的和
    第三周学习进度
    构建之法阅读笔记二
    四则运算三
    学习进度第二周
    四则运算二
    测试第二次程序
    阅读计划
  • 原文地址:https://www.cnblogs.com/kwseeker-bolgs/p/4472438.html
Copyright © 2011-2022 走看看