1-ARM Linux驱动开发-MIO控制

一、前言

MIO也属于是字符设备,将MIO复用为GPIO可以实现对LED等外设的控制,其本质是从寄存器层面对硬件的控制。这次主要记录一下GPIO控制LED的驱动。

官网ZYNQ寄存器手册https://docs.amd.com/r/en-US/ug1087-zynq-ultrascale-registers/Overview

二、物理地址与虚拟地址

1、物理地址

物理地址是内存(包括寄存器等存储器件)在硬件层面的真实地址,由硬件决定的,是固定不变的。对于存储器件来说,物理地址唯一地标识了一个存储单元,CPU 可以通过物理地址直接访问内存中的数据。不过,在一些复杂的系统架构中,如具有内存管理单元(MMU)的系统,物理地址的访问可能会受到限制或者重新映射。

2、虚拟地址

虚拟地址是操作系统(如 Linux)为应用程序提供的一种抽象的地址空间。它是应用程序所看到的内存地址,和物理地址没有直接的对应关系。主要优点是提供了内存保护和多任务支持。不同的应用程序可以有各自独立的虚拟地址空间,它们彼此之间不会相互干扰。当应用程序访问虚拟地址时,操作系统会通过内存管理单元(MMU)将虚拟地址转换为物理地址。

三、MIO简介

ZYNQ MPSOC中包含PS-MIO(Multiplexed I/O)和PS-EMIO(Extended Multiplexed I/O),其中PS - MIO是ZYNQ MPSoc中处理系统的复用输入 / 输出接口。它提供了一种将PS与外部设备直接连接的方式,共有78个MIO引脚。PS-EMIO是PS的扩展复用输入/输出接口。它主要用于扩展ZYNQ MPSoc 的I/O接口能力。当MIO的引脚数量不能满足系统对外部设备连接的需求时,就可以使用EMIO,至多有96个引脚。

image

四、应用文件

使用GPIO需要设置两个寄存器,一个是设置 GPIO的管脚复用的IOU_SLCR Module寄存器,一个是设置GPIO的管脚功能的GPIO Module寄存器。

在上面给出的ZYNQ MPSOC官方手册中可以找到对应的寄存器地址。

image

image

image

image

image

