驱动开发day2
通过物理内存映射为虚拟内存 实现三盏LED灯亮灯灭
head.h
#ifndef __HEAD_H__
#define __HEAD_H__#define PHY_LED1_MODER 0X50006000
#define PHY_LED1_ODR 0X50006014
#define PHY_RCC 0x50000A28#define PHY_LED2_MODER 0X50007000
#define PHY_LED2_ODR 0X50007014#define PHY_LED3_MODER 0X50006000
#define PHY_LED3_ODR 0X50006014#endif
test.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main(int argc,char const *argv[])
{char buf[128] = {0};int fd = open("/dev/mychrdev",O_RDWR);if(fd < 0 ){printf("打开设备文件失败\n");return -1;}printf("打开设备文件成功\n");while(1){printf("请输入要进行的操作:0(关灯)1(开灯)>");fgets(buf,sizeof(buf),stdin);//在终端第一个字符串buf[strlen(buf)-1]='\0';write(fd,buf,sizeof(buf));//将数据传递给内核}close(fd);return 0;
}
demo.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include "head.h"unsigned int major;
char kbuf[128]={};
//LED1定义三个指针指向映射后的虚拟内存
unsigned int *vir_moder1;
unsigned int *vir_odr1;
unsigned int *vir_rcc;
//LED2定义三个指针指向映射后的虚拟内存
unsigned int *vir_moder2;
unsigned int *vir_odr2;//LED3定义三个指针指向映射后的虚拟内存
unsigned int *vir_moder3;
unsigned int *vir_odr3;//封装操作方法
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__);int ret;ret=copy_to_user(ubuf,kbuf,size);if(ret){printk("copy_to_user filed\n");return -EIO;}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__);int ret;ret=copy_from_user(kbuf,ubuf,size);if(ret){printk("copy_from_user filed\n");return -EIO;}if(kbuf[0] == '0')//关灯{//关灯逻辑(*vir_odr1) &= (~(0x1 << 10));(*vir_odr2) &= (~(0x1 << 10));(*vir_odr3) &= (~(0x1 << 8));}else if(kbuf[0]=='1'){//开灯逻辑(*vir_odr1) |= (0x1 << 10); (*vir_odr2) |= (0x1 << 10); (*vir_odr3) |= (0x1 << 8); }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,
};//入口函数,安装内核模块时执行
static int __init mycdev_init(void)
{//注册字符设备major = register_chrdev(0,"mychrdev",&fops);if(major < 0){printk("字符设备驱动注册失败\n");return major;}printk("注册字符设备驱动成功major=%d\n",major);vir_rcc = ioremap(PHY_RCC,4);if(vir_rcc ==NULL){printk("物理内存地址映射失败%d\n",__LINE__);return -EFAULT;}//----------LED1进行寄存器的地址映射------------------//vir_moder1 = ioremap(PHY_LED1_MODER,4);if(vir_moder1 == NULL){printk("物理内存地址映射失败%d\n",__LINE__);return -EFAULT;}vir_odr1 = ioremap(PHY_LED1_ODR,4);if(vir_odr1 == NULL){printk("物理内存地址映射失败%d\n",__LINE__);return -EFAULT;}printk("LED1寄存器内存映射成功\n");//----------LED2进行寄存器的地址映射------------------//vir_moder2 = ioremap(PHY_LED2_MODER,4);if(vir_moder2 == NULL){printk("物理内存地址映射失败%d\n",__LINE__);return -EFAULT;}vir_odr2 = ioremap(PHY_LED2_ODR,4);if(vir_odr2 == NULL){printk("物理内存地址映射失败%d\n",__LINE__);return -EFAULT;}printk("LED2寄存器内存映射成功\n");//----------LED3进行寄存器的地址映射------------------//vir_moder3 = ioremap(PHY_LED3_MODER,4);if(vir_moder3 == NULL){printk("物理内存地址映射失败%d\n",__LINE__);return -EFAULT;}vir_odr3 = ioremap(PHY_LED3_ODR,4);if(vir_odr3 == NULL){printk("物理内存地址映射失败%d\n",__LINE__);return -EFAULT;}printk("LED3寄存器内存映射成功\n");//LED1寄存器初始化(*vir_rcc) |= (0x3 << 4);//GPIOE/GPIOF控制器时钟使能(*vir_moder1) &= (~(0x3 << 20));//MODER[21:20]->00(*vir_moder1) |= (0x1 << 20);//MODER[21:20]->01(*vir_odr1) &= (~(0x1 << 10));//默认关灯//LED2寄存器初始化 (*vir_moder2) &= (~(0x3 << 20));//MODER[21:20]->00(*vir_moder2) |= (0x1 << 20);//MODER[21:20]->01(*vir_odr2) &= (~(0x1 << 10));//默认关灯//LED3寄存器初始化(*vir_moder3) &= (~(0x3 << 16));//MODER[17:16]->00(*vir_moder3) |= (0x1 << 16);//MODER[17:16]->01(*vir_odr3) &= (~(0x1 << 8));//默认关灯return 0;
}//出口函数,卸载内核模块时执行
static void __exit mycdev_exit(void)
{//取消内存映射iounmap(vir_rcc);//LED1取消内存映射iounmap(vir_moder1);iounmap(vir_odr1);//LED2取消内存映射iounmap(vir_moder2);iounmap(vir_odr2);//LED3取消内存映射iounmap(vir_moder3);iounmap(vir_odr3);//注销字符设备驱动unregister_chrdev(major,"mychrdev");
}//用于声明入口函数
module_init(mycdev_init);
//用于声明出口函数
module_exit(mycdev_exit);
//声明当前内核模块遵循GPL协议
MODULE_LICENSE("GPL");



