USB转原生UART_autosuspend_型号兼容

USB转原生UART_autosuspend_型号兼容

NextPF 三大作业实战指南(MTK8788 / Android 15)

平台:MTK8788(SoC = MT6771)/ Android 15 / kernel-6.6

读法:每节先"是什么/为什么"(小白看),再"代码在哪/长啥样"(带全路径+行号),最后"怎么改/怎么测/怎么排错"(专业落地)。


0. 这张图要做的三件事

#原文方针人话难度
1USB-UART → USB去掉"串口转USB"外挂芯片,改用 SoC 原生串口
2确认 SoC UART + 检查并禁用 auto-suspend别让串口自动休眠,否则丢数据高(核心)
3UART 有/无可切换(同一软件)同一镜像,有串口/无串口机器都能跑

1. 名词扫盲

名词大白话
UART串口,TX发RX收两根线,最稳的点对点通信
USB-UART桥接芯片CP2102/FTDI/PL2303,把串口翻成USB插电脑
原生UARTSoC自带串口控制器,不用外挂芯片
8250经典串口寄存器标准,MTK驱动叫8250_mtk
autosuspend闲一会自动断电,串口被休眠会丢字节
pm_runtime内核运行时电源管理,autosuspend归它管
clk时钟硬件心跳,关时钟=省电=停工
APDMAMTK串口搬运工,自动搬数据省CPU
dts/pinctrl设备树/引脚复用
defconfig开关清单:=y编入 =m模块 没写=关
RTS/CTS硬件流控线,防丢包
EFRMTK扩展功能寄存器,控流控

2. 关键文件全路径清单(照着打开)

用途全路径
UART驱动kernel-6.6/drivers/tty/serial/8250/8250_mtk.c
驱动开关kernel-6.6/drivers/tty/serial/8250/KconfigSERIAL_8250_MT6577,L477)
编译挂接kernel-6.6/drivers/tty/serial/8250/Makefileobj-$(CONFIG_SERIAL_8250_MT6577)+=8250_mtk.o
设备树kernel/kernel_device_modules-6.6/arch/arm64/boot/dts/mediatek/mt6771.dts
引脚定义kernel/kernel_device_modules-6.6/include/dt-bindings/pinctrl/mt6771-pinfunc.h
USB配置kernel-6.6/arch/arm64/configs/gki_defconfig
FTDI桥驱动kernel-6.6/drivers/usb/serial/ftdi_sio.c

链路图

open("/dev/ttyS1") → tty框架 → 8250_port.c → 8250_mtk.c → mt6771.dts apuart1 → 硬件 SoC UART @0x11003000

8250_mtk.c 函数行号(已核实)

函数作用
mtk8250_dma_enable155开APDMA
mtk8250_set_flow_ctrl243流控
mtk8250_set_termios306波特率
mtk8250_runtime_suspend429关baud/bus时钟
mtk8250_runtime_resume444开时钟
mtk8250_do_pm455开关口唤醒/挂起
mtk8250_probe_of473取时钟+DMA
mtk8250_probe518开runtime PM
mtk8250_suspend/resume604/628深睡+唤醒中断
mtk8250_of_match648mediatek,mt6577-uart

3. 作业一:USB-UART → 原生 USB

现状(gki_defconfig 已核实)

542: CONFIG_USB_SERIAL=m 543: CONFIG_USB_SERIAL_FTDI_SIO=m # 现在靠FTDI桥

路径:MCU→FTDI芯片→USB→主机。

目标

MCU→SoC apuart→ttyS*,匹配mediatek,mt6577-uart(8250_mtk.c:649)。

dts 节点(mt6771.dts 已核实)

apuart1: serial@11003000 { compatible = "mediatek,mt6577-uart"; reg = <0 0x11003000 0 0x1000>; interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH 0>; clocks = <&clk26m>, <&infracfg_ao INFRACFG_AO_UART1_CG>; clock-names = "baud", "bus"; dmas = <&apdma 2 &apdma 3>; dma-names = "tx", "rx"; };

改:&apuart1 { pinctrl-0=<&uart1_pin>; status="okay"; };,FTDI 留=m兼容旧机。


4. 真实引脚号(mt6771-pinfunc.h 已核实)

信号引脚
URXD1GPIO19PINMUX_GPIO19__FUNC_URXD1
UTXD1GPIO20PINMUX_GPIO20__FUNC_UTXD1
UCTS1GPIO23PINMUX_GPIO23__FUNC_UCTS1
URTS1GPIO24PINMUX_GPIO24__FUNC_URTS1
URXD0GPIO95/96PINMUX_GPIO95__FUNC_URXD0
UTXD0GPIO96/95PINMUX_GPIO96__FUNC_UTXD0

pinctrl 示例:

uart1_pin: uart1-pins { pins { pinmux = <PINMUX_GPIO19__FUNC_URXD1>, <PINMUX_GPIO20__FUNC_UTXD1>; }; };

带流控加 GPIO23/24。


5. 作业二:禁用 autosuspend(核心)

为什么:闲→关baud/bus时钟→来数据来不及上电→丢字节。

源码(已核实)

probe(L584):pm_runtime_set_active+pm_runtime_enable
suspend(L429):while(serial_in DEBUG0)等空闲→关uart_clk/bus_clk
do_pm(L455): 开口get_sync 关口put_sync_suspend
深睡(L604):pinctrl_pm_select_sleep_state+enable_irq_wake(rx_wakeup_irq)

禁法

  • A 验证:echo on>.../power/controlautosuspend_delay_ms=-1
  • B dts不写延时
  • C 改驱动去掉pm_runtime_enable
    查:runtime_status=active,idle后不丢。

6. 作业三:型号兼容

status="okay"/"disabled"overlay 切;驱动内置;应用打不开ttyS1容错。

7. 流控(L243) / 8. DMA(L155)

HW=EFR_HW_FC开CTSI/RTSI;SW=XON1/XOFF1;DMA=dma-names tx/rx需CONFIG_SERIAL_8250_DMA。

9. 排错

现象
无ttyS1status okay+nr_uarts
丢前几字节autosuspend未禁
乱码波特率/引脚
高速丢RTS/CTS或DMA
probe失败“Can’t get uart clock” 时钟名baud/bus

10. 自检

  • echo>/dev/ttyS1收发 [ ] idle后不丢 [ ] active [ ] 双机型同镜像 [ ] dmesg无错