一种生成串口模拟数据的方法与流程

文档序号:32387761发布日期:2022-11-30 06:56阅读:43来源:国知局
一种生成串口模拟数据的方法与流程

1.本发明涉及串口数据模拟计算领域,特别涉及一种生成串口模拟数据的方法。


背景技术:

2.本部分的陈述仅仅是提供了与本发明相关的背景技术,并不必然构成现有技术。
3.开发串口相关的项目时,有时手头没有足够的串口设备或根本没有相关设备,此时需要通过某种方法来模拟串口数据。
4.发明人发现,当前通用的获取模拟方法为:
5.(1)通过虚拟串口,虚拟出一对串口,一个用于项目程序获取数据,另一个用于数据模拟软件来产生模拟数据,但linux下虚拟串口工具较少且应用不是很方便;
6.(2)通过usb转串口设备,将多个设备的a与a相连,b与b相连,其中一个设备用于项目程序,另外几个用于产生模拟数据,此方法需要多个usb转串口设备,不适合需要大量串口设备的测试场景。


技术实现要素:

7.为了解决现有技术的不足,本发明提供了一种生成串口模拟数据的方法,利用linux的串口驱动,产生模拟数据,不需要第三方工具,也不需要其他真实的串口设备,极大的提高了串口模拟数据的生成效率。
8.为了实现上述目的,本发明采用如下技术方案:
9.本发明第一方面提供了一种生成串口模拟数据的方法。
10.一种生成串口模拟数据的方法,包括以下过程:
11.串口驱动注册,添加串口端口uart_port,其中,uart_port的ops为uart_ops类型;
12.当用户空间调用write通过设备文件向串口驱动发送数据时,调用uart_ops结构中start_tx中设置的回调函数,回调函数中的start_tx设置的函数为serial_start_tx,用户空间发送的数据保存在circ_buf中,如果数据未跨越缓冲区结尾,则按第一形式保护,否则按第二形式保存;对保存的用户空间发送的数据进行校验;
13.在serial_start_tx中,对用户空间发送的数据校验成功后,组装返回报文,对返回报文中的每个字节,依次调用tty_insert_flip_char方法将数据保存到tty_buffer的data缓冲区中;
14.调用tty_flip_buffer_push方法将tty_bufhead.work添加到全局的work队列中,返回报文数据到用户空间。
15.作为可选的一种实现方式,回调函数为:void(*start_tx)(struct uart_port*)。
16.作为可选的一种实现方式,串口驱动注册,包括:
17.使用uart_register_driver方法将串口驱动uart_driver注册到内核。
18.进一步的,uart_driver包括设备名称以及主版本号和次版本号,设备名称为在/dev下显示的名称。
19.进一步的,串口驱动为分层结构,包括核心层tty_core和驱动层tty_driver,tty_driver封装在uart_driver结构中,驱动层tty_driver中包括线路规划。
20.作为可选的一种实现方式,使用uart_add_one_port添加串口端口uart_port。
21.作为可选的一种实现方式,返回报文数据到用户空间,包括:
22.用户空间通过设备文件读取串口数据时,调用串口框架的n_tty_read;
23.发送给用户空间的数据,保存在n_tty_data的read_buf中,如果有数据可读,则将数据发送到用户空间;如果无数据可读,n_tty_read中会休眠,等待调度线程从全局队列中获取数据,并调用flush_to_ldisc将数据从tty_bufhead.tail.data拷贝到tty_struct.disc_data.read_buf。
24.作为可选的一种实现方式,n_tty_read函数,包括:
25.static ssize_t n_tty_read(struct tty_struct*tty,struct file*file,unsigned char__user*buf,size_t nr)。
26.作为可选的一种实现方式,flush_to_ldisc的函数为void flush_to_ldisc(struct work_struct*work),其中,参数work为tty_bufhead中的work。
27.作为可选的一种实现方式,依次调用tty_insert_flip_char方法将数据保存到tty_buffer的data缓冲区中,其中,将返回报文的前两个字节写入缓冲区,包括以下过程:
28.写入第一个字节,1为第一个字节的值,tty_insert_flip_char(tty,1,0);
29.写入第二个字节,3为第二个字节的值,tty_insert_flip_char(tty,3,0);
30.数据组装结束后,调用tty_flip_buffer_push方法将数据发送出去。
31.与现有技术相比,本发明的有益效果是:
32.本发明所述的生成串口模拟数据的方法,利用linux的串口驱动,产生模拟数据,不需要第三方工具,也不需要其他真实的串口设备,极大的提高了串口模拟数据的生成效率。
33.本发明附加方面的优点将在下面的描述中部分给出,部分将从下面的描述中变得明显,或通过本发明的实践了解到。
附图说明
34.构成本发明的一部分的说明书附图用来提供对本发明的进一步理解,本发明的示意性实施例及其说明用于解释本发明,并不构成对本发明的不当限定。
35.图1为本发明实施例提供的串口驱动结构。
36.图2为本发明实施例提供的串口驱动分层结构示意图。
37.图3为本发明实施例提供的串口结构关联示意图。
38.图4为本发明实施例提供的circ_buf数据结构示意图。
具体实施方式
39.下面结合附图与实施例对本发明作进一步说明。
40.应该指出,以下详细说明都是示例性的,旨在对本发明提供进一步的说明。除非另有指明,本文使用的所有技术和科学术语具有与本发明所属技术领域的普通技术人员通常理解的相同含义。
41.需要注意的是,这里所使用的术语仅是为了描述具体实施方式,而非意图限制根据本发明的示例性实施方式。如在这里所使用的,除非上下文另外明确指出,否则单数形式也意图包括复数形式,此外,还应当理解的是,当在本说明书中使用术语“包含”和/或“包括”时,其指明存在特征、步骤、操作、器件、组件和/或它们的组合。
42.在不冲突的情况下,本发明中的实施例及实施例中的特征可以相互组合。
43.实施例1:
44.如图1所示,本发明实施例1提供了一种生成串口模拟数据的方法,包括以下过程:
45.1)注册串口驱动
46.使用uart_register_driver方法将串口驱动uart_driver注册到内核,uart_driver中包含了设备名称(即在/dev下显示的名称)以及主版本号和次版本号,uart_driver结构见图1。
47.串口驱动分层结构(见图2),分为核心层(tty_core)和驱动层(tty_driver),其中uart_driver结构中封装了tty_driver,驱动层中还包含线路规划(line discipline)。
48.2)添加串口端口
49.使用uart_add_one_port添加一个串口端口uart_port,uart_port的ops为uart_ops类型,此类型定义了串口各种操作的回调函数。其中的serial_start_tx是向串口驱动发送数据时,被调用到的方法,也是本发明需要重点关注的方法。
50.3)接收发送到驱动的数据
51.该部分涉及的各种数据结构,及各数据结构中的关联,见图3。
52.当用户空间,调用write通过设备文件(如:/dev/ttys1)向串口驱动发送数据时,会调用uart_ops结构中start_tx中设置的回调函数,该函数的原型为:void(*start_tx)(struct uart_port*)。以下假设start_tx设置的函数为serial_start_tx。用户空间发送的数据,保存在了circ_buf中,circ_buf结构见图4。如果数据未跨越缓冲区结尾,则数据保存方式为图4中的(1)所示,否则为图4中的(2)所示。
53.依上的述,可获取到用户空间所发送的数据,并对数据进行校验。
54.4)返回模拟数据
55.在serial_start_tx中,对用户空间发送的数据校验成功后,可组装返回报文。对返回报文中的每个字节,依次调用tty_insert_flip_char方法;tty_insert_flip_char最终将数据保存到图3中tty_buffer的data缓冲区中。
56.最后调用tty_flip_buffer_push方法将图3中tty_bufhead.work添加到全局的work队列中。
57.返回报文数据到用户空间的流程如下:
58.用户空间通过设备文件(如:/dev/ttys1)读取串口数据时,会调用到串口框架的n_tty_read。该函数的原型为:static ssize_t n_tty_read(struct tty_struct*tty,struct file*file,unsigned char__user*buf,size_t nr);
59.发送给用户空间的数据,保存在图3中n_tty_data的read_buf中,如果有数据可读,则将数据发送到用户空间;如果无数据可读,n_tty_read中会休眠,等待调度线程从上述全局队列中获取数据,并调用flush_to_ldisc将数据从tty_bufhead.tail.data拷贝到tty_struct.disc_data.read_buf;
60.flush_to_ldisc的原型为void flush_to_ldisc(struct work_struct*work),该函数参数work为tty_bufhead中的work。
61.5)驱动的安装
62.编写makefile脚本,输入make进行编译,编译成功后会生成一个.ko文件;
63.输入insmod name.ko安装驱动,安装成功后会在/dev目录下生成相应的驱动文件。
64.具体的,所述方案提供如下具体示例:
65.s1:注册串口驱动
66.使用uart_register_driver方法将串口驱动uart_driver注册到内核,uart_driver中包含了设备名称(即在/dev下显示的名称)与主、次版本号。
67.s2:添加串口端口
68.使用uart_add_one_port添加一个串口端口uart_port,uart_port的ops为uart_ops类型,此类型定义了串口各种操作的回调函数,其中的serial_start_tx是向串口发送数据时,被调用到的方法,也是本发明需要重点关注的方法。
69.s3:接收发送到驱动的数据
70.处理发送给串口驱动的数据的方法是serial_start_tx,此方法的参数类型为uart_port;
71.uart_port-》state-》xmit保存了发送给串口驱动的数据,通过xmit-》buf和xmit-》tail可遍历出所有的数据;
72.可以将数据保存到局部数组中,以方便后面的使用。接下来可以对收到报文进行校验。
73.s4:返回模拟数据
74.uart_port-》state-》port为tty_port类型,通过tty_insert_flip_char将待发送的报文写入驱动的缓冲区。
75.将返回报文的前两个字节写入缓冲区,可以利用下面的方法:
76.写入第一个字节,1为第一个字节的值;
77.tty_insert_flip_char(tty,1,0);
78.写入第二个字节,3为第二个字节的值;
79.tty_insert_flip_char(tty,3,0);
80.数据组装结束后,调用tty_flip_buffer_push方法将数据发送出去。
81.s5:模拟一条串口线下有多个设备
82.将pkg_buf第0个数据改为snd_buf的第0个数据,此方法的缺点是大多数据情况下,返回的数据都相同。
83.另一种方法是,定义一个全局数组,如(以modbus03功能码为例):
84.char test[][7]={01,03,04,01,0x1d,01,0xfa,02,03,04,01,0x1e,01,0xfb,03,03,04,01,0x1c,01,0xfc};
[0085]
后面根据s3中的从机地址,选择相应的数组数据,计算crc校验码返回数据。
[0086]
s6:驱动的安装
[0087]
编写makefile脚本,输入make进行编译,编译成功后会生成一个.ko文件;
[0088]
输入insmod name.ko安装驱动,安装成功后会在/dev目录下生成相应的驱动文件。
[0089]
以上所述仅为本发明的优选实施例而已,并不用于限制本发明,对于本领域的技术人员来说,本发明可以有各种更改和变化。凡在本发明的精神和原则之内,所作的任何修改、等同替换、改进等,均应包含在本发明的保护范围之内。
当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1