本发明涉及linux并口驱动开发技术领域,更具体而言,涉及一种基于阻塞接收机制的嵌入式linux并口驱动开发方式。
背景技术:
近些年来,随着嵌入式的快速发展,嵌入式linux系统以其源码开放、系统本身奇特的特性在嵌入式开发领域中抢占着重要的地位。其实linux系统本身拥有好多的通用设备驱动程序支持,并且针对具体的开发应用要求用户须要添加自己的程序(如机制的联合、添加合同解析等),通用的设备驱动并不适用。现今多数嵌入式设备中针对并口数据的实时采集和处理通用的技术方式是采用在驱动层中完成数据包的采集、应用层对数据包进行处理的开发方式,具体开发模式和存在的问题如下:
(1)通用的驱动层中完成并口数据包采集方式是:在驱动层为了增加cpu占有率,采用并口中断、休眠和唤起等机制实现数据的接收,通常流程是:驱动层read并口读取函数首先步入休眠,之后在中断将至的情况下接收数据并进行中断唤起read进程,并将单字节数据/数据包上传给应用层。这些机制会造成以下冲突:因为驱动层read读取之前接收的数据或数据包上传给应用层之前都是出于休眠状态嵌入式linux 串口驱动,只有在中断接收数据情况下才将read进程唤起,当read函数被唤起后正打算从缓存区读取数据时,中断又接收到新的数据,将新的数据储存于read函数读取的缓存区中,这样写入和读取缓存区的时序冲突而被新的数据覆盖,造成read读取出现丢帧。在并口通讯速度较高的情况下,因为冲突导致通讯丢帧问题更严重;
(2)应用层对并口数据的读取通过调用驱动层的read函数,通常情况下采用无阻塞读取方式(如定时查询、实时查询)或则阻塞读取方式(接收队列被挂起直到数据或数据包接收完成),非阻塞定时查询才能解决(1)所述的机制冲突问题linux操作系统介绍,会增加接收数据的实时性;非阻塞实时查询和阻塞读取方式须要驱动层相应机制配合,同样会造成(1)所述的问题;
(3)对并口数据包进行处理(如检查数据帧头和帧尾、检查数据宽度和校准位等)的开发方式通常是在应用层进行开发,而并口数据都须要经过linux内核层传送,减少了数据的实时性能,尤其是当应用层数据处理过后错误的情况下仍需重新对并口进行收发,应用层再一次调用linux内核层驱动,必然会再度增加数据的实时性能。
基于此,有必要发明一种稳定性高、实时性强的嵌入式linux并口驱动开发方式,以解决linux并口驱动中通讯丢帧问题,提升并口数据采集和处理的实时性能。
技术实现要素:
为了克服现有技术中所存在的不足linux修改文件名,本发明提供一种基于阻塞接收机制的嵌入式linux并口驱动开发方式,该方式稳定性高、实时性强,解决了linux并口驱动中通讯丢帧的问题,而且增强了并口数据采集和处理的实时性能。
为了解决上述技术问题,本发明所采用的技术方案为:
一种基于阻塞接收机制的嵌入式linux并口驱动开发方式,根据以下步骤进行:步骤一、采用字符型设备框架,设计linux并口驱动程序;步骤二、设计接收数据缓存区;步骤三、设计read函数阻塞读取机制;步骤四、设计数据包实时处理机制。
所述步骤一具体为:
1)定义一个结构体file_operationsmyuart_fops,并向结构体中添加open、read、write、close、ioctl函数;
2)定义设备名称嵌入式linux 串口驱动,并向内核注册该设备;
3)定义并口寄存器并进行虚拟地址映射,配置寄存器和引脚;
4)申明并口休眠等待队列,在open函数中初始化,并在open函数中申请并口接收中断号,初始化并口配置,初始化休眠等待队列,使其能接收中断;
5)编撰write函数:判定当前发送缓存区是否为空,之后即将发送的数据写入发送缓存区,发送数据;循环上述步骤,直到发送完指定的发送数据宽度tx_count。
所述步骤二具体为:
1)定义缓存区结构体rx_fifo,成员为:缓存区宽度fifo_size、缓存区起始偏斜地址fifo_in、缓存区结束偏斜地址fifo_out;fifo_out-fifo_in=rx_count,rx_count为并口驱动当前接收的数据宽度;
2)设计接收缓存区环型储存模式:
当(fifo_size-fifo_out)≥app_rx_count,说明剩余缓存区空间可以缓存app_rx_count厚度数据,初始化fifo_out=fifo_in,并口中断仍然处于接收状态,一旦有数据就装入缓存区,进行下一步判定;
当(fifo_size-fifo_out)
所述步骤三具体为:
1)linux并口驱动接收采用中断+休眠/唤起机制进行数据的实时接收,驱动层read函数采用阻塞读取机制以配合应用层非阻塞实时查询read读取的实时调用;
2)设置好环型缓存区后,驱动层中断函数每接收一个字节数据装入rx_fifo缓存区;驱动层read函数中采用如下阻塞机制和数据包实时处理机制:
①先判定当rx_count≥app_rx_count,即并口当前接收的数据宽度小于或等于应用层须要读取的数据宽度,直接读取缓存区的数据,有效防止驱动层read函数只有休眠后被中断唤起能够读取上传数据、中断接收数据的时序冲突;
②当rx_count<app_rx_count,即并口当前接收的数据宽度大于应用层须要读取的数据宽度,才能让read进程休眠,这时,read函数没有数据的读取和上传,只有等到rx_count≥app_rx_count才去执行①步骤。
所述步骤四具体为:驱动层read读取缓存区接收的数据后,进行数据包解析,假如数据正确,则通过copy_to_user函数将解析后的数据传递到应用层read函数,假若数据不正确,调用驱动层write函数再一次发送之前的信息,通过read函数再一次解析接收数据,假如数据仍不正确,read函数向应用层会发送接收错误信息。
与现有技术相比,本发明所具有的有益疗效为:
其二,与现有的阻塞并口驱动开发技术相比,本发明通过采用环型缓存机制和read阻塞读取判定机制,解决了驱动层read函数被调用过程中和中断之间的时序冲突而引发的数据丢帧问题;其一,与现有的非阻塞并口驱动开发技术相比,本发明通过应用程序实时调用read读取函数,驱动层采用read阻塞读取判定机制和中断休眠机制实时接收并口数据,解决了非阻塞并口驱动开发技术中所采用的应用层定时读取函数引起的实时性差问题,或则应用层实时接收数据引起的cpu占用率高等问题;其一,与传统的应用层解析数据包机制相比,本发明在驱动层read函数采用两次解析数据,提升了数据通讯确切率和实时处理数据性能。
综上所述,本发明所述的一种基于阻塞接收机制的嵌入式linux并口驱动开发方式基于原有的中断+休眠/唤起方式进行的优化和改进,有效解决了阻塞并口驱动开发技术中的丢帧问题和非阻塞并口驱动开发技术中的实时性差等问题,提升了并口通讯的稳定性和实时性。
附图说明
图1为linux并口驱动阻塞机制流程图;
图2为linux并口驱动中断接收流程图。
图中:
app_rx_count为应用层read函数读取并口接收的数据宽度;
rx_count为并口驱动当前接收的数据宽度;
fifo_in为环型缓冲区接收数据之前的起始偏斜地址;
fif0_out为环型缓冲区接收一定数据宽度的结束偏斜地址;
fifo_size为环型缓冲区大小;
ev_press为中断标志位;
rx_queue为接收等待队列。
具体施行方法
下边将结合附图对本发明作进一步详尽的描述,使本发明所记载的方案愈发容易理解。
如图1-图2所示,本发明公开了一种基于阻塞接收机制的嵌入式linux并口驱动开发方式,该方式是采用如下步骤实现的。
步骤一、linux并口驱动程序采用字符型设备框架设计,即:
1)定义一个结构体file_operationsmyuart_fops,并向结构体中添加open、read、write、close、ioctl函数;
2)定义设备名称,并向内核注册该设备;
3)定义并口寄存器并进行虚拟地址映射,配置寄存器和引脚;
4)申明并口休眠等待队列,在open函数中初始化,并在open函数中申请并口接收中断号,初始化并口配置,初始化休眠等待队列,使能接收中断;
5)编撰write函数:判定当前发送缓存区是否为空,之后即将发送的数据写入发送缓存区,发送数据;循环上述步骤,直到发送完指定的发送数据宽度tx_count。
步骤二、设计接收数据缓存区,如图1所示,即:
1)定义缓存区结构体rx_fifo,成员为:缓存区宽度fifo_size、缓存区起始偏斜地址fifo_in、缓存区结束偏斜地址fifo_out。
2)设计接收缓存区环型储存模式:
当(fifo_size-fifo_out)≥app_rx_count,说明剩余缓存区空间可以缓存app_rx_count宽度数据,初始化fifo_out=fifo_in,并口中断仍然处于接收状态,一旦有数据就装入缓存区,进行下一步判定;
当(fifo_size-fifo_out)
通过设计环型储存区,便捷了驱动层read函数缓存读取和中断函数的接收数据,环型储存机制保证储存空间的重复借助和储存数据的不遗失。
步骤三、设计read函数阻塞读取机制,如图1所示,即:
1)linux并口驱动接收采用中断+休眠/唤起机制进行数据的实时接收,如图2所示,以减少cpu的占用率。驱动层read函数采用阻塞读取机制以配合应用层非阻塞实时查询read读取的实时调用,以提升并口接收的实时性。
2)设置好环型缓存区后,驱动层中断函数每接收一个字节数据装入rx_fifo缓存区。因为应用层read函数仍然在实时调用驱动层read函数,因而驱动层read函数中采用如下阻塞机制和数据包实时处理机制:
①先判别当rx_count≥app_rx_count,即并口当前接收的数据宽度小于或等于应用层须要读取的数据宽度,直接读取缓存区的数据,这样有效地防止了驱动层read函数只有休眠后被中断唤起能够读取上传数据、中断接收数据的时序冲突。
②当rx_count<app_rx_count,即并口当前接收的数据宽度大于应用层须要读取的数据宽度,才能让read进程休眠,大大增加了cpu的使用率。在这些情况下,read函数没有数据的读取和上传,只有等到rx_count≥app_rx_count才去执行①步骤。
步骤四、设计数据包实时处理机制,如图1所示,即:
本发明将数据包解析放置在驱动层而不置于应用层,主要是为了提升应用层向内核调用数据的实时性。驱动层read读取缓存区接收的数据后,进行数据包解析(如判定帧头和帧尾、校验等),假如数据正确,则通过copy_to_user函数将解析后的数据传递到应用层read函数,假若数据不正确,调用驱动层write函数再一次发送之前的信息,通过read函数再一次解析接收数据,假如数据仍不正确,read函数向应用层会发送接收错误信息。通过驱动层两次解析数据,提升了数据的通讯正确率,也防止了应用层read函数多次调用内核层read函数,增强了数据通讯的实时性。
技术特点:
技术总结
本发明涉及Linux并口驱动开发技术领域,更具体而言,涉及一种基于阻塞接收机制的嵌入式Linux并口驱动开发方式。本发明采用字符型设备框架设计Linux并口驱动程序、设计接收数据缓存区、设计read函数阻塞读取机制、设计数据包实时处理机制,有效提升了Linux并口驱动的实时处理数据性能,稳定性高、实时性强,解决了Linux并口驱动开发技术中通讯丢帧的问题。本发明适用于嵌入式Linux设备的并口通讯。
技术研制人员:张炜;史志鹏;安彬;赫旭东;徐衍胜;宋立新
受保护的技术使用者:西安鹏跃电子科技有限公司;大同市轨道交通发展有限公司
技术研制日:2017.05.16
技术公布日:2017.09.15
本文原创地址://gulass.cn/jyzsjsjzdqrs.html编辑:刘遄,审核员:暂无