linux驱动开发之helloword

2024-06-04 23:32
文章标签 linux 开发 驱动 helloword

本文主要是介绍linux驱动开发之helloword,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

自己现在也是刚开始学习linux驱动开发的超级新手 照着别人敲了一个helloworld 然后自己把自己的理解写成注解 如有误请指出,谢谢


#include <linux/module.h>

#include <linux/types.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <linux/timer.h>    
#include <asm/atomic.h>
#include <linux/slab.h>
#include <linux/device.h>     
           
#define CDEVDEMO_MAJOR 255                       //宏定义主设备号
              
static int cdevdemo_major = CDEVDEMO_MAJOR;   //给设备主设备号赋值


struct cdevdemo_dev   //设备结构体(我目前的理解是,以后比如添加了一个摄像头设备camera,就建立一个camera的结构体)
{   
        struct cdev cdev;
};
    
struct cdevdemo_dev *cdevdemo_devp;        //指向上面那个结构体的结构体指针
    
int cdevdemo_open(struct inode *inode,struct file *filp)       //填写file_operations的open函数
{

        printk(KERN_NOTICE "============ cdevdemo_open");

        return 0;
}


int cdevdemo_release(struct inode *inode,struct file *filp)    //填写file_operations的release函数
{
        printk(KERN_NOTICE "============ cdevdemo_release");
        return 0;
}


static ssize_t cdevdemo_read(struct file *filp,char __user *buf,size_t count,loff_t *ppos)   //填写file_operations的read函数
{
        printk(KERN_NOTICE "============= cdevdemo_read");
}


static const struct file_operations cdevdemo_fops =  //刚刚上面的几个函数分别和file_operations结构体中的函数对应
{
        .owner = THIS_MODULE,
        .open  = cdevdemo_open,
        .release = cdevdemo_release,
        .read = cdevdemo_read,
};


static void cdevdemo_setup_cdev(struct cdevdemo_dev *dev,int index)
{
        printk(KERN_NOTICE "========== cdevdemo_setup_cdev 1");
        int err,devno = MKDEV(cdevdemo_major,index);
        printk(KERN_NOTICE "========== cdevdemo_setup_cdev 2");

        cdev_init(&dev->cdev,&cdevdemo_fops);                                                       //cdev_init主要是

        printk(KERN_NOTICE "========== cdevdemo_setup_cdev 3");
        dev->cdev.owner = THIS_MODULE;
        dev->cdev.ops = &cdevdemo_fops;
        printk(KERN_NOTICE "========= cdevdemo_setip_cdev 4");
        err = cdev_add(&dev->cdev,devno,1);
        printk(KERN_NOTICE "======== cdevdemo_setup_cdev 5");
        if(err)


        {
                printk(KERN_NOTICE "Error %d add cdevdemo %d",err,index);
        }
}


int cdevdemo_init(void)
{
        printk(KERN_NOTICE "==============模块初始化===============");
        int ret;
        dev_t devno = MKDEV(cdevdemo_major,0);     //生成设备号


        struct class *cdevdemo_class;                           //不清楚
        if(cdevdemo_major)                                                        //申请设备号
        {
                printk(KERN_NOTICE "======cdevdemo_init 1");


                ret = register_chrdev_region(devno,1,"cdevdemo");
        }else

       {
                printk(KERN_NOTICE "======= cdevdemo_init 2");
                ret = alloc_chrdev_region(&devno,0,1,"cdevdemo");
                cdevdemo_major = MAJOR(devno);
        }
        if(ret < 0 )                                                                 //申请设备号成功返回0,不成功返回负数,ret<0 说明申请设备号失败
        {
                printk(KERN_NOTICE "设备号申请失败");
                return ret;
        }


        cdevdemo_devp = kmalloc(sizeof(struct cdevdemo_dev),GFP_KERNEL); //分配内存,kmalloc第一个参数是分配大小,第二个详见kmalloc函数
        if(!cdevdemo_devp)                                                                                       //若分配失败 
        {
                ret = -ENOMEM;                                                   
                printk(KERN_NOTICE "Error add cdevdemo");                                   //打印 错误信息
                goto fail_malloc;                                                                                 //跳转到fail_malloc,注销设备号
        }


        memset(cdevdemo_devp,0,sizeof(struct cdevdemo_dev));      //在头文件string.h中定义的 memset 作用主要是为内存初始化一个值
        printk(KERN_NOTICE "========= devdemo_init 3");
        cdevdemo_setup_cdev(cdevdemo_devp, 0);




        cdevdemo_class = class_create(THIS_MODULE,"cdevdemo");
        device_create(cdevdemo_class,NULL, MKDEV(cdevdemo_major,0),NULL,"cdevdemo");


        printk(KERN_NOTICE "======== cdevdemo_init 4");

       return 0;


        fail_malloc:
                unregister_chrdev_region(devno,1);                                                    //注销设备号
}