//添加头文件
#include <linux/init.h>
#include <linux/module.h>
#include <linux/gpio.h>static int led_major;
static struct class *led_cls;/* gpio 内存映射地址 */
static unsigned long *gpio_addr = NULL;
static unsigned long *iou_slcr = NULL;/* gpio 寄存器物理基地址 */
#define GPIO_BASE_ADDR 0xFF0A0000
#define IOU_SLCR_ADDR 0xFF180000
/* gpio 寄存器所占空间大小 */
#define GPIO_BASE_SIZE 0x368
#define IOU_SLCR_SIZE 0x714/* gpio 引脚设置GPIO功能*/
#define GPIO_PIN_40 (unsigned int *)((unsigned long)iou_slcr + 0x000000A0)
#define GPIO_PIN_42 (unsigned int *)((unsigned long)iou_slcr + 0x000000A8)/* gpio 控制电流0*/
#define IOU_SLCR_BANK1_CTRL0 (unsigned int *)((unsigned long)iou_slcr + 0x00000154)
/* gpio 控制电流1*/
#define IOU_SLCR_BANK1_CTRL1 (unsigned int *)((unsigned long)iou_slcr + 0x00000158)
/* gpio 输入引脚选择Schmitt或CMOS*/
#define IOU_SLCR_BANK1_CTRL3 (unsigned int *)((unsigned long)iou_slcr + 0x0000015C)
/* gpio 设置上下拉*/
#define IOU_SLCR_BANK1_CTRL4 (unsigned int *)((unsigned long)iou_slcr + 0x00000160)
/* gpio 使能上下拉*/
#define IOU_SLCR_BANK1_CTRL5 (unsigned int *)((unsigned long)iou_slcr + 0x00000164)
/* gpio 引脚速率选择*/
#define IOU_SLCR_BANK1_CTRL6 (unsigned int *)((unsigned long)iou_slcr + 0x00000168)/* gpio 方向寄存器 */
#define GPIO_DIRM_1 (unsigned int *)((unsigned long)gpio_addr + 0x00000244)
/* gpio 使能寄存器 */
#define GPIO_OEN_1 (unsigned int *)((unsigned long)gpio_addr + 0x00000248)
/* gpio 输出数据寄存器 */
#define GPIO_DATA_1 (unsigned int *)((unsigned long)gpio_addr + 0x00000044)
/* gpio 输出数据控制寄存器1 */
#define GPIO_MASK_DATA_1_LSW (unsigned int *)((unsigned long)gpio_addr + 0x00000008)
/* gpio 输出数据控制寄存器2 */
#define GPIO_MASK_DATA_1_MSW (unsigned int *)((unsigned long)gpio_addr + 0x0000000C)const struct file_operations led_fops = {};//实现装载入口函数和卸载入口函数
static __init int led_drv_v1_init(void)
{printk("-------^v^-------\n");printk("-led drv v1 init-\n");//申请主设备号led_major = register_chrdev(0, "led_drv_v1", &led_fops);if (led_major < 0){printk("register chrdev faile!\n");return led_major;}printk("register chrdev ok!\n");//创建设备节点//创建设备的类别led_cls = class_create(THIS_MODULE, "led_class");printk("class create ok!\n");//创建设备device_create(led_cls, NULL, MKDEV(led_major, 0), NULL, "Myled%d", 0);printk("device create ok!\n");//1.内存映射gpio_addr = ioremap(GPIO_BASE_ADDR, GPIO_BASE_SIZE);iou_slcr = ioremap(IOU_SLCR_ADDR, IOU_SLCR_SIZE);printk("gpio_addr init over!\n");//2.MIO40 MIO42 设置成GPIO,参考手册设置iowrite32((ioread32(GPIO_PIN_40) & 0x0), GPIO_PIN_40);printk("gpio MIO40 init over!\n");iowrite32((ioread32(GPIO_PIN_42) & 0x0), GPIO_PIN_42);printk("gpio MIO42 init over!\n");// //3.MIO40 MIO42设置输出驱动电流大小// // 将 0x3FFFFFF 和 0x0 转换为二进制。// // 0011 1111 1111 1111 1111 1111 1111// // 0000 0000 0000 0000 0000 0000 0000// // 参考手册,可以知道每一位的地址都是由 CTRL0 和 CTRL1 控制的,在这里都是 10, 查看手册得 8 mA。iowrite32((ioread32(IOU_SLCR_BANK1_CTRL0) | 0x3FFFFFF), IOU_SLCR_BANK1_CTRL0);iowrite32((ioread32(IOU_SLCR_BANK1_CTRL1) & 0x0), IOU_SLCR_BANK1_CTRL1);//4.选择引脚是Schmitt还是CMOSiowrite32((ioread32(IOU_SLCR_BANK1_CTRL3) & 0x0), IOU_SLCR_BANK1_CTRL3);//5.输出管脚上下拉及使能iowrite32((ioread32(IOU_SLCR_BANK1_CTRL4) | 0x3FFFFFF), IOU_SLCR_BANK1_CTRL4);iowrite32((ioread32(IOU_SLCR_BANK1_CTRL5) | 0x3FFFFFF), IOU_SLCR_BANK1_CTRL5);//6.MIO速率的选择iowrite32((ioread32(IOU_SLCR_BANK1_CTRL6) & 0x0), IOU_SLCR_BANK1_CTRL6);//7.MIO40 MIO42 设置成输出// 40 - 26 = 14, 42 - 26 = 16// 0000 0000 000|0 0|000 0000 0000 0000//              |16 |14   // 0000 0000 000 1 0 100 0000 0000 0000// 0000 0000 0001 0100 0000 0000 0000// 0x00014000iowrite32((ioread32(GPIO_DIRM_1) | 0x00014000), GPIO_DIRM_1);//MIO40 MIO42 使能iowrite32((ioread32(GPIO_OEN_1) | 0x00014000), GPIO_OEN_1);/* MASK_DATA方式按灭LED1,LED2,这个需要自己修改相关参数 *///iowrite32((ioread32(GPIO_MASK_DATA_0_LSW ) & 0xFEFFEFFF), GPIO_MASK_DATA_0_LSW );//printk("GPIO_MASK_DATA_0_LSW = 0x%x\n", *GPIO_MASK_DATA_0_LSW);//iowrite32((ioread32(GPIO_MASK_DATA_0_MSW ) & 0xFEFFEFFF), GPIO_MASK_DATA_0_MSW );//printk("GPIO_MASK_DATA_0_MSW = 0x%x\n", *GPIO_MASK_DATA_0_MSW);//8.DATA方式按灭LED1,LED2// 1111 1111 1111 111|1 1|111 1111 1111 1111//                   |0  |0// 1111 1111 1111 1110 1011 1111 1111 1111// 0xFFFEBFFF// iowrite32((ioread32(GPIO_DATA_1) & 0xFFFEBFFF), GPIO_DATA_1);iowrite32((ioread32(GPIO_DATA_1) & 0xFFFEBFFF), GPIO_DATA_1);printk("GPIO_DATA_1 = 0x%x\n", *GPIO_DATA_1);return 0;
}static __exit void led_drv_v1_exit(void)
{iowrite32((ioread32(GPIO_DATA_1) | 0xFFFFFFFF), GPIO_DATA_1);//9.内存释放iounmap(gpio_addr);iounmap(iou_slcr);//删除设备device_destroy(led_cls, MKDEV(led_major, 0));//删除类class_destroy(led_cls);//注销主设备号unregister_chrdev(led_major, "led_drv_v1");printk("-------^v^-------\n");printk("-led drv v1 exit-\n");
}//申明装载入口函数和卸载入口函数
module_init(led_drv_v1_init);
module_exit(led_drv_v1_exit);//添加GPL协议
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Popeye");

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/2750.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

