嵌入式技术分享

Embedded Technology Sharing

嵌入式Linux字符设备驱动——2静态申请设备号

《嵌入式Linux字符设备驱动——2静态申请设备号》

嵌入式Linux字符设备驱动开发流程——以LED为例

1.设备模块加载及卸载
2.静态申请设备号
3.动态申请设备号
4.注册字符类设备
5.生成字符设备节点
6.完善字符类设备驱动
7.根据完善后的模板编写相关设备驱动

前言

设备驱动设备号申请分为静态申请和动态申请,本文为静态申请。

说明

静态申请需要先查看空闲设备号,不能用已使用的设备号
查看设备号命令

cat /proc/devices

《嵌入式Linux字符设备驱动——2静态申请设备号》

头文件

#include <linux/fs.h>               
#include <linux/cdev.h>             
#include <linux/kdev_t.h>           

设备号静态申请函数

所属文件名:char_dev.c

/**
* register_chrdev_region() - register a range of device numbers
* @from: the first in the desired range of device numbers; must include
*        the major number.
* @count: the number of consecutive device numbers required
* @name: the name of the device or driver.
*
* Return value is zero on success, a negative error code on failure.
*/
int register_chrdev_region(dev_t from, unsigned count, const char *name)
{
    struct char_device_struct *cd;
    dev_t to = from + count;
    dev_t n, next;

    for (n = from; n < to; n = next) {
        next = MKDEV(MAJOR(n)+1, 0);
        if (next > to)
            next = to;
        cd = __register_chrdev_region(MAJOR(n), MINOR(n),
                   next - n, name);
        if (IS_ERR(cd))
            goto fail;
    }
    return 0;
fail:
    to = n;
    for (n = from; n < to; n = next) {
        next = MKDEV(MAJOR(n)+1, 0);
        kfree(__unregister_chrdev_region(MAJOR(n), MINOR(n), next - n));
    }
    return PTR_ERR(cd);
}

设备号注销函数

所属文件名:char_dev.c

/**
* unregister_chrdev_region() - return a range of device numbers
* @from: the first in the range of numbers to unregister
* @count: the number of device numbers to unregister
*
* This function will unregister a range of @count device numbers,
* starting with @from.  The caller should normally be the one who
* allocated those numbers in the first place...
*/
void unregister_chrdev_region(dev_t from, unsigned count)
{
    dev_t to = from + count;
    dev_t n, next;

    for (n = from; n < to; n = next) {
        next = MKDEV(MAJOR(n)+1, 0);
        if (next > to)
            next = to;
        kfree(__unregister_chrdev_region(MAJOR(n), MINOR(n), next - n));
    }
}

程序

#include <linux/module.h>           //模块头文件
#include <linux/kernel.h>           //内核头文件
#include <linux/init.h>             //内核初始化

#include <linux/fs.h>               //字符设备函数
#include <linux/cdev.h>             //字符设备描述
#include <linux/kdev_t.h>           //系列设备号处理宏

#define DEVICE_NAME     "leds"      //字符设备名称
#define DEVICE_MINOR_NUM    2       //字符设备数量

#define DEV_MAJOR   9               //主设备号
#define DEV_MINOR   0               //次设备号,0为自动分配

static dev_t leds_dev = MKDEV(DEV_MAJOR, DEV_MINOR); 

static __init int leds_init(void)
{
    int ret = 0;
    
    
    ret = register_chrdev_region(leds_dev, DEVICE_MINOR_NUM, DEVICE_NAME);
    if(ret < 0){
        printk(KERN_EMERG "register_chrdev_region req %d is failed!\n", DEV_MAJOR);
    }
    
    printk("leds chrdev register is ok %d\n", ret);
    
    return ret;
}

static __exit void leds_exit(void)
{
    unregister_chrdev_region(leds_dev, DEVICE_MINOR_NUM);
    printk( "leds chrdev exit \n");
}

module_init(leds_init);
module_exit(leds_exit);

MODULE_LICENSE("GPL");

编译

make

加载编译后的模块

insmod leds.ko

查看加载的模块设备号,与手动分配的设备号一致

cat /proc/devices

《嵌入式Linux字符设备驱动——2静态申请设备号》

结束语

以上则为嵌入式Linux设备号静态申请的相关内容。

如果文章对您有帮助,欢迎移至上方按钮打赏博主;

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注