void cdevdemo_exit(void)                                                                                  //设备remove函数
{
        printk(KERN_NOTICE "End cdevdemo");
        cdev_del(&cdevdemo_devp->cdev);                                                        //调用设备删除函数
        kfree(cdevdemo_devp);                                                                             //释放内存
        unregister_chrdev_region(MKDEV(cdevdemo_major,0),1);                      //主线设备号
}


MODULE_LICENSE("Dual BSD/GPL");
module_param(cdevdemo_major, int, S_IRUGO);    //定模块参数,用于在加载模块时或者模块加载以后传递参数给模块。
module_init(cdevdemo_init);
module_exit(cdevdemo_exit);


这篇关于linux驱动开发之helloword的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1031437

相关文章

Linux使用fdisk进行磁盘的相关操作

《Linux使用fdisk进行磁盘的相关操作》fdisk命令是Linux中用于管理磁盘分区的强大文本实用程序,这篇文章主要为大家详细介绍了如何使用fdisk进行磁盘的相关操作,需要的可以了解下... 目录简介基本语法示例用法列出所有分区查看指定磁盘的区分管理指定的磁盘进入交互式模式创建一个新的分区删除一个存

Linux使用dd命令来复制和转换数据的操作方法

《Linux使用dd命令来复制和转换数据的操作方法》Linux中的dd命令是一个功能强大的数据复制和转换实用程序,它以较低级别运行,通常用于创建可启动的USB驱动器、克隆磁盘和生成随机数据等任务,本文... 目录简介功能和能力语法常用选项示例用法基础用法创建可启动www.chinasem.cn的 USB 驱动

基于Python开发电脑定时关机工具

《基于Python开发电脑定时关机工具》这篇文章主要为大家详细介绍了如何基于Python开发一个电脑定时关机工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 简介2. 运行效果3. 相关源码1. 简介这个程序就像一个“忠实的管家”,帮你按时关掉电脑,而且全程不需要你多做

高效管理你的Linux系统: Debian操作系统常用命令指南

《高效管理你的Linux系统:Debian操作系统常用命令指南》在Debian操作系统中,了解和掌握常用命令对于提高工作效率和系统管理至关重要,本文将详细介绍Debian的常用命令,帮助读者更好地使... Debian是一个流行的linux发行版,它以其稳定性、强大的软件包管理和丰富的社区资源而闻名。在使用

Java中的Opencv简介与开发环境部署方法

《Java中的Opencv简介与开发环境部署方法》OpenCV是一个开源的计算机视觉和图像处理库,提供了丰富的图像处理算法和工具,它支持多种图像处理和计算机视觉算法,可以用于物体识别与跟踪、图像分割与... 目录1.Opencv简介Opencv的应用2.Java使用OpenCV进行图像操作opencv安装j

Linux Mint Xia 22.1重磅发布: 重要更新一览

《LinuxMintXia22.1重磅发布:重要更新一览》Beta版LinuxMint“Xia”22.1发布,新版本基于Ubuntu24.04,内核版本为Linux6.8,这... linux Mint 22.1「Xia」正式发布啦!这次更新带来了诸多优化和改进,进一步巩固了 Mint 在 Linux 桌面

LinuxMint怎么安装? Linux Mint22下载安装图文教程

《LinuxMint怎么安装?LinuxMint22下载安装图文教程》LinuxMint22发布以后,有很多新功能,很多朋友想要下载并安装,该怎么操作呢?下面我们就来看看详细安装指南... linux Mint 是一款基于 Ubuntu 的流行发行版,凭借其现代、精致、易于使用的特性,深受小伙伴们所喜爱。对

什么是 Linux Mint? 适合初学者体验的桌面操作系统

《什么是LinuxMint?适合初学者体验的桌面操作系统》今天带你全面了解LinuxMint,包括它的历史、功能、版本以及独特亮点,话不多说,马上开始吧... linux Mint 是一款基于 Ubuntu 和 Debian 的知名发行版,它的用户体验非常友好,深受广大 Linux 爱好者和日常用户的青睐,

Linux(Centos7)安装Mysql/Redis/MinIO方式

《Linux(Centos7)安装Mysql/Redis/MinIO方式》文章总结:介绍了如何安装MySQL和Redis,以及如何配置它们为开机自启,还详细讲解了如何安装MinIO,包括配置Syste... 目录安装mysql安装Redis安装MinIO总结安装Mysql安装Redis搜索Red

Linux中Curl参数详解实践应用

《Linux中Curl参数详解实践应用》在现代网络开发和运维工作中,curl命令是一个不可或缺的工具,它是一个利用URL语法在命令行下工作的文件传输工具,支持多种协议,如HTTP、HTTPS、FTP等... 目录引言一、基础请求参数1. -X 或 --request2. -d 或 --data3. -H 或