深入解析Sysmon日志:增强网络安全与威胁应对的关键一环

不断演进的网络安全领域中&#xff0c;保持对威胁的及时了解至关重要。Sysmon日志在这方面发挥了至关重要的作用&#xff0c;通过提供有价值的见解&#xff0c;使组织能够加强其安全姿态。Windows在企业环境中是主导的操作系统&#xff0c;因此深入了解Windows事件日志、它们的…

HTMLCSS:呈现的3D树之美

效果演示 这段代码通过HTML和CSS创建了一个具有3D效果的树的图形&#xff0c;包括分支、树干和阴影&#xff0c;通过自定义属性和复杂的变换实现了较为逼真的立体效果。 HTML <div class"container"><div class"tree"><div class"…

XingHan-Team团队官网系统源码 全开源

XingHan-Team 官网程序是一个现代化的企业官网管理系统&#xff0c;由星涵网络工作室开发。 本系统提供了完整的网站内容管理功能&#xff0c;包括用户管理、内容发布、成员查询、成员申请等功能。 源码下载&#xff1a;https://download.csdn.net/download/m0_66047725/8995…

JAVA:常见 JSON 库的技术详解

1、简述 在现代应用开发中&#xff0c;JSON&#xff08;JavaScript Object Notation&#xff09;已成为数据交换的标准格式。Java 提供了多种方式将对象转换为 JSON 或从 JSON 转换为对象&#xff0c;常见的库包括 Jackson、Gson 和 org.json。本文将介绍几种常用的 JSON 处理…

【贪心】【可行范围内最大边界】SCNU习题 P25.跳跃游戏

算法思想&#xff1a; 每次迭代更新可行至的最大范围r(r必保证>原位置&#xff09;&#xff0c;至到迭代结束&#xff0c;若r>length of array则说明可以跳跃至此 #include <iostream> #include <vector> #include <string> #include <sstre…

Redis 组网方式入门

文章目录 一、组网方式1. 单实例模式描述优点缺点适用场景 2. 主从复制模式&#xff08;Master-Slave Replication&#xff09;描述优点缺点适用场景基于docker的redis主从复制1. 配置主节点2. 配置从节点3. 查看节点状态4. 验证主从数据同步5. 查看同步进度 3. 哨兵模式&#…

【系统集成项目管理工程师教程】第5章 软件工程

软件工程是一门研究用工程化方法构建和维护有效、实用和高质量软件的学科&#xff0c;涵盖软件需求、设计、实现、测试、部署交付、质量管理和过程能力成熟度等方面&#xff0c;旨在提高软件生产率、质量并降低成本&#xff0c;确保软件项目的成功开发与维护。 5.1软件工程定义…

PowerDesigner使用教程:设置注释、默认值属性

使用场景: 进行表设计时&#xff0c;我们需要对字段增加注释、设置默认值 解决方案&#xff1a; 如下图设置即可实现

如果 MySQL 主库出现了问题,从库该何去何从呢?

🚀 博主介绍:大家好,我是无休居士!一枚任职于一线Top3互联网大厂的Java开发工程师! 🚀 🌟 在这里,你将找到通往Java技术大门的钥匙。作为一个爱敲代码技术人,我不仅热衷于探索一些框架源码和算法技巧奥秘,还乐于分享这些宝贵的知识和经验。 💡 无论你是刚刚踏…

