Linux驱动【day2】
mychrdev.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]={0};
unsigned int *vir_moder;
unsigned int *vir_odr;
unsigned int *vir_rcc;unsigned int *vir_moder2;
unsigned int *vir_odr2;
unsigned int *vir_rcc2;// 封装操作方法
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;ret=copy_to_user(ubuf,kbuf,size);if(ret){printk("copy_to_user err\n");return -EIO;}return 0;
}
ssize_t mycdev_write(struct file *file, const char *ubuf, size_t size, loff_t *lof)
{int ret;//从用户拷贝ret=copy_from_user(kbuf,ubuf,size);if(ret){printk("copy_from_user err\n");return -EIO;}if(kbuf[0]=='1')//PE10开灯{//开灯逻辑(*vir_odr) |= (0X1<<10);}else if(kbuf[0]=='0'){//关灯逻辑(*vir_odr) &= (~(0X1<<10));}if(kbuf[1]=='1')//PF10开灯{//开灯逻辑(*vir_odr2) |= (0X1<<10);}else if(kbuf[0]=='0'){//关灯逻辑(*vir_odr2) &= (~(0X1<<10));}if(kbuf[2]=='1')//PE8开灯{//开灯逻辑(*vir_odr) |= (0X1<<8);}else if(kbuf[0]=='0'){//关灯逻辑(*vir_odr) &= (~(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);//进行GPIE相关寄存器的内存映射vir_odr=ioremap(LED1_ODR,4);if(vir_odr==NULL){printk("物理内存映射失败%d\n",__LINE__);return -EFAULT;}vir_rcc=ioremap(LED1_RCC,4);if(vir_rcc==NULL){printk("物理内存映射失败%d\n",__LINE__);return -EFAULT;}vir_moder=ioremap(LED1_MODER,4);if(vir_moder==NULL){printk("物理内存映射失败%d\n",__LINE__);return -EFAULT;}printk("寄存器内存映射成功\n");//进行GPIOF相关寄存器的内存映射vir_odr2=ioremap(LED2_ODR,4);if(vir_odr2==NULL){printk("物理内存映射失败%d\n",__LINE__);return -EFAULT;}vir_rcc2=ioremap(LED2_RCC,4);if(vir_rcc2==NULL){printk("物理内存映射失败%d\n",__LINE__);return -EFAULT;}vir_moder2=ioremap(LED2_MODER,4);if(vir_moder2==NULL){printk("物理内存映射失败%d\n",__LINE__);return -EFAULT;}printk("寄存器内存映射成功\n");//PE10硬件寄存器的初始化//RCC使能(*vir_rcc) |= (0X1<<4);//设置PE10为输出(*vir_moder) &= (~(0X3<<20));(*vir_moder) |= (0X1<<20);//默认关灯(*vir_odr) &= (~(0X1<<10));//PF10硬件寄存器的初始化//RCC使能(*vir_rcc2) |= (0X1<<5);//设置PF10为输出(*vir_moder2) &= (~(0X3<<20));(*vir_moder2) |= (0X1<<20);//默认关灯(*vir_odr2) &= (~(0X1<<10));//PE8硬件寄存器的初始化//设置PE10为输出(*vir_moder) &= (~(0X3<<16));(*vir_moder) |= (0X1<<16);//默认关灯(*vir_odr) &= (~(0X1<<8));return 0;
}
static void __exit mycdev_exit(void)
{//取消物理内存映射iounmap(vir_moder);iounmap(vir_odr);iounmap(vir_rcc);//取消物理内存映射iounmap(vir_moder2);iounmap(vir_odr2);iounmap(vir_rcc2);// 字符设备驱动注销unregister_chrdev(major, "mychrdev");
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");
test.c:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.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");exit(-1);}while (1){printf("输入指令控制开/关灯(LED1|LED2|LED3)==>0(OFF)/1(ON)>");fgets(buf, sizeof(buf), stdin); // 在终端输入数据传递到bufbuf[strlen(buf) - 1] = '\0'; // 替换末尾的'\n'write(fd, buf, sizeof(buf));}close(fd);return 0;
}
head.h:
#ifndef __HEAD_H__
#define __HEAD_H__//PE10
#define LED1_RCC 0X50000A28
#define LED1_MODER 0X50006000
#define LED1_ODR 0X50006014//PF10
#define LED2_RCC 0X50000A28
#define LED2_MODER 0X50007000
#define LED2_ODR 0X50007014#endif
实验结果:
相关文章:

