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

【问】如何描述一个字符设备?

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

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

京东JD商品详情接口接入文档说明参数说明

京东获得JD商品详情 API 返回值说明 item_get-获得JD商品详情 API注册测试 jd.item_get 公共参数 名称类型必须描述keyString是调用key&#xff08;必须以GET方式拼接在URL中&#xff09;secretString是调用密钥api_nameString是API接口名称&#xff08;包括在请求地址中&am…

LabVIEW电路板性能与稳定性测试系统

LabVIEW电路板性能与稳定性测试系统 概述&#xff1a; 开发基于LabVIEW的电路板性能与稳定性测试系统&#xff0c;通过集成多种测试仪器&#xff0c;实现对电路板的电气性能和长期稳定性的全面评估。系统涵盖了电压、电流、温度等多项参数的监测&#xff0c;并具备自动化测试…

微处理器体系结构

1.冯诺依曼结构 传统计算机采用冯●诺依曼(Von Neumann)结构&#xff0c;也称普林斯顿结构&#xff0c;是一种将程序指令存储器和数据存储器合并在一起的存储器结构。 特征&#xff1a; 冯●诺依曼结构的计算机程序和数据共用一个存储空间&#xff0c;程序指令存储地址和数据…

基于YOLOv8深度学习的茶叶病害检测含数据集

在当前全球竞争的时代&#xff0c;农业的重要性不容小觑。作为我国重要的经济作物&#xff0c;茶叶在农村振兴政策框架内对茶农的经济稳定起着至关重要的作用。作为云南省的特色产业和地区农业中著名的“金字品牌”&#xff0c;茶叶行业的高质量发展可以大大增强地区特色产业的…

水泵选型指南

在现代暖通空调&#xff08;HVAC&#xff09;系统中&#xff0c;冷冻水泵是关键组件之一&#xff0c;它在提供冷却和空调效果方面起着至关重要的作用。选择合适的冷冻水泵不仅可以提高系统效率&#xff0c;还能节省能源和维护成本。本文将介绍冷冻水泵选型的关键因素和步骤。 …

不装了,我是知识星球的星主,我摊牌了~

作者&#xff1a;哈哥撩编程 &#xff08;视频号同名&#xff09; 图书作者&#xff1a;程序员职场效能宝典 博客专家&#xff1a;全国博客之星第四名 超级个体&#xff1a;COC上海社区主理人 特约讲师&#xff1a;谷歌亚马逊分享嘉宾 科技博主&#xff1a;极星会首批签约…

量化交易:Miniqmt获取可转债数据和交易python代码

哈喽&#xff0c;大家好&#xff0c;我是木头左&#xff01; 低风险资产除了国债外&#xff0c;还有可转债&#xff0c;兼容有高收益的股性和低风险的债性&#xff0c;号称“下有保底&#xff0c;上不封顶”。 &#x1f50d; 可转债&#xff1a;金融市场的双面娇娃 可转债&am…

Go微服务: 基于rocketmq:server和rocketmq:broker搭建RocketMQ环境,以及生产消息和延迟消费消息的实现

RocketMQ 的搭建 1 ) 配置 docker-compose.yaml 文件 version: 3.5 services:rmqnamesrv:image: foxiswho/rocketmq:servercontainer_name: rmqnamesrvports:- 9876:9876volumes:- ./logs:/opt/logs- ./store:/opt/storenetworks:rmq:aliases:- rmqnamesrvrmqbroker:image: fo…

Vue3实战笔记(58)—从零开始掌握Vue3插槽机制,基础入门

文章目录 前言插槽基础入门总结 前言 不论是组件封装还是分析源码&#xff0c;实际开发中经常接触插槽&#xff0c;插槽是干什么用的呢&#xff1f;组件之间能够接收任意类型的 JavaScript 值作为 props&#xff0c;但组件要如何接收模板内容呢&#xff1f;在某些场景中&#…

伏图(Simdroid)5.0 电子散热模块 | 可试用

伏图-电子散热模块&#xff08;Simdroid-EC&#xff09;是云道智造基于通用多物理场仿真PaaS平台伏图开发的针对电子元器件、设备等散热的专用热仿真模块&#xff0c;内置电子产品专用零部件模型库&#xff0c;支持用户通过“搭积木”的方式快速建立电子产品的热分析模型&#…

