示例#1
0
        public void WorkerThreadMain()
        {
            while (true)
            {
                //Interlocked.Increment
                AwakeEvent.WaitOne();
                AwakeEvent.Reset();
                do
                {
                    MessageRecord mr = PopMessage();
                    if (mr == null)
                    {
                        break; // !!
                    }
                    // System.Console.WriteLine("Message:{0}",mr.Message.ToString());
                    switch (mr.Message)
                    {
                    case MessageRecord.MsgType.Clear:
                        DaraRecordList.Clear();
                        break;

                    case MessageRecord.MsgType.SetPortName:
                        Portname = (string)mr.Data;
                        break;

                    case MessageRecord.MsgType.SetDevice:
                        CurrentBoard = (Board)mr.Data;
                        break;

                    case MessageRecord.MsgType.SetBaud:
                        ReciveBaudRate = (int)mr.Data;
                        break;

                    case MessageRecord.MsgType.SetRecord:
                        DaraRecordList.Add((DataRecord)mr.Data);
                        break;

                    case MessageRecord.MsgType.SetAfterWait:
                        AfterWait = (bool)mr.Data;
                        break;

                    case MessageRecord.MsgType.Start:
                        break;

                    case MessageRecord.MsgType.Abort:
                        SerialIOThread.Abort();
                        break;
                    }
                    if (mr.Message == MessageRecord.MsgType.Start)
                    {
                        break;
                    }
                } while (true);
                AfterPopMessageEvent.Set();
                Interlocked.Increment(ref CriticalCounter);     // Enter critical section
                if (CurrentBoard == null)
                {
                    continue;
                }
                byte[] rbuf = new byte[256];
                MainState   = MainStateEnum.Reset;
                ErrorState  = ErrorStatusEnum.None;
                RecordIndex = 0;
                RecordCount = DaraRecordList.Count;
                System.IO.Ports.SerialPort port = new System.IO.Ports.SerialPort(Portname);
                port.ErrorReceived += new System.IO.Ports.SerialErrorReceivedEventHandler(port_ErrorReceived);
                {
                    try
                    {
                        port.Open();
                        port.DiscardInBuffer();
                        port.DiscardOutBuffer();
                    }
                    catch (Exception exp)
                    {
                        System.Console.WriteLine("{0}", exp.Message);
                        ErrorState = ErrorStatusEnum.PortNotFound;
                        goto ErrorExit;
                    }
                    if (StateCallback != null)
                    {
                        StateCallback();
                    }
                    port.BaudRate     = CurrentBoard.UpLoadSpeed;
                    port.WriteTimeout = 1000;
                    port.ReadTimeout  = 1000;
                    switch (CurrentBoard.DTRControl)
                    {
                    case Board.DTRControlTypeEnum.Enable1000mSecAndDisable:
                        port.DtrEnable = true;
                        port.DiscardInBuffer();
                        port.DiscardOutBuffer();
                        Thread.Sleep(1000);
                        port.DtrEnable = false;
                        port.DiscardInBuffer();
                        port.DiscardOutBuffer();
                        Thread.Sleep(100);
                        port.DiscardInBuffer();
                        port.DiscardOutBuffer();
                        break;

                    case Board.DTRControlTypeEnum.EnableAndThrough:
                        port.DtrEnable = true;
                        port.DiscardInBuffer();
                        port.DiscardOutBuffer();
                        Thread.Sleep(500);
                        port.DiscardInBuffer();
                        port.DiscardOutBuffer();
                        break;
                    }
                    for (int i = 0; i < 3; i++)
                    {// Get sync
                        byte[] com = { Cmnd_STK_GET_SYNC, Sync_CRC_EOP };
                        byte[] rq  = { Resp_STK_INSYNC, Resp_STK_OK };
                        if (!RequestForAnswer(port, com, rq, rbuf))
                        {
                            ErrorState = ErrorStatusEnum.RequestTimeout;
                            goto ErrorExit;
                        }
                    }
                    if (CurrentBoard.SoftwareMajorVersion < 4)
                    {
                        {// Software major version (No implementation on optiboot V4-)
                            byte[] com = { Cmnd_STK_GET_PARAMETER, Param_STK_SW_MAJOR, Sync_CRC_EOP };
                            byte[] rq  = { Resp_STK_INSYNC, CurrentBoard.SoftwareMajorVersion, Resp_STK_OK };
                            if (!RequestForAnswerThanLess(port, com, rq, rbuf))
                            {
                                ErrorState = ErrorStatusEnum.InvalidVersion;
                                goto ErrorExit;
                            }
                        }
                        {// Enter programming mode (No implementation on optiboot V4-)
                            byte[] com = { Cmnd_STK_ENTER_PROGMODE, Sync_CRC_EOP };
                            byte[] rq  = { Resp_STK_INSYNC, Resp_STK_OK };
                            if (!RequestForAnswer(port, com, rq, rbuf))
                            {
                                ErrorState = ErrorStatusEnum.CannotEnterProgrammingMode;
                                goto ErrorExit;
                            }
                        }
                    }
                    foreach (DataRecord record in DaraRecordList)
                    {
                        if (DaraRecordList.Count > 0)
                        {
                            MainState = MainStateEnum.Send;
                        }
                        if (StateCallback != null)
                        {
                            StateCallback();
                        }
                        if (!CheckData(record))
                        {
                            ErrorState = ErrorStatusEnum.AddressFault;
                            goto ErrorExit;
                        }
                        int sendcount;
                        RecordProcessing = 0;
                        for (sendcount = 0; sendcount < record.Data.Length;)
                        {
                            {// Load address
                                byte[] com     = new byte[4];
                                byte[] rq      = { Resp_STK_INSYNC, Resp_STK_OK };
                                int    address = record.Address + sendcount;
                                com[0] = Cmnd_STK_LOAD_ADDRESS;
                                com[1] = (byte)((address >> 1) & 0xff);
                                com[2] = (byte)((address >> 9) & 0xff);
                                com[3] = Sync_CRC_EOP;
                                if (!RequestForAnswer(port, com, rq, rbuf))
                                {
                                    ErrorState = ErrorStatusEnum.SetAddress;
                                    goto ErrorExit;
                                }
                            }

                            byte cur_send = 128;
                            if (sendcount + cur_send > record.Data.Length)
                            {
                                cur_send = (byte)(record.Data.Length - sendcount);
                            }
                            {// Write page
                                byte[] com = new byte[cur_send + 5];
                                byte[] rq  = { Resp_STK_INSYNC, Resp_STK_OK };
                                com[0] = Cmnd_STK_PROG_PAGE;
                                com[1] = 0x00;
                                com[2] = cur_send;
                                com[3] = (byte)'F';// 'F'=flash 'E'=eeprom
                                for (int i = 0; i < cur_send; i++)
                                {
                                    com[4 + i] = record.Data[sendcount + i];
                                }
                                com[com.Length - 1] = Sync_CRC_EOP;
                                if (!RequestForAnswer(port, com, rq, rbuf))
                                {
                                    ErrorState = ErrorStatusEnum.WriteData;
                                    goto ErrorExit;
                                }
                            }
                            sendcount       += cur_send;
                            RecordProcessing = (float)sendcount / (float)record.Data.Length;
                            if (StateCallback != null)
                            {
                                StateCallback();
                            }
                        }
                        if (record.Verify)
                        {
                            if (DaraRecordList.Count > 0)
                            {
                                MainState = MainStateEnum.Verify;
                            }
                            if (StateCallback != null)
                            {
                                StateCallback();
                            }
                            RecordProcessing = 0;
                            for (sendcount = 0; sendcount < record.Data.Length;)
                            {
                                {// Load address
                                    byte[] com     = new byte[4];
                                    byte[] rq      = { Resp_STK_INSYNC, Resp_STK_OK };
                                    int    address = record.Address + sendcount;
                                    com[0] = Cmnd_STK_LOAD_ADDRESS;
                                    com[1] = (byte)((address >> 1) & 0xff);
                                    com[2] = (byte)((address >> 9) & 0xff);
                                    com[3] = Sync_CRC_EOP;
                                    if (!RequestForAnswer(port, com, rq, rbuf))
                                    {
                                        ErrorState = ErrorStatusEnum.SetAddress;
                                        goto ErrorExit;
                                    }
                                }

                                byte cur_recv = 128;
                                if (sendcount + cur_recv > record.Data.Length)
                                {
                                    cur_recv = (byte)(record.Data.Length - sendcount);
                                }
                                {// Read page
                                    byte[] com = new byte[5];
                                    com[0] = Cmnd_STK_READ_PAGE;
                                    com[1] = 0x00;
                                    com[2] = cur_recv;
                                    com[3] = (byte)'F';
                                    com[4] = Sync_CRC_EOP;
                                    if (!RequestForAnswer(port, com, rbuf, cur_recv + 2))
                                    {
                                        ErrorState = ErrorStatusEnum.ReadData;
                                        goto ErrorExit;
                                    }
                                    if (rbuf[0] != Resp_STK_INSYNC || rbuf[cur_recv + 1] != Resp_STK_OK)
                                    {
                                        ErrorState = ErrorStatusEnum.VerifyUnmuch;
                                        goto ErrorExit;
                                    }
                                    for (int i = 0; i < cur_recv; i++)
                                    {
                                        if (record.Data[sendcount + i] != rbuf[i + 1])
                                        {
                                            ErrorState = ErrorStatusEnum.VerifyUnmuch;
                                            goto ErrorExit;
                                        }
                                    }
                                }
                                sendcount       += cur_recv;
                                RecordProcessing = (float)sendcount / (float)record.Data.Length;
                                if (StateCallback != null)
                                {
                                    StateCallback();
                                }
                            }
                        }
                        RecordIndex++;
                    }
                    {// Leave programming mode
                        byte[] com = { Cmnd_STK_LEAVE_PROGMODE, Sync_CRC_EOP };
                        byte[] rq  = { Resp_STK_INSYNC, Resp_STK_OK };
                        if (!RequestForAnswer(port, com, rq, rbuf))
                        {
                            ErrorState = ErrorStatusEnum.Unknown;
                            goto ErrorExit;
                        }
                    }
                    if (AfterWait)
                    {
                        Interlocked.Decrement(ref CriticalCounter);// Exit critical section
                        port.BaudRate = ReciveBaudRate;
                        MainState     = MainStateEnum.ConsoleMonitor;
                        if (StateCallback != null)
                        {
                            StateCallback();
                        }
                        System.Text.StringBuilder sb = new System.Text.StringBuilder();
                        while (true)
                        {
                            if (CountMessage() > 0)
                            {
                                port.Close();
                                port.Dispose();
                                MainState  = MainStateEnum.Idle;
                                ErrorState = ErrorStatusEnum.Success;
                                // ここでstateをメインに返してInvokeするとAwakeWorkerに突入中の場合デッドロックするのでそのまま次に回す
                                break;
                            }
                            if (port.BytesToRead == 0)
                            {
                                Thread.Sleep(20);
                                continue;
                            }
                            do
                            {
                                char c = (char)port.ReadChar();
                                sb.Append(c);
                            } while (port.BytesToRead > 0);
                            if (sb.Length > 0)
                            {
                                if (ReciveCallback != null)
                                {
                                    ReciveCallback(sb.ToString());
                                }
                                sb.Remove(0, sb.Length);
                            }
                        }
                    }
                    else
                    {
                        port.Close();
                        port.Dispose();
                        Interlocked.Decrement(ref CriticalCounter);
                        MainState  = MainStateEnum.Idle;
                        ErrorState = ErrorStatusEnum.Success;
                        if (StateCallback != null)
                        {
                            StateCallback();
                        }
                        continue;
                    }
                    continue;
ErrorExit:
                    while (PopMessage() != null)
                    {
                        ;
                    }
                    port.Close();
                    port.Dispose();
                    if (CriticalCounter == 1)
                    {
                        Interlocked.Decrement(ref CriticalCounter);
                    }
                    MainState = MainStateEnum.Abort;
                    if (StateCallback != null)
                    {
                        StateCallback();
                    }
                    continue;
                }
            }
        }
示例#2
0
 public RetornoPadraoDTO(string mensagem, ErrorStatusEnum status, dynamic retorno = null)
 {
     this.Mensagem = mensagem;
     this.Status   = status;
     this.Retorno  = retorno;
 }