Linux2.6设备驱动开发

2024-08-21 15:52
文章标签 开发 驱动 设备 linux2.6

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

一:Linux2.6驱动设备开发的特点

1:首先是属于字符型设备注册的方法之一

        这种开发接口是在Linux2.6引入的,之前的版本不支持这种开发方式,也是目前最标准的开发方式。

2:Linux2.6的设备开发

        不再去限制设备号,与其对应的就是需要去申请可用的设备号。

3:Linux2.6注册完毕设备且成功之后并不会生成设备文件

对于这种情况有两种方法:

        通过指令手动生成

        通过内核其他接口函数生成

4:Linux2.6与杂项的区别

杂项:

        优点:简单

        缺点:没有分类。能注册的设备有限

Linux2.6:

        有点:主设备号不限制。2^12个主设备号,设备分类;2^20个次设备号

        缺点:函数流程相对于杂项复杂

总结:Linux2.6相对于杂项而言复杂,Linux2.6设备号范围比杂项大。

二:Linux2.6 驱动开发架构

1、先去申请设备号->alloc_chrdev_region();

2、初始化Linux2.6核心结构体 cdev->cdev_init();

3、添加注册设备->cdev_add

4、生成一个与之相对应的设备文件:class_create device_create

总结:在使用Linux2.6驱动时的开发步骤,需要先申请设备号,然后进行初始化,然后添加注册的设备,最后生成设备文件。

三:linux2.6驱动开发接口

现在进入到具体的开发流程

1:如何在内核中申请一个可以用的设备号

头文件:

#include "linux/fs.h"

对应的接口函数:

