• Linux 添加设备驱动程序


      1.创建驱动文件my_drive.c

    #include "linux/kernel.h"
    #include "linux/module.h"
    #include "linux/fs.h"
    #include "linux/init.h"
    #include "linux/types.h"
    #include "linux/errno.h"
    #include "linux/uaccess.h"
    #include "linux/kdev_t.h"
     
    #define MAX_SIZE 1024
     
    int my_open(struct inode *inode, struct file *file);
    int my_release(struct inode *inode, struct file *file);
    ssize_t my_read(struct file *file, char __user *user, size_t t, loff_t *f);
    ssize_t my_write(struct file *file, const char __user *user, size_t t, loff_t *f);
     
    char message[MAX_SIZE] = "my drive start to work";  //打开设备时会显示的消息
    int device_num;//设备号
    char* devName = "my_drive";//设备名
     
    struct file_operations pStruct =
    { 
        open:my_open, 
        release:my_release, 
        read:my_read, 
        write:my_write, 
    };
     
    /* 注册 */
    int init_module()
    {
        int ret;
     
        ret = register_chrdev(0, devName, &pStruct);
        if (ret < 0)
        {
            printk("failed to register my drive.
    ");
            return -1;
        }
        else
        {
            printk("my drive has been registered!
    ");
            printk("id: %d
    ", ret);
            device_num = ret;
     
            return 0;
        }
    }
     
    //注销
    void cleanup_module()
    {
        unregister_chrdev(device_num, devName);
        printk("unregister successful.
    ");
    }
     
     
    //打开
    int my_open(struct inode *inode, struct file *file)
    {
        printk("open my_drive OK!
    ");
        try_module_get(THIS_MODULE);
        return 0;
    }
     
    //关闭
    int my_release(struct inode *inode, struct file *file)
    {
        printk("Device released!
    ");
        module_put(THIS_MODULE);
     
        return 0;
    }
     
     
    //读设备里的信息
    ssize_t my_read(struct file *file, char __user *user, size_t t, loff_t *f)
    {
        if(copy_to_user(user,message,sizeof(message)))
        {
            return -2;
        }
        return sizeof(message);
    }
     
    //向设备里写信息
    ssize_t my_write(struct file *file, const char __user *user, size_t t, loff_t *f)
    {
        if(copy_from_user(message,user,sizeof(message)))
        {
            return -3;
        }
        return sizeof(message);
    }
    my_drive.c

      2.同目录下创建Makefile

    obj-m := my_drive.o    #这里是上面所创建的c文件名.o
        PWD := $(shell pwd)
        KERNELDIR := /usr/src/linux-4.14    #你要安装mod的内核版本 
    all:
        make -C $(KERNELDIR) M=$(PWD) modules
     
     
    .PHONY: clean
    clean:
        rm -rf *.o *~ core *.ko *.mod.c modules.order Module.symvers
    Makefile

      3.使用make生成驱动程序

      4.插入内核模块insmod my_drive.ko

      5.查看内核输出日志dmesg,获取设备号

      6.根据输出的设备号,创建设备mknod /dev/my_drive c 245 0 (245为设备号)

      7.编写测试程序

    test.c

      8.效果 

      

      9.卸载设备和模块

      rm /dev/my_drive

      rmmod my_drive

  • 相关阅读:
    Spring bean的循环依赖以及解决方式
    在Java中为什么实现了Cloneable接口,就能调用Object的clone方法?
    Java-Objects类-deepEquals()和equals()详解
    Linux TCP状态TIME_WAIT 过多的处理
    mysql字符串区分大小写的问题
    java 类加载
    java native 理解
    Maven配置阿里镜像仓库
    Cannot find name ‘XX‘. Do you need to change your target library? Try changing the `lib` compiler
    Typescript Interfaces(接口)添加任意key值/内容
  • 原文地址:https://www.cnblogs.com/wshr007/p/10510589.html
Copyright © 2020-2023  润新知