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

[驱动开发]字符设备驱动应用——点灯

点亮开发板stm32mp157的三盏灯

//头文件
#ifndef __LED_H__
#define __LED_H__//封装GPIO寄存器                                
typedef struct {                          volatile unsigned int MODER;   // 0x00volatile unsigned int OTYPER;  // 0x04volatile unsigned int OSPEEDR; // 0x08volatile unsigned int PUPDR;   // 0x0Cvolatile unsigned int IDR;     // 0x10volatile unsigned int ODR;     // 0x14
}gpio_t;//宏定义基地址
#define PHY_LED1_ADDR 0x50006000
#define PHY_LED2_ADDR 0x50007000
#define PHY_LED3_ADDR 0x50006000
#define PHY_RCC 0x50000A28#endif

//应用程序
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>int main(int argc, const char *argv[])
{char buf[128]={0};int fd = open("/dev/mychrdev",O_RDWR);if(fd < 0){printf("打开设备文件失败\n");exit(-1);}while(1){bzero(buf,sizeof(buf));printf("选择LED:1 2 3>>>");fgets(buf,sizeof(buf),stdin);printf("输入控制命令:0熄灭 1开灯>>>");fgets(buf+1,sizeof(buf),stdin);buf[strlen(buf)-1]='\0';write(fd,buf,sizeof(buf));}close(fd);return 0;}
//驱动程序
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include "led.h"char kbuf[128]={0};
gpio_t *vir_led1;
gpio_t *vir_led2;
gpio_t *vir_led3;
unsigned int *vir_rcc;
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)
{int ret;if(sizeof(kbuf) < size)            //判断用户空间长度是否比内核空间大size=sizeof(kbuf);ret=copy_to_user(ubuf,kbuf,size);  //将内核数据拷贝到用户if(ret){printk("copy_to_user filed\n");return -EIO;}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)
{int ret;if(sizeof(kbuf) < size)size=sizeof(kbuf);ret=copy_from_user(kbuf,ubuf,size);if(ret){printk("copy_from_user filed\n");return -EIO;}if(kbuf[0]=='1')      //LED1{if(kbuf[1]=='1')  					//开灯vir_led1->ODR |= (0x1 << 10);else if(kbuf[1]=='0') 				//关灯vir_led1->ODR &= (~(0x1 << 10));}else if(kbuf[0]=='2')      //LED2{if(kbuf[1]=='1')  					//开灯vir_led2->ODR |= (0x1 << 10);else if(kbuf[1]=='0') 				//关灯vir_led2->ODR &= (~(0x1 << 10));}else if(kbuf[0]=='3')      //LED3{if(kbuf[1]=='1')  					//开灯vir_led3->ODR |= (0x1 << 8);else if(kbuf[1]=='0') 				//关灯vir_led3->ODR &= (~(0x1 << 8));}printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);return 0;
}
int mycdev_close(struct inode *inode, struct file *file)
{printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);return 0;
}//定义一个操作方法结构体变量并初始化
struct file_operations fops =
{.open    =  mycdev_open,.read    =  mycdev_read,.write   =  mycdev_write,.release =  mycdev_close,
};int led_init(void)
{//映射物理寄存器vir_led1=ioremap(PHY_LED1_ADDR,sizeof(gpio_t));if(vir_led1 == NULL){printk("vir_led1寄存器地址映射表失败\n");return -EFAULT;}vir_led2=ioremap(PHY_LED2_ADDR,sizeof(gpio_t));if(vir_led2 == NULL){printk("vir_led2寄存器地址映射表失败\n");return -EFAULT;}vir_led3=ioremap(PHY_LED3_ADDR,sizeof(gpio_t));if(vir_led3 == NULL){printk("vir_led1寄存器地址映射表失败\n");return -EFAULT;}vir_rcc=ioremap(PHY_RCC,4);if(vir_rcc==NULL){printk("vir_rcc寄存器地址映射表失败\n");return -EFAULT;}printk("寄存器地址映射成功\n");//寄存器初始化(*vir_rcc) |= (0x3 << 4);//rcc使能vir_led1->MODER &= (~(0X3 << 20));//设置为输出vir_led1->MODER |= (0x1 << 20);vir_led1->ODR &= (~(0x1 << 10));//灭灯vir_led2->MODER &= (~(0X3 << 20));//设置为输出vir_led2->MODER |= (0x1 << 20);vir_led2->ODR &= (~(0x1 << 10));//灭灯vir_led3->MODER &= (~(0X3 << 16));//设置为输出vir_led3->MODER |= (0x1 << 16);vir_led3->ODR &= (~(0x1 << 8));//灭灯printk("硬件寄存器初始化成功\n");return 0;
}
static int __init mycdev_init(void)
{//字符设备驱动注册major = register_chrdev(0,"mychrdev",&fops);if(major < 0){printk("字符设备驱动注册失败\n");return major;}printk("字符设备驱动注册成功major=%d\n",major);//初始化ledled_init();return 0;
}static void __exit mycdev_exit(void)
{//取消寄存器地址映射iounmap(vir_led1);iounmap(vir_led2);iounmap(vir_led3);iounmap(vir_rcc);//字符设备驱动注销unregister_chrdev(major,"mychrdev");printk("字符设备驱动注销\n");
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

结果

相关文章:

[驱动开发]字符设备驱动应用——点灯

点亮开发板stm32mp157的三盏灯 //头文件 #ifndef __LED_H__ #define __LED_H__//封装GPIO寄存器 typedef struct { volatile unsigned int MODER; // 0x00volatile unsigned int OTYPER; // 0x04volatile unsign…...

前端学习——Vue (Day5)

自定义指令 <template><div><h1>自定义指令</h1><input v-focus ref"inp" type"text" /></div> </template><script> export default {// mounted(){// this.$ref.inp.focus()// }// 2. 局部注册指令di…...

Ceph版本

每个Ceph的版本都有一个英文的名称和一个数字形式的版本编号 第一个 Ceph 版本编号是 0.1&#xff0c;发布于2008 年 1月。之后是0.2,0.3....多年来&#xff0c;版本号方案一直没变。 2015年 4月0.94.1 (Hammer 的第一个修正版) 发布后&#xff0c;为了避免 0.99 (以及 0.100…...

cspm是什么?考了有用吗?

CSPM是项目管理专业人员能力评价等级证书&#xff0c;相当于 PMP 的本土化&#xff0c;CSPM 相关问题大家都很关心&#xff0c;今天就给大家全面解答一下 CSPM到底是何方神圣&#xff1f; 文章主要是解答下面几个常见问题&#xff0c;其他问题可以留言或者私信咨询我哦~ 一、什…...

Java阶段五Day14

Java阶段五Day14 文章目录 Java阶段五Day14分布式事务整合demo案例中架构&#xff0c;代码关系发送半消息本地事务完成检查补偿购物车消费 鲁班周边环境调整前端启动介绍启动前端 直接启动的项目gateway&#xff08;网关&#xff09;login&#xff08;登录注册&#xff09;atta…...

【计算机网络】应用层协议 -- 安全的HTTPS协议

文章目录 1. 认识HTTPS2. 使用HTTPS加密的必要性3. 常见的加密方式3.1 对称加密3.2 非对称加密3.3 非对称加密对称加密 4. 引入CA证书4.1 CA认证4.2 数据签名4.3 非对称机密对称加密证书认证4.4 常见问题 5. 总结 1. 认识HTTPS HTTPS全称为 Hyper Text Tranfer Protocol over …...

小程序通过ip+port+路径获取服务器中的图片

配置IIS 首先需要配置IIS。 打开控制面板,接下来的流程按下图所示。 安装好后,按“win”键,搜索IIS 选择一个ip地址,或手动填写,端口号按需更改...

Codeforces Round 888 (Div. 3)(A-F)

文章目录 ABCDEF A 题意&#xff1a; 就是有一个m步的楼梯。每一层都有k厘米高&#xff0c;现在A的身高是H&#xff0c;给了你n个人的身高问有多少个人与A站在不同层的楼梯高度相同。 思路&#xff1a; 我们只需要去枚举对于A来说每一层和他一样高&#xff08;人的身高和楼…...

【人工智能】深度神经网络、卷积神经网络(CNN)、多卷积核、全连接、池化

深度神经网络、卷积神经网络(CNN)、多卷积核、全连接、池化) 文章目录 深度神经网络、卷积神经网络(CNN)、多卷积核、全连接、池化)深度神经网络训练训练深度神经网络参数共享卷积神经网络(CNN)卷积多卷积核卷积全连接最大池化卷积+池化拉平向量激活函数优化小结深度神经…...