int alloc_chrdev_region(dev_t *dev, //uint32_t类型数字,也就是申请的设备号unsigned baseminor,//申请的起始次设备号unsigned count,//连续申请的设备数量const char *name)//任意填写名字

函数功能:向内核申请目前可以用的设备号,可以申请多个设备号

函数返回值:

成功返回0,失败返回非0

释放设备号接口:

void unregister_chrdev_region(dev_t from, //填写的申请的首设备号unsigned count//释放几个信号
)

2:linux2.6的设备注册

头文件:

#include "linux/cdev.h"

初始化函数:

void cdev_init(struct cdev *cdev, //要初始化的cdev核心结构体const struct file_operations *fops//与cdev做绑定,注册的设备都会用此内核接口
)

动态开辟空间的方法:kzalloc();

添加函数:

int cdev_add(struct cdev *p, //cdev核心结构体dev_t dev, //要注册的设备的首设备号unsigned count//要注册的设备的数量)

删除函数:

void cdev_del(struct cdev *p//核心结构体
)

3:设备文件的生成

手动生成:

mknod /dev/led c 234(主设备号) 0(次设备号)

自动生成:

内核接口:

想要生成设备文件必须先创建类结构体->class

struct class * cls = class_create(THIS_MODULE,"led_class");

销毁一个类:

class_destroy(struct class * cls)
有了类结构体你就可以创建设备文件了struct device *device_create(struct class *class,struct device *parent,dev_t devt,void *drvdata,const char *fmt, ...
) *
class:刚才得到的类结构体
*parent:设备的父设备->没有父设备->NULL
*devt设备的设备号
*drvdata创建设备附带的私有数据->NULL
*fmt,...:跟 printf 一样的
直接当作字符串传递也是一样的
他就是你创建设备文件的名字!

如何销毁一个设备文件:

void device_destroy(struct class *class, dev_t devt)
class:类结构体
devt:设备号

4:事例:linux2.6下的LED驱动

#include"linux/fs.h"
#include"linux/module.h"
#include"linux/kernel.h"
#include"linux/cdev.h"
#include"linux/gpio.h"
#include"device.h"dev_t  mydevnum;//设备号
struct cdev mycdev;//Cdev核心结构体
struct file_operations ops;//内核层的文件操集合结构体
struct class * cls;//类设备文件结构体
//开灯回调函数int led_on (struct inode *i, struct file *f)
{gpio_set_value(21,1);gpio_set_value(22,0);return 0;
}
//关灯回调函数
int led_off (struct inode *i, struct file *f)
{gpio_set_value(21,0);gpio_set_value(22,1);return 0;
}
//入口函数
static int __init myled_init(void)
{//申请设备号int ret = alloc_chrdev_region(&mydevnum,0,1,"myled");if(ret < 0){return -EINVAL;//加载失败}printk("主设备:%d\t\t次设备:%d\r\n",mydevnum>>20,mydevnum&0xFFFFF);//初始化Linux2.6 cdev结构体ops.owner = THIS_MODULE;ops.open = led_on;ops.release =led_off;cdev_init(&mycdev,&ops);//添加cdev设备cdev_add(&mycdev,mydevnum,1);//生成一个类设备文件cls=class_create(THIS_MODULE, "led_class");//创建设备文件device_create(cls,NULL,mydevnum,NULL,"led");//初始化硬件gpio_request(21,"led1");gpio_request(22,"led2");gpio_direction_output(21,0);gpio_direction_output(22,0);return 0;
}
//出口函数
static void __exit myled_exit(void)
{//卸载程序只有一个原则 ->倒序gpio_free(21);gpio_free(22);device_destroy(cls,mydevnum);class_destroy(cls);cdev_del(&mycdev);unregister_chrdev_region(mydevnum,1);
}
module_init(myled_init);
module_exit(myled_exit);
MODULE_LICENSE("GPL");

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



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

相关文章

如何在Ubuntu上安装NVIDIA显卡驱动? Ubuntu安装英伟达显卡驱动教程

《如何在Ubuntu上安装NVIDIA显卡驱动?Ubuntu安装英伟达显卡驱动教程》Windows系统不同,Linux系统通常不会自动安装专有显卡驱动,今天我们就来看看Ubuntu系统安装英伟达显卡... 对于使用NVIDIA显卡的Ubuntu用户来说,正确安装显卡驱动是获得最佳图形性能的关键。与Windo

一文教你如何解决Python开发总是import出错的问题

《一文教你如何解决Python开发总是import出错的问题》经常朋友碰到Python开发的过程中import包报错的问题,所以本文将和大家介绍一下可编辑安装(EditableInstall)模式,可... 目录摘要1. 可编辑安装(Editable Install)模式到底在解决什么问题?2. 原理3.

Android与iOS设备MAC地址生成原理及Java实现详解

《Android与iOS设备MAC地址生成原理及Java实现详解》在无线网络通信中,MAC(MediaAccessControl)地址是设备的唯一网络标识符,本文主要介绍了Android与iOS设备M... 目录引言1. MAC地址基础1.1 MAC地址的组成1.2 MAC地址的分类2. android与I

Python+PyQt5开发一个Windows电脑启动项管理神器

《Python+PyQt5开发一个Windows电脑启动项管理神器》:本文主要介绍如何使用PyQt5开发一款颜值与功能并存的Windows启动项管理工具,不仅能查看/删除现有启动项,还能智能添加新... 目录开篇:为什么我们需要启动项管理工具功能全景图核心技术解析1. Windows注册表操作2. 启动文件

嵌入式Linux之使用设备树驱动GPIO的实现方式

《嵌入式Linux之使用设备树驱动GPIO的实现方式》:本文主要介绍嵌入式Linux之使用设备树驱动GPIO的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、设备树配置1.1 添加 pinctrl 节点1.2 添加 LED 设备节点二、编写驱动程序2.1

嵌入式Linux驱动中的异步通知机制详解

《嵌入式Linux驱动中的异步通知机制详解》:本文主要介绍嵌入式Linux驱动中的异步通知机制,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、异步通知的核心概念1. 什么是异步通知2. 异步通知的关键组件二、异步通知的实现原理三、代码示例分析1. 设备结构

使用Python开发Markdown兼容公式格式转换工具

《使用Python开发Markdown兼容公式格式转换工具》在技术写作中我们经常遇到公式格式问题,例如MathML无法显示,LaTeX格式错乱等,所以本文我们将使用Python开发Markdown兼容... 目录一、工具背景二、环境配置(Windows 10/11)1. 创建conda环境2. 获取XSLT

Android开发环境配置避坑指南

《Android开发环境配置避坑指南》本文主要介绍了Android开发环境配置过程中遇到的问题及解决方案,包括VPN注意事项、工具版本统一、Gerrit邮箱配置、Git拉取和提交代码、MergevsR... 目录网络环境:VPN 注意事项工具版本统一:android Studio & JDKGerrit的邮

Python开发文字版随机事件游戏的项目实例

《Python开发文字版随机事件游戏的项目实例》随机事件游戏是一种通过生成不可预测的事件来增强游戏体验的类型,在这篇博文中,我们将使用Python开发一款文字版随机事件游戏,通过这个项目,读者不仅能够... 目录项目概述2.1 游戏概念2.2 游戏特色2.3 目标玩家群体技术选择与环境准备3.1 开发环境3

Go语言开发实现查询IP信息的MCP服务器

《Go语言开发实现查询IP信息的MCP服务器》随着MCP的快速普及和广泛应用,MCP服务器也层出不穷,本文将详细介绍如何在Go语言中使用go-mcp库来开发一个查询IP信息的MCP... 目录前言mcp-ip-geo 服务器目录结构说明查询 IP 信息功能实现工具实现工具管理查询单个 IP 信息工具的实现服