七、【misc】杂项驱动模型

一、杂项设备驱动设计步骤

1、定义一个杂项设备结构体

1
2
3
4
5
6
7
8
9
10
struct miscdevice  {
    int minor;                    //次设备号
    const char *name;       //设备名和设备文件名一致
    const struct file_operations *fops;  //文件操作集合
    struct list_head list;
    struct device *parent;
    struct device *this_device;
    const char *nodename;
    umode_t mode;
};

2、杂项设备的注册和注销

(1)注册

1
int misc_register(struct miscdevice * misc)

(2)注销

1
int misc_deregister(struct miscdevice *misc) 

二、使用杂项设备模型写led流水灯驱动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/ioport.h>
#include <linux/io.h>
#include <linux/uaccess.h>
#include <linux/types.h>
#include <linux/gpio.h>
#include <cfg_type.h>
#include <linux/miscdevice.h>
 
#define LED_ON  _IOW('L',0,unsigned long)  
#define LED_OFF _IOW('L',1,unsigned long)
 
struct led_gpio_t{
    unsigned int gpio;
    char gpio_name[20];
};
 
 
static struct led_gpio_t led_gpioC[]=
{
    {PAD_GPIO_C+17,"D8_GPIOC17"},
    {PAD_GPIO_C+7,"D9_GPIOC7"},
    {PAD_GPIO_C+8,"D10_GPIOC8"},
};
 
 
 
static long led_ioctl(struct file *flip, unsigned int cmd, unsigned long arg)
{
    if(arg>10||arg<7)
   {
    return -EINVAL;
   }
    switch(cmd)
    {
        case LED_ON:
            gpio_set_value(led_gpioC[arg-8].gpio,0);
            break;
        case LED_OFF:
            gpio_set_value(led_gpioC[arg-8].gpio,1);
            break;
        default:
            return -ENOIOCTLCMD;   
    }
    return 0;
}
 
struct file_operations led_misc_fops=
{
    .unlocked_ioctl = led_ioctl,
};
 
static struct miscdevice led_misc={
    .minor = MISC_DYNAMIC_MINOR,   //表示由系统分配次设备号
    .name = "led_misc",
    .fops =  &led_misc_fops,
    };
static int __init  led_init(void)
{
      int ret,i;
       printk(KERN_INFO"led_init\n");
      ret = misc_register(&led_misc);
      if(ret < 0)
      {
            printk(KERN_INFO"led misc register fail.\n");
        goto misc_register_err;
      }
    for(i=0;i<3;i++)
    {
         ret = gpio_request(led_gpioC[i].gpio, led_gpioC[i].gpio_name);
         if(ret < 0)
         {
            printk(KERN_INFO"gpio_request fail.\n");
            goto gpio_request_err;
         }
    }
    for(i=0;i<3;i++)
    {
        gpio_direction_output(led_gpioC[i].gpio, 1);
    }
    return 0;
 
gpio_request_err:
    while(i--)
    {
        gpio_free(led_gpioC[i].gpio);
    }
misc_register_err:
        return 0;
}
 
static void __exit led_exit(void)
{
    int i;
    printk(KERN_INFO"xxxx__exit\n");
      for(i=0;i<3;i++)
     {
        gpio_free(led_gpioC[i].gpio);
     }
     misc_deregister(&led_misc);     
}
module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL"); 

main.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/ioctl.h>
 
 
#define LED_ON  _IOW('L',0,unsigned long)  
#define LED_OFF _IOW('L',1,unsigned long)
int main()
{
    int fd,ret;
 
    char buff[2]={0};
    fd = open("/dev/led_misc",O_RDWR);
    if(fd<0)
    {
        perror("open led_misc error!");       
    }
    while(1)
    {
        ioctl(fd,LED_ON,8);
        sleep(1);
        ioctl(fd,LED_OFF,8);
        ioctl(fd,LED_ON,9);
        sleep(1);
         ioctl(fd,LED_OFF,9);
        ioctl(fd,LED_ON,10);
        sleep(1);
        ioctl(fd,LED_OFF,10);
         
    }
     
     close(fd);
     return 0;
}

  

  

posted @   轻轻的吻  阅读(157)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示