1 LED 驱动基础知识
参考资料:
视频教程:http://dev.t-firefly.com/thread-100406-1-1.html
总结:
RK3399的 GPIO
-
RK3399 的 GPIO 概述
- 共有五组:GPIO0~4,每组 GPIO 中一般有 32 位 IO 引脚:A0A7、B0B7、C0C7、D0D7
- 对于每组 GPIO,有 3 个相关寄存器:
Data Register
(用于输出数据)EXT Data Register
(用于输入数据)Data Dir Register
(输入/输出设置)
-
与 GPIO 相关的三个单元
- CRU:Clock & Reset Unit 时钟和复位单元(使能 GPIO 模块)
- PMU:Power Management Unit 电源管理单元(设置 GPIO0 的模式)
- GRF:General Register Files 通用寄存器文件(设置 GPIO1~4 的模式)
- GPIO:General Purpose Input/Output 通用的输入输出
-
驱动实现步骤
- 通过 CRU 中寄存器使能 GPIO 模块
- 通过 PMU 或 GRF 设置 GPIO 的模式
- 设置 GPIO 本身的寄存器设置引脚方向
- 设置或读取引脚的数据
LED 驱动程序框架
- 总体框架:
- 上层:
leddrv.c
(通用上层,抽象出led_opr
结构体,在下层实现)led_opr
结构体元素包括.init
(初始化) 和.ioctrl
(打开/关闭)
- 下层:
board_rk3399.c
(根据 RK3399 具体引脚实现led_opr
结构体)
- 上层:
关于 RK3399 的 LED 相关寄存器总结:
模块 | 基地址 | 内部寄存器 | 偏移地址 | 备注 |
---|---|---|---|---|
CRU | 0xFF760000 | PMUCRU_CLKGATE_CON1 | 0x0104 | 使能 GPIO0~1 的时钟 |
CRU_CLKGATE_CON31 | 0x037c | 使能 GPIO2~4 的时钟 | ||
PMU | 0xFF310000 | PMUGRF_GPIO0A_IOMUX | 0x00000 | GPIO0A iomux control |
PMUGRF_GPIO0B_IOMUX | 0x00004 | GPIO0B iomux control | ||
PMUGRF_GPIO1A_IOMUX | 0x00010 | GPIO1A iomux control | ||
PMUGRF_GPIO1B_IOMUX | 0x00014 | GPIO1B iomux control | ||
PMUGRF_GPIO1C_IOMUX | 0x00018 | GPIO1C iomux control | ||
GRF | 0xFF770000 | GRF_GPIO2A_IOMUX | 0x0e000 | GPIO2A iomux control |
GRF_GPIO2B_IOMUX | 0x0e004 | GPIO2B iomux control | ||
GRF_GPIO2C_IOMUX | 0x0e008 | GPIO2C iomux control | ||
GRF_GPIO2D_IOMUX | 0x0e00c | GPIO2D iomux control | ||
GRF_GPIO3A_IOMUX | 0x0e010 | GPIO3A iomux control | ||
GRF_GPIO3B_IOMUX | 0x0e014 | GPIO3B iomux control | ||
GRF_GPIO3C_IOMUX | 0x0e018 | GPIO3C iomux control | ||
GRF_GPIO3D_IOMUX | 0x0e01c | GPIO3D iomux control | ||
GRF_GPIO4A_IOMUX | 0x0e020 | GPIO4A iomux control | ||
GRF_GPIO4B_IOMUX | 0x0e024 | GPIO4B iomux control | ||
GRF_GPIO4C_IOMUX | 0x0e028 | GPIO4C iomux control | ||
GRF_GPIO4D_IOMUX | 0x0e02c | GPIO4D iomux control | ||
GPIO | GPIO0: 0xFF720000 GPIO1: 0xFF730000 GPIO2: 0xFF780000 GPIO3: 0xFF788000 GPIO4: 0xFF790000 | GPIO_SWPORTA_DR | 0x0000 | Port A data register |
GPIO_SWPORTA_DDR | 0x0004 | Port A data direction register | ||
GPIO_EXT_PORTA | 0x0050 | Port A clear interrupt register |
2 关于 DTS 设备树的学习总结
参考资料:
视频:https://www.bilibili.com/video/av64817023?from=search&seid=17090770102484605167
相关名词:
- DTS:Device Tree Source
- DTSI:Device Tree Source Include
- FDT:Flattened Device Tree
- OF: Open Firmware
- DTB: Device Tree Blob
- DTC: Device Tree Compile
基本概念:
- 所在目录:
kernel/arch/arm64/boot/dts/
- DTS 由被命名的节点和属性组成
.dts
文件被编译成.dtb
二进制文件,用 DTC 编译- 在开发板中
/proc/device-tree
文件夹下查看设备节点是否添加成功
DTS 添加使用过程:
- 添加新的
.dts
文件 - 修改
Makefile
- 编译设备树
make dtbs
,将 dts 编译为 dtb bootloader
(u-boot)启动内核时,自动加载dtb
文件,展开设备树节点,提供 OF API- 驱动调用节点
设备树语法:
[label:]node-name[@unit-address]{
[properties definitions]
[child nodes]
};
-
节点名称:
<名称> [@<设备地址>]
(名称不超过 31 bits,设备地址可选,用以区分设备,真正地址在reg
属性中指示,“/”表示根节点) -
属性:
- 文本字符串(无结束符):
string-property = "a string"
- 32 位无符号整数 cell:
cell-property = <0xbeef 123 23>
- 二进制数据:
binary-property = [01 23 45]
- 不同数据形式:
mixed-property = "a string", <0xbeef 123 23>, [01 23 45]
- 文本字符串(无结束符):
常见属性:
compatible
:兼容属性,指定了兼容的驱动,是一个字符串列表,实际在代码中匹配model
:用来准确的定义这个硬件是什么reg
:描述地址,reg = <address length address length …>
status
:设置节点状态,“okay”、“disabled”……#address-cells
:限定其子节点reg
中address
字段的长度#size-cells
:限定其子节点reg
中length
字段的长度- 中断信息:
interrupt-controller
、#interrupt-cells
、interrupt-parent
、interrupts
等属性 - 寻找节点 API:
of_find_node_by_path
等 - 获取节点属性 API:
of_find_property
3 理解学习 Camera 驱动架构
参考资料:
- UVC 驱动详解:[https://blog.csdn.net/ds1130071727/article/details/100777723](https://blog.csdn
.net/ds1130071727/article/details/100777723)
整理总结:
-
uvc驱动所在目录:kernel/drivers/media/usb/uvc/
-
uvc驱动分析:
- 分为Video Control Interface和Video Streaming Interface
- VideoControl Interface用于控制,比如设置亮度。它内部有多个Unit/Terminal(在程序里Unit/Terminal都称为entity)
- VideoStreaming Interface用于获得视频数据,也可以用来选择fromat/frame(VS可能有多种format, 一个format支持多种frame, frame用来表示分辨率等信息)
- UVC驱动调用过程:
const struct v4l2_file_operations uvc_fops = { .owner = THIS_MODULE, .open = uvc_v4l2_open, .release = uvc_v4l2_release, .ioctl = uvc_v4l2_ioctl, .read = uvc_v4l2_read, .mmap = uvc_v4l2_mmap, .poll = uvc_v4l2_poll, };
- 提供的ioctl命令有:
VIDIOC_QUERYCAP /* 获取设备支持的操作 */ VIDIOC_G_FMT /* 获取设置支持的视频格式 */ VIDIOC_S_FMT /* 设置捕获视频的格式 */ VIDIOC_REQBUFS /* 向驱动提出申请内存的请求 */ VIDIOC_QUERYBUF /* 向驱动查询申请到的内存 */ VIDIOC_QBUF /* 将空闲的内存加入可捕获视频的队列 */ VIDIOC_DQBUF /* 将已经捕获好视频的内存拉出已捕获视频的队列 */ VIDIOC_STREAMON /* 打开视频流 */ VIDIOC_STREAMOFF /* 关闭视频流 */ VIDIOC_QUERYCTRL /* 查询驱动是否支持该命令 */ VIDIOC_G_CTRL /* 获取当前命令值 */ VIDIOC_S_CTRL /* 设置新的命令值 */ VIDIOC_G_TUNER /* 获取调谐器信息 */ VIDIOC_S_TUNER /* 设置调谐器信息 */ VIDIOC_G_FREQUENCY /* 获取调谐器频率 */ VIDIOC_S_FREQUENCY /* 设置调谐器频率 */