相关文章:
驱动开发day2
通过物理内存映射为虚拟内存 实现三盏LED灯亮灯灭 head.h #ifndef __HEAD_H__ #define __HEAD_H__#define PHY_LED1_MODER 0X50006000 #define PHY_LED1_ODR 0X50006014 #define PHY_RCC 0x50000A28#define PHY_LED2_MODER 0X50007000 #define PHY_LED2_ODR 0X50007014#defin…...
【CANoe】文件处理_hex文件读取解析
hex文件里面只有00,01,04三种码。那么我们在解析的时候只需要对这三种不同状态的进行不同的解析即可。 hex文件格式的解析,可阅读:HEX文件格式详解 首先创建一个Block的结构体,根据经验我们知道,一个数据…...
人脸识别顶会论文及源码合集,含2023最新
今天和大家聊聊人脸识别。 人脸识别的技术经过不断发展已经相当成熟,在门禁、监控、手机解锁、移动支付等实际场景都能看到。我们比较熟悉的识别方式是基于可见光图像的人脸识别,这种方式有个非常明显的缺点:光线限制。 在近两年的人脸识别…...
介绍drawio和图表使用场景
图表介绍 drawio是一个基于Web技术的草图、简图和图表的解决方案。 drawio支持在线编辑器,app.diagram.net.并支持不同的操作系统的桌面版离线安装版本。如:windows, linux, macOS。 对于个人或者团队,把图表绘制的安全放到第一位ÿ…...
leetcode-1438: 绝对差不超过限制的最长连续子数组
给你一个整数数组 nums ,和一个表示限制的整数 limit,请你返回最长连续子数组的长度,该子数组中的任意两个元素之间的绝对差必须小于或者等于 limit 。 如果不存在满足条件的子数组,则返回 0 。 示例 1: 输入&#x…...
【数据结构初阶】九、排序的讲解和实现(直接插入 \ 希尔 \ 直接选择 \ 堆 \ 冒泡 -- C语言)
相关代码gitee自取: C语言学习日记: 加油努力 (gitee.com) 接上期: 【数据结构初阶】八、非线性表里的二叉树(二叉树的实现 -- C语言链式结构)-CSDN博客 排序 排序的概念 所谓排序,就是使一串记录,按照…...
uview组件使用笔记
图标样式 修改图标的样式 通过color参数修改图标的颜色通过size参数修改图标的大小,单位为rpx 效果图 <u-icon name"photo" color"#2979ff" size"28"></u-icon>图片图标 1.3.0 这里说的图片图标,指的是小…...
Linux1024一篇通俗易懂的liunx命令操作总结(第十课)
Linux1024一篇通俗易懂的liunx命令操作总结(第十课) 一 liunx 介绍 Linux是一种免费开源的操作系统,它的设计基于Unix。它最早是由芬兰的一位大学生Linus Torvalds在1991年开始编写的,取名为Linux。Linux具有高度的灵活性和可定制性,可以在…...
nuxt使用i18n进行中英文切换
中文效果图: 英文效果图: 版本: 安装: npm install --save nuxtjs/i18n 新建en.js与zh.js两个文件进行切换显示 en.js内容 import globals from ./../js/global_valexport default {/******* 公共内容开始* *****/seeMore: &quo…...
机器人制作开源方案 | 行星探测车实现WiFi视频遥控功能
1. 功能描述 本文示例所实现的功能为:用手机APP,通过WiFi通信遥控R261样机行星探测车移动,以及打开、关闭行星探测车太阳翼。 2. 电子硬件 在这个示例中,我们采用了以下硬件,请大家参考: 主控板 Basra主控…...
Angular main 中的enableProdMode
enableProdMode一次深度解析 在Angular的开发过程中,我们经常会遇到一个名为enableProdMode的设置。这个设置位于Angular的主模块(main module)中,它的主要作用是启用生产模式。那么,什么是生产模式?为什么…...
驱动day2:LED灯实现三盏灯的亮灭
head.h #ifndef __HEAD_H__ #define __HEAD_H__ #define PHY_PE_MODER 0x50006000 #define PHY_PF_MODER 0x50007000 #define PHY_PE_ODR 0x50006014 #define PHY_PF_ODR 0x50007014 #define PHY_RCC 0x50000A28#endif 应用程序 #include <stdio.h> #include <sys/…...
Android 编译错误:module xxx1 missing dependencies:xxx2
编译错误log module xxx1 missing dependencies:xxx2 分析方向 1.缺少依赖库 添加依赖库 shared_libs: ["libhidlbase","libhidltransport","libhwbinder","liblog","libutils","libcutils",],2.缺…...
使用EasyExcel实现Excel导入导出
介绍 EasyExcel是一个基于Java的、快速、简洁、解决大文件内存溢出的Excel处理工具。 他能让你在不用考虑性能、内存的等因素的情况下,快速完成Excel的读、写等功能。 快速:快速的读取excel中的数据。 简洁:映射excel和实体类,让…...
京东手机销售数据:2023年9月京东手机行业TOP10品牌排行榜
鲸参谋监测的京东平台9月份手机市场销售数据已出炉! 9月份,手机市场销售整体呈现下滑。鲸参谋数据显示,今年9月,京东平台手机销量为300万,环比下降约20%,同比下降约18%;销售额为92亿,…...
常量字符串
一、常量字符串是什么? 常量字符串是一个常量,它的值是首字符的地址 比如 "abcdefg" 或 "123456789" 就是常量字符串 二、常量字符串与普通字符串的区别 1.常量字符串不可更改,而普通字符串可以更改 利用memcpy内存…...
【活体检测】“深度学习驱动的人脸反欺诈检测系统:性能提升与多模型支持“
微调小视科技开源静默活体检测模型加载方式,性能提升8倍 I. 引言 在当今数字化时代,人脸反欺诈检测在各种应用中发挥着重要作用,从人脸识别到金融欺诈检测。为了满足不断增长的需求,深度学习技术已成为关键工具,但性…...
Howler.js HTML5声音引擎
介绍 Howler.js是一个不错的HTML5声音引擎。功能强大,性能不错,用起来也很方便。 1. 官网 https://howlerjs.com/ GitHub https://github.com/goldfire/howler.js 2. 兼容性 Howler默认使用Web Audio,但在IE上可以自动转为HTML 5 Audio。这…...
centos 7.9每天定期发送最新备份文件到另外一台服务器
1.需求 在本地化部署的过程中,为了使系统相对来说高可用,一般情况下,我们都会做一个负载,但是客户又会考虑成本,所以只有可怜巴巴的两台服务器,要全部服务都做负载,这个就实现不了。所以只能把…...
一文全面了解:一个神奇的 react-antd-admin 动态菜单
在React v18中使用React Router v6和Ant Design (antd) v5来动态生成菜单和路由,同时使用MockJS来模拟接口请求菜单数据,可以按照以下步骤进行: 创建一个React应用: 使用Create React App或您喜欢的其他方式创建一个React应用。 安装必要的依赖: 在项目目录中运行以下命令…...
如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...
微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
MySQL JOIN 表过多的优化思路
当 MySQL 查询涉及大量表 JOIN 时,性能会显著下降。以下是优化思路和简易实现方法: 一、核心优化思路 减少 JOIN 数量 数据冗余:添加必要的冗余字段(如订单表直接存储用户名)合并表:将频繁关联的小表合并成…...
Golang——7、包与接口详解
包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...
Qt 事件处理中 return 的深入解析
Qt 事件处理中 return 的深入解析 在 Qt 事件处理中,return 语句的使用是另一个关键概念,它与 event->accept()/event->ignore() 密切相关但作用不同。让我们详细分析一下它们之间的关系和工作原理。 核心区别:不同层级的事件处理 方…...
若依登录用户名和密码加密
/*** 获取公钥:前端用来密码加密* return*/GetMapping("/getPublicKey")public RSAUtil.RSAKeyPair getPublicKey() {return RSAUtil.rsaKeyPair();}新建RSAUti.Java package com.ruoyi.common.utils;import org.apache.commons.codec.binary.Base64; im…...
[特殊字符] 手撸 Redis 互斥锁那些坑
📖 手撸 Redis 互斥锁那些坑 最近搞业务遇到高并发下同一个 key 的互斥操作,想实现分布式环境下的互斥锁。于是私下顺手手撸了个基于 Redis 的简单互斥锁,也顺便跟 Redisson 的 RLock 机制对比了下,记录一波,别踩我踩过…...
