华清远见嵌入式学习——驱动开发——day9
目录
作业要求:
作业答案:
代码效果:
编辑
Platform总线驱动代码:
应用程序代码:
设备树配置:
作业要求:
通过platform总线驱动框架编写LED灯的驱动,编写应用程序测试,发布到CSDN
作业答案:
代码效果:
Platform总线驱动代码:
#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>//主设备号
int major;//用于上传目录和设备节点信息
struct class *cls;
struct device *device;// led设备号
struct gpio_desc *gpiono1;
struct gpio_desc *gpiono2;
struct gpio_desc *gpiono3;// 创建功能码
#define LED_ON _IOW('l', 1, int)
#define LED_OFF _IOW('l', 0, int)// ioctl函数,用于控制led设备
long mycdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{switch (cmd){case LED_ON:switch (arg){case 1:gpiod_set_value(gpiono1, 1);break;case 2:gpiod_set_value(gpiono2, 1);break;case 3:gpiod_set_value(gpiono3, 1);break;}break;case LED_OFF:switch (arg){case 1:gpiod_set_value(gpiono1, 0);break;case 2:gpiod_set_value(gpiono2, 0);break;case 3:gpiod_set_value(gpiono3, 0);break;}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++){device = 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("解析led3对应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");
应用程序代码:
#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 _IOW('l',1,int)
#define LED_OFF _IOW('l',0,int)int main(int argc, char const *argv[])
{int a,b;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);printf("请输入要控制的灯\n");printf("1(LED1) 2(LED2) 3(LED3)\n");printf("请输入>");scanf("%d",&b);switch(a){case 1:ioctl(fd,LED_ON,b);break;case 0:ioctl(fd,LED_OFF,b);break;}}close(fd);return 0;
}
设备树配置:
/dts-v1/;
#include "stm32mp157.dtsi"
#include "stm32mp15xa.dtsi"
#include "stm32mp15-pinctrl.dtsi"
#include "stm32mp15xxac-pinctrl.dtsi"
#include "stm32mp15xx-fsmp1x.dtsi"
/ {model = "HQYJ STM32MP157 FSMP1A Discovery Board";compatible = "st,stm32mp157a-dk1", "st,stm32mp157";aliases {serial0 = &uart4;serial5 = &usart3;};chosen {stdout-path = "serial0:115200n8";};reserved-memory {gpu_reserved: gpu@d4000000 {reg = <0xd4000000 0x4000000>;no-map;};optee_memory: optee@0xde000000 {reg = <0xde000000 0x02000000>;no-map;};};mynode@0x12345678{compatible = "hqyj,mynode";astring="hello 23091";uint =<0xaabbccdd 0x11223344>;binarry=[00 0c 29 7b f9 be];mixed ="hello",[11 22],<0x12345678>;};myled{led1-gpio=<&gpioe 10 0>; led2-gpio=<&gpiof 10 0>;led3-gpio=<&gpioe 8 0>; };myirq{compatible = "hqyj,myirq";interrupt-parent = <&gpiof>;interrupts=<9 0>,<7 0>,<8 0>;};myplatform{compatible = "hqyj,myplatform";led1-gpio=<&gpioe 10 0>;led2-gpio=<&gpiof 10 0>;led3-gpio=<&gpioe 8 0>; interrupt-parent = <&gpiof>;interrupts=<9 0>;reg=<0X12345678 0X400>;};
};
相关文章:
华清远见嵌入式学习——驱动开发——day9
目录 作业要求: 作业答案: 代码效果: 编辑 Platform总线驱动代码: 应用程序代码: 设备树配置: 作业要求: 通过platform总线驱动框架编写LED灯的驱动,编写应用程序测试&…...
formality:set_constant应用
我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧? 拾陆楼知识星球入口 往期文章链接: formality:形式验证流程 scan mode func的功能检查需要把scan mode设置成0。...
sqllabs的order by注入
当我们在打开sqli-labs的46关发现其实是个表格,当测试sort等于123时,会根据列数的不同来进行排序 我们需要利用这个点来判断是否存在注入漏洞,通过加入asc 和desc判断页面有注入点 1、基于使用if语句盲注 如果我们配合if函数,表达…...
《The Art of InnoDB》第二部分|第4章:深入结构-磁盘结构-redo log
4.3 redo log 目录 4.3 redo log 4.3.1 redo log 介绍 4.3.2 redo log 的作用 4.3.3 redo log file 结构 4.3.4 redo log 提交逻辑 4.3.5 redo log 持久化逻辑 4.3.6 redo log 检查点 4.3.7 小结...
大模型安全相关论文
LLM对于安全的优势 “Generating secure hardware using chatgpt resistant to cwes,” Cryptology ePrint Archive, Paper 2023/212, 2023评估了ChatGPT平台上代码生成过程的安全性,特别是在硬件领域。探索了设计者可以采用的策略,使ChatGPT能够提供安…...
回归预测 | Matlab实现PSO-BiLSTM-Attention粒子群算法优化双向长短期记忆神经网络融合注意力机制多变量回归预测
回归预测 | Matlab实现PSO-BiLSTM-Attention粒子群算法优化双向长短期记忆神经网络融合注意力机制多变量回归预测 目录 回归预测 | Matlab实现PSO-BiLSTM-Attention粒子群算法优化双向长短期记忆神经网络融合注意力机制多变量回归预测预测效果基本描述程序设计参考资料 预测效果…...
[算法沉淀记录] 排序算法 —— 堆排序
排序算法 —— 堆排序 算法基础介绍 堆排序(Heap Sort)是一种基于比较的排序算法,它利用堆这种数据结构来实现排序。堆是一种特殊的完全二叉树,其中每个节点的值都必须大于或等于(最大堆)或小于或等于&am…...
C++ //练习 9.33 在本节最后一个例子中,如果不将insert的结果赋予begin,将会发生什么?编写程序,去掉此赋值语句,验证你的答案。
C Primer(第5版) 练习 9.33 练习 9.33 在本节最后一个例子中,如果不将insert的结果赋予begin,将会发生什么?编写程序,去掉此赋值语句,验证你的答案。 环境:Linux Ubuntu࿰…...
[corCTF 2022] CoRJail: From Null Byte Overflow To Docker Escape
前言 题目来源:竞赛官网 – 建议这里下载,文件系统/带符号的 vmlinux 给了 参考 [corCTF 2022] CoRJail: From Null Byte Overflow To Docker Escape Exploiting poll_list Objects In The Linux Kernel – 原作者文章,poll_list 利用方式…...
thinkphp6定时任务
这里主要是教没有用过定时任务没有头绪的朋友, 定时任务可以处理一些定时备份数据库等一系列操作, 具体根据自己的业务逻辑进行更改 直接上代码 首先, 是先在 tp 中的 command 方法中声明, 如果没有就自己新建一个, 代码如下 然后就是写你的业务逻辑 执行定时任务 方法写好了…...
支持国密ssl的curl编译和测试验证(上)
目录 1. 编译铜锁ssl库2. 编译nghttp2库3. 编译curl4. 验证4.1 查看版本信息4.2 验证国密ssl握手功能4.3 验证http2协议功能 以下以ubuntu 22.04环境为例进行编译 本次编译采用铜锁sslnghttp2curl,使得编译出来的curl可以支持国密ssl,并且可以支持http2…...
包装类详解
概述 Java提供了两个类型系统,基本类型与引用类型,使用基本类型在于效率,然而很多情况,会创建对象使用,因为对象可以做更多的功能,如果想要我们的基本类型像对象一样操作,就可以使用基本类型对…...
vue3与vue2的区别
Vue 3和Vue 2在以下几个方面有一些区别: 性能提升:Vue 3对渲染性能和内存占用进行了优化,使用了Proxy代理对象,比Vue 2的Object.defineProperty更高效。此外,Vue 3还引入了静态树提升(Static Tree Hoisting…...
SSL OV证书和DV、EV证书的区别
在网站搭建的过程中和小程序开发过程中,很难免会有需要用到SSL证书的地方,但是目前数字证书种类繁多,该选择什么类型的证书成为了一个令人纠结的问题。 目前在市场上较为常见的证书分为三种:DV域名验证型证书;OV组织验…...
一款.NET下 WPF UI框架介绍
WPF开源的UI框架有很多,如HandyControl、MahApps.Metro、Xceed Extended WPF Toolkit™、Modern UI for WPF (MUI)、Layui-WPF、MaterialDesignInXamlToolkit、等等,今天小编带大家认识一款比较常用的kaiyuanUI---WPF UI,这款ui框架美观现代化,用起来也超级方便, 界面展示…...
东莞IBM服务器维修之IBM x3630 M4阵列恢复
记录东莞某抖音电商公司送修一台IBM SYSTEM X3630 M4文档服务器RAID6故障导致数据丢失的恢复案例 时间:2024年02月20日, 服务器品牌:IBM System x3630 M4,阵列卡用的是DELL PERC H730P 服务器用途和用户位置:某抖音电…...
Flask基础学习4
19-【实战】问答平台项目结构搭建_剪_哔哩哔哩_bilibili 参考如上大佬的视频教程,本博客仅当学习笔记,侵权请联系删除 问答发布的web前端页面实现 register.html {% extends base.html %}{% block head %}<link rel"stylesheet" href&q…...
mac安装zookeeper
下载地址: http://archive.apache.org/dist/zookeeper/ 注意:由于Zookeeper从3.5.5版本开始,带有bin名称的包才是我们想要的下载可以直接使用的里面有编译后的二进制的包,而之前的普通的tar.gz的包里面是只是源码的包无法直接使…...
IT资讯——全速推进“AI+鸿蒙”战略布局!
文章目录 每日一句正能量前言坚持长期研发投入全速推进“AI鸿蒙”战略 人才战略新章落地持续加码核心技术生态建设 后记 每日一句正能量 人总要咽下一些委屈,然后一字不提的擦干眼泪往前走,没有人能像白纸一样没有故事,成长的代价就是失去原来…...
数据结构知识点总结-线性表(3)-双向链表定义、循环单链表、、循环双向链表、静态链表、顺序表与链表的比较
双向链表定义 单链表结点中只有一个指向其后继的指针,这使得单链表只能从头结点依次顺序地向后遍历。若要访问某个结点的前驱结点(插入、删除操作时),只能从头开始遍历,访问后继结点的时间复杂度为 O(1) , …...
wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...
【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...
关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...
短视频矩阵系统文案创作功能开发实践,定制化开发
在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...
【分享】推荐一些办公小工具
1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由:大部分的转换软件需要收费,要么功能不齐全,而开会员又用不了几次浪费钱,借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...
