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

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

相关文章

基于 Cursor 开发 Spring Boot 项目详细攻略

《基于Cursor开发SpringBoot项目详细攻略》Cursor是集成GPT4、Claude3.5等LLM的VSCode类AI编程工具,支持SpringBoot项目开发全流程,涵盖环境配... 目录cursor是什么?基于 Cursor 开发 Spring Boot 项目完整指南1. 环境准备2. 创建

Java实现字节字符转bcd编码

《Java实现字节字符转bcd编码》BCD是一种将十进制数字编码为二进制的表示方式,常用于数字显示和存储,本文将介绍如何在Java中实现字节字符转BCD码的过程,需要的小伙伴可以了解下... 目录前言BCD码是什么Java实现字节转bcd编码方法补充总结前言BCD码(Binary-Coded Decima

SpringBoot 多环境开发实战(从配置、管理与控制)

《SpringBoot多环境开发实战(从配置、管理与控制)》本文详解SpringBoot多环境配置,涵盖单文件YAML、多文件模式、MavenProfile分组及激活策略,通过优先级控制灵活切换环境... 目录一、多环境开发基础(单文件 YAML 版)(一)配置原理与优势(二)实操示例二、多环境开发多文件版

使用docker搭建嵌入式Linux开发环境

《使用docker搭建嵌入式Linux开发环境》本文主要介绍了使用docker搭建嵌入式Linux开发环境,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录1、前言2、安装docker3、编写容器管理脚本4、创建容器1、前言在日常开发全志、rk等不同

Python实战之SEO优化自动化工具开发指南

《Python实战之SEO优化自动化工具开发指南》在数字化营销时代,搜索引擎优化(SEO)已成为网站获取流量的重要手段,本文将带您使用Python开发一套完整的SEO自动化工具,需要的可以了解下... 目录前言项目概述技术栈选择核心模块实现1. 关键词研究模块2. 网站技术seo检测模块3. 内容优化分析模

Java+AI驱动实现PDF文件数据提取与解析

《Java+AI驱动实现PDF文件数据提取与解析》本文将和大家分享一套基于AI的体检报告智能评估方案,详细介绍从PDF上传、内容提取到AI分析、数据存储的全流程自动化实现方法,感兴趣的可以了解下... 目录一、核心流程:从上传到评估的完整链路二、第一步:解析 PDF,提取体检报告内容1. 引入依赖2. 封装

基于Java开发一个极简版敏感词检测工具

《基于Java开发一个极简版敏感词检测工具》这篇文章主要为大家详细介绍了如何基于Java开发一个极简版敏感词检测工具,文中的示例代码简洁易懂,感兴趣的小伙伴可以跟随小编一起学习一下... 目录你是否还在为敏感词检测头疼一、极简版Java敏感词检测工具的3大核心优势1.1 优势1:DFA算法驱动,效率提升10

Python开发简易网络服务器的示例详解(新手入门)

《Python开发简易网络服务器的示例详解(新手入门)》网络服务器是互联网基础设施的核心组件,它本质上是一个持续运行的程序,负责监听特定端口,本文将使用Python开发一个简单的网络服务器,感兴趣的小... 目录网络服务器基础概念python内置服务器模块1. HTTP服务器模块2. Socket服务器模块

Java 与 LibreOffice 集成开发指南(环境搭建及代码示例)

《Java与LibreOffice集成开发指南(环境搭建及代码示例)》本文介绍Java与LibreOffice的集成方法,涵盖环境配置、API调用、文档转换、UNO桥接及REST接口等技术,提供... 目录1. 引言2. 环境搭建2.1 安装 LibreOffice2.2 配置 Java 开发环境2.3 配

Python38个游戏开发库整理汇总

《Python38个游戏开发库整理汇总》文章介绍了多种Python游戏开发库,涵盖2D/3D游戏开发、多人游戏框架及视觉小说引擎,适合不同需求的开发者入门,强调跨平台支持与易用性,并鼓励读者交流反馈以... 目录PyGameCocos2dPySoyPyOgrepygletPanda3DBlenderFife