wince系统串口接收数据不完整怎么办?

费心干饭王 2015-04-13 05:15:43
wince系统的核心芯片为S3C2416,wince系统主要接收485串口发送过来的数据并将数据保存的SD卡中,波特率为115200.但是保存的SD卡中的数据丢失,怎么办??[/size]?用C++编写
...全文
711 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
xuebatiantang 2016-11-21
  • 打赏
  • 举报
回复
楼主您好,我现在学习的方面跟你帖子中提到的关联性很大,能不能麻烦您把你做的源码发给我一份,谢谢您,邮箱wangziRUI16@126.com,麻烦了
费心干饭王 2015-04-25
  • 打赏
  • 举报
回复
[quote=引用 18 楼 9527 的回复:] 1)线程1中收到串口数据,把它追加到一个缓冲队列中区(例如用C++的vector、queue),或者直接复制到预留的缓冲区(C常用的环形缓冲区)都可以,做完memcpy或者pushback。你现在这么弄也行。 2)通知你可以简单的用一个boolean或者用event,结合WaitForSingleObject 3)我所说的块存储就是我一再强调的不要随读随写,要以32K或64K为单位,减少对于Flash的写次数,无论是flash还是传统的磁盘零散数据写都是效率不高的。 对于你现在的情况,不要管那么多,修改你得CommDealTread线程,把LeaveCriticalSection(&g_cs);句前提挪到m_str.ReleaseBuffer();后就应该可以有效解决你的问题。 [/qu现在上面方法对于波特率为57600是正确的,但是对于更高的波特率115200还是存在数据丢失的情况,怎么办?
费心干饭王 2015-04-25
  • 打赏
  • 举报
回复
引用 18 楼 9527 的回复:
1)线程1中收到串口数据,把它追加到一个缓冲队列中区(例如用C++的vector、queue),或者直接复制到预留的缓冲区(C常用的环形缓冲区)都可以,做完memcpy或者pushback。你现在这么弄也行。 2)通知你可以简单的用一个boolean或者用event,结合WaitForSingleObject 3)我所说的块存储就是我一再强调的不要随读随写,要以32K或64K为单位,减少对于Flash的写次数,无论是flash还是传统的磁盘零散数据写都是效率不高的。 对于你现在的情况,不要管那么多,修改你得CommDealTread线程,把LeaveCriticalSection(&g_cs);句前提挪到m_str.ReleaseBuffer();后就应该可以有效解决你的问题。
现在利用上面的提议修改CommDealTread线程,把LeaveCriticalSection(&g_cs);句前提挪到m_str.ReleaseBuffer();数据存储还存在丢失的现象
费心干饭王 2015-04-25
  • 打赏
  • 举报
回复
1)线程1中收到串口数据,把它追加到一个缓冲队列中区(例如用C++的vector、queue),或者直接复制到预留的缓冲区(C常用的环形缓冲区)都可以,做完memcpy或者pushback。你现在这么弄也行。 2)通知你可以简单的用一个boolean或者用event,结合WaitForSingleObject 3)我所说的块存储就是我一再强调的不要随读随写,要以32K或64K为单位,减少对于Flash的写次数,无论是flash还是传统的磁盘零散数据写都是效率不高的。 对于你现在的情况,不要管那么多,修改你得CommDealTread线程,把LeaveCriticalSection(&g_cs);句前提挪到m_str.ReleaseBuffer();后就应该可以有效解决你的问题。 [/quote] 利用修改CommDealTread线程,把LeaveCriticalSection(&g_cs);句前提挪到m_str.ReleaseBuffer();这种方法还是存在数据丢失的现象。
9527 2015-04-24
  • 打赏
  • 举报
