分块从串口发送图片数据,总是丢失部分数据,救命~急!急!急!急 (100分)在线等

chinaren_xf 2008-09-18 07:37:21
各位牛人,我在这里先谢谢您看这个帖子了!

我现在做的是用arm9,linux系统通过串口把大小是20k的图片发送到无线通讯模块。

方法是,先把图片mmap到内存,然后分段发送到串口,通过串口到通讯模块发送到pc机,第一次测试的是5k的图片,

没有问题,第二次测试是20k的txt文件,没有问题,但是发送20k的图片的时候(3次测试都用一个方法),数据在发送一部分后出现丢失情况,并且丢失的大小和位置不确定,请问这是什么原因造成的呢?

我怀疑一个是通讯模块的缓冲小,不能完成串口发送数据的全部传输,导致数据丢失,还有就是串口本身问题,使得数据丢失,再就是内存读取使得数据丢失。

现在非常着急,赶着救命啊,各位大大,走过路过,指点一二啊,我感激不尽@如果能告诉解决的办法就更好了,现在

只能用串口传输,请帮帮忙看看~~~!!!!!!!!!!!!!!!!!!!!!!!!!
...全文
410 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
huanglan1226 2012-03-07
  • 打赏
  • 举报
回复
问题解决了没?我用串口发送大数据量也会出现数据丢失的情况,如果解决的话,麻烦说一下,谢谢~~
wwblackjack1972 2008-09-21
  • 打赏
  • 举报
回复
改用xmodem之类的协议的,可靠很多
chinaren_xf 2008-09-19
  • 打赏
  • 举报
回复
感谢楼上各位大大的恢复,今天我会把所有的指点都试一边,希望能解决问题,如果有问题,跟请各位再次伸手帮帮忙,
我先谢谢了。
chinaren_xf 2008-09-19
  • 打赏
  • 举报
回复
感谢楼上各位大大的恢复,今天我会把所有的指点都试一边,希望能解决问题,如果有问题,跟请各位再次伸手帮帮忙,
我先谢谢了。
chinaren_xf 2008-09-19
  • 打赏
  • 举报
回复
今天没有全部做完,明天继续试验,希望有好的结论~立马结贴
bshawk 2008-09-18
  • 打赏
  • 举报
回复 1
你代码中sb.st_size,是如何得到的?没有看到相关代码,是用fstat得到的么?
把这个值printf出来看看!

另外,也可以考虑先不用mmap方式读取数据,而是直接用read来读取试验下!

gogofly_lee 2008-09-18
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 chinaren_xf 的回复:]
很感谢您的回复,您说的方法我试过,就是arm和pc的串口互联,用串口监听工具看,但是由于数据太多,很难比较
能否在请问一下,如果这种方式怎么判断数据是否正常呢?
恳请您不要嫌我麻烦多多指点一下
[/Quote]
你可以发送自己按顺序组织的数据,比如从0x00,0x01,0x02,..... 大数据量发送,很容易看出是否丢包.
chinaren_xf 2008-09-18
  • 打赏
  • 举报
回复 1
代码如下
fd = OpenDev(dev);
if (fd>0){ set_speed(fd,19200);}
else {
printf("Can't Open Serial Port!\n");
exit(0);
}
if (set_Parity(fd,8,1,'S')== -1) {
printf("Set Parity Error\n");
exit(1);
}

img_fd = open("/root/Documents/002.jpg",O_RDWR);

if(img_fd < 0)
{ perror("open the image");
exit(1);
}

img_addr = mmap(NULL,sb.st_size,PROT_READ,MAP_PRIVATE,img_fd,0);
if(img_addr == MAP_FAILED)
{ perror("map the image");
exit(1);
}
LastDataSize = sb.st_size % 512;
Pkg_num = sb.st_size /512;
img_index = 0;


_BSP(fd);
if(LastDataSize == 0)
{
for(i = 0; i < Pkg_num; i++)
{
usleep(450000);

memcpy(PKG.data,img_addr + img_index,512);
len=write(fd,PKG.data,sizeof(_PKG));
printf("buff=%d\n",sizeof(_PKG));
img_index += 512;
len_sum+=len;
}
#ifdef debug
printf("len_sum=%d\n",len_sum);
#endif

}

else{
for(i = 0; i < (Pkg_num-1); i++)
{
usleep(450000);

memcpy(PKG.data,img_addr + img_index,512);
len = write(fd,PKG.data,sizeof(_PKG));
img_index += 512;
len_sum+=len;
}
memcpy(PKG.data,img_addr + img_index,LastDataSize);
len=write(fd,PKG.data,LastDataSize);
}


借鉴了网络上前辈的好方法
bshawk 2008-09-18
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 cceczjxy 的回复:]
一般的串口传输数据,最好自己定义一套通讯协议,比如规定一包数据有多长,发送的数据如何应答,怎么超时重传,怎么效验等等,不能完全依赖底层的串口协议.
[/Quote]

