RS485在Linux内核(驱动)及全志T113平台上的实现(7)

接前一篇文章:RS485在Linux内核(驱动)及全志T113平台上的实现(6)

本文内容参考:

RS485 Serial Communications --- The Linux Kernel documentation

Linux环境下RS-485驱动程序开发与实现-CSDN博客

【imx6ul】linux下rs485的使用_linux rs485-CSDN博客

全志R40 串口485 控制操作_485发送控制脚-CSDN博客

Allwinner T113 UART转485_t113 485配置-CSDN博客

RS485自动方向切换模式-CSDN博客

特此致谢!

二、RS485内核(驱动)核心结构

上一回由struct uart_port讲到了其中最为核心的struct uart_ops。上一回也讲到了,该结构是串口驱动三大核心数据结构之一。本回开始对struct uart_ops进行讲解。为了便于理解和回顾,再次贴出struct uart_ops定义,在kernel/linux-5.10-origin/include/linux/serial_core.h中,如下:

cpp 复制代码
/*
 * This structure describes all the operations that can be done on the
 * physical hardware.  See Documentation/driver-api/serial/driver.rst for details.
 */
struct uart_ops {
	unsigned int	(*tx_empty)(struct uart_port *);
	void		(*set_mctrl)(struct uart_port *, unsigned int mctrl);
	unsigned int	(*get_mctrl)(struct uart_port *);
	void		(*stop_tx)(struct uart_port *);
	void		(*start_tx)(struct uart_port *);
	void		(*throttle)(struct uart_port *);
	void		(*unthrottle)(struct uart_port *);
	void		(*send_xchar)(struct uart_port *, char ch);
	void		(*stop_rx)(struct uart_port *);
	void		(*enable_ms)(struct uart_port *);
	void		(*break_ctl)(struct uart_port *, int ctl);
	int		(*startup)(struct uart_port *);
	void		(*shutdown)(struct uart_port *);
	void		(*flush_buffer)(struct uart_port *);
	void		(*set_termios)(struct uart_port *, struct ktermios *new,
				       struct ktermios *old);
	void		(*set_ldisc)(struct uart_port *, struct ktermios *);
	void		(*pm)(struct uart_port *, unsigned int state,
			      unsigned int oldstate);
 
	/*
	 * Return a string describing the type of the port
	 */
	const char	*(*type)(struct uart_port *);
 
	/*
	 * Release IO and memory resources used by the port.
	 * This includes iounmap if necessary.
	 */
	void		(*release_port)(struct uart_port *);
 
	/*
	 * Request IO and memory resources used by the port.
	 * This includes iomapping the port if necessary.
	 */
	int		(*request_port)(struct uart_port *);
	void		(*config_port)(struct uart_port *, int);
	int		(*verify_port)(struct uart_port *, struct serial_struct *);
	int		(*ioctl)(struct uart_port *, unsigned int, unsigned long);
#ifdef CONFIG_CONSOLE_POLL
	int		(*poll_init)(struct uart_port *);
	void		(*poll_put_char)(struct uart_port *, unsigned char);
	int		(*poll_get_char)(struct uart_port *);
#endif
};

前文书曾提到过,struct uart_ops是串口端口操作函数集,也就是UART底层操作函数集。其指向一组硬件相关的操作函数(发送数据、接收数据、设置波特率、中断处理等)。驱动必须实现这些函数才能让串口工作。不同的UART控制器(如8250、ttySAC、pl011等)会实现自己的struct uart_ops实例,内核通过统一的接口调用这些硬件相关的操作,实现 "上层统一、底层差异化" 的串口驱动架构。

下边就来逐一解析相关成员回调函数。

  • unsigned int (*tx_empty)(struct uart_port *);

检查发送缓冲区是否为空。

  • void (*set_mctrl)(struct uart_port *, unsigned int mctrl);

设置调制解调器控制信号。

  • unsigned int (*get_mctrl)(struct uart_port *);

获取调制解调器控制信号。

  • void (*stop_tx)(struct uart_port *);

停止发送。

  • void (*start_tx)(struct uart_port *);

启动(开始)发送。

  • void (*throttle)(struct uart_port *);

暂停接收(限流)。

throttle(字面意为 "节流 / 限流")是struct uart_ops中用于暂停串口数据接收的操作接口,当上层串口缓冲区(tty 层)即将满时,内核会调用这个函数,通知底层驱动停止接收新的数据,防止数据溢出丢失。throttle由内核tty层自动触发,驱动开发者无需主动调用,只需实现底层硬件操作逻辑。

对于支持硬件流控(RTS/CTS)的 UART,throttle除了关闭接收中断,还需控制RTS引脚(拉低),让发送方主动停止发送。

  • void (*unthrottle)(struct uart_port *);

恢复接收(解除限流)。

throttle通常需要和unthrottle成对实现 ------ 只实现throttle会导致串口接收被暂停后无法恢复,数据传输中断。

  • void (*send_xchar)(struct uart_port *, char ch);

发送xChar。

  • void (*stop_rx)(struct uart_port *);

停止接收。

struct uart_ops更多成员的解析,请看下回。

相关推荐
派勤电子2 天前
多路串口工控主板深度解析:适配设备场景、RS485选型规范、性能误区与丢包故障溯源
rs485·工控主板·工控主板选型·多串口工控主板·多路串口主板
csdn_aspnet2 天前
C# 多个串口多个线程发送数据和接收数据
c#·串口·thread·com·serialport
鸿芯微控科技8 天前
MFC通信数据跳变怎么排查?RS485接线、丢帧与流量反馈验证
python·mfc·rs485·质量流量控制器·通信异常
阿钱真强道11 天前
04 极物科技 | 创明RS485窗帘 - 快速接入指南
智能家居·rs485·极物·极物智能·极物科技·创明窗帘·窗帘控制
深念Y12 天前
无头电视盒子改服务器调优记录
linux·运维·服务器·串口·嵌入式·电视盒子·海思
WWJA王文举16 天前
RS485通信超时全面排查:终端电阻、A/B线、DE方向控制、串口参数和Modbus一次讲透
stm32·通信协议·rs485
2401_8534482319 天前
使用 ADC 采样实现 RS485 数据接收与协议显示
rs485·协议解析·差分信号·adc 采样·uart 解析
燕卫博23 天前
借助AI的力量,将 ZYNQ 开发板改造成一个虚拟专用网络网关
人工智能·串口·嵌入式·zynq·reasonix·ser2mcp
Industio_触觉智能1 个月前
RK3576开发板UART驱动实战教程(下),基于触觉智能开发板演示
嵌入式硬件·硬件架构·串口·uart·智能硬件·rs232·rs485
smallerxuan2 个月前
Linux 设备模型、设备管理与设备驱动
linux·设备模型·设备管理·设备驱动