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

Linux驱动开发(二)--字符设备驱动开发提升 LED驱动开发实验

1、地址映射

在编写驱动之前,需要知道MMU,也就是内存管理单元,在老版本的 Linux 中要求处理器必须有 MMU,但是现在Linux 内核已经支持无 MMU 的处理器了。
MMU的功能如下:
  • 完成虚拟空间到物理空间的映射
  • 内存保护,设置存储器的访问权限,设置虚拟存储空间的缓冲特性

 我们重点来讲第一点,物理空间映射,虚拟空间到物理空间的映射,也叫做地址映射。
先了解虚拟地址(VA,Virtual Address)物理地址(PA,PhyscicalAddress)这两个概念,对于 32 位 的处理器来说,虚拟地址范围是 2^32=4GB,我们的开发板上有 512MB DDR3,这 512MB 的 内存就是物理内存,经过 MMU 可以将其映射到整个 4GB 的虚拟空间。

所以后续我们访问相关引脚进行操作的时候,如果没有开启 MMU 的话 直接向 0X020E0068 这个寄存器地址写入数据就可以配置 GPIO1_IO03 的复用功能。现在开启 了 MMU,并且设置了内存映射,因此就不能直接0X020E0068 这个地址写入数据了。我们必须得到 0X020E0068 这个物理地址在 Linux 系统里面对应的虚拟地址,这里就涉及到了物理内 存和虚拟内存之间的转换,需要用到两个函数:ioremap iounmap
总得来说也就是上面的步骤多加了一个IO映射的一个过程,仅此而已。

 

2、引脚操作回顾

2.1 STM32 GPIO回顾

主要是通过流程来作为思维的引导。
我们一般拿到一款全新的芯片,第一个要做的事情的就是驱动其 GPIO,控制其 GPIO 输出高低电平,我们学习 I.MX6U 也一样的,先来学习一下 I.MX6U GPIO。在学习 I.MX6U 的 GPIO 之前,我们先来回顾一下 STM32 GPIO 初始化(如果没有学过 STM32 就不用回顾了),我们以最常见的 STM32F103 为例来看一下 STM32 GPIO 初始化,示例代码如下:

void LED_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//使能 PB 端口时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //PB5 端口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO 口速度GPIO_Init(GPIOB, &GPIO_InitStructure); //根据设定参数初始化 GPIOB.5GPIO_SetBits(GPIOB,GPIO_Pin_5); //PB.5 输出高
}

看不止是看代码,要看流程,1.使能时钟  2.初始化GPIO,比如上下拉、速度  3.io口是否需要复用 4.GPIO输出高电平还是低电平 这是流程。

我们还需要了解相关位操作,具体如下所示:

分别是写(设置),读(清除)

val = data_reg;
val = val | (1<<n);
data_reg = val;

上述为写操作,具体涉及 “ | ”,不影响其他位。

val = data_reg;
val = val & ~(1<<n);
data_reg = val;

上述为读操作,具体涉及 “ ~  “  ” & ”,不影响其他位。

3、编译驱动程序

