Linux下自定义虚拟串口驱动

为了解决在海思HI3520D SOC上无多余串口的问题,作者创建了一个虚拟串口驱动,使得内核能欺骗上层应用认为打开的是真实串口。驱动按照Linux UART框架编写,并包含一个设备节点供虚拟串口管理进程使用。经过调试,驱动的select读写功能正常,并实现了异步通知来管理实际串口通信。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前些天给新的板子修改BUG的时候,发现这块板子的串口是接在板载MCU上,我们的主SOC(海思HI3520D)上已经没有多余的串口。于是问题来了… 我们很多的上层应用都是通过串口和传感器通讯的,而且程序都是默认使用SOC上的串口,即打开/dev/ttyAMAx,然后调用Linux的select系统调用去和传感器交互数据的,代码都是C++写的,如果要做到兼容,必须修改基类的方法,这不符合软件的开闭原则…. 所以我打算写一个虚拟串口驱动,让内核去欺骗上层应用:”喂,你打开的真的是一个串口哦”。然后再定义一个虚拟串口管理进程,让这个进程去和单片机通讯进行实际串口收发。

驱动代码

今天先上一个尚未测试的驱动代码,按照linux uart框架写的,并且添加了一个给虚拟串口管理进程使用设备节点。这段代码可能会因为内核版本不同而编译不过,目前在3.16.0-30-generic内核版本下编译成功。

明天开始调试…. (2015-11-28)
今天终于完成了单元测试,虚拟串口的select读写均正常,另外使用了异步通知的方式来通知管理者进程,去更新实际的串口,先上一串调试通过的代码。(2015-12-1)
添加了多串口的支持,修正了资源竞争的问题。(2015-12-2)

/*
* Dummy serial driver by sdliu <sdliu@hongdian.com>
* The real hardware was installed in the MCU which is attached to our SOC(HI3520D).
* This driver depends on a serial manager which will process in the userspace
*/

#include <linux/module.h>
#include <linux/ioport.h>
#include <linux/init.h>
#include <linux/console.h>
#include <linux/sysrq.h>
#include <linux/device.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/serial_core.h>
#include <linux/serial.h>
#include <linux/amba/bus.h>
#include <linux/amba/serial.h>
#include <linux/clk.h>
#include <linux/slab.h>
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/scatterlist.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <linux/tty_flip.h>
#include <linux/circ_buf.h>

#include <asm/io.h>
#include <linux/platform_device.h>

// #include <asm/sizes.h>

#define prt_dbg
#ifdef prt_dbg
#define drintk printk
#else
#define drintk(...) 
#endif

#define DUMMY_SERIAL_NR         4

static int dummy_serial_major = 0;
static int dummy_serial_minor_start = 0;
static struct dummy_uart_port *dummy_array[DUMMY_SERIAL_NR];

unsigned int dummy_serial_nr = 1;
module_param(dummy_serial_nr, uint, S_IRUGO);

// static DECLARE_WAIT_QUEUE_HEAD(dummy_wq); 

int dummy_fasync(int fd, struct file *filp, int mode);

struct dummy_port_data {
    // unsigned char port_idx;

    unsigned long tx_fifo_size;
    unsigned long rx_fifo_size;
};

struct dummy_uart_port {
    struct uart_port port;

    struct dummy_port_data *port_data;

    char type[12];

    unsigned char *tx_fifo;
    unsigned char *rx_fifo;

    unsigned long tx_len;
    unsigned long rx_len;

    unsigned int mctrl;
    unsigned int baud;

    struct ktermios termios;
    struct fasync_struct *async_queue;
    struct semaphore async_sem;

    struct completion manager_activie;
    struct completion write_ok; 
    wait_queue_head_t poll_wq; 

    int manager_reset;

    int is_default_termios : 1;
    unsigned long status;

    struct cdev c_dev;
    int index;
};



static struct class *dummy_class;

static unsigned int dummy_tx_empty(struct uart_port *port)
{

    struct dummy_uart_port *dummy = (struct dummy_uart_port *)port;

    drintk("dummy_tx_empty %d\n", dummy->tx_len);

    // return TIOCSER_TEMT;
    return dummy->tx_len > 0 ? 0 : TIOCSER_TEMT;
}

static void dummy_set_mctrl(struct uart_port *port, unsigned int
<think>好的,用户的问题是关于如何开发或实现虚拟串口转网口的驱动方案。我需要先理解用户的需求。他们可能是在尝试将传统的串口设备通过网络进行连接,比如远程监控或控制设备。需要将串口数据通过网络传输,可能涉及到虚拟串口驱动开发,网络协议处理,以及数据透明传输。 首先,根据用户提供的引用资料,特别是引用[3]提到的串口和网络数据双向透明传输,支持TCP/UDP模式,这可能是一个硬件解决方案。但用户问的是驱动开发,所以可能更偏向软件实现。引用[4]提到使用虚拟串口软件如VSPD,通过虚拟一对串口,再通过小程序转发数据到网络端口。这可能是一个中间件方案,而不是驱动层面的开发。 用户需要的是开发层面的方案,可能需要涉及操作系统内核驱动开发,比如在Windows或Linux下创建虚拟串口,然后将其数据转发到网络。在Linux中,可以使用内核模块如tty层驱动,或者使用用户空间的方案,比如socat工具,但开发的话可能需要更底层的实现。 另外,引用[2]提到Linux串口虚拟化通过网络访问,可能涉及socat或ser2net这样的工具,但用户可能需要自定义开发。对于驱动开发,可能需要了解操作系统如何处理串口设备,如何创建虚拟串口,以及如何将网络套接字与虚拟串口绑定。 还需要考虑不同的工作模式,如TCP Server/Client或UDP,如何处理连接和数据的双向传输。引用[3]中的硬件方案可能已经实现了这些,但软件驱动需要自己处理这些协议。 安全性方面,引用[3]提到的参数配置可能需要通过上位机进行,因此在驱动或应用中提供配置接口也很重要。用户可能需要开发一个配置工具来设置IP、端口、串口参数等。 总结,可能的方案包括:1. 使用现有的虚拟串口软件配合网络转发程序;2. 开发内核驱动实现虚拟串口到网络的桥接;3. 用户态服务程序,使用伪终端或虚拟串口库,结合网络通信。需要根据用户的具体需求和技术栈选择合适的方案,并参考现有的资料和开源项目。</think>### 虚拟串口转网口驱动实现方案 #### 1. **核心实现原理** 虚拟串口转网口的核心是通过软件或硬件将串口数据流与网络协议(TCP/UDP)绑定,实现双向透明传输。具体技术路径包括: - **虚拟串口驱动层**:在操作系统中创建虚拟COM端口(如Windows的VSPD或Linux的`tty`伪终端),模拟物理串口的读写行为[^4][^2]。 - **网络协议栈
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值