当前位置:首页 > 公众号精选 > 嵌入式云IOT技术圈
[导读]从这篇博文开始,我将开始手把手教会大家写Linux设备驱动程序 这是开篇,如何来写第一个字符设备驱动程序。 首先,写一个最简单的字符设备驱动程序需要什么?或者说我们需要了解什么? 1、每一个字符设备至少需要有一个设备号 2、设备号 = 主设备号 + 次设备

从这篇博文开始,我将开始手把手教会大家写Linux设备驱动程序

这是开篇,如何来写第一个字符设备驱动程序。


首先,写一个最简单的字符设备驱动程序需要什么?或者说我们需要了解什么?

1、每一个字符设备至少需要有一个设备号

2、设备号 = 主设备号 + 次设备号

3、同一类设备的主设备号一般是相同的,但不是绝对的。


那么,写一个简单的字符设备驱动程序,我们需要内核里的这几个头文件,因为我们需要调用一个基本的宏和一些基本的函数来给我们使用。

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

打开linux内核源代码,进入include/linux/,找到cdev.h,打开,我们会看到这个结构体:

struct cdev {

//设备模型相关的

struct kobject kobj;

//所属于哪个模块--->THIS MODULE

struct module *owner;

//利用file_operations跟用户态进行操作--->有open , read , write 等方法

const struct file_operations *ops;

//链表,将设备插入到一条链表里去

struct list_head list;

//通过设备号匹配对应的驱动

dev_t dev;

//要注册字符设备的个数

unsigned int count;

};

还会看到以下的函数:

void cdev_init(struct cdev *, const struct file_operations *);

struct cdev *cdev_alloc(void);

void cdev_put(struct cdev *p);

int cdev_add(struct cdev *, dev_t, unsigned);

void cdev_del(struct cdev *);

void cd_forget(struct inode *);

这里我们需要的就是以上的这个结构体,还有cdev_init,cdev_add,cdev_del这三个函数,其余的暂时用不着。本节暂时不会用到以上的函数,下节将会使用。


然后看到#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))

我们在接下来写的这个字符设备就需要创建一个设备号,所以我们需要MKDEV这个宏,第一个参数表示主设备号,第二个参数表示次设备号。


我们知道如何去创建一个设备号,那么创建了设备号,还没有对这个设备进行注册,这时候就需要#include <linux/fs.h>这个头文件里的一个函数:

extern int register_chrdev_region(dev_t, unsigned, const char *);

既然有注册,当然就有释放,所以还需要:

extern void unregister_chrdev_region(dev_t, unsigned);

好了,有了这些基本知识,可以开始我们的第一个字符设备驱动程序的编写。


编写这个简单的字符设备需要以下步骤:

1、创建设备号

2、注册设备号

3、如何驱动模块退出的时候,我们需要注销设备的操作。


好了,开始写代码:


#include <linux/init.h>

#include <linux/module.h>

#include <linux/sched.h>

#include <linux/kernel.h>

#include <linux/cdev.h>

#include <linux/kdev_t.h>

#include <linux/fs.h>

//定义一个结构体变量,用来表示设备号--->cdev.h--->dev_t

dev_t dev_no ;

static int __init  cdev_test_init(void)

{

int ret ;

printk("HELLO KERNEL FOR CDEV!\n");

//1、创建设备号-->第一个是主设备号,第二个是次设备号

//主设备号可以通过cat /proc/devices查看,如果设备号已经被占用,则需要使用没有使用过的设备号

dev_no  = MKDEV(222,2);

//2、注册设备号

//count表示要分配多少个设备号

ret = register_chrdev_region(dev_no,1,"my_dev");

if(ret < 0){

//如果注册失败,跳转到对应的位置。

goto register_error ;

}

return 0 ;

register_error:

return ret ;

}

static int __exit cdev_test_exit(void)

{

//注销驱动-->后面写1表示从dev_no开始连续一个设备

unregister_chrdev_region(dev_no,1);

return 0 ;

}


module_init(cdev_test_init);

module_exit(cdev_test_exit);

MODULE_LICENSE("GPL");

再和以前一样,写一个Kconfig和Makefile

Kconfig

menu "4412_CDEV_DRV"

     config CDEV_TEST

          bool "cdev_test"

          default n

   help

 if you select , you can use it


endmenu

Makefile

obj-y += cdev_test.o

再到上层的driver目录下Kconfig和Makefile中添加相应的语句,跟以往一样这里是在driver目录下创建了一个4char_dev的目录。
接下来在内核根目录下make menuconfig配置相应的驱动:





将编译生成的zImage下载至开发板,打开串口调试,会看到以下log,说明驱动已经开始运行了:


接下来通过adb shell进入安卓系统的根目录下:

cat /proc/devices

我们成功的看到主设备号222的字符设备驱动my_dev已经成功装载了。






免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

为了满足日益增长的数据处理需求,铁威马NAS推出了全新的性能巅峰2024年旗舰之作F4-424 Pro,并搭载了最新的操作系统--TOS 6。这款高效办公神器的问世,无疑将为企业和专业人士带来前所未有的便捷与效率。

关键字: 存储 Linux 服务器

双系统将是下述内容的主要介绍对象,通过这篇文章,小编希望大家可以对双系统的相关情况以及信息有所认识和了解,详细内容如下。

关键字: 双系统 Windows Linux

USB摄像头是一种采用USB接口的视频采集设备,其优点在于即插即用、操作简便,无需额外驱动程序,支持笔记本电脑,并且成本较低,可以支持远程网络观看。

关键字: usb摄像头 驱动程序

安装Linux操作系统并不复杂,下面是一个大致的步骤指南,以帮助您完成安装。1. 下载Linux发行版:首先,您需要从Linux发行版官方网站下载最新的ISO镜像文件。

关键字: Linux 操作系统 ISO镜像

计算机是由一堆硬件组成的,为了有限的控制这些硬件资源,于是就有了操作系统的产生,操作系统是软件子系统的一部分,是硬件基础上的第一层软件。

关键字: Linux 操作系统 计算机

Linux操作系统是一套免费使用和自由传播的类Unix操作系统,通常被称为GNU/Linux。它是由林纳斯·托瓦兹在1991年首次发布的,并基于POSIX和UNIX的多用户、多任务、支持多线程和多CPU的操作系统。Lin...

关键字: Linux 操作系统

所谓进程间通信就是在不同进程之间传播或交换信息,它是一组编程接口,让程序员能够协调不同的进程,使之能在一个操作系统里同时运行,并相互传递、交换信息;还可以让一个程序能够在同一时间里处理许多用户的需求。

关键字: Linux 进程通信 编程接口

串口通信作为一种最传统的通信方式,在工业自动化、通讯、控制等领域得到广泛使用。

关键字: Linux 串口通信 通讯

与两相双极步进电机的驱动电路相比,两相单极步进电机的驱动电路在输入段配置、内部逻辑及控制电路和驱动电路使用双通道方面基本相同,但是输出段的配置不同。

关键字: 四相步进电机 驱动程序 程序电路

2023年11月16日: MikroElektronika(MIKROE) ,作为一家通过提供基于成熟标准的创新式硬软件产品来大幅缩短开发时间的嵌入式解决方案公司,今天宣布推出一款基于单线设备的软硬件开源解决方案Cli...

关键字: 嵌入式 Linux 操作系统
关闭
关闭