news 2026/4/17 23:57:18

在泰山派(RK3566)上给ST7789屏幕写SPI驱动,我踩过的那些设备树和DMA的坑

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
在泰山派(RK3566)上给ST7789屏幕写SPI驱动,我踩过的那些设备树和DMA的坑

在RK3566平台为ST7789屏幕开发SPI驱动的实战避坑指南

当一块ST7789 SPI屏幕遇上Rockchip RK3566芯片,看似简单的驱动开发背后隐藏着无数细节陷阱。本文将带你深入设备树配置、DMA优化和SPI时序调校的实战现场,还原从零搭建显示系统的完整思考路径。

1. 设备树配置:从寄存器映射到引脚复用的精确控制

设备树作为硬件描述的核心载体,其正确性直接决定驱动能否正常识别设备。在RK3566平台上,SPI控制器的设备树节点继承自RK3568设计,但需要特别注意以下几点:

1.1 SPI控制器基础配置解析

Rockchip SPI控制器在设备树中的典型定义如下:

spi3: spi@fe640000 { compatible = "rockchip,rk3066-spi"; reg = <0x0 0xfe640000 0x0 0x1000>; interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>; clocks = <&cru CLK_SPI3>, <&cru PCLK_SPI3>; clock-names = "spiclk", "apb_pclk"; dmas = <&dmac0 26>, <&dmac0 27>; dma-names = "tx", "rx"; pinctrl-names = "default", "high_speed"; pinctrl-0 = <&spi3m0_cs0 &spi3m0_pins>; pinctrl-1 = <&spi3m0_cs0 &spi3m0_pins_hs>; num-cs = <2>; status = "disabled"; };

关键参数说明:

  • reg:物理地址映射范围,必须与芯片手册完全一致
  • clock-names:主时钟和APB总线时钟的命名约定不可更改
  • dmas:DMA通道分配需要核对芯片资源占用情况

1.2 外设节点定义常见陷阱

为ST7789添加子节点时,开发者常犯的三个典型错误:

