基于GPIO握手和EDMA的UART串口通信方法
技术领域
本发明涉及串口通信领域,特别涉及基于GPIO握手和EDMA的UART串口通信方法。
背景技术
UART是Universal Asynchronous Receiver/Transmitter的缩写,即通用异步接收发送,当其作为DSP的发送侧时,能将DSP待发送的并行数据转换成串行数据并发送到DSP的***设备,当其作为DSP的接收侧时,能将DSP***设备发送过来的串行数据转换成并行数据并接收。由于UART硬件连接简单,通信协议便于实现,在嵌入式***和工业控制***中大量使用。但是传统的串口协议有两个缺陷存在:
1、每次只收发一个数据符号(5~8data bit),如果对每个数据符号都要CPU介入处理,效率非常低。
2、在使用串口来进行突发的数据包传输时,串口通信协议本身没有规定如何划分数据包的边界,需要自行实现数据包的分界。
对于第一个缺陷的解决,主要是通过增加数据缓冲区和DMA机制来减少CPU的介入频率。专利200410100137.0就介绍了这样的一种处理方法。但是该专利对于第二个缺陷并没有给出解决方案。同时该专利通过使用虚拟端口和虚拟FIFO控制器来实现收发包的缓存。这种方法的缺陷在于:
1、限制了使用该技术的DSP设备必须存在一个虚拟端口和一个虚拟FIFO控制器。
2、限制了缓存FIFO必须位于***组件地址中,而不能灵活的使用DSP的L2、DDR等内存位置。
发明内容
本发明的目的在于克服现有技术的缺点与不足,提供基于GPIO握手和EDMA的UART串口通信方法。
本发明的目的通过以下的技术方案实现:
基于GPIO握手和EDMA的UART串口通信方法,包含以下步骤:
S1、指定一块收发数据的缓存;
S2、当使用UART进行数据发送时,利用EDMA将待发送的数据搬移到UART的发送FIFO中,然后由UART发送给对端设备;
S3、EDMA完成数据搬移后,会产生一个中断,在中断服务程序中启动一个T毫秒的定时器;在定时器中断服务程序中通过一个标志位来告知发送端继续发送新的数据包,当数据包已经发送完毕时通知对端设备;
S4、当使用UART进行数据接收时,接收侧在UART初始化过程中配置第一个数据包的接收地址给EDMA,当UART开始进行数据接收时,一旦接收FIFO接收到的数据超过设定的阈值后,UART会产生一个EDMA事件用来通知EDMA,EDMA会自动将接收FIFO中的数据搬移到配置好的接收缓存中;双方约定,当对端设备发送完一个数据包后,对端设备会拉高GPIO N管脚,这时候GPIO N管脚产生一个上升沿事件,通过配置该GPIO N管脚的上升沿事件映射为EDMA事件,该事件会等当前的数据包接收完毕后自动更新EDMA的接收参数,自动配置好下一个数据包的接收地址;然后在EDMA更新完下一个数据包的接收参数后,会在中断服务程序中通过Post一个信号量来通知UART驱动软件对一个完整的数据包进行接收处理。
至此,完成了UART串口数据收发的全过程。
步骤S1中,所述缓存的的缓存地址空间包括DSP芯片内的L2地址、DDR地址、其他能被EDMA访问到的外设地址。
步骤S2中,所述定时器的时长由发送链路上的物理延时决定。
步骤S3中,所述当数据包已经发送完毕时通知对端设备,是通过拉高GPIOM管脚来完成的。这样方便接收端处理。
所述UART,其初始化配置具体如下:
(1)初始化UART寄存器,进行一些最基本的初始化配置;
(2)申请一个信号量用于UART接收时通知CPU取数;
(3)申请两个GPIO管脚资源,两个GPIO管脚分别为GPIO M管脚、GPION管脚,GPIO管脚具备两种功能:当设置其作为输入管脚时,可以读取其相关寄存器获取到当前该管脚的电平状态,当设置其作为输出管脚时,可以设置其相关寄存器来拉高或者拉低该管脚的电平状态;GPIO M管脚用于发送流程,在发送完一个数据包后设置其为高电平状态用于通知接收端芯片,这样就需要配置GPIO M管脚为输出管脚,GPIO N管脚用于接收流程,配置其在上升沿时触发事件,故需要配置该管脚为输入管脚,由对端设备发送完一个完整的数据包后拉高其管脚,是GPIO产生一个事件给EDMA;
(4)配置与UART电性相连的EDMA通道X,用于将待发送的数据搬移到UART发送FIFO,并注册该EDMA通道相对应的中断服务程序,用于发送数据搬移完成后的中断处理;后续每次进入该中断服务程序会启动一个T毫秒长度的定时器,T值由发送FIFO到接收端链路上的物理延时决定;该定时主要用于保证发送FIFO的数据完全发送到接收端;同时在定时器达到计数时间后会触发一个定时中断来通知发送侧CPU该数据包已经完成发送,释放CPU资源。并在该中断服务程序中拉高GPIO M管脚为高电平,通知接收端一个完整的包发送完毕;
(5)配置UART电性相连的EDMA通道Y,用于将UART接收FIFO中的数据搬移到CPU预先设置好的接收缓冲区中,同时在该步骤中配置好第一个接收数据包的首地址;
(6)配置GPIO N管脚电性相连的EDMA通道Z,同时将下一个数据包接收段的目的地址提前配置好,并注册该EDMA通道相对应的中断服务程序,用于将下一个数据包的地址更新到EDMA通道Y,同时根据通道Y中的EDMA接收参数获取到当前数据包的长度信息;
(7)初始化接收缓冲区的读写指针为该缓冲区的起始位置,写指针用于硬件接收到一个数据包后指示下一个可用来接收包的缓冲区位置,由EDMA通道Z的中断服务程序维护;读指针用于CPU高层软件读取一个待接收的包,读取完毕后更新到下一个等待读取的数据包位置;通过软硬件分别维护读写指针,能避免数据包的读取错误,并且根据当前的软件使用场景,可以合理的增加或者减少缓冲区的大小,提供更好的数据存储服务;
(8)使能EDMA通道X、EDMA通道Y、EDMA通道Z,使其处于工作状态,从而完成整个初始化的配置。
步骤S2中,所述使用UART进行数据发送,具体为:
(1)CPU应用程序作为数据发送的源头,首先配置好发送EDMA通道X的发送参数,源地址为待发送的数据缓冲区,目的地址为UART发送FIFO;
(2)手动触发EDMA通道X进行搬移:EDMA每次搬移N Byte数据到发送FIFO后,UART将发送FIFO中的数据依次发往对端设备,当FIFO为空后会自动触发EDMA通道X进行下一个NByte数据的搬移,直到当前配置好一个数据包的所有数据搬移完毕;
(3)当前数据包的所有数据搬移完毕后EDMA通道X会产生一个完成中断,调用事先注册的中断服务程序;该中断服务程序会启动一个T毫秒长度的定时器,T值由发送FIFO到接收端的物理链路延时决定;该定时主要用于保证发送FIFO的数据完全发送到接收端;
(4)在定时器达到T毫秒后会触发一个定时中断来通知发送侧CPU该数据包已经完成发送,并在该中断服务程序中拉高GPIO M管脚为高电平,通知接收端一个完整的数据包发送完毕。方便接收端对接收包的划分处理;
整个UART数据发送流程中,CPU完成第一步后,后续的操作由各外设模块配合中断自动完成整个数据包的发送以及通知功能,无需CPU进行过多的干涉,操作简单,节省CPU资源。
步骤S4中,所述使用UART进行数据接收,具体为:
(1)对端设备开始发送数据包,UART硬件开始接收数据,当UART接收FIFO中的数据长度超过指定的阈值后,会产生一个事件通知EDMA通道Y来进行数据的搬移,EDMA通道Y会将接收FIFO中的数据搬移到接收缓冲区,并等待下一次事件的产生;
(2)如果接收包的长度大于设定值,重复步骤(1)至接收包的长度小于设定值;当对端设备发送完一个数据包的数据后,设置GPIO N管脚状态为高电平,这时会产生一个EDMA事件从而触发GPIO N管脚对应的EDMA通道Z进行EDMA通道Y接收数据包参数的更新,如果当前的数据包还未接收完毕,则会等待当前数据包接收完毕后才会将下一个数据包的接收参数更新到通道Y;
(3)当接收参数更新完毕后,会产生一个完成中断,在中断服务程序中通过查询接收通道Y的EDMA接收长度参数(该参数在前面的搬移时要注意避免被覆盖)来获取当前已经接收包的长度信息并更新该长度信息为下一个数据包的待接收初始状态,然后更新接收缓冲区的写指针,同时将该写指针对应的下一个数据包的指针更新到EDMA通道Z的相应位置;
(4)将初始化配置中申请的信号量进行POST操作,用于通知CPU进行新的数据包接收;
(5)CPU在Pend中等待第四步释放的信号量,当收到Post信号量后,得知有一个新的数据包等待接收,接收完后更新接收缓冲区的读指针到下一个待接收包的位置。
整个接收过程中,CPU只需要在Pend中等待信号量的释放,从而获取到当前待接收的完整数据包,而不需要CPU再去判断是否一个完整的包接收完毕,流程操作简单,无需CPU过度干涉,并极大提升了UART的通信效率,并节省了CPU的资源。
本发明的实现需要用到3个EDMA通道、分别绑定到UART串口发送、UART串口接收、GPIO管脚N,本文对这3个EDMA通道分别命名EDMA通道X、EDMA通道Y、EDMA通道Z以示区分,这样通过配置EDMA的参数就能自动实现相关的搬移功能。同时也需要使用到2个GPIO管脚,分别命名GPIO M管脚、GPIO N管脚。GPIO M管脚用于UART发送流程,用来通知对端设备一个完整的包已经发送完毕。GPIO N管脚用于UART接收流程,接收对端发来的数据发送完成信号,DSP能通过该信号来完成一次接收包的分割。还需要使用一个信号量,信号量可以用来对一块共享的资源进行互斥操作、也能完成消息的通知。在UART初始化的过程中申请一个信号量,在接收数据的时候通过Pend信号量来等待接收中断服务程序中Post信号量,当驱动软件等到一个信号量后就可以进行相关处理。
本发明与现有技术相比,具有如下优点和有益效果:
1、本发明通过使用EDMA进行数据搬移,减少了UART串口收发数据时需要CPU频繁介入的问题,并通过GPIO握手来实现接收包的自动分割和收发包状态通知功能,提高了UART串口通信的效率,减低了CPU资源的消耗。
2、EDMA是Enhanced Direct Memory Access的缩写,即增强型直接存储访问,能够完成数据快速搬移,工作过程无需CPU介入。GPIO是General Purpose Input Output的缩写,即通用目的输入输出,一般的DSP设备中GPIO有多个管脚,每个管脚可以设置其作为输入管脚还是输出管脚,当作为输入管脚时,能够通过查询相应管脚的状态寄存器来知道改管脚的电平状态,当作为输出管脚时,能通过写寄存器来配置其为高电平还是低电平,GPIO管脚还能产生DSP核中断和EDMA事件,用于完成相应的功能。本发明提供了一种基于GPIO握手和EDMA的串口通信办法,解决了传统串口协议中的缺陷a与缺陷b所阐述的问题,并解决了专利200410100137.0所存在的缺陷a/b所描述的问题,充分利用DSP内部的外设资源,提高了串口通信的效率,降低了对CPU资源的消耗。
3、本发明充分利用DSP上EDMA、GPIO资源来配合UART进行收发数据通信,通过利用EDMA功能来自动完成UART收发FIFO到外部数据缓冲区之间的数据搬移,而无需CPU频繁介入。同时通过GPIO握手信号来通知接收端进行数据包的接收,并能快速的区分接收数据包的边界和自动更新下一个接收包的地址。这样就极大的提升了使用UART串口的通信效率、减少UART收发数据包时频繁地去打断CPU的处理,能提高CPU资源的利用率。同时该方案通过使用GPIO信号与对端设备进行约定,在一定程度上提升了对端设备使用UART接收的便利性,从而在整个***层面上提升了使用UART串口通信的工作效率。
附图说明
图1为UART初始化配置的流程图。
图2为整个数据交互的流程图。
具体实施方式
下面结合实施例及附图对本发明作进一步详细的描述,但本发明的实施方式不限于此。
基于GPIO握手和EDMA的UART串口通信方法,包含以下步骤:
S1、指定一块收发数据的缓存;
所述缓存的的缓存地址空间包括DSP芯片内的L2地址、DDR地址、其他能被EDMA访问到的外设地址;
S2、当使用UART进行数据发送时,利用EDMA将待发送的数据搬移到UART的发送FIFO中,然后由UART发送给对端设备;
所述定时器的时长由发送链路上的物理延时决定;
如图2,所述使用UART进行数据发送,具体为:
(1)CPU应用程序作为数据发送的源头,首先配置好发送EDMA通道X的发送参数,源地址为待发送的数据缓冲区,目的地址为UART发送FIFO;
(2)手动触发EDMA通道X进行搬移:EDMA每次搬移N Byte数据到发送FIFO后,UART将发送FIFO中的数据依次发往对端设备,当FIFO为空后会自动触发EDMA通道X进行下一个NByte数据的搬移,直到当前配置好一个数据包的所有数据搬移完毕;
(3)当前数据包的所有数据搬移完毕后EDMA通道X会产生一个完成中断,调用事先注册的中断服务程序;该中断服务程序会启动一个T毫秒长度的定时器,T值由发送FIFO到接收端的物理链路延时决定;该定时主要用于保证发送FIFO的数据完全发送到接收端;
(4)在定时器达到T毫秒后会触发一个定时中断来通知发送侧CPU该数据包已经完成发送,并在该中断服务程序中拉高GPIO M管脚为高电平,通知接收端一个完整的数据包发送完毕。方便接收端对接收包的划分处理;
整个UART数据发送流程中,CPU完成第一步后,后续的操作由各外设模块配合中断自动完成整个数据包的发送以及通知功能,无需CPU进行过多的干涉,操作简单,节省CPU资源。
S3、EDMA完成数据搬移后,会产生一个中断,在中断服务程序中启动一个T毫秒的定时器;在定时器中断服务程序中通过一个标志位来告知发送端继续发送新的数据包,当数据包已经发送完毕时通知对端设备;
所述当数据包已经发送完毕时通知对端设备,是通过拉高GPIO M管脚来完成的;这样方便接收端处理;
S4、当使用UART进行数据接收时,接收侧在UART初始化过程中配置第一个数据包的接收地址给EDMA,当UART开始进行数据接收时,一旦接收FIFO接收到的数据超过设定的阈值后,UART会产生一个EDMA事件用来通知EDMA,EDMA会自动将接收FIFO中的数据搬移到配置好的接收缓存中;双方约定,当对端设备发送完一个数据包后,对端设备会拉高GPIO N管脚,这时候GPIO N管脚产生一个上升沿事件,通过配置该GPIO N管脚的上升沿事件映射为EDMA事件,该事件会等当前的数据包接收完毕后自动更新EDMA的接收参数,自动配置好下一个数据包的接收地址;然后在EDMA更新完下一个数据包的接收参数后,会在中断服务程序中通过Post一个信号量来通知UART驱动软件对一个完整的数据包进行接收处理。
如图2,所述使用UART进行数据接收,具体为:
(1)对端设备开始发送数据包,UART硬件开始接收数据,当UART接收FIFO中的数据长度超过指定的阈值后,会产生一个事件通知EDMA通道Y来进行数据的搬移,EDMA通道Y会将接收FIFO中的数据搬移到接收缓冲区,并等待下一次事件的产生;
(2)如果接收包的长度大于设定值,重复步骤(1)至接收包的长度小于设定值;当对端设备发送完一个数据包的数据后,设置GPIO N管脚状态为高电平,这时会产生一个EDMA事件从而触发GPIO N管脚对应的EDMA通道Z进行EDMA通道Y接收数据包参数的更新,如果当前的数据包还未接收完毕,则会等待当前数据包接收完毕后才会将下一个数据包的接收参数更新到通道Y;
(3)当接收参数更新完毕后,会产生一个完成中断,在中断服务程序中通过查询接收通道Y的EDMA接收长度参数(该参数在前面的搬移时要注意避免被覆盖)来获取当前已经接收包的长度信息并更新该长度信息为下一个数据包的待接收初始状态,然后更新接收缓冲区的写指针,同时将该写指针对应的下一个数据包的指针更新到EDMA通道Z的相应位置;
(4)将初始化配置中申请的信号量进行POST操作,用于通知CPU进行新的数据包接收;
(5)CPU在Pend中等待第四步释放的信号量,当收到Post信号量后,得知有一个新的数据包等待接收,接收完后更新接收缓冲区的读指针到下一个待接收包的位置;
整个接收过程中,CPU只需要在Pend中等待信号量的释放,从而获取到当前待接收的完整数据包,而不需要CPU再去判断是否一个完整的包接收完毕,流程操作简单,无需CPU过度干涉,并极大提升了UART的通信效率,并节省了CPU的资源。
至此,完成了UART串口数据收发的全过程。
图1描述了使用UART串口初始化的主要资源配置情况,如图1,所述UART,其初始化配置具体如下:
(1)初始化UART寄存器,进行一些最基本的初始化配置;
(2)申请一个信号量用于UART接收时通知CPU取数;
(3)申请两个GPIO管脚资源,两个GPIO管脚分别为GPIO M管脚、GPION管脚,GPIO管脚具备两种功能:当设置其作为输入管脚时,可以读取其相关寄存器获取到当前该管脚的电平状态,当设置其作为输出管脚时,可以设置其相关寄存器来拉高或者拉低该管脚的电平状态;GPIO M管脚用于发送流程,在发送完一个数据包后设置其为高电平状态用于通知接收端芯片,这样就需要配置GPIO M管脚为输出管脚,GPIO N管脚用于接收流程,配置其在上升沿时触发事件,故需要配置该管脚为输入管脚,由对端设备发送完一个完整的数据包后拉高其管脚,是GPIO产生一个事件给EDMA;
(4)配置与UART电性相连的EDMA通道X,用于将待发送的数据搬移到UART发送FIFO,并注册该EDMA通道相对应的中断服务程序,用于发送数据搬移完成后的中断处理;后续每次进入该中断服务程序会启动一个T毫秒长度的定时器,T值由发送FIFO到接收端链路上的物理延时决定;该定时主要用于保证发送FIFO的数据完全发送到接收端;同时在定时器达到计数时间后会触发一个定时中断来通知发送侧CPU该数据包已经完成发送,释放CPU资源。并在该中断服务程序中拉高GPIO M管脚为高电平,通知接收端一个完整的包发送完毕;
(5)配置UART电性相连的EDMA通道Y,用于将UART接收FIFO中的数据搬移到CPU预先设置好的接收缓冲区中,同时在该步骤中配置好第一个接收数据包的首地址;
(6)配置GPIO N管脚电性相连的EDMA通道Z,同时将下一个数据包接收段的目的地址提前配置好,并注册该EDMA通道相对应的中断服务程序,用于将下一个数据包的地址更新到EDMA通道Y,同时根据通道Y中的EDMA接收参数获取到当前数据包的长度信息;
(7)初始化接收缓冲区的读写指针为该缓冲区的起始位置,写指针用于硬件接收到一个数据包后指示下一个可用来接收包的缓冲区位置,由EDMA通道Z的中断服务程序维护;读指针用于CPU高层软件读取一个待接收的包,读取完毕后更新到下一个等待读取的数据包位置;通过软硬件分别维护读写指针,能避免数据包的读取错误,并且根据当前的软件使用场景,可以合理的增加或者减少缓冲区的大小,提供更好的数据存储服务;
(8)使能EDMA通道X、EDMA通道Y、EDMA通道Z,使其处于工作状态,从而完成整个初始化的配置。
上述实施例为本发明较佳的实施方式,但本发明的实施方式并不受上述实施例的限制,其他的任何未背离本发明的精神实质与原理下所作的改变、修饰、替代、组合、简化,均应为等效的置换方式,都包含在本发明的保护范围之内。