当前位置: 首页 > news >正文

通过platform总线驱动框架编写LED灯的驱动,编写应用程序测试

mydev.c

#include <linux/init.h>
#include <linux/module.h>
#include <linux/of_gpio.h>
#include <linux/gpio.h>
#include <linux/platform_device.h>
#include <linux/mod_devicetable.h>// 创建功能码
#define LED_ON _IO('l', 1)
#define LED_OFF _IO('l', 0)int major;
struct class *cls;
struct device *devi;struct gpio_desc *gpiono1; // led1设备号
struct gpio_desc *gpiono2; // led2设备号
struct gpio_desc *gpiono3; // led3设备号long mycdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{switch (cmd){case LED_ON:gpiod_set_value(gpiono1, 1);gpiod_set_value(gpiono2, 1);gpiod_set_value(gpiono3, 1);break;case LED_OFF:gpiod_set_value(gpiono1, 0); gpiod_set_value(gpiono2, 0);gpiod_set_value(gpiono3, 0);break;}return 0;
}// 定义操作方法结构体变量并赋值
struct file_operations fops = {.unlocked_ioctl = mycdev_ioctl,};
//封装probe函数,当设备和驱动匹配成功之后执行
int pdrv_probe(struct platform_device *dev)
{printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);// 字符设备驱动注册major = register_chrdev(0, "mychrdev", &fops);if (major < 0){printk("字符设备驱动注册失败\n");return major;}printk("字符设备驱动注册成功:major=%d\n", major);// 向上提交目录cls = class_create(THIS_MODULE, "mychrdev");if (IS_ERR(cls)){printk("向上提交目录失败\n");return -PTR_ERR(cls);}printk("向上提交目录成功\n");// 向上提交设备节点信息int i; for (i = 0; i < 3; i++){devi = device_create(cls, NULL, MKDEV(major, i), NULL, "myled%d", i);if (IS_ERR(dev)){printk("向上提交设备节点失败\n");return -PTR_ERR(dev);}}printk("向上提交设备节点成功\n");// 解析LED1的gpio编号gpiono1 = gpiod_get_from_of_node(dev->dev.of_node, "led1-gpio", 0, GPIOD_OUT_LOW, NULL);if (gpiono1 == NULL){printk("解析led1对应gpio编号失败\n");return -ENXIO;}printk("解析led1对应gpio编号成功\n");// 解析LED1的gpio编号gpiono2 = gpiod_get_from_of_node(dev->dev.of_node, "led2-gpio", 0, GPIOD_OUT_LOW, NULL);if (gpiono2 == NULL){printk("解析led2对应gpio编号失败\n");return -ENXIO;}printk("解析led2对应gpio编号成功\n");// 解析LED1的gpio编号gpiono3 = gpiod_get_from_of_node(dev->dev.of_node, "led3-gpio", 0, GPIOD_OUT_LOW, NULL);if (gpiono3 == NULL){printk("解析led3对应gpio编号失败\n");return -ENXIO;}printk("解析gpio编号成功\n");return 0;
}// 封装remove函数,用于驱动和设备卸载时执行
int pdrv_remove(struct platform_device *dev)
{// 销毁设备节点信息device_destroy(cls, MKDEV(major, 0));// 销毁设备节点信息int i;for (i = 0; i < 3; i++){device_destroy(cls, MKDEV(major, i));}// 释放gpio编号gpiod_put(gpiono1);gpiod_put(gpiono2);gpiod_put(gpiono3);// 销毁目录class_destroy(cls);// 注销字符设备驱动unregister_chrdev(major, "mychrdev");printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);return 0;
}
// 构建用于匹配的设备树表
struct of_device_id oftable[] = {{.compatible = "hqyj,myplatform",},{/* end node */}, // 防止数组越界
};
// 分配驱动对象并初始化
struct platform_driver pdrv = {.probe = pdrv_probe,.remove = pdrv_remove,.driver = {.name = "bbbbb",.of_match_table = oftable, // 设置设备树匹配},};
// 一键注册宏
module_platform_driver(pdrv);MODULE_LICENSE("GPL");

test.c

#include<stdlib.h>
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<unistd.h>
#include<string.h>
#include<sys/ioctl.h>
//创建功能码
#define LED_ON _IO('l',1)  
#define LED_OFF _IO('l',0)int main(int argc, char const *argv[])
{int a;int fd=open("/dev/myled0",O_RDWR);if(fd<0){printf("打开设备文件失败\n");exit(-1);}while(1){//从终端读取printf("请输入要实现的功能\n");printf("0(关灯) 1(开灯)\n");printf("请输入>");scanf("%d",&a);switch(a){case 1:ioctl(fd,LED_ON);break;case 0:ioctl(fd,LED_OFF);break;}}close(fd);return 0;
}

相关文章:

通过platform总线驱动框架编写LED灯的驱动,编写应用程序测试

mydev.c #include <linux/init.h> #include <linux/module.h> #include <linux/of_gpio.h> #include <linux/gpio.h> #include <linux/platform_device.h> #include <linux/mod_devicetable.h>// 创建功能码 #define LED_ON _IO(l, 1) #d…...

费舍尔FISHER金属探测器探测仪维修F70

美国FISHER LABS费舍尔地下金属探测器&#xff0c;金属探测仪等维修&#xff08;考古探金银铜探宝等仪器&#xff09;。 费舍尔F70视听目标ID金属探测器&#xff0c;Fisher 金属探测器公司成立于1931年&#xff0c;在实验条件很艰苦的情况下&#xff0c;研发出了地下金属探测器…...

Airtest-Selenium实操小课③:下载可爱猫猫图片

1. 前言 那么这周我们看看如何实现使用Airtest-Selenium实现自动搜索下载可爱的猫猫图片吧~ 2. 需求分析和准备 整体的需求大致可以分为以下步骤&#xff1a; 打开chrome浏览器 打开百度网页 搜索“可爱猫猫图片” 定位图片元素 创建存储图片的文件夹 下载可爱猫猫图片…...

Druid无法登录监控页面

问题表现&#xff1a;在配置和依赖都正确的情况下&#xff0c;无法通过配置的用户名密码登录Druid的监控页面 检查配置发现 配置的用户名和密码和请求中参数是一致的&#x1f914; Debug发现 ResourceServlet 是Druid的登录实现&#xff0c; 且调试发现usernameParam是null&am…...

【Linux系统化学习】深入理解匿名管道(pipe)和命名管道(fifo)

目录 进程间通信 进程间通信目的 进程间通信的方式 管道 System V IPC&#xff08;本地通信&#xff09; POSIX IPC&#xff08;网络通信&#xff09; 管道 什么是管道 匿名管道 匿名管道的创建 匿名管道的使用 匿名管道的四种情况 匿名管道的五种特性 命名管道 …...

信息学奥赛一本通1209:分数求和

1209&#xff1a;分数求和 时间限制: 1000 ms 内存限制: 65536 KB 提交数: 19111 通过数: 10647 【题目描述】 输入n个分数并对他们求和&#xff0c;并用最简形式表示。所谓最简形式是指&#xff1a;分子分母的最大公约数为11&#xff1b;若最终结果的分母为11&am…...

LabVIEW储氢材料循环寿命测试系统

LabVIEW储氢材料循环寿命测试系统 随着氢能技术的发展&#xff0c;固态储氢技术因其高密度和安全性成为研究热点。储氢材料的循环寿命是衡量其工程应用的关键。然而&#xff0c;传统的循环寿命测试设备存在成本高、测试效率低、数据处理复杂等问题。设计了一种基于LabVIEW软件…...

Unity3D 框架如何搭建基于纯Lua的U框架与开发模式详解

前言 Unity3D 是一款非常流行的游戏开发引擎&#xff0c;它支持C#、JavaScript和Boo等多种脚本语言。而Lua语言作为一种轻量级的脚本语言&#xff0c;也在游戏开发中得到了广泛应用。本文将介绍如何在Unity3D框架中搭建基于纯Lua的U框架&#xff0c;并详细讲解其开发模式。 对…...

Linux常见指令(2)

目录 1、tar指令 &#xff01; 2、bc指令 3、uname 4、重要热键 5、关机 1、tar指令 &#xff01; 功能&#xff1a;压缩/解压缩文件或目录,类似zip 我们先来看一下我们的文件即目录&#xff0c;接下来我们输入指令&#xff1a; tar -czf test.tgz test 压缩 -c &#xf…...

【C++】封装

1.封装的意义 封装是C面向对象三大特性之一 实例化&#xff08;通过一个类 创建一个对象的过程&#xff09; 类中的属性和行为 我们统一称为 成员 属性 成员属性 成员变量 行为 成员函数 成员方法 封装的意义&#xff1a; 1.将属性和行为作为一个整体&#xff0c;表现生活中的事…...

Maxwell安装部署

1 Maxwell输出格式 database&#xff1a;变更数据所属的数据库table&#xff1a;变更数据所属的表type&#xff1a;数据变更类型ts&#xff1a;数据变更发生的时间xid&#xff1a;事务idcommit&#xff1a;事务提交标志&#xff0c;可用于重新组装事务data&#xff1a;对于inse…...

说一下JVM类加载机制?

Java中的所有类&#xff0c;都需要由类加载器装载到JVM中才能运行。类加载器本身也是一个类&#xff0c;而它的工作就是把class文件从硬盘读取到内存中。 在写程序的时候&#xff0c;我们几乎不需要关心类的加载&#xff0c;因为这些都是隐式装载的&#xff0c;除非我们有特殊…...

解决SpringAMQP工作队列模型程序报错:WARN 48068:Failed to declare queue: simple.queue

这里写目录标题 1.运行环境2.报错信息3.解决方案4.查看解决之后的效果 1.运行环境 使用docker运行了RabbitMQ的服务器&#xff1a; 在idea中导入springAMQP的jar包&#xff0c;分别编写了子模块生产者publisher&#xff0c;消费者consumer&#xff1a; 1.在publisher中运行测试…...

mysql在服务器中的主从复制Linux下

mysql在服务器中的主从复制Linux下 为什么要进行主从复制主从复制的原理主从复制执行流程操作步骤主库创建从库创建 测试 为什么要进行主从复制 在业务中通常会有情况&#xff0c;在sql执行时&#xff0c;将表锁住&#xff0c;导致不能进行查询&#xff0c;这样就会影响业务的…...

QT-Day2

思维导图 作业 使用手动连接&#xff0c;将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数 将登录按钮使用qt5版本的连接到自定义的槽函数中&#xff0c;在槽函数中判断ui界面上输入的账号是否为"admin"&#x…...

流量分析——陇剑杯 2021【签到、jwt】

目录 签到1、攻击者正在进行的可能是什么协议的网络攻击 jwt1、该网站使用了______认证方式。前置知识&#xff1a;解&#xff1a; 2、黑客绕过验证使用的jwt中&#xff0c;id和username是3、黑客获取webshell之后&#xff0c;权限是什么4、黑客上传的恶意文件文件名是5、黑客在…...

Java并发基础:原子类之AtomicIntegerFieldUpdater全面解析

本文概要 AtomicIntegerFieldUpdater类提供了一种高效、简洁的方式来原子性地更新对象的volatile字段&#xff0c;无需使用重量级的锁机制&#xff0c;它通过基于反射的API实现了细粒度的并发控制&#xff0c;提升了多线程环境下的性能表现。 AtomicIntegerFieldUpdater核心概…...

普中51单片机学习(串口通信)

串口通信 原理 计算机通信是将计算机技术和通信技术的相结合&#xff0c;完成计算机与外部设备或计算机与计算机之间的信息交换 。可以分为两大类&#xff1a;并行通信与串行通信。并行通信通常是将数据字节的各位用多条数据线同时进行传送 。控制简单、传输速度快&#xff1…...

【ArcGIS】利用高程进行坡度分析

在ArcGIS中利用高程进行坡度分析 坡度ArcGIS实操参考 坡度 坡度是地表单元陡缓的程度&#xff0c;通常把坡面的垂直高度和水平距离的比值称为坡度。 坡度的表示方法有百分比法、度数法、密位法和分数法四种&#xff0c;其中以百分比法和度数法较为常用。 &#xff08;1&#…...

递归读取文件夹下的所有文件

水一篇文章 &#x1f436; 代码 package file;import org.apache.commons.lang3.StringUtils; import org.junit.Test;import java.io.File; import java.util.Objects;/*** FlattenDirFiles** author allens* date 2024/2/19*/ public class FlattenDirFiles {// 文件数量pri…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录

ASP.NET Core 是一个跨平台的开源框架&#xff0c;用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录&#xff0c;以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

mongodb源码分析session执行handleRequest命令find过程

mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程&#xff0c;并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令&#xff0c;把数据流转换成Message&#xff0c;状态转变流程是&#xff1a;State::Created 》 St…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业

6月9日&#xff0c;国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解&#xff0c;“超级…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列&#xff0c;以便知晓哪些列包含有价值的数据&#xff0c;…...

算法笔记2

1.字符串拼接最好用StringBuilder&#xff0c;不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?

现有的 Redis 分布式锁库&#xff08;如 Redisson&#xff09;相比于开发者自己基于 Redis 命令&#xff08;如 SETNX, EXPIRE, DEL&#xff09;手动实现分布式锁&#xff0c;提供了巨大的便利性和健壮性。主要体现在以下几个方面&#xff1a; 原子性保证 (Atomicity)&#xff…...

免费数学几何作图web平台

光锐软件免费数学工具&#xff0c;maths,数学制图&#xff0c;数学作图&#xff0c;几何作图&#xff0c;几何&#xff0c;AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...