前言

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. Linux Bash Script conditions

    Linux Bash Script conditions shell 编程之条件判断 条件判断式语句.单分支 if 语句.双分支 if 语句.多分支 if 语句.case 语句 refs http:/ ...

  2. TypeScript & Canvas 实现可视化白板

    TypeScript & Canvas 实现可视化白板 https://excalidraw.com/ https://github.com/excalidraw/excalidraw ref ...

  3. js 快速排序 All In One

    js 快速排序 All In One 快速排序 / Quick Sort "use strict"; /** * * @author xgqfrms * @license MIT ...

  4. full stack & front end

    full stack & front end https://github.com/frank-lam/fullstack-tutorial https://github.com/haizli ...

  5. 以太坊手续费上涨,矿工出逃,VAST前景向好!

    根据最新数据显示,以太坊的Gas费用在最近几天大幅飙涨,尤其是在过去2小时内,增幅约20%,一度达到了17.67美元.而这也导致了,许多基于以太坊协议的相关项目无法被生态建设者使用,很多矿工也纷纷出逃 ...

  6. VAST助推NGK公链热度升温,日活超过以太坊!

    在区块链市场,如果说过去是比特币和以太坊的时代,那么现在和未来绝对是NGK的时代. NGK公链的出现,让区块链市场看到了新的希望.它不仅仅是开放的和可编程的,而且是低Gas燃耗的,以及创新共识机制的. ...

  7. django学习-11.开发一个简单的醉得意菜单和人均支付金额查询页面

    1.前言 刚好最近跟技术部门的[产品人员+UI人员+测试人员],组成了一桌可以去公司楼下醉得意餐厅吃饭的小team. 所以为了实现这些主要点餐功能: 提高每天中午点餐效率,把点餐时间由20分钟优化为1 ...

  8. java基础学习——Swing图形化用户界面编程

    原文链接:https://blog.csdn.net/yiziweiyang/article/details/52317240 链接有详细解释,也有例子,以下是个人参照例子实验的代码. package ...

  9. 【Notes_4】现代图形学入门——光栅化、离散化三角形、深度测试与抗锯齿

    光栅化 Viewport Transform(视口变换) 将经过MVP变换后得到的单位空间模型变换到屏幕上,屏幕左边是左下角为原点. 所以视口变换的矩阵 \[M_{viewport}=\begin{p ...

  10. Ability之间或者进程间数据传递之对象(Sequenceable序列化)

    鸿蒙入门指南,小白速来!0基础学习路线分享,高效学习方法,重点答疑解惑--->[课程入口] 这两天51cto上的一个粉丝朋友问了我一个问题,Ability之间使用Sequenceable序列化传 ...