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; } } }
public RetornoPadraoDTO(string mensagem, ErrorStatusEnum status, dynamic retorno = null) { this.Mensagem = mensagem; this.Status = status; this.Retorno = retorno; }