Пример #1
0
 void comn_DataReceived(object sender, SerialDataReceivedEventArgs e)
 {
     if (!start)
     {
         return;
     }
     try
     {
         if (!transmittingYmodem)
         {
             string msg = string.Empty;
             if (transmitState == YmodeSendState.WAIT_START)
             {
                 char c = (char)comn.ReadChar();
                 msg += c;
                 //接收到'C'--CRC16
                 if (c == 'C')
                 {
                     //rMainform.ShowMCUMsg("\n\r Waiting for the file to be sent ...\n\r");
                     transmittingYmodem = true;
                     YmodeStateChanged?.Invoke(12, "进入Ymode模式");
                     recData.Clear();
                 }
                 else
                 {
                     msg += comn.ReadExisting(); //读取串口缓冲区数据
                     comn.Write(new[] { (byte)0x31 }, 0, 1);
                 }
             }
             else  //文件发送完毕后的信息
             {
                 msg += comn.ReadExisting(); //读取串口缓冲区数据
             }
             YmodeResponseGot?.Invoke(msg);
         }
         else
         {
             byte[] temp  = new byte[128];
             int    count = comn.Read(temp, 0, temp.Length);
             if (count > 0)
             {
                 recData.EnqueueRange(temp, 0, count);
             }
         }
     }
     catch (Exception Err)
     {
         YmodeStateChanged?.Invoke(11, "串口通信错误");
     }
 }
Пример #2
0
 private byte ReadNextByte()
 {
     if (recData.Count > 0)
     {
         byte c = recData.Dequeue();
         System.Diagnostics.Debug.WriteLine(c);
         YmodeResponseGot?.Invoke((char)c + " ");
         return(c);
     }
     else
     {
         return(0xFF);   //  error
     }
 }