#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <asm/mach/map.h>
#include <asm/uaccess.h>
#include <asm/io.h>#define LED_MAJOR 200 /* 主设备号 */
#define LED_NAME "led" /* 设备名字 */#define LEDOFF 0 /* 关灯 */
#define LEDON 1 /* 开灯 */#define CCM_CCGR1_BASE (0X020C406C) 
#define SW_MUX_GPIO1_IO03_BASE (0X020E0068)
#define SW_PAD_GPIO1_IO03_BASE (0X020E02F4)
#define GPIO1_DR_BASE (0X0209C000)
#define GPIO1_GDIR_BASE (0X0209C004)static void __iomem *IMX6U_CCM_CCGR1;
static void __iomem *SW_MUX_GPIO1_IO03;
static void __iomem *SW_PAD_GPIO1_IO03;
static void __iomem *GPIO1_DR;
static void __iomem *GPIO1_GDIR;/** @description : LED 打开/关闭* @param - sta : LEDON(0) 打开 LED,LEDOFF(1) 关闭 LED* @return : 无*/
void led_switch(u8 sta)
{u32 val = 0;if(sta == LEDON) {val = readl(GPIO1_DR);val &= ~(1 << 3); writel(val, GPIO1_DR);}else if(sta == LEDOFF) {val = readl(GPIO1_DR);val |= (1 << 3);writel(val, GPIO1_DR);} 
}static int led_open (struct inode *inodp, struct file *filp)
{return 0;
}static ssize_t led_read (struct file *filp, char __user *buf, size_t cnt, loff_t *offt)
{return 0;
}/*
* @description : 向设备写数据
* @param - filp : 设备文件,表示打开的文件描述符
* @param - buf : 要写给设备写入的数据
* @param - cnt : 要写入的数据长度
* @param - offt : 相对于文件首地址的偏移
* @return : 写入的字节数,如果为负值,表示写入失败
*/
static ssize_t led_write (struct file *filp, const char __user *buf, size_t cnt, loff_t *offt)
{int retvalue = 0;unsigned char databuf[1];unsigned char ledstat;retvalue = copy_from_user(databuf,buf,cnt);if(retvalue < 0){printk("kernel write failed\r\n");return -EFAULT;}ledstat = databuf[0];if(ledstat == LEDON){led_switch(LEDON);}else if(ledstat == LEDOFF){led_switch(LEDOFF);}return 0;
}/** @description : 关闭/释放设备* @param - filp : 要关闭的设备文件(文件描述符)* @return : 0 成功;其他 失败*/
static int led_release (struct inode *inodp, struct file *filp)
{return 0;
}static struct file_operations led_fops = {.owner   = THIS_MODULE,.open    = led_open,.read    = led_read,.write   = led_write,.release = led_release,
};static int __init led_init(void){int retvalue = 0;u32 val = 0;IMX6U_CCM_CCGR1 = ioremap(CCM_CCGR1_BASE,4);SW_MUX_GPIO1_IO03 = ioremap(SW_MUX_GPIO1_IO03_BASE,4);SW_PAD_GPIO1_IO03 = ioremap(SW_PAD_GPIO1_IO03_BASE,4);GPIO1_DR = ioremap(GPIO1_DR_BASE,4);GPIO1_GDIR = ioremap(GPIO1_GDIR_BASE,4);/* 2、使能 GPIO1 时钟 */val = readl(IMX6U_CCM_CCGR1);val &= ~(3 << 26); /* 清除以前的设置 */val |= (3 << 26); /* 设置新值 */writel(val, IMX6U_CCM_CCGR1);/* 3、设置 GPIO1_IO03 的复用功能,将其复用为* GPIO1_IO03,最后设置 IO 属性。*/writel(5, SW_MUX_GPIO1_IO03);/* 寄存器 SW_PAD_GPIO1_IO03 设置 IO 属性 */writel(0x10B0, SW_PAD_GPIO1_IO03);/* 4、设置 GPIO1_IO03 为输出功能 */val = readl(GPIO1_GDIR);val &= ~(1 << 3); /* 清除以前的设置 */val |= (1 << 3); /* 设置为输出 */writel(val, GPIO1_GDIR);/* 5、默认关闭 LED */val = readl(GPIO1_DR);val |= (1 << 3); writel(val, GPIO1_DR);//设备号 名字 字符模型驱动的一个结构体retvalue = register_chrdev(LED_MAJOR,LED_NAME,&led_fops);if(retvalue < 0){// exit}return 0;
}static void __exit led_exit(void){iounmap(IMX6U_CCM_CCGR1);iounmap(SW_MUX_GPIO1_IO03);iounmap(SW_PAD_GPIO1_IO03);iounmap(GPIO1_DR);iounmap(GPIO1_GDIR);unregister_chrdev(LED_MAJOR,LED_NAME);
}module_init(led_init);
module_exit(led_exit);MODULE_LICENSE("GPL");
MODULE_AUTHOR("7yewh");

相关文章:

Linux驱动开发(二)--字符设备驱动开发提升 LED驱动开发实验

1、地址映射 在编写驱动之前&#xff0c;需要知道MMU&#xff0c;也就是内存管理单元&#xff0c;在老版本的 Linux 中要求处理器必须有 MMU&#xff0c;但是现在Linux 内核已经支持无 MMU 的处理器了。 MMU的功能如下&#xff1a; 完成虚拟空间到物理空间的映射 内存保护&…...

钡铼BL101网关助力智慧城市路灯远程智能管控

在迈向智慧城市的征途中&#xff0c;基础设施的智能化改造是关键一环&#xff0c;而路灯作为城市脉络的照明灯塔&#xff0c;其智能化升级对于节能减排、提升城市管理效率具有重要意义。钡铼BL101网关&#xff0c;作为Modbus转MQTT的专业桥梁&#xff0c;正以其卓越的性能和广泛…...

