【讯为Linux驱动开发】2.注册一个字符设备

news2024/11/24 4:02:06
【问】如何描述一个字符设备?

dev结构体

其中需要关心三个成员变量:

所属模块 :struct module *owner;

文件操作结构体: const struct file_operations *ops

设备号 : dev_t

当应用层使用指令open("/dev/hello", HELLO),系统就会进入驱动程序中执行cdev_open函数

【问】 如何连接系统调用open和驱动程序dev_open函数

file_operations结构体中就将这两个函数进行连接:

static struct file_operations cdev_ops = {
     .owner = THIS_MODULE;
     .open = cdev_open;
}
【问】应用程序和驱动程序的桥梁是什么?

设备节点,设备节点创建在/dev目录下。

比如 open("/dev/hello" ,HELLO);

【问】如何创建设备节点?

使用udev机制,在注册设备的时候自动创建,在注销设备的时候自动销毁。

1.创建类:

class_creat(struct module *owner ,const char *name)

THIS_MODULE 和 类的名字

对应删除:class_destroy(struct class *cls) 类

2.在类下创建设备:

device_creat(struct class *cls ,struct device *parent, dev_t devt , NULL ,const char *fmt )

1.哪个类     2.父设备是谁? NULL一般    3.设备号     4.NULL 5.设备节点的名字

3.删除类:

device_destroy(struct class *cls, dev_t devt)

类    设备号

【注册字符设备模版 】

static int major = 0;
static int minor = 0;
module_param(major ,int ,S_IRUGO);
module_param(minor ,int ,S_IRUGO);

dev_t dev_num;

static int cdev_open(struct inode *inode, struct file *filp)
{
    printk("cdev_open success\n");
    return 0;
}

static ssize_t cdev_read(struct file *filp, char __user *buf, size_t cnt, loff_t *offt)
{
    printk("cdev_read success\n");
    return 0;
}

static ssize_t cdev_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offt)
{
    printk("cdev_write success\n");
    return 0;            
}

static int cdev_release(struct inode *inode, struct file *filp)
{
    printk("cdev_release success\n");
    return 0;       
}

struct file_operations cdev_file_operations = {
    .owner = THIS_MODULE;
    .open = cdev_open;
    .read = cdev_read;
    .write = cdev_write;
    .release = cdev_release;
}


struct cdev cdev_test;


static int moduleparam_init()
{
        int ret;
        /* 动态申请 */
        ret = alloc_chrdev_region(&dev_num,0,1);  
        if(ret<0)
        {
           printk("alloc_chrdev_region error\n");
        }
          //动态注册设备号成功,则打印
           printk("alloc_chrdev_region ok\n");  
           major_num =MAJOR(dev_num); //将主设备号取出来
           minor_num = MINOR(dev_num);//将次设备号取出来
           printk("major_num = %d\n",major_num);//打印传入进来的主设备号
           printk("minor_num = %d\n",minor_num);//打印传入进来的次设备号
           
           cdev_test.owner = THIS_MODULE;
           cdev_init(cdev_test, cdev_file_operations);
           cdev_add(&cdev_test, dev_num, 1);
           
           class = class_creat(THIS_MODULE, "test");
           device = device_creat(class,NULL,dev_num,,NULL,"/dev/test")
          
           return 0;
}

static void hello_exit(void)
{
  unregister_chrdev_region(MKDEV(major_num,minor_num),DEVICE_NUMBER);//注销设备号
  cdev_del(&cdev_test);  //销毁字符设备

  device_destroy(class,dev_num);
  class_destroy(class);

  printk("gooodbye! \n");
}

module_init(moduleparam_init);
module_init(moduleparam_exit);

【应用程序验证】

int main(int argc, char *argv[])
{
 int fd;
 char buf[64] = 0;
 fd = open("/dev/test", HELLO);  /* 打开设备节点 */   
 close(fd);
 return 0;  
}
【问】app.c如何编译?

使用3568开发板对应的交叉编译器

linux源码  / prebuilts /gcc /linux-x86 / aarch64 / gcc ..............................

然后进入bin文件夹找到 gnu - gcc

编译命令:

进入app.c目录:

交叉编译器的绝对路径 加 / 交叉编译器的名字  加  app.c

生成a.out文件

拷贝 a.outfile .ko 文件进开发板

加载:insmod file.ko