回复
引用 9 楼 lxh1244 的回复:
[quote=引用 6 楼 9527 的回复:] 想了想,楼主应该是和我之前一个同事一样,在串口接收线程中堵塞的写文件了,和什么SD卡之类一点关系都没。。。这种做法绝对是不行的,开两个线程吧
你的想法应该是对的,我现在就是开了两个线程,但是两个线程数据之间的共享不能很好的控制。[/quote] 如果仅仅是从串口接收并保存到SD卡,这个逻辑是很容易实现的。 1)线程1:串口线程接收到数据,仅仅把它添加到一个内存缓冲区中,然后直接返回 2)线程2通过线程1的通知机制或者定时机制,进行块数据的保存,不要随来随写。 唯一需要同步的地方就是这个内存缓冲区的写指针和读指针,以及缓冲区的存储满处理 不负责,你慢慢调试就可以了
9527 2015-04-24
  • 打赏
  • 举报
回复
引用 17 楼 lxh1244 的回复:
[quote=引用 15 楼 9527 的回复:] [quote=引用 14 楼 lxh1244 的回复:] [quote=引用 13 楼 9527 的回复:] 最简单的优化方式,把你写入时候的临界保护修改为仅仅从串口数据缓冲区读时进行,不要扩大化到写入操作后。另外,你显然也没有按照块数据写的方式,不要频繁操作IO
好的,我试试,有没有这方面的程序,我刚刚开始学习编程,对于线程的应用不怎么样[/quote] 例子很多的,不过你用wince的话,还是建议到MFC社区去,这个应用也很简单,你现在这么做就能满足你得要求了。[/quote]
引用 15 楼 9527 的回复:
[quote=引用 14 楼 lxh1244 的回复:] [quote=引用 13 楼 9527 的回复:] 最简单的优化方式,把你写入时候的临界保护修改为仅仅从串口数据缓冲区读时进行,不要扩大化到写入操作后。另外,你显然也没有按照块数据写的方式,不要频繁操作IO
好的,我试试,有没有这方面的程序,我刚刚开始学习编程,对于线程的应用不怎么样[/quote] 例子很多的,不过你用wince的话,还是建议到MFC社区去,这个应用也很简单,你现在这么做就能满足你得要求了。[/quote] 好的,谢谢,我实验一下,成功了结贴
引用 10 楼 9527 的回复:
[quote=引用 9 楼 lxh1244 的回复:] [quote=引用 6 楼 9527 的回复:] 想了想,楼主应该是和我之前一个同事一样,在串口接收线程中堵塞的写文件了,和什么SD卡之类一点关系都没。。。这种做法绝对是不行的,开两个线程吧
你的想法应该是对的,我现在就是开了两个线程,但是两个线程数据之间的共享不能很好的控制。[/quote] 如果仅仅是从串口接收并保存到SD卡,这个逻辑是很容易实现的。 1)线程1:串口线程接收到数据,仅仅把它添加到一个内存缓冲区中,然后直接返回 2)线程2通过线程1的通知机制或者定时机制,进行块数据的保存,不要随来随写。 唯一需要同步的地方就是这个内存缓冲区的写指针和读指针,以及缓冲区的存储满处理 不负责,你慢慢调试就可以了[/quote] 我还有几个问题: 1.你说的线程1中的数据添加到内存缓冲区中,然后直接返回[i[/i]什么意思? 2.线程1怎样通知线程2? 3.数据怎样实现你说的块存储? [/quote] 1)线程1中收到串口数据,把它追加到一个缓冲队列中区(例如用C++的vector、queue),或者直接复制到预留的缓冲区(C常用的环形缓冲区)都可以,做完memcpy或者pushback。你现在这么弄也行。 2)通知你可以简单的用一个boolean或者用event,结合WaitForSingleObject 3)我所说的块存储就是我一再强调的不要随读随写,要以32K或64K为单位,减少对于Flash的写次数,无论是flash还是传统的磁盘零散数据写都是效率不高的。 对于你现在的情况,不要管那么多,修改你得CommDealTread线程,把LeaveCriticalSection(&g_cs);句前提挪到m_str.ReleaseBuffer();后就应该可以有效解决你的问题。
费心干饭王 2015-04-24
  • 打赏
  • 举报