C# 日志框架 NLog、log4net 和 Serilog对比

文章目录 前言NLog、log4net 和 Serilog 三个框架的详细对比:一、NLog优点:缺点:二、 log4net优点缺点三、Serilog优点缺点四、Serilog使用举例总结前言 NLog、log4net 和 Serilog 三个框架的详细对比: NLog、log4net 和 Serilog 是三个非常流行的 .NET 日志框架,它们各自…

本地缓存库分析(四):fastcache

文章目录 本系列前言设计索引和数组怎么判断是否被覆盖其他问题 源码走读数据结构setget 总结 本系列 本地缓存库分析&#xff08;一&#xff09;&#xff1a;golang-lru本地缓存库分析&#xff08;二&#xff09;&#xff1a;bigcache本地缓存库分析&#xff08;三&#xff0…

安科瑞5G基站直流叠光监控系统-安科瑞黄安南

基站现状和趋势 5G基站是专门提供5G网络服务的公用移动通信基站。5G基站主要用于提供5G空口协议功能&#xff0c;支持与用户设备、核心网之间的通信。按照逻辑功能划分&#xff0c;5G基站可分为5G基带单元与5G射频单元&#xff0c;二者之间可通过CPRI或eCPRI接口连接。 2019年…

Pr 视频效果:过渡

效果面板/视频效果/过渡 Video Effects/Transition Adobe Premiere Pro 的视频效果中&#xff0c;过渡 Transition效果组用于创建单个剪辑内过渡效果的一组视频效果。这些效果可以增强视频的视觉连贯性&#xff0c;添加创意性的视觉转换&#xff0c;为观众提供流畅的观看体验。…

DataX 的安装配置和使用 (详细版)

1&#xff0c;上传解压 1&#xff0c;开始上传安装包到你虚拟机上放置安装包的文件夹 2&#xff0c;开始解压 ,配置环境变量 1、上传 /opt/modules 2、解压 tar -zxvf datax.tar.gz -C /opt/installs 3、修改 vi /etc/profile 配置环境变量&#xff1a; export DAT…

zookeeper安装

安装之前&#xff1a;先关闭三台服务器的防火墙&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; systemctl stop firewalld systemctl disable firewalld 1)上传 /opt/modules下面 2&#xff09;解压 /opt/installs下面 tar -zxvf zookeeper-3.4.10.tar.gz …

Nature文章《deep learning》文章翻译

这篇文章是对Nature上《deep learning》文章的翻译。原作者 Yann LeCun, Yoshua Bengio& Geoffrey Hinton。 这篇文章的中心思想是深入探讨深度学习在机器学习中的革命性贡献&#xff0c;重点介绍其在特征学习、监督学习、无监督学习等方面的突破&#xff0c;并阐述其在图…

动态规划—整数拆分

class Solution {public int integerBreak(int n) {int[] dp new int[n1];dp[2] 1;for(int i 3; i< n; i){for(int j 1; j< i/2; j){//j拆i&#xff0c;只需要遍历到 i/2 就可以&#xff0c;后面没有必要遍历dp[i] Math.max(dp[i], Math.max(j*(i-j) , j*dp[i-j]));…

OceanBase V4.3.3,首个面向实时分析场景的GA版本发布

在10月23日举办的 OceanBase年度发布会 上&#xff0c;我们怀着激动之情&#xff0c;正式向大家宣布了 OceanBase 4.3.3 GA 版的正式发布&#xff0c;这也是OceanBase 为实时分析&#xff08;AP&#xff09;场景打造的首个GA版本。 2024 年初&#xff0c;我们推出了 4.3.0 版本…

儿童安全座椅行业全面深入分析

儿童安全座椅就是一种专为不同体重&#xff08;或年龄段&#xff09;的儿童设计&#xff0c;将孩子束缚在安全座椅内&#xff0c;能有效提高儿童乘车安全的座椅。欧洲强制性执行标准ECE R44/03的定义是&#xff1a;能够固定到机动车辆上&#xff0c;带有ISOFIX接口、LATCH接口的…

算法笔记:Day-09(初始动态规划)

509. 斐波那契数 斐波那契数 &#xff08;通常用 F(n) 表示&#xff09;形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始&#xff0c;后面的每一项数字都是前面两项数字的和。也就是&#xff1a; F(0) 0&#xff0c;F(1) 1 F(n) F(n - 1) F(n - 2)&#xff0c;其中 …