手动创建设备节点 : mknod /dev/test c 2350 (设备名字和驱动中一致)

(在dev/test中可以看到设备节点)

执行 a.out 应用程序: ./a.out

成功调用,打印出驱动中的这两句话:

实验效果:

加载:insmod file.ko

因为是自动创建设备节点,所以 ls /dev/test  直接看

执行:./a.out

---------------------------------------------

-----------------------打印出打开设备和卸载设备信息

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1804205.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在群晖上通过Docker部署DB-GPT

最近一直有网友在后台私信&#xff0c;发的内容高度统一&#xff0c;只有后面 8 位数字不一样&#xff0c;都是 &#xff03;22232 xxxxxxxx&#xff0c;有谁知道是什么意思吗&#xff1f;在我印象中&#xff0c;这是第二次这么大规模的发类似的字符串了 什么是 DB-GPT ? DB-G…

项目总结报告(Word模板)

2 项目工作成果 2.1 交付给用户的产品 2.2 交付给研发中心的产品 2.2.1 代码部分 2.2.2 文档部分 2.3 需求完成情况与功能及性能符合性统计 2.3.1 需求完成情况统计 2.3.2 功能符合性分析 2.3.3 性能符合性分析 3 项目工作分析 3.1 项目计划与进度实施分析 3.1.1 开发进度 3.1.…

kube-promethesu新增k8s组件监控(etcd\kube-controller-manage\kube-scheduler)

我们的k8s集群是二进制部署,版本是1.20.4 同时选择的kube-prometheus版本是kube-prometheus-0.8.0 一、prometheus添加自定义监控与告警&#xff08;etcd&#xff09; 1、步骤及注意事项&#xff08;前提&#xff0c;部署参考部署篇&#xff09; 1.1 一般etcd集群会开启HTTP…

【设计模式】行为型设计模式之 状态模式,带你探究有限状态机FSM的三种实现方式

什么是有限状态机 Finite state Machine FSM 简称状态机&#xff1a;状态机由三部分组成&#xff0c;状态(State) 事件(Event) 和动作(Action)组成。 其中事件也被称为转移条件&#xff0c;事件触发状态的转移和动作的执行。不过动作不是必须的&#xff0c;也可能只存在状态转…

【机器人和人工智能——自主巡航赛项】进阶篇

文章目录 案例要求创建地图rviz仿真 保存地图坐标点定位识别训练主逻辑理解语音播报模块匹配二维码识别多点导航讲解视频其余篇章 案例要求 创建地图 ./1-gmapping.sh 把多个launch文件融合在sh文件里面 rviz仿真 rviz是rose集成的可视化界面&#xff0c;查看机器人的各项数…

html+CSS+js部分基础运用17

在图书列表中&#xff0c;为书名“零基础学JavaScript”和“HTML5CSS3精彩编程200例”添加颜色。&#xff08;请用class或style属性实现&#xff09;&#xff0c;效果如下图1所示&#xff1a; 图1 图书列表 Class和style的综合应用。&#xff08;1&#xff09;应用class的对象、…

CNN简介与实现

CNN简介与实现 导语整体结构卷积层卷积填充步幅三维卷积立体化批处理 实现 池化层特点实现 CNN实现可视化总结参考文献 导语 CNN全称卷积神经网络&#xff0c;可谓声名远扬&#xff0c;被用于生活中的各个领域&#xff0c;也是最好理解的神经网络结构之一。 整体结构 相较于…

Servlet-01

文章目录 Servlet创建Servlet探究Servlet的生命周期 HttpServletWebServlet注解详解 重定向与请求转发ServletContextServletContext中的接口 HttpServletRequestHttpServletResponse状态码解释Cookie Servlet Q&#xff1a;它能做什么呢&#xff1f; A&#xff1a;我们可以通…

使用汇编和proteus实现仿真数码管显示电路

proteus介绍&#xff1a; proteus是一个十分便捷的用于电路仿真的软件&#xff0c;可以用于实现电路的设计、仿真、调试等。并且可以在对应的代码编辑区域&#xff0c;使用代码实现电路功能的仿真。 汇编语言介绍&#xff1a; 百度百科介绍如下&#xff1a; 汇编语言是培养…

1-5 C语言操作符