如何优雅的使用Github Action服务来将Hexo部署到Github Pages

文章目录 参考文章前提条件1. 初始化Hexo2. 初始化仓库3. 创建Token4. 修改_config.yml5. 配置Github Action工作流6. 推送验证7. 配置Github Pages8. 修改Hexo主题样式10. 添加文章遇到了一些问题和方案1. 网站没有样式问题2. 图片不显示 参考文章 Bilibili视频教程-9分钟零成…...

After Effects 2024 mac/win版:创意视效,梦想起航

After Effects 2024是一款引领视效革命的专业软件&#xff0c;汇聚了创意与技术的精华。作为Adobe推出的全新版本&#xff0c;它以其强大的视频处理和动画创作能力&#xff0c;成为从事设计和视频特技的机构&#xff0c;如电视台、动画制作公司、个人后期制作工作室以及多媒体工…...

信息打点web篇----web后端源码专项收集

前言 欢迎来到我的博客 个人主页:北岭敲键盘的荒漠猫-CSDN博客 专栏描述&#xff1a;因为第一遍过信息收集的时候&#xff0c;没怎么把收集做回事 导致后来在实战中&#xff0c;遭遇资产获取少&#xff0c;可渗透点少的痛苦&#xff0c;如今决定 从头来过&#xff0c;全面全方位…...

ArcGIS批量投影转换的妙用(地理坐标系转换为平面坐标系)

​ 点击下方全系列课程学习 点击学习—>ArcGIS全系列实战视频教程——9个单一课程组合系列直播回放 这次文章我们来介绍一下&#xff0c;如何巧妙用要素数据集来实现要素的批量投影。不需要ArcGIS的模型构建器与解决。 例如&#xff0c;有多个要素要将CGCS_2000地理坐标系投…...

YOLOv10训练自己的数据集(图像目标检测)

目录 1、下载代码 2、环境配置 3、准备数据集 4、yolov10训练 可能会出现报错&#xff1a; 1、下载代码 源码地址&#xff1a;https://github.com/THU-MIG/yolov10 2、环境配置 打开源代码&#xff0c;在Terminal中&#xff0c;使用conda 创建虚拟环境配置 命令如下&a…...

解决不能拉取 docker 镜像

# 编辑镜像仓库文件 sudo vi /etc/docker/daemon.json { "registry-mirrors": ["https://registry.docker-cn.com","https://s3d6l2fh.mirror.aliyuncs.com"] }# 重启docker sudo systemctl restart docker参考 https://blog.csdn.net/u01019733…...

44、基于深度学习的癌症检测(matlab)

1、基于深度学习的癌症检测原理及流程 基于深度学习的癌症检测是利用深度学习算法对医学影像数据进行分析和诊断&#xff0c;以帮助医生准确地检测癌症病变。其原理和流程主要包括以下几个步骤&#xff1a; 数据采集&#xff1a;首先需要收集包括X光片、CT扫描、MRI等医学影像…...

Vue3 【仿 react 的 hook】封装 useTitle

效果预览 页码加载时&#xff0c;自动获取网页标题通过input输入框&#xff0c;可以实时改变网页标题 代码实现 index.vue <template><h1>网页的标题为&#xff1a; {{ titleRef }}</h1><p>通过input输入框实时改变网页的标题 <input v-model"…...

CSS 计数器

CSS 计数器 CSS 计数器是 CSS 中一个强大但经常被忽视的功能。它们允许开发者创建和管理计数器,这些计数器可以在文档中自动递增,非常适合用于编号章节、列表项或其他文档元素。在本文中,我们将深入探讨 CSS 计数器的使用方法、优势和实际应用场景。 CSS 计数器的基本概念…...

磁力搜索器,解读新一代的搜索引擎方式,磁力王、磁力猫等引擎的异同及原理

最近国内几年&#xff0c;不依赖追踪服务器的磁力搜索开始流行&#xff0c;成为新的资源搜索的方式。 我们平常所说的磁力王&#xff08;jigecili.com)、磁力猫(yinghuacili.com)、bt磁力&#xff08;btcili.cn)、磁力狗最新版&#xff08;cilizhai.net)、磁力兔子、磁力宝、人…...

Apache Doris 全新分区策略 Auto Partition 应用场景与功能详解 | Deep Dive系列