失去SSL证书,会对网站安全造成什么影响?

作为网络世界中的“身份证”&#xff0c;SSL证书可以在网络世界中证明你是一个真实可信的企业或个人网站&#xff0c;而不是一个钓鱼网站。且在网站的服务器上部署SSL证书后&#xff0c;可以使网站与访问者之间通过SSL协议建立安全的加密连接&#xff0c;确保在Web服务器和浏览…...

gitee中fork了其他仓库,如何在本地进行同步

GitHub 操作&#xff1a;同步 Fork 来的仓库&#xff08;上游仓库&#xff09;_sigmarising的博客-CSDN博客 1. 设置upstream 2. git pull --rebase 3. 然后再执行pull、push操作...

java项目之社区生活超市管理系统(ssm+mysql+jsp)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的社区生活超市管理系统。技术交流和部署相关看文章末尾&#xff01; 开发环境&#xff1a; 后端&#xff1a; 开发语言&#xff1a;Java 框…...

WebGPU(七):C++头部封装

WebGPU(七)&#xff1a;C头部封装 在前面的学习中&#xff0c;我们使用的都是原生态的WebGPU API&#xff0c;那是基于C语言的API&#xff0c;但是为了更高效的开发&#xff0c;我们可以使用一个基于C的库。 根据参考的教程&#xff0c;这个github库提供更加纤细的描述。它提…...