&spi3 { status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&spi3m1_cs0 &spi3m1_pins>; spi_lcd@0 { compatible = "sitronix,st7789v"; reg = <0>; // CS0线选择 spi-max-frequency = <32000000>; // 必须明确指定的参数: dc-gpios = <&gpio3 RK_PC1 GPIO_ACTIVE_HIGH>; reset-gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_LOW>; // 显示方向配置 rotation = <90>; }; };

注意:ST7789的dc-gpios(数据/命令选择引脚)必须正确定义,否则无法正常发送命令和数据。

2. SPI通信协议层的精细调校

2.1 时钟极性与时序匹配

ST7789对SPI模式有严格时序要求,设备树中需明确配置:

spi_lcd@0 { spi-cpol; // 时钟极性 spi-cpha; // 时钟相位 spi-3wire; // 3线模式节省IO };

实测发现,当时钟频率超过40MHz时,需要启用Rockchip特有的高速模式:

pinctrl-1 = <&spi3m1_cs0 &spi3m1_pins_hs>;

2.2 数据传输优化技巧

通过对比不同传输方式的效率:

传输方式240x240帧率CPU占用率
单字节传输8 FPS95%
DMA传输32 FPS15%
打包传输(16KB)45 FPS20%

实现高效传输的核心代码:

static void st7789_bulk_write(uint8_t *buf, size_t len) { struct spi_transfer xfer = { .tx_buf = buf, .len = len, .bits_per_word = 8, }; spi_sync_transfer(spi_dev, &xfer, 1); }

3. DMA配置的深水区

3.1 内存对齐与缓存一致性

DMA传输必须保证缓冲区物理地址对齐:

#define DMA_ALIGN 32 uint8_t *fb_buf = kmalloc(BUF_SIZE, GFP_DMA | GFP_KERNEL); if (!fb_buf) { fb_buf = dma_alloc_coherent(&spi_dev->dev, BUF_SIZE, &dma_handle, GFP_KERNEL); }

3.2 中断风暴预防

当DMA传输完成中断过于频繁时,需要调整阈值:

&dmac0 { rockchip,burst-length = <4>; rockchip,burst-threshold = <0>; };

4. 与LVGL框架的协同优化

4.1 双缓冲机制实现

static struct { uint16_t *front_buf; uint16_t *back_buf; struct mutex lock; } display; void lvgl_flush_cb(lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color) { mutex_lock(&display.lock); memcpy(display.back_buf, color, area->x2 * area->y2 * 2); schedule_work(&flush_work); mutex_unlock(&display.lock); }

4.2 垂直同步信号模拟

通过GPIO模拟VSYNC可显著减少撕裂:

static void vsync_thread(void *data) { while (!kthread_should_stop()) { gpio_set_value(vsync_gpio, 1); udelay(1); gpio_set_value(vsync_gpio, 0); msleep(16); // 60Hz刷新率 } }

5. 调试技巧与性能分析

5.1 逻辑分析仪抓包要点

配置示波器触发条件:

  • SPI时钟边沿触发
  • CS下降沿作为触发源
  • 捕获深度至少4K samples

5.2 内核trace工具链

echo 1 > /sys/kernel/debug/tracing/events/spi/enable cat /sys/kernel/debug/tracing/trace_pipe

典型问题诊断流程:

  1. 检查SPI时钟是否正常输出
  2. 验证CS信号切换时机
  3. 确认DC线电平变化符合协议
  4. 测量数据传输实际速率

在完成所有调试后,最终实现的显示系统可以达到:

  • 60FPS全屏刷新
  • 低于5ms的输入延迟
  • 内存占用控制在8MB以内
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/17 23:55:00

【平衡小车进阶】(一)蓝牙串口协议解析与多模式遥控实现(附源码)

1. 蓝牙串口通信基础与硬件选型 玩平衡小车最爽的部分莫过于用手机遥控了&#xff0c;但很多小伙伴卡在蓝牙通信这一关。我当年第一次用HC-05模块时&#xff0c;光是AT指令配置就折腾了一整天。现在回头看&#xff0c;其实只要掌握几个关键点就能少走弯路。 核心硬件选择方面&a…

作者头像 李华
网站建设 2026/4/17 23:53:14

CentOS 7防火墙实战:firewall-cmd端口转发配置与排错指南

1. 端口转发基础概念与原理 端口转发就像邮局的分拣员工作。想象你寄往"大楼A-8080房间"的包裹&#xff0c;被分拣员悄悄改成了"大楼B-8088房间"的地址标签&#xff0c;而收件人完全不知道这个变化。在CentOS 7中&#xff0c;firewalld就是这个智能分拣员&…

作者头像 李华
网站建设 2026/4/17 23:53:14

Golang如何部署到Linux服务器_Golang Linux部署教程【实用】

必须手动下载官方tar.gz包解压至/usr/local/go并配置GOROOT、PATH和GOPROXY&#xff1b;禁用apt等包管理器安装&#xff0c;因其版本滞后、路径混乱且不支持embed/泛型等新特性。直接上结论&#xff1a;别用 apt install golang&#xff0c;必须手动下载官方 go1.22.5.linux-am…

作者头像 李华
网站建设 2026/4/17 23:52:15

一文读懂蓝牙BQB认证:列名 vs. 非列名,你的产品到底该走哪条路?(附SIG官网操作截图)

蓝牙BQB认证实战指南&#xff1a;列名与非列名的智能选择策略 当你的智能硬件产品需要集成蓝牙功能时&#xff0c;BQB认证是绕不开的关键环节。但面对SIG官网上复杂的认证体系&#xff0c;许多技术决策者常常陷入困惑——究竟该选择成本较低的列名方式&#xff0c;还是必须进行…

作者头像 李华
网站建设 2026/4/17 23:50:26

STM32LL库实战入门:从零搭建高效开发环境

1. 为什么选择STM32 LL库开发&#xff1f; 第一次接触STM32 LL库的开发者可能会有疑问&#xff1a;已经有了HAL库和标准库&#xff0c;为什么还要学习LL库&#xff1f;这个问题要从嵌入式开发的效率需求说起。我在实际项目中遇到过这样的情况&#xff1a;使用STM32F030芯片做电…

作者头像 李华