Linux驱动【day2】
mychrdev.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]{0}; unsigned int…...

4、Nginx 配置实例-反向代理
文章目录 4、nginx 配置实例-反向代理4.1 反向代理实例一4.1.1 实验代码 4.3 反向代理实例二4.3.1 实验代码 【尚硅谷】尚硅谷Nginx教程由浅入深 志不强者智不达;言不信者行不果。 4、nginx 配置实例-反向代理 4.1 反向代理实例一 实现效果:使用 nginx…...

2023年世界机器人大会回顾
1、前记: 本次记录是我自己去世界机器人博览会参观的一些感受,所有回顾为个人感兴趣部分的机器人产品分享。整个参观下来最大的感受就是科学技术、特别是机器人技术和人工智能毫无疑问地、广泛的应用在我们日常生活的方方面面,在安全巡检、特…...

Mac系统 AndroidStudio Missing essential plugin:org.jetbrains.android报错
打开Android Studio,提示 Missing essential plugin:org.jetbrains.android错误,产生的原因是Kotlin被禁用。 解决的方法是删除disabled_plugins.txt,Mac OS对应的路径为: /Users/xzh/Library/Application Support/Google/AndroidStudio202…...

读书笔记:多Transformer的双向编码器表示法(Bert)-1
多Transformer的双向编码器表示法 Bidirectional Encoder Representations from Transformers,即Bert; 本笔记主要是对谷歌Bert架构的入门学习: 介绍Transformer架构,理解编码器和解码器的工作原理;掌握Bert模型架构…...

第二证券:股利支付率和留存收益率的关系?
股利付出率和留存收益率是股票出资中非常重要的目标,它们可以反映公司的盈余才能和未来开展的潜力。那么,二者之间究竟有什么联系呢? 一、股利付出率和留存收益率的定义 股利付出率是指公司向股东分配的股息占当期净利润的比例,通…...

煤矿虚拟仿真 | 采煤工人VR虚拟现实培训系统
随着科技的发展,虚拟现实(VR)技术已经逐渐渗透到各个行业,其中包括煤矿行业。VR技术可以为煤矿工人提供一个安全、真实的环境,让他们在虚拟环境中进行实际操作和培训,从而提高他们的技能水平和安全意识。 由广州华锐互动开发的采煤…...

buuctf crypto 【[GXYCTF2019]CheckIn】解题记录
1.打开文件,发现密文 2.一眼base64,解密一下 3.解密后的字符串没有什么规律,看了看大佬的wp,是rot47加密,解密一下(ROT5、ROT13、ROT18、ROT47位移编码)...

微服务05-Docker基本操作
Docker的定义 1.什么是Docker Docker是一个快速交付应用、运行应用的技术: 可以将程序及其依赖、运行环境一起打包为一个镜像,可以迁移到任意Linux操作系统运行时利用沙箱机制形成隔离容器,各个应用互不干扰启动、移除都可以通过一行命令完…...

OpenHarmony创新赛|赋能直播第三期
开放原子开源大赛OpenHarmony创新赛赋能直播间持续邀请众多技术专家一起分享应用开发技术知识,本期推出OpenHarmony应用开发之音视频播放器和三方库的使用和方法,助力开发者掌握多媒体应用技术的开发能力和使用三方库提升应用开发的效率和质量࿰…...