编辑&#xff1a;SelectDB 技术团队 在当今数据驱动的时代&#xff0c;如何高效、有序地管理数据库中的海量数据成为挑战。为了处理庞大的数据集&#xff0c;分布式数据库引入了类似分区和分桶策略&#xff0c;通过将数据按特定规则划分成较小的单位并分布到不同节点上&#x…...

【Linux】关于在华为云中开放了端口后仍然无法访问的问题

已在安全组中添加规则: 通过指令: netstat -nltp | head -2 && netstat -nltp | grep 8080 运行结果: 可以看到服务器确实处于监听状态了. 通过指令 telnet 公网ip port 也提示: "正在连接xxx.xx.xx.xxx...无法打开到主机的连接。 在端口 8080: 连接失败"…...

Linux系统ubuntu20.04 无人机PX4 开发环境搭建(失败率很低)

Linux系统ubuntu20.04 无人机PX4 开发环境搭建 PX4固件下载开发环境搭建MAVROS安装安装地面站QGC PX4固件下载 PX4的源码处于GitHub&#xff0c;因为众所周知的原因git clone经常失败&#xff0c;此处从Gitee获取PX4源码和依赖模块。 git clone https://gitee.com/voima/PX4-…...

中间件(express)

中间件&#xff08;express&#xff09; 在Express.js中&#xff0c;中间件&#xff08;Middleware&#xff09;是一个重要的组成部分&#xff0c;用于处理HTTP请求和响应。中间件函数具有特定的签名&#xff0c;并可以接受请求对象&#xff08;req&#xff09;、响应对象&…...

【代码随想录算法训练Day44】LeetCode 322.零钱兑换、LeetCode 279.完全平方数、LeetCode139.单词拆分

Day44 动态规划第六天 LeetCode 322.零钱兑换 dp数组的含义&#xff1a;装满容量为j的背包需要的最少物品数为dp[j] 递推公式&#xff1a;dp[j]min(dp[j-coins[i]]1,dp[j]) 初始化&#xff1a;dp[0]0,dp[j]INT_MAX 遍历顺序&#xff1a;个数问题与遍历顺序无关&#xff0c;都…...

ChatGLM2-6B 部署

本文主要对 ChatGLM2-6B 模型的部署和推理过程进行介绍。 一、部署环境 在阿里云服务器上部署&#xff0c;具体环境如下&#xff1a; modelscope:1.9.5 pytorch 2.0.1 tensorflow 2.13.0 python 3.8 cuda 118 ubuntu 20.04 CPU 8 core 内存 30 GiB GPU NVIDIA A10 2…...

武汉工程大学24计算机考研数据,有学硕招收调剂,而专硕不招收调剂!

武汉工程大学是一所以工为主&#xff0c;覆盖工、理、管、经、文、法、艺术、医学、教育学等九大学科门类的多科性教学研究型大学&#xff0c;是湖北省重点建设高校、湖北省国内一流学科建设高校&#xff0c;入选卓越工程师教育培养计划、中西部高校基础能力建设工程、“新工科…...

python爬虫之selenium自动化操作

python爬虫之selenium自动化操作 需求&#xff1a;操作淘宝去掉弹窗广告搜索物品后进入百度回退又前进 selenium模块的基本使用 问题&#xff1a;selenium模块和爬虫之间具有怎样的关联? 1、便捷的获取网站中动态加载的数据 2、便捷实现模拟登录 什么是selenium模块&#x…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

Oracle查询表空间大小

1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节&#xff0c;供应链协同管理在供应链上下游企业之间建立紧密的合作关系&#xff0c;通过信息共享、资源整合、业务协同等方式&#xff0c;实现供应链的全面管理和优化&#xff0c;提高供应链的效率和透明度&#xff0c;降低供应链的成…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

论文笔记——相干体技术在裂缝预测中的应用研究

目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术&#xff1a;基于互相关的相干体技术&#xff08;Correlation&#xff09;第二代相干体技术&#xff1a;基于相似的相干体技术&#xff08;Semblance&#xff09;基于多道相似的相干体…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

基于IDIG-GAN的小样本电机轴承故障诊断

目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) ​梯度归一化(Gradient Normalization)​​ (2) ​判别器梯度间隙正则化(Discriminator Gradient Gap Regularization)​​ (3) ​自注意力机制(Self-Attention)​​ 3. 完整损失函数 二…...

省略号和可变参数模板

本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...