前言

4. LED芯片手册分析

本章节记录实现LED寄存器配置,芯片手册分析。

4.1 内存管理单元MMU

简单介绍一下MMU。

4.1.1 MMU的功能

功能:

  • 虚拟地址翻译为物理地址
  • 管理、保护内存。

不同的进程有各自的虚拟地址空间,某个进程中的程序不能修改另外一个进程所使用的物理地址,以此使得进程之间互不干扰,相互隔离。

作用:

* 保护内存:MMU给一些指定的内存设置了读写权限。存在于页表中。当有程序操作该内存时,MMU会查找页表中的权限继续匹配。

* 实现虚拟地址到物理地址的转换:CPU可以运行在虚拟的内存当中,虚拟内存一般要比实际内存大很多,使得CPU可以运行比较大的应用程序。(原理可百度

4.1.2 TLB的作用

TLB(Translation Lookaside Buffer)。

问题:当只有一级页表进行地址转换的时候,CPU每次读写数据都需要访问两次内存, 第一次是访问内存中的页表,第二次是根据页表找到真正需要读写数据的内存地址; 如果使用两级了表,那么CPU每次读写数据都需要访问3次内存。。。这样就很繁琐。

解决:MMU最先访问TLB,假设TLB中包含可以直接转换此虚拟地址的地址描述符, 则会直接使用这个地址描述符检查权限和地址转换,如果TLB中没有这个地址描述符, MMU才会去访问页表并找到地址描述符之后进行权限检查和地址转换, 然后再将这个描述符填入到TLB中以便下次使用。

4.2 地址转换函数

映射函数:ioremap()

取消映射函数:iounmap()

4.2.1 ioremap函数

函数原型:void __iomem *ioremap(phys_addr_t paddr, unsigned long size)

  • 参数:

    • paddr:被映射的 IO 起始地址(物理地址)。
    • size:需要映射的空间大小,以字节为单位。
  • 返回值:
    • 一个指向 __iomem 类型的指针,当映射成功后便返回一段虚拟地址空间的起始地址。

通过返回的虚拟空间起始地址可以对内存进行读写。为了提高平台的可移植性,建议使用以下读写函数:

unsigned int ioread8(void __iomem *addr)
unsigned int ioread16(void __iomem *addr)
unsigned int ioread32(void __iomem *addr) void iowrite8(u8 b, void __iomem *addr)
void iowrite16(u16 b, void __iomem *addr)
void iowrite32(u32 b, void __iomem *addr)

与以上函数相似的函数:writeb、writew、writel、readb、readw、readl

注意:其中 writexiowritex 的区别是,writex 不进行端序检查。

4.2.2 iounmap函数

函数原型:void iounmap(void *addr)

  • 参数:

    • addr:需要取消 ioremap 映射之后的起始地址(虚拟地址)。

4.3 LED驱动

已知:

  • 以 IMX6 为例。
  • RGB引脚分别为 GPIO1_IO04、GPIO4_IO20、GPIO4_19

    简要步骤:
  1. 查看原理图,分析出 LED 是低电平亮还是高电平亮。找出对应的 GPIO
  2. GPIO 寄存器进行操作:(寄存器表在 《IMX6ULLRM(6ULL用户手册).pdf》 中查找)
    1. 使能时钟:使能 GPIO 对应的时钟;
    2. 引脚复用:设置引脚复用为 GPIO
    3. 引脚属性:配置引脚属性(上下拉、速率、驱动能力);
    4. 控制引脚:控制GPIO引脚,输出高低电平。
  3. 分层、分离:
    1. 上层为系统,模块的出入口函数。
    2. 下层为硬件:分离:
      1. 各种板卡, 提供不同的引脚数据。
      2. 驱动实现。

4.3.1 配置GPIO时钟

寄存器表在 《IMX6ULLRM(6ULL用户手册).pdf》 中查找。

由图可知,GPIO1 的时钟是由寄存器 CCM_CCGR1 中的 [27-26] bit控制。

该寄存器地址为:Address: 20C_4000h base + 6Ch offset = 20C_406Ch

寄存器值配置参考上图。

使能 GPIO1时钟:寄存器 CCM_CCGR1 中的 [27-26] bit 配置为 [27-26]: 0b11

4.3.2 配置引脚复用

配置引脚复用为 GPIO

查看手册 IOMUX 章节。

由上图可以看出,寄存器 IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO04 [3-0] 设置为 0b0101 时。GPIO1_IO04 就配置为 GPIO1 模式。

4.3.3 引脚属性

配置引脚属性。

由上图得,寄存器为 IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO04。地址为 Address: 20E_0000h base + 2F8h offset = 20E_02F8h

分析:

  • HYS(bit16):用来使能迟滞比较器 。
  • PUS(bit15-bit14):用来设置上下拉电阻大小。
  • PUE(bit13):当 IO 作为输入的时候,这个位用来设置 IO 使用上下拉还是状态保持器。
  • PKE(bit12):用来使能或者禁止上下拉/状态保持器功能。
  • ODE(bit11):IO 作为输出的时候,此位用来禁止或者使能开漏输出。
  • SPEED(bit7-bit6):当 IO 用作输出的时候,此位用来设置 IO 速度。
  • DSE(bit5-bit3):当 IO 用作输出的时候用来设置 IO 的驱动能力。
  • SRE(bit0):设置压摆率。

把该寄存器配置为:0x1F838,即为 1 1111 1000 0011 1000

4.3.4 引脚控制

参考 《IMX6ULLRM(6ULL用户手册).pdf》 中的 28.5 GPIO Memory Map/Register Definition 章节。

控制引脚输入还是输出。

由上图可知,GPIO1的数据基地址为 Base address = 0x0209C000

GPIOx_GDIR 地址为 Base address + 4h = 0x0209C004

输出高低电平。

地址为 Base address = 0x0209C000

当该引脚配置为 GPIO OUTPUT MODE 时,即可通过设置该引脚来输出高低电平。

同时,该引脚在 GPIO 模式时,不管 OUTPUT 还是 INPUT。都可以通过读该寄存器值来判断该引脚的高低电平。

【linux】驱动-4-LED芯片手册分析的更多相关文章

  1. Linux驱动之LED驱动编写

    从上到下,一个软件系统可以分为:应用程序.操作系统(内核).驱动程序.结构图如下:我们需要做的就是写出open.read.write等驱动层的函数.一个LED驱动的步骤如下: 1.查看原理图,确定需要 ...

  2. Linux驱动架构之pinctrl子系统分析(一)

    1.前言在嵌入式系统中,许多SoC的内部都包含了pin控制器,通过芯片内部的pin控制器,我们可以配置一个或者一组引脚的状态和功能特性,Linux内核为了统一各SoC厂商的引脚管理,提供了pinctr ...

  3. linux驱动之LED驱动

    通过之前的学习,了解到linux驱动编写的流程是:先通过注册函数注册我们编写的入口函数,然后在入口函数中获取设备号->注册字符设备->自动创建设备节点->获取设备树信息,最后通过销毁 ...

  4. 1.7见识一下什么叫Linux驱动:LED

    1.任何的Linux驱动都有一个装载函数(装载驱动时调用)和一个卸载函数(卸载驱动时调用): 2.装载函数和卸载函数分别通过module_init和module_exit宏指定.

  5. Linux驱动中的platform总线分析

    copy from :https://blog.csdn.net/fml1997/article/details/77622860 概述 从Linux2.6内核起,引入一套新的驱动管理和注册机制:pl ...

  6. linux驱动之LED驱动_1

    步骤: 1.框架 2.完好硬件的操作: a.看原理图.引脚 b.看2440手冊 c.写代码: IO口须要用ioremap映射 我的板子电路例如以下所看到的 1.配置GPBCON 寄存器,配置输出   ...

  7. (55)Linux驱动开发之一驱动概述

                                                                                                      驱动 ...

  8. Linux驱动之按键驱动编写(中断方式)

    在Linux驱动之按键驱动编写(查询方式)已经写了一个查询方式的按键驱动,但是查询方式太占用CPU,接下来利用中断方式编写一个驱动程序,使得CPU占有率降低,在按键空闲时调用read系统调用的进程可以 ...

  9. Linux驱动之按键驱动编写(查询方式)

    在Linux驱动之LED驱动编写已经详细介绍了一个驱动的编写过程,接着来写一个按键驱动程序,主要是在file_operations结构中添加了一个read函数.还是分以下几步说明 1.查看原理图,确定 ...

随机推荐

  1. es6 curry function

    es6 curry function // vuex getters export const getAdsFilterConfig = (state) => (spreader) => ...

  2. JavaScript 注释规范

    JavaScript 注释规范 总原则 As short as possible(如无必要,勿增注释).尽量提高代码本身的清晰性.可读性. As long as necessary(如有必要,尽量详尽 ...

  3. free open movie API all in one

    free open movie API all in one movie API TMDb API The Movie Database https://www.themoviedb.org/docu ...

  4. yapi & mock JSON

    yapi & mock JSON json, body https://hellosean1025.github.io/yapi/documents/mock.html response bo ...

  5. VAST上线后,如何提升NGK算力生态的收益和流动性?

    自比特币诞生以来,"挖矿"一词就成功地步入了大众的视野,也成为了加密货币领域最重要的组成部分之一.无论是早前基于比特币和以太坊为主的算力挖矿,还是逐步进入大众视野的质押挖矿,亦或是 ...

  6. 让 gRPC 提供 REST 服务

    让 gRPC 提供 REST 服务 Intro gRPC 是一个高性能.开源和通用的 RPC 框架,面向移动和 HTTP/2 设计. gRPC 基于 HTTP/2 标准设计,带来诸如双向流.流控.头部 ...

  7. int和Integer的比较详解

    说明: int为基本类型,Integer为包装类型: 装箱: 基本类型---> 包装类型 int ---> Integer 底层源码: .intValue() 拆箱: 包装类型---> ...

  8. Docker Elasticsearch 集群配置

    一:选用ES原因 公司项目有些mysql的表数据已经超过5百万了,各种业务的查询入库压力已经凸显出来,初步打算将一个月前的数据迁移到ES中,mysql的老数据就物理删除掉. 首先是ES使用起来比较方便 ...

  9. 使用OWASP Dependency-Check对应用做个安检

    俗话说"人怕出名猪怕壮",当系统小有名气以后就会被一些黑客盯上,三天两头的用各种漏洞扫描工具做渗透,如果不希望某天你负责的系统因为安全问题而出名,那就提前行动起来吧,这就是今天要讲 ...

  10. 将VMware虚拟机最小化到托盘栏

    版权:本文采用「署名-非商业性使用-相同方式共享 4.0 国际」知识共享许可协议进行许可.   目录 前言 将VMware最小化到托盘栏的方法 1.下载 Trayconizer 2.解压 trayco ...