linux内核中GPIO的使用(一)--IO内存

2023-10-30

一、相关概念
使用IO内存将物理地址映射为虚拟地址,再通过对虚拟地址的操作来控制硬件。所谓的IO内存是指一种编址方式,不同cpu平台使用的编址方式不同,一种是“IO内存”方式,也叫统一编址方式,是指内存和外设的地址是在同一个地址空间上的,如:ARM、powerpc 、MIPS等平台;另一种是“IO端口”方式,也叫独立编址方式,是指内存的地址空间和外设的地址空间是分开的,如x86平台。在嵌入式系统中,可以通过查看两个文件中的内容来确认是哪一种编址方式:/proc/iomem/proc/ioports,哪一个文件有内容就表示该平台使用哪一种编址方式。

二、程序设计思路
驱动安装—>申请IO内存资源—>物理地址的映射—>得到虚拟地址—>访问虚拟地址—>控制外设硬件
驱动卸载—>解除地址映射—>释放IO内存资源
用到的函数有:
request_mem_region()、ioremap()、release_mem_region()、iounmap()

三、程序设计与分析
1)申请IO内存资源

        struct resource * request_mem_region( resource_size_t start, resource_size_t n, const char *name)
        参数分析:
        resource_size_t start:IO内存的开始地址,该地址是物理地址;
        resource_size_t n:要申请的IO内存资源的大小,单位为字节;
        const char *name:给所申请的IP内存资源取一个名字;
        返回值:
            申请成功,返回一个struct resource类型的指针;
            申请失败,返回NULL

2)释放IO内存资源

        void release_mem_region(resource_size_t start, resource_size_t n)
        参数分析:
        resource_size_t start:IO内存的开始地址,该地址是物理地址;
        resource_size_t n:要申请的IO内存资源的大小,单位为字节;

3)IO内存映射(物理地址—>虚拟地址)

        void __iomem *ioremap(phys_addr_t offset, unsigned long size)
        参数分析:
        phys_addr_t offset:准备映射的物理地址空间的开始地址            
        unsigned long size:要映射的物理地址空间的大小,单位为字节
        返回值:
            映射成功,返回一个虚拟地址
            映射失败,返回NULL

4)IO内存映射的解除

        void iounmap(volatile void __iomem *addr);
        参数分析:
            volatile void __iomem *addr:前面映射得到的虚拟地址

四、简单的实例
简单的LED驱动,实现对基于S5PV210平台的LED灯控制,所用寄存器:GPJ2CON(0xe0200280)、GPJ2DAT(0xe0200284),主要代码如下:

static int * GPJ2CON_VA;    /*定义全局变量*/
static int * GPJ2DAT_VA;
static struct resource * gpio_led_source; 
.....

在驱动的初始化函数static int __init leddev_init(void)中添加相关代码:

        gpio_led_source = request_mem_region(0xe0200280, 8, “GPIO_LED”);
        if(gpio_led_source == NULL)     
        {
            printk("led_request_mem_region error!\n");
            goto err_led_request_mem_region;   /*出错处理*/
        }
        GPJ2CON_VA = ioremap(0xe0200280, 8);  
        if(GPJ2CON_VA == NULL)
        {
            printk("led ioremap error!\n");
            goto err_led_ioremap;             /*出错处理*/
        }
        GPJ2DAT_VA = GPJ2CON_VA + 1;          /* GPJ2CON和GPJ2DAT的地址刚好相邻*/

        *GPJ2CON_VA &= ~0xffff;           /*initial led GPIO*/
        *GPJ2CON_VA |= 0x1111;
        *GPJ2DAT_VA |= 0xf;
        printk("GPIO initial success!\n");

在驱动的退出函数static int __exit leddev_exit(void)中:

        iounmap(GPJ2CON_VA);               /*解除IO映射*/
        release_mem_region(0xe0200280, 8); /*释放IO内存资源*/
        unregister_chrdev_region(MKDEV(leddev_Major, leddev_Minor), 1);             /*注销设备号*/
        cdev_del(&ledodev);                /*从内核中删除设备 */
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

linux内核中GPIO的使用(一)--IO内存 的相关文章

