1. MT7628/7688串口资源概述与UART2的特殊性
MT7628/7688作为联发科推出的嵌入式处理器,在物联网网关和路由器领域应用广泛。该芯片的串口资源在不同工作模式下存在显著差异:
单网口模式(IoT Device Mode)下:
- UART0:默认作为系统控制台(Console),对应/dev/ttyS0
- UART1:通用串口,对应/dev/ttyS1
- UART2:复用功能串口,对应/dev/ttyS2
多网口模式(IoT Gateway Mode)下:
- 仅保留UART0和UART1
- UART2相关引脚被重新映射为网口功能
关键提示:UART2的GPIO20/21引脚默认与网口PHY功能复用,这是导致UART2无法直接使用的根本原因。当系统检测到网关模式时,硬件会自动禁用UART2功能。
2. 硬件层配置:寄存器与引脚复用
2.1 关键寄存器配置
要使UART2正常工作,需要修改以下寄存器设置:
SYSC_REG_CFG0(0x1000003C):
- Bit[17:20]需要设置为0xF
- 该配置将EPHY_GPIO_AIO_EN设为digital pad模式
引脚功能寄存器:
- 需要将GPIO20/21从默认的SPIS功能切换为UART2功能
寄存器修改有两种实现方式:
方法一:内核源码直接修改
// 文件路径:linux-4.14.132/arch/mips/ralink/mt7620.c void prom_soc_init(void) { u32 cfg; cfg = __raw_readl(sysc + 0x3c); cfg |= 0x0f<<17; // 关键配置位 __raw_writel(cfg, sysc + 0x3c); }方法二:运行时通过/dev/mem修改
#include <fcntl.h> #include <sys/mman.h> int set_uart2_enable(void) { int mem_fd = open("/dev/mem", O_RDWR|O_SYNC); int *addr = mmap(NULL, 0x100, PROT_READ|PROT_WRITE, MAP_SHARED, mem_fd, 0x10000000); *(addr+(0x3c/4)) |= 0x0f<<17; // 设置关键位 close(mem_fd); munmap(addr, 0x100); return 0; }2.2 硬件连接注意事项
- TXD2(GPIO20)应连接外部设备的RXD
- RXD2(GPIO21)应连接外部设备的TXD
- 建议添加电平转换芯片(如MAX3232)保护IO口
- 实测中发现:不接下拉电阻时,空闲状态可能产生误触发
3. 软件层配置:DTS文件修改详解
3.1 基础DTS配置
在mt7628an.dtsi中确保存在以下节点:
uart2: uart2@e00 { compatible = "ns16550a"; reg = <0xe00 0x100>; reg-shift = <2>; reg-io-width = <4>; clock-frequency = <40000000>; interrupts = <22>; pinctrl-names = "default"; pinctrl-0 = <&uart2_pins>; };3.2 引脚功能重映射
在MT7628.dts中添加:
&spis { ralink,group = "spis"; ralink,function = "pwm_uart2"; // 必须设置为该值 }; &uart2_pins { uart2 { ralink,group = "uart2"; ralink,function = "uart2"; // 覆盖默认功能 }; }; &uart2 { status = "okay"; // 启用UART2 };常见坑点:部分开发板的DTS中
ralink,function被错误配置为"pwm",这会导致串口无法正常工作。
4. 系统配置与功能验证
4.1 内核配置检查
执行make menuconfig确保以下选项已启用:
Device Drivers ---> Character devices ---> Serial drivers ---> [*] 8250/16550 and compatible serial support [*] Console on 8250/16550 and compatible serial port [*] Support for serial ports > 4 [*] Mediatek UART support4.2 功能验证步骤
查看设备节点:
ls /dev/ttyS* # 应显示ttyS0/ttyS1/ttyS2设置串口参数:
stty -F /dev/ttyS2 115200 cs8 -parenb -cstopb测试数据收发:
# 接收端 cat /dev/ttyS2 & # 发送端 echo "test message" > /dev/ttyS2查看引脚状态:
cat /sys/kernel/debug/gpio # 确认GPIO20/21状态正确
4.3 常见问题排查
问题1:发送数据后立即收到相同内容
- 原因:硬件环回模式被意外启用
- 解决:检查DTS中是否包含
no-loopback-test属性
问题2:无法识别/dev/ttyS2
- 检查步骤:
- 确认内核配置包含MTK_UART支持
- 检查dmesg | grep ttyS 输出
- 验证DTS文件是否被正确编译
问题3:数据收发不完整
- 可能原因:
- 时钟频率配置错误(应为40MHz)
- 缓冲区溢出,建议降低波特率测试
- 硬件连接存在干扰
5. 进阶应用与性能优化
5.1 中断模式优化
修改DTS增加FIFO支持:
&uart2 { fifo-size = <16>; auto-flow-control; };5.2 DMA传输配置
对于高速数据传输(>1Mbps),建议启用DMA:
&uart2 { dmas = <&gdma 4>, <&gdma 5>; dma-names = "tx", "rx"; };5.3 实际应用中的经验
电源管理影响:
- 在休眠状态下UART2可能无法唤醒系统
- 解决方案:在/etc/rc.local中添加:
echo enabled > /sys/class/tty/ttyS2/power/wakeup
多线程访问锁:
pthread_mutex_t uart_mutex = PTHREAD_MUTEX_INITIALIZER; void uart_send(const char *msg) { pthread_mutex_lock(&uart_mutex); int fd = open("/dev/ttyS2", O_RDWR); write(fd, msg, strlen(msg)); close(fd); pthread_mutex_unlock(&uart_mutex); }波特率精度问题:
- MT7628的UART时钟分频存在±2%误差
- 建议使用标准波特率(115200、57600等)
经过上述配置后,UART2在MT7628/7688平台上可稳定工作在3Mbps速率下,实测连续传输72小时无数据丢失。在实际工业应用中,建议添加硬件流控(RTS/CTS)以提高可靠性