字符设备驱动开发-注册-设备文件创建

2023-12-24 11:01

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

一、字符设备驱动

linux系统中一切皆文件

1、应用层:  APP1  APP2  ...

fd = open("led驱动的文件",O_RDWR);

read(fd);

write();

close();

2、内核层:  

对灯写一个驱动

 led_driver.c

 driver_open();

 driver_read();

 driver_write();  

 driver_close();

struct file_operations

 {

int (*open) (struct inode *, struct file *);   

ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);

ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);       

int (*release) (struct inode *, struct file *);//(close)

}

cdev:

设备号1           设备号2             设备号n

设备驱动1     设备驱动2    ....    设备驱动n

设备号:32位,无符号数字

高12位   :主设备号 :区分哪一类设备

低20位   :次设备号 :区分同类中哪一个设备

3、硬件层:  LED   uart  ADC  PWM

每个驱动里面都有对应的file_operations

1)open的过程:

open打开文件,这个文件与底层的驱动的设备号有关系,

通过设备号访问设备驱动中的struct file_operations里面的open函数。

2)read的过程:

open函数会有一个返回值,文件描述符fd,read函数通过fd

找到驱动中的struct file_operations里面的read函数。

Led驱动:字符设备   步骤:
  1. 注册字符设备驱动 - 得到一个字符设备驱动的框架,并且得到设备号
  2. 确定操作的硬件设备 - led灯(初始化灯)
  3. 初始化灯(先建立灯实际物理地址和虚拟地址之间的映射)- 
  4. 基于操作系统开发,操作虚拟内存,
  5. 用户空间数据拷贝到内核空间数据的交互(用户使用的时候,驱动才会被真正运行,涉及数据交互)
  6. 在应用层创建一个设备文件(设备节点)
 file_operations 操作方法结构体

struct file_operations

 {

int (*open) (struct inode *, struct file *);   

ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);

ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);       

int (*release) (struct inode *, struct file *);//(close)

}

二、字符设备驱动的注册

1、注册一个字符设备驱动register_chrdev

int register_chrdev(unsigned int major, const char *name, const struct file_operations *fops)
功能:注册一个字符设备驱动
参数:@major:主设备号  
			  :如果你填写的值大于0,它认为这个就是主设备号
			  :如果你填写的值为0,操作系统给你分配一个主设备号@name :名字	cat /proc/devices @fops :操作方法结构体
返回值:major>0 ,成功返回0,失败返回错误码(负数) vi -t EIO
		major=0,成功主设备号,失败返回错误码(负数)		  当注册一个字符设备驱动的时候。

如果成功的话,当你使用cat /proc/devices 命令查看的时候可以看到系统自动分配的主设备号和这个名字

2、注销一个字符设备驱动

void unregister_chrdev(unsigned int major, const char *name)
	功能:注销一个字符设备驱动
	参数:@major:主设备号@name:名字
	返回值:无

三、手动创建设备文件 mknod

sudo mknod led (路径是任意) c/b  主设备号   次设备号

sudo rf led 删除的时候记得加-rf

1、设备驱动程序

#include <linux/module.h>
#include <linux/init.h>
#include <linux/printk.h>
#include <linux/fs.h>#define NAME "chrdev_devled"int major = 0; //保存主设备号
// open read write release 初始化
int myopen(struct inode *node, struct file *file_t)
{printk("%s %s %d\n", __FILE__, __func__, __LINE__);return 0;
}
ssize_t myread(struct file *file_t, char __user *ubuf, size_t n, loff_t *off_t)
{printk("%s %s %d\n", __FILE__, __func__, __LINE__);return 0;
}
ssize_t mywrite(struct file *file_t, const char __user *ubuf, size_t n, loff_t *off_t)
{printk("%s %s %d\n", __FILE__, __func__, __LINE__);return 0;
}
int myclose(struct inode *node, struct file *file_t)
{printk("%s %s %d\n", __FILE__, __func__, __LINE__);return 0;
}
struct file_operations fops = {.open = myopen,.read = myread,.write = mywrite,.release = myclose,
};
//入口函数
static int __init chrdev_init(void)
{printk("%s %s %d\n", __FILE__, __func__, __LINE__);//注册字符设备驱动: 主设备号 驱动名 结构体
    major=register_chrdev(major, NAME, &fops);//容错判断if(major < 0){printk("chrdev_register err.\n");return -EINVAL;}return 0;
}
//出口函数
static void __exit chrdev_exit(void)
{printk(KERN_ERR "%s %s %d\n", __FILE__, __func__, __LINE__);//注销字符设备驱动unregister_chrdev(major, NAME);
}
module_init(chrdev_init);//入口
module_exit(chrdev_exit);//出口
MODULE_LICENSE("GPL");//协议

