GSM模块_GPRS传输长数据包时的经验总结

来源:互联网 发布:windows 10 激活 编辑:程序博客网 时间:2024/06/05 09:55

前言

    本文接着之前的项目继续往下做,现在需要增加一个程序在线升级的功能,代码通过GPRS传输给ARM,然后更新到Flash,完成程序升级。
    为了缩短程序升级的时间,也为了和之前的软件一致,我们设置每次数据传输的最大长度为2K,即2048字节,加上数据格式帧头和AT命令帧头,实际接收的数据长度为2075字节。 
 

遇到的新问题

1、当GPRS传输数据超过一定长度的时候,GSM模块有可能会把数据分段传输到MCU,比如上面提到的2075字节,有时会一次性发回来,有时会分成1400字节和675字节传给MCU,而在服务器端,数据都是一起传输回来的,那么分段的时候就需要对数据进行拼接处理。
    可以将数据长度作为是否需要进行拼接的依据,我们在设计数据帧的时候,在帧头放入了数据的长度信息。当每次接收到服务器发回来的数据帧的时候,取出AT命令里的长度信息AT_Length和数据帧里的数据长度信息DATA_Length。
将两者进行比较
if( DATA_Length > AT_Length)    
//说明数据出现了分段的情况,将接收状态置为 RECEIVE_ING,当接收到下一帧数据的时候,将AT_Length1 + AT_Length2组成新的AT_Length。与之前的DATA_Length进行比较。如果还是出现DATA_Length比较大的情况,那么以此类推,继续接收下一帧数据,直到AT_Length >= DATA_Length,此时将接收状态置为RECEIVE_READY,在应用程序里面将接收到的数据取出处理。

2、前期开发的时候由于测试数据长度都比较短,所以我直接在串口中断里面对数据进行处理,包括将有效数据拷贝到指定的RAM里面。而当数据长度加长,特别是有问题1出现时,很容易导致中断处理时间过长,后续数据接收不到的情况。这个问题在软件设计之初就应该是不被允许的,或者说这样的操作本身就是错误的,是需要尽量避免的,希望大家在设计的时候注意。中断里面应该尽量减少操作,尽快跳出中断,以处理后续的中断事件。
    由于GPRS数据格式的特殊性,我在数据处理的时候,分配了两块存储空间UART_Buf和GPRS_Buf,UART_Buf用于接收串口中断数据,GPRS_Buf用于存储预处理后的数据,即存储服务器发回来的有效数据。我在开头提到的数据格式特殊性,就是指串口接收到的原始数据会包含AT命令的帧头,结束符,操作的应答等等不需要过多关注的内容,但是又为了中断操作的及时性,我会先把这些数据一并存在UART_Buf里面,简化串口中断处理。
    UART_Buf直接在中断里面进行处理,每次进中断,只需要将数据填到这个Buf的尾部,如果接收到AT命令的结束符,这个时候对数据进行一次判断,判断是否是服务器发回来的数据,如果是,记录数据存储的位置Addr,并对该位置的状态进行设置,设置成RECEIVE_READY,然后跳出中断,其他操作在主循环里面进行。
    GPRS_Buf预处理的操作首先判断位置的状态,当检测到有状态置为RECEIVE_READY的时候,取出Addr信息,将Addr开始地址的数据依次取出,判断AT数据帧头,AT_Length和DATA_Length ,这个时候有可能会需要进行分段拼接的处理,在问题1里面已经讲到了。当取出该位置的有效数据后,将有效数据存储到GPRS_Buf里面,并将该位置的状态设置成RECEIVE_EMPTY,这样该位置就可以用于下一次数据的接收处理。

总结

本文简单介绍了GSM模块串口中断的设计,数据存储方式的设计,以及数据长度较大时应该注意的地方,供大家设计的时候参考。
1 0