回复
引用 15 楼 9527 的回复:
[quote=引用 14 楼 lxh1244 的回复:] [quote=引用 13 楼 9527 的回复:] 最简单的优化方式,把你写入时候的临界保护修改为仅仅从串口数据缓冲区读时进行,不要扩大化到写入操作后。另外,你显然也没有按照块数据写的方式,不要频繁操作IO
好的,我试试,有没有这方面的程序,我刚刚开始学习编程,对于线程的应用不怎么样[/quote] 例子很多的,不过你用wince的话,还是建议到MFC社区去,这个应用也很简单,你现在这么做就能满足你得要求了。[/quote]
引用 15 楼 9527 的回复:
[quote=引用 14 楼 lxh1244 的回复:] [quote=引用 13 楼 9527 的回复:] 最简单的优化方式,把你写入时候的临界保护修改为仅仅从串口数据缓冲区读时进行,不要扩大化到写入操作后。另外,你显然也没有按照块数据写的方式,不要频繁操作IO
好的,我试试,有没有这方面的程序,我刚刚开始学习编程,对于线程的应用不怎么样[/quote] 例子很多的,不过你用wince的话,还是建议到MFC社区去,这个应用也很简单,你现在这么做就能满足你得要求了。[/quote] 好的,谢谢,我实验一下,成功了结贴
引用 10 楼 9527 的回复:
[quote=引用 9 楼 lxh1244 的回复:] [quote=引用 6 楼 9527 的回复:] 想了想,楼主应该是和我之前一个同事一样,在串口接收线程中堵塞的写文件了,和什么SD卡之类一点关系都没。。。这种做法绝对是不行的,开两个线程吧
你的想法应该是对的,我现在就是开了两个线程,但是两个线程数据之间的共享不能很好的控制。[/quote] 如果仅仅是从串口接收并保存到SD卡,这个逻辑是很容易实现的。 1)线程1:串口线程接收到数据,仅仅把它添加到一个内存缓冲区中,然后直接返回 2)线程2通过线程1的通知机制或者定时机制,进行块数据的保存,不要随来随写。 唯一需要同步的地方就是这个内存缓冲区的写指针和读指针,以及缓冲区的存储满处理 不负责,你慢慢调试就可以了[/quote] 我还有几个问题: 1.你说的线程1中的数据添加到内存缓冲区中,然后直接返回[i[/i]什么意思? 2.线程1怎样通知线程2? 3.数据怎样实现你说的块存储?
费心干饭王 2015-04-24
  • 打赏
  • 举报
回复
引用 6 楼 9527 的回复:
想了想,楼主应该是和我之前一个同事一样,在串口接收线程中堵塞的写文件了,和什么SD卡之类一点关系都没。。。这种做法绝对是不行的,开两个线程吧
你的想法应该是对的,我现在就是开了两个线程,但是两个线程数据之间的共享不能很好的控制。
费心干饭王 2015-04-24
  • 打赏
  • 举报
回复
引用 3 楼 zzbinfo 的回复:
SD卡的读写不会慢到这种程度吧?如果数据量不大的话可以先接收完在慢慢写试试看
试过这种方法,将所有接收的数据转换之后存到一个总的字符串中,但是还是出现错误。
费心干饭王 2015-04-24
  • 打赏
  • 举报
回复
引用 15 楼 9527 的回复:
[quote=引用 14 楼 lxh1244 的回复:] [quote=引用 13 楼 9527 的回复:] 最简单的优化方式,把你写入时候的临界保护修改为仅仅从串口数据缓冲区读时进行,不要扩大化到写入操作后。另外,你显然也没有按照块数据写的方式,不要频繁操作IO
好的,我试试,有没有这方面的程序,我刚刚开始学习编程,对于线程的应用不怎么样[/quote] 例子很多的,不过你用wince的话,还是建议到MFC社区去,这个应用也很简单,你现在这么做就能满足你得要求了。[/quote]
引用 15 楼 9527 的回复:
[quote=引用 14 楼 lxh1244 的回复:] [quote=引用 13 楼 9527 的回复:] 最简单的优化方式,把你写入时候的临界保护修改为仅仅从串口数据缓冲区读时进行,不要扩大化到写入操作后。另外,你显然也没有按照块数据写的方式,不要频繁操作IO
好的,我试试,有没有这方面的程序,我刚刚开始学习编程,对于线程的应用不怎么样[/quote] 例子很多的,不过你用wince的话,还是建议到MFC社区去,这个应用也很简单,你现在这么做就能满足你得要求了。[/quote] 好的,谢谢,我实验一下,成功了结贴
9527 2015-04-24
  • 打赏
  • 举报
回复
引用 14 楼 lxh1244 的回复:
[quote=引用 13 楼 9527 的回复:] 最简单的优化方式,把你写入时候的临界保护修改为仅仅从串口数据缓冲区读时进行,不要扩大化到写入操作后。另外,你显然也没有按照块数据写的方式,不要频繁操作IO
好的,我试试,有没有这方面的程序,我刚刚开始学习编程,对于线程的应用不怎么样[/quote] 例子很多的,不过你用wince的话,还是建议到MFC社区去,这个应用也很简单,你现在这么做就能满足你得要求了。
费心干饭王 2015-04-24
  • 打赏
  • 举报
回复
引用 13 楼 9527 的回复:
最简单的优化方式,把你写入时候的临界保护修改为仅仅从串口数据缓冲区读时进行,不要扩大化到写入操作后。另外,你显然也没有按照块数据写的方式,不要频繁操作IO
好的,我试试,有没有这方面的程序,我刚刚开始学习编程,对于线程的应用不怎么样
9527 2015-04-24
  • 打赏
  • 举报
回复
最简单的优化方式,把你写入时候的临界保护修改为仅仅从串口数据缓冲区读时进行,不要扩大化到写入操作后。另外,你显然也没有按照块数据写的方式,不要频繁操作IO
9527 2015-04-24
  • 打赏
  • 举报
回复
楼主,我只说一句,你用多线程的目的是什么,你看看自己的代码,加上临界以后,多线程是不是又按照单线程方式来走了。 再看看我给你的建议,串口接收部分,收了就把数据放到缓冲区去,减少等待。不要和写入部分有任何的交集。
费心干饭王 2015-04-24
  • 打赏
  • 举报
回复
现在开了两个线程 // 创建串口接收线程 hRecvThread = CreateThread(0, 0, CommRecvTread, this, 0, &IDThread); if (hRecvThread == NULL) { MessageBox(_T("创建接收线程失败!")); return; } //创建数据存储线程 hDealThread= CreateThread(0, 0, CommDealTread, this, 0, &IDThread1); if (hDealThread == NULL) { MessageBox(_T("创建接收线程失败!")); return; } 串口接收线程函数为 /******************************************************************************************* 函数名称: CSerialPortDlg::CommRecvTread 描 述: 串口接收线程 输入参数: LPVOID lparam: 线程参数,创建线程时传入 输出参数: 无 返 回: 0: 线程退出, 返回值没特殊含义 ********************************************************************************************/ DWORD CSerialPortDlg::CommRecvTread(LPVOID lparam) { DWORD dwCommModemStatus; COMSTAT ComStat; DWORD dwErrorFlags; DWORD dwLength; DWORD willLen; CString tmp; CSerialPortDlg *pDlg = (CSerialPortDlg*)lparam; while(TRUE) { if (WaitForSingleObject(pDlg->m_ExitThreadEvent, 0) == WAIT_OBJECT_0) break; WaitCommEvent(pDlg->m_hComm,&dwCommModemStatus,NULL); if (dwCommModemStatus & EV_RXCHAR) { ClearCommError(pDlg->m_hComm,&dwErrorFlags,&ComStat); dwLength=ComStat.cbInQue; if(dwLength<=0) { continue; } EnterCriticalSection(&g_cs);//进入临界区 unsigned char *recvBuf = new unsigned char[dwLength]; ReadFile(pDlg->m_hComm, recvBuf,dwLength,&willLen, NULL); for (int i = 0; i < (int)willLen; i++, recvBuf[i]) { count++; tmp.Format(_T("0%X"), recvBuf[i]); tmp = tmp.Right(2); m_strRecDisp += tmp; if(count==16) { m_strRecDisp+=_T("\r\n"); count=0; } } m_Strlist.AddHead(m_strRecDisp); delete[] recvBuf; m_strRecDisp=_T(""); LeaveCriticalSection(&g_cs);////离开临界区 } } return 0; } /******************************************************************************************* 函数名称: CSerialPortDlg::CommDealTread 描 述: 接收数据保存 输入参数: 无 输出参数: 无 返 回: FALSE: 失败; TRUE: 成功 ********************************************************************************************/ //LONG CSerialPortDlg::OnCommRecv( unsigned char *buf, int buflen) DWORD CSerialPortDlg::CommDealTread(LPVOID lparam) { DWORD len; CString m_str; char *pcharbuff; while(TRUE) { /* 等待线程退出事件 */ if(m_Strlist.GetCount()>0) { EnterCriticalSection(&g_cs); m_str=m_Strlist.GetTail(); len = m_str.GetLength(); pcharbuff = new char[len]; LPTSTR pStr =m_str.GetBuffer(len); WideCharToMultiByte(CP_ACP, 0, pStr, len, pcharbuff, len, NULL, NULL); m_str.ReleaseBuffer(); m_File1.SeekToEnd(); m_File1.Write(pcharbuff,len); m_File1.Flush(); m_str=_T(""); if (pcharbuff != NULL) delete[] pcharbuff; LeaveCriticalSection(&g_cs); } } return 1; 帮忙看一下,哪里出现错误,在这里我利用了临界区,防止对线程对数据的同时操作。
费心干饭王 2015-04-23
  • 打赏
  • 举报
回复
不好意思,请两天忙着考试,忘记看帖子。我现在就是开了两个线程,但是好像还是不对 ,是不是我每次接收数据和存储数据的过程中要设置全局数据的互斥?
9527 2015-04-20
  • 打赏
  • 举报
回复
想了想,楼主应该是和我之前一个同事一样,在串口接收线程中堵塞的写文件了,和什么SD卡之类一点关系都没。。。这种做法绝对是不行的,开两个线程吧
9527 2015-04-20
  • 打赏
  • 举报
回复
对于串口来说,再慢的SD卡读写速度应该也足够了,你肯定是频繁写SD卡造成了性能慢,可以试试: 1)使用fopen系列函数进行文件读写,不要频繁的开关文件 2)或者自己做个缓冲写,就是攒到一定数量数据,例如64K,阶段性写入。 随读随写肯定是不行的。
draculamx 2015-04-18
  • 打赏
  • 举报