随机推荐

  • Java的Integer类

    1 用途 包装一个对象中的原始类型int的值 封装基本数据类型 int 将字符串转成基本数据类型 int 2 特点 类型为Integer的对象包含一个单一字段 其类型为int 此外 该类还提供了一些将int转换为String和String转
  • Git - 生成 SSH 公钥

    生成 SSH 公钥 如前所述 许多 Git 服务器都使用 SSH 公钥进行认证 为了向 Git 服务器提供 SSH 公钥 如果某系统用户尚未拥有密钥 必须事先为其生成一份 这个过程在所有操作系统上都是相似的 首先 你需要确认自己是否已经拥有
  • centos安装ruby

    可以使用 sudo yum install ruby 直接安装 但安装的是旧版本 不建议使用 1 去ruby官网直接下载安装包 http www ruby lang org en downloads 燃鹅 下载不了 那就借助 某雷吧 把安装
  • 查看linux是否已经安装了apache

    查看linux是否已经安装了apache 解决方法 查看linux是否已经安装了apache服务 可以通过执行 http www yayihouse com yayishuwu chapter 1800
  • 网易云params和encSecKey的获取

    网易云params和encSecKey的获取 params和encSecKey有什么用 软件准备 1 python及其对应的编辑器 推荐pycharm 2 发条js调试工具 我使用的是1 9版本 js代码分析 定位生成位置 分析传入参数 代
  • 关于软件设计使用中一些的原则简述

    概述 向大家介绍过一些软件开发的原则 比如优质代码的十诫和Unix传奇 下篇 中所以说的UNIX的设计原则 相信大家从中能够从中学了解到一些设计原理方面的知识 正如我在 再谈 我是怎么招聘程序 中所说的 一个好的程序员通常由其操作技能 知识
  • 雅思口语 九月新题 答案

    目录 你大概多长时间练习一次编程 你为什么选择这个专业 What are your career goals in the field of software engineering What sparked your interest i
  • uniapp-h5中的文件流下载和指定的url下载总结(解决下载后的pdf打开空白情况)

    uniapp h5中的文件流下载和指定的url下载总结 解决下载后的pdf打开空白情况 一 uniapp h5文件流下载 场景 之所以会有文件流需求 前端给到一些水印内容 然后后台会给文件加上我们给到的水印并以文件流形式返回 这里以pdf格
  • 汇编语言之字符串的比较和查找

    汇编语言之字符串的比较和查找 基础知识 串比较指令涉及两个串 目的串地址为ES DI 源串地址为DS SI 操作如下 1 字节 CMPSB 操作 ES DI DS SI DI 1 SI 1 2 字 CMPSW 操作 ES DI DS SI
  • python django(一)学习笔记之二 (python读取EXCL在html展示)

    利用EXCL的数据 进行一个饼状的分析图 直接了当的看出在市场的份额的占比多少 承接第一天的内容和开发环境 以及目录 在settings py 中 加入 INSTALLED APPS ch01 apps Ch01Config django
  • Docker安装操作常用服务器软件

    1 查看centos版本 rpm q centos release 2 更新yum yum update y 3 删除以前版本的docker yum remove docker docker client docker client lat
  • k8s 证书生成 cfssl

    命令下载工具 傻瓜式执行 wget https pkg cfssl org R1 2 cfssl linux amd64 wget https pkg cfssl org R1 2 cfssljson linux amd64 wget ht
  • Verdi实现信号的平移

    在Verilog System verilog中 xxx可以实现延迟指定时间的功能 而在使用verdi查看信号波形并进行分析时 同样也可以实现类似的功能 注 这种信号平移是有其应用场景的 例如 在某些仿真模型中 为了模拟实际的信号延迟 信号
  • 极光笔记

    随着全球化进程的深入 跨境数据传输与存储问题已经变得愈发重要 推送服务的数据中心节点选择不仅关乎数据访问速度和用户体验 同时也直接牵扯到数据合规性和安全保障 EngageLab Push深知这一点 为了满足更多国际客户和全球用户触达需求 我
  • java resultset获取列数_Java语言如何获取ResultSet的行数和列数

    ResultSet接口表示在数据库的数据表中查询的结果集 ResultSet 对象具有指向其当前数据行的指针 最初 指针被置于第一行之前 Java没有提供直接返回ResultSet行数的函数 或方法 如果想知道ResultSet的行数 有以
  • 图像去噪的快速入门学习

    1 理论基础 数学基础 高等数学 线性代数 概率统计 矩阵论 数值分析等 信号处理 统计信号处理 统计学习理论等 2 文献资料阅读 常用的数据库 IEEE IEE Electronic Library Elsevier SpringerLi
  • Python(4) Numpy,控制台完全输出ndarray

    import numpy as np np set printoptions threshold np nan print ndarray 当ndarray里面的存放的数据维度过大时 在控制台会出现不能将ndarray完全输出的情况 中间部
  • NDIS网络数据监控程序NDISMonitor(3)-----NdisMonitro应用程序(C#)

    转载请标明是引用于 http blog csdn net chenyujing1234 欢迎大家拍砖 1 主窗口Load函数ctrlForm Load 1 先调用GetExtensions来获得运行目录下bin目录中的所有文件 通过载入为A
  • 【maven】The forked VM terminated without saying properly

    1 概述 转载 https blog csdn net zhglance article details 53695653 一直在使用Maven开发项目 最近遇到了一个让人头疼的问题 在网上搜索竟然没有找到中文描述的解决方式 自己找了英文网
  • linux内核中GPIO的使用(一)--IO内存

    一 相关概念 使用IO内存将物理地址映射为虚拟地址 再通过对虚拟地址的操作来控制硬件 所谓的IO内存是指一种编址方式 不同cpu平台使用的编址方式不同 一种是 IO内存 方式 也叫统一编址方式 是指内存和外设的地址是在同一个地址空间上的 如