C语言提供了非常丰富的操作符&#xff0c;使得C语言使用起来非常的方便 算数操作符&#xff1a; 加 减 乘 除 取模 【 - * / %】 注&#xff1a;除号的两端都是整数的时候执行的是整数的除法&#xff0c;如果…

Unity 编辑器扩展,获取目录下所有的预制件

先看演示效果 实现方案 1创建几个用于测试的cube 2&#xff0c;创建一个Editor脚本 3&#xff0c;编写脚本内容 附上源码 using UnityEditor; using UnityEngine;public class GetPrefeb : EditorWindow {private string folderPath "Assets/Resources"; // 指定预…

【Python】数据处理:文本文件操作

在Python中&#xff0c;处理文本文件是非常常见的任务。可以使用内置的open函数来打开、读取和写入文本文件。 打开文件 使用open函数打开文件。该函数有两个主要参数&#xff1a; open(file, moder, buffering-1, encodingNone, errorsNone, newlineNone, closefdTrue, ope…

ssm602社区医疗保健监控系统+vue【以测试】

前言&#xff1a;&#x1f469;‍&#x1f4bb; 计算机行业的同仁们&#xff0c;大家好&#xff01;作为专注于Java领域多年的开发者&#xff0c;我非常理解实践案例的重要性。以下是一些我认为有助于提升你们技能的资源&#xff1a; &#x1f469;‍&#x1f4bb; SpringBoot…

【设计模式】行为型设计模式之 策略模式学习实践

介绍 策略模式&#xff08;Strategy&#xff09;&#xff0c;就是⼀个问题有多种解决⽅案&#xff0c;选择其中的⼀种使⽤&#xff0c;这种情况下我们 使⽤策略模式来实现灵活地选择&#xff0c;也能够⽅便地增加新的解决⽅案。⽐如做数学题&#xff0c;⼀个问题的 解法可能有…

Linux shell编程基础

Shell 是一个用 C 语言编写的程序&#xff0c;它是用户使用 Linux 的桥梁。Shell 既是一种命令语言&#xff0c;又是一种程序设计语言。Shell 是指一种应用程序&#xff0c;这个应用程序提供了一个界面&#xff0c;用户通过这个界面访问 Linux 内核的服务。 Shell 脚本&#x…

GQA,MLA之外的另一种KV Cache压缩方式:动态内存压缩(DMC)

0x0. 前言 在openreview上看到最近NV的一个KV Cache压缩工作&#xff1a;https://openreview.net/pdf?idtDRYrAkOB7 &#xff0c;感觉思路还是有一些意思的&#xff0c;所以这里就分享一下。 简单来说就是paper提出通过一种特殊的方式continue train一下原始的大模型&#x…

打破 AIGC 算力困境,io.net 如何实现“GPU 互联网”?

AIGC 在全球快速发展的当下&#xff0c;诸多项目深陷 GPU 运力不足&#xff0c;速度放缓、任务宕机、项目崩溃等困境&#xff0c;作为瞄准 AI 理念和 DePIN 赛道的 Solana 生态项目新星 io.net 来说&#xff0c;如何集成项目控制与云计算服务成为抢占市场的重要发力方向。第 11…

将web项目打包成electron桌面端教程(一)vue3+vite+js

说明&#xff1a;后续项目需要web端和桌面端&#xff0c;为了提高开发效率&#xff0c;准备直接将web端的代码打包成桌面端&#xff0c;在此提前记录一下demo打包的过程&#xff0c;需要注意的是vue2或者vue3的打包方式各不同&#xff0c;如果你的项目不是vue3vitejs&#xff0…

Nagios的安装和使用

*实验* *nagios安装和使用* Nagios 是一个监视系统运行状态和网络信息的监视系统。Nagios 能监视所指定的本地或远程主机以及服务&#xff0c;同时提供异常通知功能等. Nagios 可运行在 Linux/Unix 平台之上&#xff0c;同时提供一个可选的基于浏览器的 WEB 界面以方便系统管…

go语言后端开发学习(二)——基于七牛云实现的资源上传模块

前言 在之前的文章中我介绍过我们基于gin框架怎么实现本地上传图片和文本这类的文件资源(具体文章可以参考gin框架学习笔记(二) ——相关数据与文件的响应)&#xff0c;但是在我们实际上的项目开发中一般却是不会使用本地上传资源的方式来上传的&#xff0c;因为文件的上传与读…