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

一、字符设备驱动

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.hqwc.cn/news/294859.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024年【北京市安全员-C3证】考试试卷及北京市安全员-C3证理论考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年北京市安全员-C3证考试试卷为正在备考北京市安全员-C3证操作证的学员准备的理论考试专题&#xff0c;每个月更新的北京市安全员-C3证理论考试祝您顺利通过北京市安全员-C3证考试。 1、【多选题】SC型施工升降机…

【Proteus仿真】【Arduino单片机】蓝牙遥控小车

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真Arduino单片机控制器&#xff0c;使LCD1602液晶&#xff0c;L298电机&#xff0c;直流电机&#xff0c;HC05/06蓝牙模块等。 主要功能&#xff1a; 系统运行后&#xff0c;LCD1602…

单片机第三季-第七课:STM32中断体系

1&#xff0c;NVIC NVIC: Nested Vector Interrupt Control&#xff0c;嵌套向量中断控制器&#xff1b; 68个可屏蔽中断通道。 数据手册得向量表结合起始代码查看&#xff1a; 可以理解为数组里&#xff08;__Vectors &#xff09;定义了数据类型为DCD的许多个元素。 下边…

算法与数据结构--散列表与哈希算法

引入 我们知道c的set和unorder_set&#xff08;map本质上也是set&#xff0c;就是把set的存储对象换成键值对结构体&#xff09;&#xff0c;set底层是红黑树实现的&#xff0c;那么unorder_set是怎么实现的呢&#xff1f;这一节就来讲讲实现unorder_set的哈希表&#xff0c;也…

[每周一更]-(第78期):Nginx负载均衡proxy_pass代理模块常用参数配置

0、负载均衡的策略 使用场景示例 # 定义要包含在负载均衡方案中的服务器。 # 最好使用服务器的私有IP以获得更好的性能和安全性。 http {upstream backend {server 10.1.0.101;server 10.1.0.102;server 10.1.0.103;}server{server_name game1.test.com;listen 80;location / {…

java流浪动物保护系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 java Web 流浪动物保护系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql…

Ubuntu 常用命令之 echo 命令用法介绍

&#x1f4d1;Linux/Ubuntu 常用命令归类整理 echo 是一个在 Ubuntu 系统下常用的命令&#xff0c;主要用于在终端输出字符串或者变量。 echo 的基本语法 echo [option] [string]echo 命令的参数包括 -n&#xff1a;不输出结尾的换行符。-e&#xff1a;启用反斜杠转义字符。…

【mongoose】 Model.create() no longer accepts a callback 报错解决

在最新版的 mongoose 操作 MongoDB 数据库的时候&#xff0c;当我们插入一条数据时候&#xff0c;会报错 &#xff1a;Model.create() no longer accepts a callback&#xff0c;看了很多文章都说是&#xff0c;版本太高&#xff0c;都妥协选择了降低回旧版本&#xff0c;但我就…

服务器数据恢复-误操作导致xfs分区数据丢失的数据恢复案例

服务器数据恢复环境&#xff1a; 某品牌OceanStorT系列某型号存储MD1200磁盘柜&#xff0c;组建的raid5磁盘阵列。上层分配了1个lun&#xff0c;安装的linux操作系统&#xff0c;划分两个分区&#xff0c;分区一通过lvm进行扩容&#xff0c;分区二格式化为xfs文件系统。 服务器…

YZ系列工具之YZ03:高版本Excel的自定义菜单

我给VBA下的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。我的教程一共九套一部VBA手册&#xff0c;教程分为初级、中级、高级三大部分。是对VBA的系统讲解&#xff0c;从简单的…

搜索二叉树(超详解)

文章目录 前言查找搜索二叉树的结构insertfinderase递归版本Findinserterase 二叉树的拷贝问题搜索二叉树的应用Key模型Key/Value的模型 前言 普通二叉树其实意义不大&#xff0c; 如果用二叉树存储数据的话&#xff0c;还不如顺序表&#xff0c;链表这些。 搜索二叉树它的意义…

如何改善与 Next Paint (INP) 的交互

但谷歌也会关注访问者到达后你的网站体验有多好。 在过去的几年里&#xff0c;谷歌已经彻底改变了哪些页面体验信号被收集并用作排名因素。 在引入核心网络指标后&#xff0c;谷歌逐渐调整了它们的衡量方式&#xff0c;以便更好地反映真实的用户体验。 然而&#xff0c;随着…