18 linux字符设备驱动之设备号

字符设备驱动与设备号管理
本文介绍Linux中字符设备驱动的基本概念及设备号管理方式,包括如何通过设备文件调用驱动、设备号的重要性和使用规范,以及申请和释放设备号的具体方法。

设备驱动通常是给用户进程来调用的, 但用户进程通过什么来调用驱动?
最常用的是设备驱动里实现字符设备驱动, 实现后在”/dev”目录里提供一个设备文件, 然后用户进程就可以通过操作设备文件来调用驱动.

如pc上的uart设备文件:
crw-rw—- 1 root dialout 4, 64 Jun 8 09:20 /dev/ttyS0
crw-rw—- 1 root dialout 4, 65 Jun 8 09:20 /dev/ttyS1
crw-rw—- 1 root dialout 4, 66 Jun 8 09:20 /dev/ttyS2
crw-rw—- 1 root dialout 4, 67 Jun 8 09:20 /dev/ttyS3

第一个字符’c’表示字符设备文件,也就是此设备文件对应着一个字符设备驱动.
设备文件名字不重要,不管改成什么名字,功能还是可以用的.

设备文件的设备号才是最重要的.设备号由主设备号和次设备号组成.
如ttyS0的主设备号是4, 次设备号是64.
主设备号通常表示一个字符设备驱动, 上面4个uart设备它们驱动方法应是一样的,可以共用一个驱动。
在驱动里可通过次设备号来区分不同的硬件接口.

设备驱动里在初始化时也需指定使用哪些设备号。当用户进程操作设备文件时,内核会根据设备文件的设备号找到对应的设备驱动,从而让用户进程通过内核与设备驱动建立联系,实现调用驱动里实现的功能.

//////////////////////////////////////////////////////////
设备号很重要,在系统里是不可以重用的资源。注意是设备号不能重用,但主设备号可不可以重用?

在linux内核里用类型”dev_t”来表示一个设备号. 其实就是一个unsigned int.

dev_t类型有32位数, 其中高12位用于存放主设备号,低20位用于存放次设备号.
在”include/linux/kdev_t.h”里有提供设备号的操作宏:

#define MINORBITS   20
#define MINORMASK   ((1U << MINORBITS) - 1)

#define MAJOR(dev)  ((unsigned int) ((dev) >> MINORBITS))
#define MINOR(dev)  ((unsigned int) ((dev) & MINORMASK))
#define MKDEV(ma,mi)    (((ma) << MINORBITS) | (mi))

////////////////////////////////////////
设备号使用前需要向内核申请,使用完后需返还内核。

#include <linux/fs.h>    

//静态:申请指定的设备号, from指设备号(需已指定主设备和次设备号), count指使用该驱动有多少个设备(次设备号), name设备名(用于查看用, 长度不能超过64字节   )
int register_chrdev_region(dev_t from, unsigned count, const char *name);


//动态申请设备号, 由内核分配没有使用的主设备号, 分配好的设备号存在dev(不需初始化), baseminor指次设备号从多少开始, count指设备个数, name设备名 
int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count,
            const char *name)

//释放设备号, from指设备号, count指设备数
void unregister_chrdev_region(dev_t from, unsigned count)

//可通过”cat /proc/devices”查看系统里主设备号的使用状况
//也可在内核源码的documentations/devices.txt可查看设备号的保留用途.

/////////////////////
测试代码:

    #include <linux/init.h>
    #include <linux/module.h>
    #include <linux/fs.h>

    #define MYMA  1234
    #define MYMI  3344
    #define COUNT    3

    dev_t devid; //用于存放设备号 
    static int __init test_init(void)
    {
        int ret;

        devid = MKDEV(MYMA, MYMI); //生成一个设备号
        ret = register_chrdev_region(devid, COUNT, "mydev");
        if (ret < 0)
            goto err0;

        //执行到这里,则有三个设备号(1234,3344), (1234, 3345), (1234, 3346)
        return 0;
    err0:
        return ret;
    }

    static void __exit test_exit(void)
    {
        //使用完后需回收设备号
        unregister_chrdev_region(devid, COUNT);
    }

    module_init(test_init);
    module_exit(test_exit);

    MODULE_LICENSE("GPL");
编译后加载模块后 :
cat /proc/devices
... 
1234 mydev
This bundle contains a modified CP210x driver for the 4.10.0 kernel (Ubuntu 17.04). It contains: - Support for the CP2102N NOTE: This driver is an example of how to perform GPIO operations within the CP210x driver since the driver on kernel.org does not support GPIO at this time. This driver has only been written and tested on the Linux 3.13.0 kernel on Ubuntu 14.04. This driver is a modified version of the existing driver in the Linux 3.13.0 kernel, which is maintained at kernel.org. It is recommened to use the driver there that matches your specific kernel version: www.kernel.org Build instrutions: Ubuntu: 1. make ( your cp210x driver ) 2. cp cp210x.ko to /lib/modules//kernel/drivers/usb/serial 3. insmod /lib/modules/<kernel-version/kernel/drivers/usb/serial/usbserial.ko 4. insmod cp210x.ko RedHat: 1. yum update kernel* //need to update the kernel first otherwise your header won't match 2. yum install kernel-devel kernel-headers //get the devel and header packages. 3. reboot //your build link should be fixed after your system come back 4. make ( your cp210x driver ) // should be able to build successfully at this point 5. cp cp210x.ko to /lib/modules//kernel/drivers/usb/serial 6a. insmod /lib/modules/<kernel-version/kernel/drivers/usb/serial/usbserial.ko 6. insmod cp210x.ko 7. sudo chmod 666 /dev/ttyUSB0 8. sudo chmod 666 /dev/ttyUSB1 GPIO example: This shows how to use the two IOCTLs to set GPIO state. Build instructions: 1. g++ cp210x_gpio_example.c -o cp210x_gpio_example 2. ./cp210x_gpio_example
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值