Linux 网络通信epoll详解( 10 ) -【Linux通信架构系列 】

系列文章目录 C技能系列 Linux通信架构系列 C高性能优化编程系列 深入理解软件架构设计系列 高级C并发线程编程 期待你的关注哦&#xff01;&#xff01;&#xff01; 现在的一切都是为将来的梦想编织翅膀&#xff0c;让梦想在现实中展翅高飞。 Now everything is for the…...

java源码-List源码解析

Java中的List是一个接口&#xff0c;它定义了一组操作列表的方法。List接口的常见子类包括ArrayList、LinkedList和Vector等。 以下是Java中List接口及其常见方法的源码解析&#xff1a; 1. List接口定义 public interface List<E> extends Collection<E> { …...

Mybatis的动态SQL

动态 sql 是Mybatis的强⼤特性之⼀&#xff0c;能够完成动态的 sql 语句拼接。 动态 SQL 大大减少了编写代码的工作量&#xff0c;更体现了 MyBatis 的灵活性、高度可配置性和可维护性。 Mybatis里的动态标签主要有: <if><trim><where><set><forea…...

嵌入式系统中的GPIO控制:从理论到实践与高级应用

本文将探讨嵌入式系统中的GPIO(通用输入输出)控制,着重介绍GPIO的原理和基本用法。我们将使用一个实际的示例项目来演示如何通过编程配置和控制GPIO引脚。将基于ARM Cortex-M微控制器,并使用C语言进行编写。 GPIO是嵌入式系统中最常见且功能最强大的接口之一。它允许硬件工…...

7D透明屏的市场应用广泛,在智能家居中有哪些应用表现?

7D透明屏是一种新型的显示技术&#xff0c;它能够实现透明度高达70%以上的显示效果。这种屏幕可以应用于各种领域&#xff0c;如商业广告、展览展示、智能家居等&#xff0c;具有广阔的市场前景。 7D透明屏的工作原理是利用光学投影技术&#xff0c;将图像通过透明屏幕投射出来…...

[游戏开发][Unity] 打包Xcode工程模拟器+真机调试

苹果开发者账号 账号分三类&#xff0c;个人&#xff0c;公司&#xff0c;企业&#xff0c;价格99/99/299美金 新注册账号的基本设置按网上的教程来就行 我们公司是企业账号&#xff0c;我的苹果开发者账号是公司一个User 下面讲述一下一个全新的打包机处理流程 首先是要把…...

python 添加环境变量

1 查看是否设置环境变量 和 使用的python在哪里安装 import sys import os# 获取Python的安装目录 import os import syspython_path sys.executable # 这个是python.exe的路径python_path os.path.dirname(python_path) print("Python安装路径:", python_path)# …...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

(二)TensorRT-LLM | 模型导出(v0.20.0rc3)

0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述&#xff0c;后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作&#xff0c;其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...

FastAPI 教程:从入门到实践

FastAPI 是一个现代、快速&#xff08;高性能&#xff09;的 Web 框架&#xff0c;用于构建 API&#xff0c;支持 Python 3.6。它基于标准 Python 类型提示&#xff0c;易于学习且功能强大。以下是一个完整的 FastAPI 入门教程&#xff0c;涵盖从环境搭建到创建并运行一个简单的…...

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域&#xff0c;向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能&#xff0c;能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作&#xff0c;并通过具体…...

以光量子为例,详解量子获取方式

光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学&#xff08;silicon photonics&#xff09;的光波导&#xff08;optical waveguide&#xff09;芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中&#xff0c;光既是波又是粒子。光子本…...

逻辑回归暴力训练预测金融欺诈

简述 「使用逻辑回归暴力预测金融欺诈&#xff0c;并不断增加特征维度持续测试」的做法&#xff0c;体现了一种逐步建模与迭代验证的实验思路&#xff0c;在金融欺诈检测中非常有价值&#xff0c;本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...

探索Selenium:自动化测试的神奇钥匙

目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...

c++第七天 继承与派生2

这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分&#xff1a;派生类构造函数与析构函数 当创建一个派生类对象时&#xff0c;基类成员是如何初始化的&#xff1f; 1.当派生类对象创建的时候&#xff0c;基类成员的初始化顺序 …...

如何应对敏捷转型中的团队阻力

应对敏捷转型中的团队阻力需要明确沟通敏捷转型目的、提升团队参与感、提供充分的培训与支持、逐步推进敏捷实践、建立清晰的奖励和反馈机制。其中&#xff0c;明确沟通敏捷转型目的尤为关键&#xff0c;团队成员只有清晰理解转型背后的原因和利益&#xff0c;才能降低对变化的…...

Chrome 浏览器前端与客户端双向通信实战

Chrome 前端&#xff08;即页面 JS / Web UI&#xff09;与客户端&#xff08;C 后端&#xff09;的交互机制&#xff0c;是 Chromium 架构中非常核心的一环。下面我将按常见场景&#xff0c;从通道、流程、技术栈几个角度做一套完整的分析&#xff0c;特别适合你这种在分析和改…...