赞同!并且一定要这样做,不然很多时侯问题说不清楚!
不过LZ的GPRS模块好像不受他编程控制,所以这个方法估计对LZ不行!

对串口来说,它不知道你上层发送的是什么,既然20K的txt都没有问题,图片照说也应该可以! 可以的话,关键部分代码贴出来大家分析下!
chinaren_xf 2008-09-18
  • 打赏
  • 举报
回复
谢谢您的回复,我现在就是定义了一个简单的协议,应用的是crc校验,现在网络上crc校验程序很成熟了,
很多前辈给的源码,但是,crc校验函数的返回值都是int型,而函数中的crc值却是short型,用ccitt的生成多项式
这样的返回类型会使得校验玛多了2个字节,但是该成short编译却通不过去,为什么呢?
另外我定义的一个结构提中存放的分段数据和crc校验,然后把这个结构体发送到串口,但是如果发送最后一组数据
小于结构体中定义的段的长度,那么段的后几位都是00,这样就影响了图片数据的结束标志,该怎么发送最后的数据+crc呢?
一直在线等待各位大大的指点,等待中!!!!!!!!!
cceczjxy 2008-09-18
  • 打赏
  • 举报
回复
一般的串口传输数据,最好自己定义一套通讯协议,比如规定一包数据有多长,发送的数据如何应答,怎么超时重传,怎么效验等等,不能完全依赖底层的串口协议.
chinaren_xf 2008-09-18
  • 打赏
  • 举报
回复
十分谢谢bshawk的回复,我从串口发送数据没有制定协议,因为很短的距离连接的通讯模块。并不是ppp拨号。是模块自动
通电就上网,通过gprs传输的,我仅仅负责把数据传到这个模块中,如果把数据包放小,加校验的话,一幅图片传输会很慢。
传输时间上不允许这么做的,另外我在串口初始化的设置中已经声明了按照原始模式输出,谢谢您的提醒.
我是刚刚接触这中方式的编程,请别嫌我,期待各位大大的再次指点。
chinaren_xf 2008-09-18
  • 打赏
  • 举报
回复
感谢speme 回复,流量我试过定义缓冲区buff[100] buff[200] buff[500] buff[1000] buff[3000]
arm串口的传输速率是19200,每次发送一段以后我等待的时间分别为0.1s 0.1s 0.5s 0.9s 2s
依然是丢失数据,请在给些指点,
谢谢了
bshawk 2008-09-18
  • 打赏
  • 举报
回复
如果你怀疑无线模块的内部缓存?那将包尽量放小,然后包加上校验并且等待接收方确认收到包之后再发下一包,确保数据正确完整到达!

按理说,你20K的txt文件都没有问题,图片应该没有问题! 另外注意下串口ESCAPE字符的问题!
-------------------------------------------

不知道你走的什么协议? 你的无线模块是指GSM/GPRS无线模块么?是在arm上,通过ppp将无线模块拨上网,通过GPRS进行的数据传输么? 还是其它方式?
speme 2008-09-18
  • 打赏
  • 举报
回复
我认为应该是流量控制的问题。
chinaren_xf 2008-09-18
  • 打赏
  • 举报
回复
很感谢您的回复,您说的方法我试过,就是arm和pc的串口互联,用串口监听工具看,但是由于数据太多,很难比较
能否在请问一下,如果这种方式怎么判断数据是否正常呢?
恳请您不要嫌我麻烦多多指点一下
gogofly_lee 2008-09-18
  • 打赏
  • 举报
回复
要找出原因,可以试一下下面的方法;
既然你是用的无线模块,可能比较好做: 把串口接到无线模块那端的通信线都接到你PC的串口上,监视接受的数据,看数据是否有丢失的情况,从而可以判断是你的主机端或者是无线模块丢包,具体连接咨询一下你们的硬件工程师,着也是调试BT等常用的方式.
chinaren_xf 2008-09-18
  • 打赏
  • 举报
回复
十分感谢 lights_joy ,我想过这样,但是能不能请您说下我的猜测的错误可不可能出现呢?
我加的crc校验,但是crc网络上的源码都是crc可以使short型,return crc,但是校验函数的类型却必须是int才能编译通过,这样我采用ccitt的crc就编程了32位了,就像这样
unsigned int crc{unsinged short crc;return crc}
恳请各位大大再次伸手帮帮忙,请告知原因,并且如何吧crc加到数据后面一起发送。
我现在的方法是定义结构体,其中两个元素,data,crc,然后传送&struct这样
嵌云阁主 2008-09-18
  • 打赏
  • 举报
回复
加校验,错误重传
chinaren_xf 2008-09-18
  • 打赏
  • 举报
回复
99999999999999999999999999999999999999999999999999999

23,125

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