Beispiel #1
0
        public void Close()
        {
            if (comn != null)
            {
                comn.DataReceived -= this.comn_DataReceived;
            }
            start = false;

            transmitState      = YmodeSendState.WAIT_START;
            transmittingYmodem = false;
            pktSize            = 0;
            resSize            = 0;
            blkNumber          = 0;
            ackReceived        = false;
            errors             = 0;
            fsFWSent           = false;
            fileBytes          = null;
            fileName           = null;
            fileIndex          = 0;
            lastRec            = 0;
        }
Beispiel #2
0
        private void timConnect_Tick(object state)
        {
            while (true)
            {
                Thread.Sleep(200);
                if (start)
                {
                    if (!transmittingYmodem)
                    {
                        if (tickNum++ > 15)
                        {
                            transmitState = YmodeSendState.WAIT_START;
                            pktSize       = 0;
                            resSize       = 0;
                            blkNumber     = 0;
                            ackReceived   = false;
                            errors        = 0;
                            fsFWSent      = false;
                            fileIndex     = 0;
                            lastRec       = 0;
                            YmodeStateChanged?.Invoke(11, "请断电,重连设备...");
                            tickNum = 1;
                        }
                    }
                    else
                    {
                        tickNum = 1;

                        bool next = recData.Count > 0;
                        while (next)
                        {
                            next = Ymodem_Transmit() == 0 && recData.Count > 0;
                        }
                    }
                }
            }
        }
Beispiel #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 */
        }