天天看点

【linux】驱动-4-LED芯片手册分析

目录

前言

4. LED芯片手册分析

4.1 内存管理单元MMU

4.1.1 MMU的功能

4.1.2 TLB的作用

4.2 地址转换函数

4.2.1 ioremap函数

4.2.2 iounmap函数

4.3 LED驱动

4.3.1 配置GPIO时钟

4.3.2 配置引脚复用

4.3.3 引脚属性

4.3.4 引脚控制

参考:

《IMX6ULLRM(6ULL用户手册).pdf》

李柱明博客:https://www.cnblogs.com/lizhuming/

本文链接:https://www.cnblogs.com/lizhuming/p/14588172.html

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

简单介绍一下MMU。

功能:

将虚拟地址翻译为物理地址。

管理、保护内存。

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

作用:

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

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

【linux】驱动-4-LED芯片手册分析

TLB(Translation Lookaside Buffer)。

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

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

映射函数:<code>ioremap()</code>。

取消映射函数:<code>iounmap()</code>。

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

参数:

paddr:被映射的 IO 起始地址(物理地址)。

size:需要映射的空间大小,以字节为单位。

返回值:

一个指向 __iomem 类型的指针,当映射成功后便返回一段虚拟地址空间的起始地址。

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

与以上函数相似的函数:<code>writeb、writew、writel、readb、readw、readl</code>。

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

函数原型:<code>void iounmap(void *addr)</code>

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

已知:

以 IMX6 为例。

RGB引脚分别为 GPIO1_IO04、GPIO4_IO20、GPIO4_19。

简要步骤:

查看原理图,分析出 LED 是低电平亮还是高电平亮。找出对应的 GPIO。

对 GPIO 寄存器进行操作:(寄存器表在 《IMX6ULLRM(6ULL用户手册).pdf》 中查找)

使能时钟:使能 GPIO 对应的时钟;

引脚复用:设置引脚复用为 GPIO;

引脚属性:配置引脚属性(上下拉、速率、驱动能力);

控制引脚:控制GPIO引脚,输出高低电平。

分层、分离:

上层为系统,模块的出入口函数。

下层为硬件:分离:

各种板卡, 提供不同的引脚数据。

驱动实现。

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

【linux】驱动-4-LED芯片手册分析

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

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

【linux】驱动-4-LED芯片手册分析

寄存器值配置参考上图。

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

配置引脚复用为 GPIO。

查看手册 IOMUX 章节。

【linux】驱动-4-LED芯片手册分析

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

配置引脚属性。

【linux】驱动-4-LED芯片手册分析
【linux】驱动-4-LED芯片手册分析

由上图得,寄存器为 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。

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

控制引脚输入还是输出。

【linux】驱动-4-LED芯片手册分析
【linux】驱动-4-LED芯片手册分析

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

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

输出高低电平。

【linux】驱动-4-LED芯片手册分析

地址为 Base address = 0x0209C000。

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

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