【13】Camunda7-第一个BPMN流程

在前一篇博文里&#xff0c;我们介绍了Camunda Modeler&#xff0c;那么接下来&#xff0c;我们就使用这个设计器工具绘制我们的第一个BPMN流程。 1. 场景概述 关于第一个流程&#xff0c;这里计划以我们最常见的请假审批流程为例&#xff0c;它涉及到表单设计、人工审批任务等…

从0开始用TCN预测股价

源码地址 由于用的是tensflow&#xff0c;其实和pytorch差不多看懂就行&#xff08;pytorch版本我还在改&#xff0c;有些难度&#xff09;因为这里面的tcn结构是用的 别人的代码https://github.com/philipperemy/keras-tcn 首先说一下什么是TCN 首先我想说 我们预测股票价格…

Science项目文章 | 中国农科院作科所研究团队解析“复粒稻”多粒簇生的机制

2024年3月8日&#xff0c;由中国农业科学院作物科学研究所童红宁研究员领衔的研究团队在Science发表题为“Enhancing rice panicle branching and grain yield through tissue-specific brassinosteroid inhibition”的研究论文。该研究报道了复粒稻多粒簇形成的机制&#xff0…

python-flask项目的服务器线上部署

在部署这部分我首先尝试了宝塔面板&#xff0c;始终连接失败 换了一种思路选择了Xshell成功连接 首先我们需要下载个免费版本的Xshell 免费的&#xff1a;家庭/学校免费 - NetSarang Website 下载完毕打开 1新建-> 输入服务器的账号密码&#xff1a; 在所有会话中点击自…

WalleWeb简化你的DevOps部署流程

walle-web&#xff1a;简化部署流程&#xff0c;提升开发效率&#xff0c;Walle Web让DevOps触手可及 - 精选真开源&#xff0c;释放新价值。 概览 Walle Web是一个功能强大且免费开源的DevOps平台&#xff0c;旨在简化和自动化代码部署流程。它支持多种编程语言&#xff0c;包…

学习axios拦截器

axios拦截器的作用&#xff1a;用于在请求发送前和响应返回后对请求和响应进行统一处理&#xff0c;例如添加公共请求头、处理请求参数、统一处理错误信息等。拦截器提供了一种灵活、高效的方式来管理HTTP请求和响应&#xff0c;帮助在前端开发中更好地处理数据交互。 这是一个…

Commons-Collections篇-CC3链

前言 我们分析前两条链CC1和CC6时&#xff0c;都是利用invoke反射调用的Runtime().getRuntime().exec()来执行命令。而很多时候服务器的代码当中的黑名单会选择禁用Runtime CC3链主要通过动态加载类加载机制来实现自动执行恶意类代码 1.环境安装 可以接着使用我们之前分析C…

植物大战僵尸杂交版2.0.88最新版安装包

游戏简介 游戏中独特的杂交植物更是为游戏增添了不少亮点。这些杂交植物不仅外观独特&#xff0c;而且拥有更强大的能力&#xff0c;能够帮助玩家更好地应对游戏中的挑战。玩家可以通过一定的条件和方式&#xff0c;解锁并培养这些杂交植物&#xff0c;从而不断提升自己的战斗…

重大变化,2024软考!

根据官方发布的2024年度计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试安排&#xff0c;2024年软考上、下半年开考科目有着巨大变化&#xff0c;我为大家整理了相关信息&#xff0c;大家可以看看&#xff01; &#x1f3af;2024年上半年&#xff1a;5月25日&am…

【动手学深度学习】卷积神经网络(AlexNet)的研究详情

目录 &#x1f30a;1. 研究目的 &#x1f30a;2. 研究准备 &#x1f30a;3. 研究内容 &#x1f30d;3.1 卷积神经网络&#xff08;AlexNet&#xff09; &#x1f30d;3.2 练习 &#x1f30a;4. 研究体会 &#x1f30a;1. 研究目的 多层感知机模型选择&#xff1a;比较不同…