Beispiel #1
0
        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;
            }
        }
Beispiel #2
0
        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;
            }
        }
Beispiel #3
0
        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;
        }
Beispiel #4
0
        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;
            }
        }