void timer_RcvFlush_Tick(object sender, EventArgs e) { timer_RcvFlush.Enabled = false; //空闲的时候把最后的数据刷到窗体上 if ((current_rnode != null) && (rcv_recving == false)) { rcv_flushing = true; Dbg.WriteLine("Flush rcv data:{0} rcv:{1} sp:{2}", current_rnode.length, rcv_recving, Func.RTC_TimeSpan_MS(last_rcv_data_time)); if (current_rnode.length > 0) { if (efifo_raw_2_str.is_full == true) { Dbg.WriteLine("###3.COM:{0} recv fifo is full:{1}, data miss!!!", serialport.IsOpen, efifo_raw_2_str.GetValidNum()); return; } efifo_raw_2_str.Input(current_rnode); current_rnode = null; event_recv.Set(); } rcv_flushing = false; } }
void ThreadEntry_ComRecv() { while (true) { check_thread_ComRecv++; step_thread_ComRecv = 0; if (efifo_raw_2_str.GetValidNum() == 0) { step_thread_ComRecv = 1; event_recv.WaitOne(1000); //FIFO已经空了,则在这里一直等待,直到有事件过来,可以有效降低CPU的占用率 } else { step_thread_ComRecv = 2; tyRcvNode output_rnode = efifo_raw_2_str.Output(); if (output_rnode.length > 0) { step_thread_ComRecv = 3; #if false //false, true //打印发送数据 Dbg.Write("com Data[{0}]:", raw_data_buffer.Length); for (int i = 0; i < raw_data_buffer.Length; i++) { Dbg.Write(" {0:X}", raw_data_buffer[i]); } Dbg.Write("\r\n"); #endif if (fm.fp.is_active == true) { step_thread_ComRecv = 4; int recv_len; byte[] recv_data; recv_len = fm.fp.DataConvert(output_rnode.buffer, output_rnode.length, out recv_data); if (recv_len > 0) { DataHandle(recv_data, recv_len, true); } } else { step_thread_ComRecv = 5; DataHandle(output_rnode.buffer, output_rnode.length, true); } } else { step_thread_ComRecv = 6; Dbg.Assert(false, "###why output data is zero length?"); } step_thread_ComRecv = 7; epool_rcv.Put(output_rnode.pnode); } step_thread_ComRecv = 8; } }
public COM() { efifo_raw_2_str.Init(tyRcvNode.RCV_NODE_NUM); //eFIFO能管理8K个元素 for (int i = 0; i < tyRcvNode.RCV_NODE_NUM; i++) //每个元素8K大小,一共64MB,如果收的比做得快,那只能丢失了 { //第一次收到10个,不满攒住,第二次收到4096,则会溢出! tyRcvNode rnode = new tyRcvNode(tyRcvNode.RCV_CACHE_SIZE + COM_BUFFER_SIZE_MAX); PNode <tyRcvNode> pnode = new PNode <tyRcvNode>(); rnode.pnode = pnode; epool_rcv.Add(pnode, rnode); //Dbg.WriteLine("Add node:{0} to ePool", rnode.GetHashCode()); } efifo_str_2_show.Init(tyShowOp.SHOW_NODE_NUM); //上面采用eFIFO搬运 for (int i = 0; i < tyShowOp.SHOW_NODE_NUM; i++) { tyShowOp snode = new tyShowOp(); PNode <tyShowOp> pnode = new PNode <tyShowOp>(); snode.pnode = pnode; epool_show.Add(pnode, snode); //Dbg.WriteLine("Add node:{0} to ePool", rnode.GetHashCode()); } timer_AutoSnd = new System.Timers.Timer(); //实例化Timer类,设置间隔时间为1000毫秒 timer_AutoSnd.Elapsed += new System.Timers.ElapsedEventHandler(timer_AutoSnd_Tick); //到达时间的时候执行事件 timer_AutoSnd.AutoReset = true; //设置是执行一次(false)还是一直执行(true) timer_AutoSnd.Enabled = false; //是否执行System.Timers.Timer.Elapsed事件 timer_AutoSnd.Interval = cfg.auto_send_inverval_100ms * 100; timer_RcvFlush = new System.Timers.Timer(); timer_RcvFlush.Elapsed += new System.Timers.ElapsedEventHandler(timer_RcvFlush_Tick); timer_RcvFlush.AutoReset = false; timer_RcvFlush.Enabled = false; timer_RcvFlush.Interval = 500; }
void ISR_COM_DataRec(object sender, SerialDataReceivedEventArgs e) //串口接受函数 { rcv_recving = true; last_rcv_data_time = DateTime.Now; timer_RcvFlush.Stop(); timer_RcvFlush.Enabled = false;//timer重新计时 timer_RcvFlush.Enabled = true; if ((COM_Op.com_is_closing == true) || (serialport.IsOpen == false) || (rcv_flushing == true)) { rcv_recving = false; return; } event_recv.Set(); //无论有没有资源,都唤醒recv线程去取FIFO //如果FIFO已经满了,最后一个current_rnode会一直接一直接,然后突破了buffer的长度 if (efifo_raw_2_str.is_full == true) { Dbg.WriteLine("###1.COM:{0} recv fifo is full:{1}, data miss!!!", serialport.IsOpen, efifo_raw_2_str.GetValidNum()); UpdateMissData(); rcv_recving = false; return; } if (current_rnode == null) { PNode <tyRcvNode> pnode = epool_rcv.Get(); if (pnode == null) { Dbg.WriteLine("###COM:{0} recv pool is full:{1}({2}), data miss!!!", serialport.IsOpen, epool_rcv.nr_got, epool_rcv.nr_ent); UpdateMissData(); rcv_recving = false; return; } else { current_rnode = pnode.obj; } current_rnode = pnode.obj; current_rnode.length = 0; //把长度清零,避免长度越界 } int com_recv_buff_length = serialport.Read(current_rnode.buffer, current_rnode.length, serialport.ReadBufferSize); if (com_recv_buff_length > 0) { bbbb = DateTime.Now; current_rnode.length += com_recv_buff_length; #if false current_rnode.log_len[current_rnode.log_cnt % 128] = com_recv_buff_length; current_rnode.log_sz[current_rnode.log_cnt % 128] = current_rnode.length; current_rnode.log_cnt++; #endif //当缓存较多的时候,优先提高平滑性(收得太慢/显示得太慢) if ((epool_rcv.nr_got < epool_rcv.nr_ent / 128) && //64 (epool_show.nr_got < epool_show.nr_ent / 128)) { handle_data_thresdhold = 0; } else if ((epool_rcv.nr_got < epool_rcv.nr_ent / 64) && //128 (epool_show.nr_got < epool_show.nr_ent / 64)) { handle_data_thresdhold = 1024; } else if ((epool_rcv.nr_got < epool_rcv.nr_ent / 32) || //256 (epool_show.nr_got < epool_show.nr_ent / 32)) { handle_data_thresdhold = tyRcvNode.RCV_CACHE_SIZE; } if (current_rnode.length >= handle_data_thresdhold) { if (efifo_raw_2_str.is_full == true) { Dbg.WriteLine("###2.COM:{0} recv fifo is full:{1}, data miss!!!", serialport.IsOpen, efifo_raw_2_str.GetValidNum()); record.miss_data += (uint)current_rnode.length; rcv_recving = false; return; } efifo_raw_2_str.Input(current_rnode); current_rnode = null; } else { rcv_recving = false; return; } event_recv.Set(); #if false Dbg.Write("RECA[{0}]: in:{1}-{2} out:{3}-{4}", com_recv_buff_length, com_recv_fifo_top, com_recv_fifo_buttom, fp_out_top, fp_out_buttom); for (int v = 0; v < com_recv_buff_length; v++) { Dbg.Write(" {0:X}", rcv_fifo.buffer[v]); } Dbg.Write("\r\n"); #endif rcv_recving = false; } }