2、应用层读取程序

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>#include <stdio.h>int main(int argc,char *argv[])
{
    int fd = -1;
    char buf[32] = "";if(argc < 2){
        printf("请输入要打开的文件\n");return 1;}    fd = open(argv[1],O_RDWR);if(fd < 0){
        printf("open %s failed\n",argv[1]);return 2;}
    read(fd,buf,sizeof(buf));
    write(fd,buf,sizeof(buf));
    read(fd,buf,sizeof(buf));
    write(fd,buf,sizeof(buf));
    printf("buf=%s\n",buf);
    close(fd);
    fd = -1;return 0;
}

3、操作步骤:

--make 驱动文件

--insmod 安装驱动

--cat /proc/devicse 查看设备号

--sudo mknod led c 244 0 创建设备文件(设备节点)

--dmesg 查看消息

--sudo dmesg -C删除消息 

--sudo gcc app.c 编译应用层读取文件

--./app .led读取

--led--dmesg 查看消息

这篇关于字符设备驱动开发-注册-设备文件创建的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

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

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

usb接口驱动异常问题常用解决方案

《usb接口驱动异常问题常用解决方案》当遇到USB接口驱动异常时,可以通过多种方法来解决,其中主要就包括重装USB控制器、禁用USB选择性暂停设置、更新或安装新的主板驱动等... usb接口驱动异常怎么办,USB接口驱动异常是常见问题,通常由驱动损坏、系统更新冲突、硬件故障或电源管理设置导致。以下是常用解决

使用Python开发一个带EPUB转换功能的Markdown编辑器

《使用Python开发一个带EPUB转换功能的Markdown编辑器》Markdown因其简单易用和强大的格式支持,成为了写作者、开发者及内容创作者的首选格式,本文将通过Python开发一个Markd... 目录应用概览代码结构与核心组件1. 初始化与布局 (__init__)2. 工具栏 (setup_t

Spring Shell 命令行实现交互式Shell应用开发

《SpringShell命令行实现交互式Shell应用开发》本文主要介绍了SpringShell命令行实现交互式Shell应用开发,能够帮助开发者快速构建功能丰富的命令行应用程序,具有一定的参考价... 目录引言一、Spring Shell概述二、创建命令类三、命令参数处理四、命令分组与帮助系统五、自定义S

Python通过模块化开发优化代码的技巧分享

《Python通过模块化开发优化代码的技巧分享》模块化开发就是把代码拆成一个个“零件”,该封装封装,该拆分拆分,下面小编就来和大家简单聊聊python如何用模块化开发进行代码优化吧... 目录什么是模块化开发如何拆分代码改进版:拆分成模块让模块更强大:使用 __init__.py你一定会遇到的问题模www.

Spring Security基于数据库的ABAC属性权限模型实战开发教程

《SpringSecurity基于数据库的ABAC属性权限模型实战开发教程》:本文主要介绍SpringSecurity基于数据库的ABAC属性权限模型实战开发教程,本文给大家介绍的非常详细,对大... 目录1. 前言2. 权限决策依据RBACABAC综合对比3. 数据库表结构说明4. 实战开始5. MyBA

使用Python开发一个简单的本地图片服务器

《使用Python开发一个简单的本地图片服务器》本文介绍了如何结合wxPython构建的图形用户界面GUI和Python内建的Web服务器功能,在本地网络中搭建一个私人的,即开即用的网页相册,文中的示... 目录项目目标核心技术栈代码深度解析完整代码工作流程主要功能与优势潜在改进与思考运行结果总结你是否曾经

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

Python基于wxPython和FFmpeg开发一个视频标签工具

《Python基于wxPython和FFmpeg开发一个视频标签工具》在当今数字媒体时代,视频内容的管理和标记变得越来越重要,无论是研究人员需要对实验视频进行时间点标记,还是个人用户希望对家庭视频进行... 目录引言1. 应用概述2. 技术栈分析2.1 核心库和模块2.2 wxpython作为GUI选择的优

利用Python开发Markdown表格结构转换为Excel工具

《利用Python开发Markdown表格结构转换为Excel工具》在数据管理和文档编写过程中,我们经常使用Markdown来记录表格数据,但它没有Excel使用方便,所以本文将使用Python编写一... 目录1.完整代码2. 项目概述3. 代码解析3.1 依赖库3.2 GUI 设计3.3 解析 Mark