zoukankan      html  css  js  c++  java
  • 【linux】驱动-4-LED芯片手册分析


    前言

    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。都可以通过读该寄存器值来判断该引脚的高低电平。

  • 相关阅读:
    Python标准异常topic
    文件打开的模式和文件对象方法
    python中常用的一些字符串
    zabbix3.2.0beta2 监控模版
    人工智能 --test
    Jenkins 2.7.3 LTS 发布
    Python中的socket 模块
    hibenater返回map
    去掉JavaScript Validator
    properties工具类
  • 原文地址:https://www.cnblogs.com/lizhuming/p/14588172.html
Copyright © 2011-2022 走看看