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

原文地址:https://www.cnblogs.com/lizhuming/p/14588172.html