Пример #3
0
        /**
         * @brief  Transmit a file using the ymodem protocol
         * @param
         * @retval
         */
        private byte Ymodem_Transmit()
        {
            byte i;
            bool CRC16_F = true;
            byte c;

            ackReceived = false;  //默认
            c           = ReadNextByte();

            //先判断是否结束传输或改变状态
            switch (transmitState)
            {
            case YmodeSendState.WAIT_START:
                if (c == CRC16)
                {
                    ackReceived = true;

                    YmodeResponseGot?.Invoke("\n\r The file is being sent ...\n\r");
                    YmodeStateChanged?.Invoke(13, "发送文件信息");
                    lastState     = transmitState;
                    transmitState = YmodeSendState.SEND_FILENAME;     //开始发送文件名及其大小
                }
                break;

            case YmodeSendState.SEND_FILENAME:
                if (c == ACK)
                {
                    YmodeStateChanged?.Invoke(13, "文件信息确认");
                    lastState = transmitState;
                }
                else
                {
                    if (c == CRC16)
                    {
                        if (lastState == YmodeSendState.SEND_FILENAME && lastRec == ACK)
                        {
                            ackReceived = true;
                            YmodeStateChanged?.Invoke(13, "开始发送文件");
                            transmitState = YmodeSendState.SEND_DATA;     //开始发送文件内容
                        }
                        else
                        {
                            errors++;
                            if (errors > 10)
                            {
                                ackReceived = true;
                            }
                        }
                    }
                }
                break;

            case YmodeSendState.SEND_DATA:
                if (c == ACK)
                {
                    ackReceived = true;
                    YmodeProgressUpdated?.Invoke(fileIndex);
                    if (fsFWSent)
                    {
                        transmitState = YmodeSendState.SEND_EOT;     //当前文件内容发送完毕
                    }
                }
                break;

            case YmodeSendState.SEND_EOT:
                if (c == ACK)
                {
                    lastState     = transmitState;
                    transmitState = YmodeSendState.SEND_LASTPACK;
                }
                break;

            case YmodeSendState.SEND_LASTPACK:
                if (c == CRC16 && lastState == YmodeSendState.SEND_EOT && lastRec == ACK)
                {
                    ackReceived = true;
                }
                else if (c == ACK)
                {
                    start = false;
                    transmittingYmodem = false;     //结束Ymodem发送
                                                    //通知“固件升级”子窗口固件升级成功
                                                    //rMainform.ReportFwUpdateResult("Succeed");
                    YmodeProgressFinished?.Invoke("Succeed");
                    YmodeStateChanged?.Invoke(14, "文件发送成功");
                    return(1);    //直接返回,然后可以发送APP代码的CRC16值
                }
                break;

            case YmodeSendState.SEND_CA:
                if (c == ACK)
                {
                    ackReceived        = true;
                    transmittingYmodem = false;     //结束Ymodem发送
                    return(0);
                }
                break;

            default:
                break;
            }

            lastRec = c;

            if (c == CA)
            {
                if (ReadNextByte() == CA) //连续两次读到CA
                {
                    transmittingYmodem = false;
                    YmodeStateChanged?.Invoke(11, "发送失败,请重试...");
                    return(0xFF); /*  error */
                }
            }

            //根据新状态来判断是否要准备新数据包
            switch (transmitState)
            {
            case YmodeSendState.SEND_FILENAME:
                if (ackReceived)    //下位机等待数据包下位机接收成功
                {
                    errors = 0;     //清零出错计数
                                    // Here 128 bytes package is used
                    pktSize = PACKET_SIZE;

                    // Prepare first block,对应数据包序号为0
                    Ymodem_PrepareIntialPacket(ref packet_data, fileName, (uint)fileBytes.Length);
                    fsFWSent  = false;
                    resSize   = (uint)fileBytes.Length;
                    fileIndex = 0;
                    blkNumber = 1;     //接下来发送第1个数据包
                }
                else
                {
                    errors++;
                }
                break;

            case YmodeSendState.SEND_DATA:
                if (ackReceived)    //上次数据包下位机接收成功
                {
                    errors = 0;     //清零出错计数
                                    // Prepare next packet
                    Ymodem_PreparePacket(ref packet_data, blkNumber, resSize);

                    /*
                     * //修改第一个数据包,加入CRC值和文件长度
                     * if (blkNumber == 1)
                     * {
                     *  UInt16 crc = CalcFileCRC16(ref fiFW);
                     * }
                     */

                    if (resSize >= PACKET_1K_SIZE)     //剩余字节数大于等于1024
                    {
                        // Here 1024 bytes package is used to send the packets
                        pktSize = PACKET_1K_SIZE;
                    }
                    else if (resSize > PACKET_SIZE)     //剩余字节数大于128且小于1024
                    {
                        pktSize = PACKET_1K_SIZE;
                    }
                    else     //剩余字节数小于等于128,且大于0
                    {
                        pktSize = PACKET_SIZE;
                    }
                    if (resSize > PACKET_1K_SIZE)     //判断是否还有数据包需要发送
                    {
                        resSize -= PACKET_1K_SIZE;
                        if (blkNumber > (fileBytes.Length / 1024))     //发送的数据包数量不能超出数据包总数量
                        {
                            transmittingYmodem = false;
                            return(0xFF);    //  error
                        }
                        else
                        {
                            blkNumber++;
                        }
                    }
                    else
                    {
                        blkNumber++;
                        resSize  = 0;
                        fsFWSent = true;     //文件数据发送完毕,准备进入下一状态
                    }
                }
                else
                {
                    errors++;
                }
                break;

            case YmodeSendState.SEND_LASTPACK: //发送序号为0的空数据包,结束文件传输
                if (ackReceived)               //上次数据包发送成功
                {
                    errors = 0;
                    // Last packet preparation
                    packet_data[0] = SOH;
                    packet_data[1] = 0;
                    packet_data[2] = 0xFF;
                    for (i = PACKET_HEADER; i < (PACKET_SIZE + PACKET_HEADER); i++)
                    {
                        packet_data[i] = 0x00;
                    }
                    pktSize = PACKET_SIZE;
                }
                break;

            case YmodeSendState.SEND_EOT:
            case YmodeSendState.SEND_CA:
                if (ackReceived)     //上次数据包发送成功
                {
                    errors = 0;
                }
                else
                {
                    errors++;
                }
                break;

            default:
                break;
            }

            if (errors >= 0xFF)
            {
                transmittingYmodem = false;
                //通知“固件升级”子窗口固件升级失败
                //rMainform.ReportFwUpdateResult("Fail");
                YmodeProgressFinished?.Invoke("Fail");
                YmodeStateChanged?.Invoke(11, "发送失败...");
                return(errors);
            }
            else //发送上次的数据包或新数据包
            {
                if ((transmitState == YmodeSendState.SEND_FILENAME) ||
                    (transmitState == YmodeSendState.SEND_DATA) ||
                    (transmitState == YmodeSendState.SEND_LASTPACK))
                {
                    bool send = false;
                    if (transmitState == YmodeSendState.SEND_FILENAME && ackReceived)
                    {
                        send = true;
                        System.Diagnostics.Debug.WriteLine("发送文件名大小");
                    }
                    else if (transmitState == YmodeSendState.SEND_DATA && ackReceived)
                    {
                        send = true;
                        System.Diagnostics.Debug.WriteLine("发送文件内容:" + (blkNumber - 1));
                    }
                    else if (transmitState == YmodeSendState.SEND_LASTPACK && ackReceived)
                    {
                        send = true;
                        System.Diagnostics.Debug.WriteLine("发送最后空数据");
                    }

                    if (send) //新数据包待发送,重新计算校验值
                    {
                        // Send CRC or CheckSum based on CRC16_F
                        if (CRC16_F)
                        {
                            packCRC = Cal_CRC16(ref packet_data, 3, pktSize); //前3个数据不包含在CRC计算范围内
                        }
                        else
                        {
                            packCheckSum = CalChecksum(ref packet_data, 3, pktSize); //前3个数据不包含在CRC计算范围内
                        }

                        //send packet
                        try
                        {
                            System.Diagnostics.Debug.WriteLine("CRC16:" + packCRC);
                            int len = pktSize + PACKET_HEADER;
                            // Send CRC or CheckSum based on CRC16_F
                            if (CRC16_F)
                            {
                                packet_data[len]     = (byte)(packCRC >> 8);
                                packet_data[len + 1] = (byte)(packCRC & 0xFF);
                                len += 2;
                            }
                            else
                            {
                                packet_data[len] = packCheckSum;
                                len += 1;
                            }

                            comn.Write(packet_data, 0, len);
                            ackReceived = false; //在接收事件处理函数中判断是否发送成功
                        }
                        catch (Exception e)
                        {
                            transmittingYmodem = false;
                            DataSendFailed?.Invoke();
                            YmodeStateChanged?.Invoke(11, "串口通信错误");
                            return(0xFF); /*  error */
                        }
                    }
                }

                else if (transmitState == YmodeSendState.SEND_EOT) //send EOT
                {
                    try
                    {
                        if (ackReceived)
                        {
                            comn.Write(new[] { EOT }, 0, 1);
                            ackReceived = false; //在接收事件处理函数中判断是否发送成功
                            System.Diagnostics.Debug.WriteLine("发送EOT");
                        }
                    }
                    catch (Exception e)
                    {
                        transmittingYmodem = false;
                        YmodeStateChanged?.Invoke(11, "串口通信错误");
                        return(0xFF); //  error
                    }
                }
            }

            return(0); /* packet trasmitted successfully */
        }