回复
引用 2 楼 lxh1244 的回复:
没有设置数据的起始和结束位,只是下位机以240个字节作为一帧发送到wince系统。现在主要的问题是SD卡存储数据速度太慢造成数据的丢失,请问我怎么解决这一问题?现在正在实验一种方法就是在程序中开了两个线程,一个线程用于读串口数据,另外一个线程用于将数据保存的SD卡中,其中防止来年改革线程对数据操作混乱,用了CStringList类,读到的数据添加到CStringList的头,写的时候从CStringList尾部进行截取。但是结果还是不对????怎么办?
如果长时间运行,你的程序没有出现内存不足的情况的话,那么证明你这个数据缓冲区是足够大的,现在的问题就是检查一下你对CStringList的应用是否正确,正常情况下应该是尾部添加,头部读取,读取完以后删除已经读取的那个节点。 还有就是你接收串口数据的时候,是否发生了串口的硬件缓冲区溢出(你读得太慢),如果有这种情况发生的话,你的数据肯定不完整
zzbinfo 2015-04-17
  • 打赏
  • 举报
回复
SD卡的读写不会慢到这种程度吧?如果数据量不大的话可以先接收完在慢慢写试试看
加载更多回复(2)

1,317

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder 网络及通讯开发
社区管理员
  • 网络及通讯开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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