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">…...
JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...
pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...
基于Springboot+Vue的办公管理系统
角色: 管理员、员工 技术: 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能: 该办公管理系统是一个综合性的企业内部管理平台,旨在提升企业运营效率和员工管理水…...
区块链技术概述
区块链技术是一种去中心化、分布式账本技术,通过密码学、共识机制和智能合约等核心组件,实现数据不可篡改、透明可追溯的系统。 一、核心技术 1. 去中心化 特点:数据存储在网络中的多个节点(计算机),而非…...
