四时宝库

程序员的知识宝库

Linux设备驱动开发概述(linux设备驱动视频教程)

本次只概述字符设备驱动开发,直接上干货

linux驱动开发流程如下:

实例:增加一个新的系统调用

1、添加新的内核函数 打开/arch/arm/sys_arm.c文件

        asmlinkage int sys_add(int x,int y)
        {
            printk("enter sys_add\n");
            return x+y;
        }

2、更新头文件 arch/arm/include/asm/unistd.h

#define __NR_add (__NR_SYSCALL_BASE+374)

3、更新系统调用表 arch/arm/kernel/calls.S

CALL(sys_add)

4、make

5、开发板加载新内核

测试程序:

    #include <stdio.h>
    /*
    int add(int x,int y)
    {
        return syscall(374,x,y);
    }
    */
    int main()
    {
        int result = 0;
        result = syscall(374,12,13);
        printf("sys_add call result = %d\n",result);
        return 0;
    }

字符设备(顺序读写,不带缓冲)

块设备 (读写的顺序不固定,带有读写缓冲)

网络设备

例如字符设备驱动框架,硬件上有一个字符设备,内核中就有一个cdev结构与之对应。

    struct cdev {
        struct kobject kobj;
        struct module *owner;
        const struct file_operations *ops;
        struct list_head list;
        dev_t dev;    //设备号
        unsigned int count;
    };

每一个cdev都有一个设备号,设备号(32bit)= 主设备号(高12bit)+次设备号(低20bit)

主设备号:代表一个类型的设备

次设备号:用于区分该设备中的不同个体

设备号的选取:

-》静态分配:

看现在的内核中那些主设备号没有被使用,选择一个使用

            cat /proc/devices
            Documentation\divice.txt
            #include <linux/init.h>
            #include <linux/module.h>
            #include CDD_MAJOR 253
            #include CDD_MINOR 0
            /*声明一个设备号*/
            dev_t dev = 0;
            int __init add_init(void)
            {
                int ret = 0;
                //dev = CDD_MAJOR << 20 + CDD_MINOR;
                dev = MKDEV(CDD_MAJOR,CDD_MINOR);
                /*注册设备号
                第一个参数:注册的气势设备号,
                第二个参数:连续注册的设备号的个数,
                第三个参数:the name of the device or driver.
                */
                ret = register_chrdev_region(dev, 1, "cdd_dome");
                if(ret<0)
                {
                    printk("register_chrdev_region failed\n");
                    goto failure_register_chrdev;
                }
                return 0;
            failure_register_chrdev:
                return ret;
            }
            void __exit cdd_exit(void)
            {
                /*注销设备号*/
                unregister_chrdev_region(dev, 1);
            }
            module_init(cdd_init);
            module_exit(cdd_exit);

-》动态分配:

            u32 cdd_major = 0;
            u32 cdd_minor = 0;

cdev的操作函数

            cdev_init(...)//初始化cdev
            cdev_add(...)//注册cdev
            cdev_del(...)//注销cdev

至此在linux下字符设备的注册流程已完成。

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言
    友情链接