docker镜像详解
目录 什么是docker镜像镜像相关命令docker pulldocker imagesdocker searchdocker rmi导出 / 导入镜像 镜像分层镜像摘要镜像摘要的作用分发散列值 什么是docker镜像 Docker镜像是Docker容器的基础组件,它包含了运行一个应用程序所需的一切,包括代码、运…...

二叉树的顺序结构以及堆的实现——【数据结构】
W...Y的主页 😊 代码仓库分享 💕 上篇文章,我们认识了什么是树以及二叉树的基本内容、表示方法……接下来我们继续来深入二叉树,感受其中的魅力。 目录 二叉树的顺序结构 堆的概念及结构 堆的实现 堆的创建 堆的初始化与…...

手写一个摸鱼神器:使用python手写一个看小说的脚本,在ide中输出小说内容,同事直呼“还得是你”
文章目录 一、准备python环境二、分析小说网的章节目录三、分析小说网的章节内容四、编写python脚本五、验证一下吧 一、准备python环境 windows从0搭建python3开发环境与开发工具 Python爬虫基础(一):urllib库的使用详解 Python爬虫基础&a…...

【Python 实战】---- 实现批量图片的切割
1. 需求场景 在实际开发中,我们会遇到一种很无聊,但是又必须实现的需求,就是比如协议、大量的宣传页面、大量的静态介绍页面、或者大量静态页面,但是页面高度很高,甚至高度可能会达到50000px,但是为了渲染…...

MAYA粒子基础_场
重力场 牛顿场 径向场 均匀场和重力场的区别 空气场 推动物体 阻力场 推动物体 涡流场 湍流场 体积轴场...

趣解设计模式之《我买了宝马,为啥不让我停这?》
〇、小故事 我们怎么识别一辆汽车是宝马品牌的汽车呢?虽然宝马汽车车辆型号非常的多,而且外型也各不相同,但是只要是宝马品牌的汽车,它的车头一定会有宝马汽车的logo,那么这个就是大家最直观去确认一辆车是不是宝马牌…...
MyBatis Plus 中 LocalDateTime 引发的一些问题和解决办法
简介 在使用 MyBatis Plus 进行数据库操作时,我们经常会遇到处理日期时间类型的需求。然而,在某些情况下,使用 LocalDateTime 类型可能会引发一些问题。本文将详细介绍这些问题,并提供相应的解决办法。 问题描述: 1…...

谁懂啊!自制的科普安全手册居然火了
自制的科普安全手册居然火了 谁懂啊! 嗨嗨嗨!小仙女们,有没有见过这样的可以翻页的电子安全手册呢?自己随手就能轻松制作手册,结果一晚浏览量这么多!这可真是让人又惊又喜啊!快来分享一下我的喜…...

强化学习-论文调研-泛化性能力度量
1.[ICML2019]Quantifying Generalization in Reinforcement Learning 文章提出16000多个单智能体闯关游戏CoinRun,通过智能体在分割开的训练环境和测试环境上表现的性能作为RL泛化性的度量。具体而言作者通过”奔跑硬币泛化曲线“ (CoinRun Gener…...

CSS中图片旋转超出父元素解决办法
下面的两种解决办法都会导致图片缩小,可以给图片进行初始化的宽高设置 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge">…...

XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...

【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...

图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
MinIO Docker 部署:仅开放一个端口
MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...
人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent
安全大模型训练计划:基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标:为安全大模型创建高质量、去偏、符合伦理的训练数据集,涵盖安全相关任务(如有害内容检测、隐私保护、道德推理等)。 1.1 数据收集 描…...
HTML前端开发:JavaScript 获取元素方法详解
作为前端开发者,高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法,分为两大系列: 一、getElementBy... 系列 传统方法,直接通过 DOM 接口访问,返回动态集合(元素变化会实时更新)。…...

MySQL的pymysql操作
本章是MySQL的最后一章,MySQL到此完结,下一站Hadoop!!! 这章很简单,完整代码在最后,详细讲解之前python课程里面也有,感兴趣的可以往前找一下 一、查询操作 我们需要打开pycharm …...