arm学习之stm32设备树学习-中断控制led灯亮灭+字符设备指令控制led灯亮灭
中断控制led灯亮灭
驱动文件源码
led-key.c
#include<linux/init.h>
#include<linux/module.h>
#include<linux/of.h>
#include<linux/of_gpio.h>
#include<linux/gpio.h>
#include<linux/of_irq.h>
#include<linux/interrupt.h>
struct device_node *led_dev;
struct device_node *key_dev;
struct gpio_desc *gpiono_led_1;
struct gpio_desc *gpiono_led_2;
struct gpio_desc *gpiono_led_3;
unsigned int irqno_1;
unsigned int irqno_2;
unsigned int irqno_3;
irqreturn_t myirq_handler(int irq, void *dev){printk("irq=%d\n",irq);switch (irq){case 71:gpiod_set_value(gpiono_led_1,!gpiod_get_value(gpiono_led_1));break;case 72:gpiod_set_value(gpiono_led_2,!gpiod_get_value(gpiono_led_2));break;case 73:gpiod_set_value(gpiono_led_3,!gpiod_get_value(gpiono_led_3));break;} return IRQ_HANDLED;
}
static int __init mycdev_init(void){ int ret;led_dev = of_find_node_by_path("/leds");if(led_dev == NULL){printk("解析led灯设备树节点失败\n");return -EFAULT;}printk("解析led灯设备树成功\n");key_dev = of_find_node_by_path("/myirq");if(key_dev == NULL){printk("解析中断设备树节点失败\n");return -EFAULT;}printk("解析中断设备树成功\n");gpiono_led_1 = gpiod_get_from_of_node(led_dev,"led1-gpios",0,GPIOD_OUT_LOW,NULL);if(IS_ERR(gpiono_led_1)){printk("获取GPIO号失败\n");return -PTR_ERR(gpiono_led_1);}gpiono_led_2 = gpiod_get_from_of_node(led_dev,"led2-gpios",0,GPIOD_OUT_LOW,NULL);if(IS_ERR(gpiono_led_2)){printk("获取GPIO号失败\n");return -PTR_ERR(gpiono_led_2);}gpiono_led_3 = gpiod_get_from_of_node(led_dev,"led3-gpios",0,GPIOD_OUT_LOW,NULL);if(IS_ERR(gpiono_led_3)){printk("获取GPIO号失败\n");return -PTR_ERR(gpiono_led_3);}printk("申请GPIO编号成功\n");irqno_1 = irq_of_parse_and_map(key_dev,0);if(!irqno_1){printk("解析中断号失败\n");return -ENXIO;}printk("解析软中断号成功 irqno=%d\n",irqno_1);irqno_2 = irq_of_parse_and_map(key_dev,1);if(!irqno_2){printk("解析中断号失败\n");return -ENXIO;}printk("解析软中断号成功 irqno=%d\n",irqno_2);irqno_3 = irq_of_parse_and_map(key_dev,2);if(!irqno_3){printk("解析中断号失败\n");return -ENXIO;}printk("解析软中断号成功 irqno=%d\n",irqno_3);//注册中断ret = request_irq(irqno_1,myirq_handler,IRQF_TRIGGER_FALLING,"key1",NULL);if(ret){printk("注册中断1失败\n");return ret;}//注册中断ret = request_irq(irqno_2,myirq_handler,IRQF_TRIGGER_FALLING,"key2",NULL);if(ret){printk("注册中断2失败\n");return ret;}//注册中断ret = request_irq(irqno_3,myirq_handler,IRQF_TRIGGER_FALLING,"key3",NULL);if(ret){printk("注册中断3失败\n");return ret;}printk("注册中断成功\n");return 0;
}
static void __exit mycdev_exit(void){free_irq(irqno_1,NULL);free_irq(irqno_2,NULL);free_irq(irqno_3,NULL);gpiod_set_value(gpiono_led_1,0);gpiod_put(gpiono_led_1);gpiod_set_value(gpiono_led_2,0);gpiod_put(gpiono_led_2);gpiod_set_value(gpiono_led_3,0);gpiod_put(gpiono_led_3);
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");
字符设备指令控制led灯亮灭
驱动文件
led-cmd.c
#include<linux/init.h>
#include<linux/module.h>
#include<linux/io.h>
#include<linux/fs.h>
#include<linux/of.h>
#include<linux/of_gpio.h>
#include<linux/gpio.h>
struct device_node *led_dev;
struct gpio_desc *gpiono_led_1;
struct gpio_desc *gpiono_led_2;
struct gpio_desc *gpiono_led_3;
struct class *cls;
struct device *dev;
char kbuf[128]={0};
unsigned int major;//定义一个变量保存主设备号
//封装操作方法
int mycdev_open(struct inode *inode, struct file *file)
{printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);return 0;
}
ssize_t mycdev_read(struct file *file, char *ubuf, size_t size, loff_t *lof)
{printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);return 0;
}
ssize_t mycdev_write(struct file *file, const char *ubuf, size_t size, loff_t *lof)
{printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);long ret;ret=copy_from_user(kbuf,ubuf,size);switch (kbuf[0]){case '1':gpiod_set_value(gpiono_led_1,!gpiod_get_value(gpiono_led_1));break;case '2':gpiod_set_value(gpiono_led_2,!gpiod_get_value(gpiono_led_2));break;case '3':gpiod_set_value(gpiono_led_3,!gpiod_get_value(gpiono_led_3));break;} return 0;
}
int mycdev_close(struct inode *inode, struct file *file)
{printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);return 0;
}
void all_led_init(void){int ret;led_dev = of_find_node_by_path("/leds");if(led_dev == NULL){printk("解析led灯设备树节点失败\n");//return -EFAULT;}gpiono_led_1 = gpiod_get_from_of_node(led_dev,"led1-gpios",0,GPIOD_OUT_LOW,NULL);if(IS_ERR(gpiono_led_1)){printk("获取GPIO号失败\n");//return -PTR_ERR(gpiono_led_1);}gpiono_led_2 = gpiod_get_from_of_node(led_dev,"led2-gpios",0,GPIOD_OUT_LOW,NULL);if(IS_ERR(gpiono_led_2)){printk("获取GPIO号失败\n");//return -PTR_ERR(gpiono_led_2);}gpiono_led_3 = gpiod_get_from_of_node(led_dev,"led3-gpios",0,GPIOD_OUT_LOW,NULL);if(IS_ERR(gpiono_led_3)){printk("获取GPIO号失败\n");// return -PTR_ERR(gpiono_led_3);}printk("申请GPIO编号成功\n");
}
//定义一个操作方法结构体变量并且初始化
struct file_operations fops={.open=mycdev_open,.release=mycdev_close,.read=mycdev_read,.write=mycdev_write,
};
static int __init mycdev_init(void){ //注册字符设备驱动major=register_chrdev(0,"mychrdev",&fops);if(major<0){printk("注册字符设备驱动失败\n");return major;}printk("注册字符设备驱动成功major=%d\n",major);// 向上提交目录cls = class_create(THIS_MODULE, "mycdev");if (IS_ERR(cls)){printk("向上提交目录失败\n");return -PTR_ERR(cls);}printk("向上提交目录信息成功\n");// 向上提交设备节点信息dev = device_create(cls, NULL, MKDEV(major, 0), NULL, "mycdev");if (IS_ERR(dev)){printk("向上提交设备节点信息失败\n");return -PTR_ERR(dev);}printk("向上提交设备节点成功\n");all_led_init();return 0;
}
static void __exit mycdev_exit(void){gpiod_set_value(gpiono_led_1,0);gpiod_put(gpiono_led_1);gpiod_set_value(gpiono_led_2,0);gpiod_put(gpiono_led_2);gpiod_set_value(gpiono_led_3,0);gpiod_put(gpiono_led_3);//注销字符设备驱动//销毁节点信息device_destroy(cls,MKDEV(major,0));//销毁目录信息class_destroy(cls);unregister_chrdev(major,"mychrdev");
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");
应用文件
led.c
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char const *argv[])
{char buf[128] = {0};int fd = open("/dev/mycdev", O_RDWR);if (fd < 0){printf("打开设备文件失败\n");exit(-1);}while (1){printf("请输入控制命令:1(led1关灯/开灯)2(led2关灯/开灯)3(led3关灯/开灯)>");fgets(buf, sizeof(buf), stdin); // 从终端输入数据到bufbuf[strlen(buf) - 1] = '\0'; // 将buf末尾的'\n'切换为'\0'write(fd, buf, sizeof(buf)); }close(fd);return 0;
}
相关文章:
arm学习之stm32设备树学习-中断控制led灯亮灭+字符设备指令控制led灯亮灭
中断控制led灯亮灭 驱动文件源码 led-key.c #include<linux/init.h> #include<linux/module.h> #include<linux/of.h> #include<linux/of_gpio.h> #include<linux/gpio.h> #include<linux/of_irq.h> #include<linux/interrupt.h> s…...

快速开发框架若依的基础使用详解
Hi I’m Shendi 快速开发框架若依的基础使用详解 最近在为公司制作新的项目,经过了一段时间的技术沉淀,我开始尝试接触市面上用的比较多的快速开发框架,听的最多的当属若依吧 于是就选用了若依 介绍 为什么选?目的是为了提高开发…...

RabbitMQ 教程 | 第4章 RabbitMQ 进阶
👨🏻💻 热爱摄影的程序员 👨🏻🎨 喜欢编码的设计师 🧕🏻 擅长设计的剪辑师 🧑🏻🏫 一位高冷无情的编码爱好者 大家好,我是 DevO…...

小程序如何从分类中移除商品
有时候商家可能需要在商品分类中删除某些商品,无论是因为商品已下架、库存不足还是其他原因。在这篇文章中,我们将介绍如何从分类中移除商品。 方式一:分类管理中删除商品。 进入小程序管理后台,找到分类管理,在分…...

P1219 [USACO1.5] 八皇后 Checker Challenge
题目 思路 非常经典的dfs题,需要一点点的剪枝 剪枝①:行、列,对角线的标记 剪枝②:记录每个皇后位置 代码 #include<bits/stdc.h> using namespace std; const int maxn105; int a[maxn];int n,ans; bool vis1[maxn],vis…...

如何在不使用脚本和插件的情况下手动删除 3Ds Max 中的病毒?
如何加快3D项目的渲染速度? 3D项目渲染慢、渲染卡顿、渲染崩溃,本地硬件配置不够,想要加速渲染,在不增加额外的硬件成本投入的情况下,最好的解决方式是使用渲云云渲染,在云端批量渲染,批量出结…...

SpringCloud Gateway 在微服务架构下的最佳实践
作者:徐靖峰(岛风) 前言 本文整理自云原生技术实践营广州站 Meetup 的分享,其中的经验来自于我们团队开发的阿里云 CSB 2.0 这款产品,其基于开源 SpringCloud Gateway 开发,在完全兼容开源用法的前提下&a…...

Android studio修改app图标
步骤如下: 1.右键app名称→New→ImageAsset 2. 进行下面的配置 图源:https://blog.csdn.net/Qingshan_z/article/details/126661650 3.配置分辨率 4.图标自动保存在mipmap文件夹下 再启动就更换成功了!!! 参考&…...

<C++> 三、内存管理
1.C/C内存分布 我们先来看下面的一段代码和相关问题 int globalVar 1; static int staticGlobalVar 1; void Test() {static int staticVar 1;int localVar 1;int num1[10] {1, 2, 3, 4};char char2[] "abcd";const char *pChar3 "abcd";int *ptr1…...

大模型开发(十五):从0到1构建一个高度自动化的AI项目开发流程(上)
全文共5600余字,预计阅读时间约13~20分钟 | 满满干货(附全部代码),建议收藏! 本文目标:提出一种利用大语言模型(LLMs)加快项目的开发效率的解决思路,本文作为第一部分,主要集中在如何完整的执行引导Chat模…...

HarmonyOS 开发基础(二)组件拼凑简单登录页面
一、简单登录页面 Entry Component /* 组件可以基于struct实现,组件不能有继承关系,struct可以比class更加快速的创建和销毁。*/ struct Index {State message: string Hello Worldbuild() {// https://developer.harmonyos.com/cn/docs/documentation/…...

flutter minio
背景 前端 经常需要上传文件 图片 视频等等 到后端服务器, 如果到自己服务器 一般会有安全隐患。也不方便管理这些文件。如果要想使用一些骚操作 比如 按照前端请求生成不同分辨率的图片,那就有点不太方便了。 这里介绍以下 minio,࿰…...
ChatGPT:人工智能交互的新时代
ChatGPT的背景和发展: ChatGPT是OpenAI公司在GPT-3基础上的进一步升级。GPT(Generative Pre-trained Transformer)是一种基于Transformer架构的深度学习模型,它能够处理自然语言,实现自动对话、写作等任务。而ChatGPT在…...

C. Binary String Copying - 思维
分析: 赛时我是直接模拟的,tle然后mle,补提,发现规律,每一个改变的字符串都只会对应一个需要改变的区间,例如第一个样例前两个101100 -> 011100和101100 -> 011100,对应区间在确定改变的范…...

哈工大计算机网络课程网络安全基本原理详解之:密钥分发中心与公钥认证中心
哈工大计算机网络课程网络安全基本原理详解之:密钥分发中心与公钥认证中心 在介绍密钥分发中心的概念前,先来回顾一下之前介绍的身份认证协议AP4.0:利用随机数R来避免“回放攻击”,并借助于对称加密算法来保证R的加密传输和解密&…...

md5sum
概念作用及原理 md5sum是一种常用的哈希算法,用于计算数据的MD5哈希值。MD5(Message Digest Algorithm 5)是一种广泛使用的加密散列函数,用于将任意长度的数据映射为固定长度的哈希值(通常是128位)。这个哈…...

图文档数字化:实现高效管理的几大步骤
在当今数字化时代,企业越来越意识到数字化管理对于图文档的重要性。传统的纸质文件管理往往效率低下,容易出现丢失和混乱的情况。为了提高工作效率、降低成本并确保数据安全,许多企业选择采用PDM(产品数据管理)系统来实…...
服务器磁盘占用过高分析
使用命令 du -sh查看出占用较大的目录,如下: 目录大小处理办法/usr/local/mysql/data16G转移部分文件/usr/local/nacos2.1G维持现状/logs4.4G删除部分文件/var1.9G删除部分文件 du -sh命令使用示例: du -sh /* 查看根目录各文件(夹)占用大小…...

【C语言】通讯录3.0 (文件存储版)
前言 通讯录是一种记录联系人信息的工具,包括姓名、电话号码、电子邮件地址、住址等。 文章的一二三章均于上一篇相同,可以直接看第四章改造内容。 此通讯录是基于通讯录2.0(动态增长版)的基础上进行增加文件操作功能,…...
【C#常用操作】
excel相关操作 using Excel Microsoft.Office.Interop.Excel;public Excel.Application app; public Excel.Workbooks wbs; public Excel.Workbook wb; public Excel.Worksheets wss; public Excel.Worksheet ws;/// <summary> /// 取得打开excel句柄 /// </summary…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...