单片机Ymodem协议C语言,YMODEM协议串口文件传输

本文档介绍了Ymodem协议的C语言实现,适用于单片机环境。代码包括Ymodem类的定义,包含了接收和发送文件的各个阶段,如建立连接、数据传输和结束传输等。通过设置时间间隔、最大错误次数等参数,实现文件的可靠传输。
摘要由CSDN通过智能技术生成

/**

******************************************************************************

* @file    Ymodem.cpp

* @author  XinLi

* @version v1.0

* @date    21-January-2018

* @brief   Ymodem protocol module source file.

******************************************************************************

* @attention

*

*

Copyright © 2018 XinLi

*

* This program is free software: you can redistribute it and/or modify

* it under the terms of the GNU General Public License as published by

* the Free Software Foundation, either version 3 of the License, or

* (at your option) any later version.

*

* This program is distributed in the hope that it will be useful,

* but WITHOUT ANY WARRANTY; without even the implied warranty of

* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

* GNU General Public License for more details.

*

* You should have received a copy of the GNU General Public License

* along with this program.  If not, see .

*

******************************************************************************

*/

/* Header includes -----------------------------------------------------------*/

#include "Ymodem.h"

#include

/* Macro definitions ---------------------------------------------------------*/

/* Type definitions ----------------------------------------------------------*/

/* Variable declarations -----------------------------------------------------*/

/* Variable definitions ------------------------------------------------------*/

/* Function declarations -----------------------------------------------------*/

/* Function definitions ------------------------------------------------------*/

/**

* @brief  Ymodem constructor.

* @param  [in] timeDivide: The fractional factor of the time the ymodem is called.

* @param  [in] timeMax:    The maximum time when calling the ymodem.

* @param  [in] errorMax:   The maximum error count when calling the ymodem.

* @note   The longest waiting time = call time / (@timeDivide + 1) * (@timeMax + 1).

* @return None.

*/

Ymodem::Ymodem(uint32_t timeDivide, uint32_t timeMax, uint32_t errorMax)

{

this->timeDivide = timeDivide;

this->timeMax    = timeMax;

this->errorMax   = errorMax;

this->timeCount  = 0;

this->errorCount = 0;

this->dataCount  = 0;

this->code       = CodeNone;

this->stage      = StageNone;

}

/**

* @brief  Set the fractional factor of the time the ymodem is called.

* @param  [in] timeDivide: The fractional factor of the time the ymodem is called.

* @return None.

*/

void Ymodem::setTimeDivide(uint32_t timeDivide)

{

this->timeDivide = timeDivide;

}

/**

* @brief  Get the fractional factor of the time the ymodem is called.

* @param  None.

* @return The fractional factor of the time the ymodem is called.

*/

uint32_t Ymodem::getTimeDivide()

{

return timeDivide;

}

/**

* @brief  Set the maximum time when calling the ymodem.

* @param  [in] timeMax: The maximum time when calling the ymodem.

* @return None.

*/

void Ymodem::setTimeMax(uint32_t timeMax)

{

this->timeMax = timeMax;

}

/**

* @brief  Get the maximum time when calling the ymodem.

* @param  None.

* @return The maximum time when calling the ymodem.

*/

uint32_t Ymodem::getTimeMax()

{

return timeMax;

}

/**

* @brief  Set the maximum error count when calling the ymodem.

* @param  [in] errorMax: The maximum error count when calling the ymodem.

* @return None.

*/

void Ymodem::setErrorMax(uint32_t errorMax)

{

this->errorMax = errorMax;

}

/**

* @brief  Get the maximum error count when calling the ymodem.

* @param  None.

* @return The maximum error count when calling the ymodem.

*/

uint32_t Ymodem::getErrorMax()

{

return errorMax;

}

/**

* @brief  Ymodem receive.

* @param  None.

* @return None.

*/

void Ymodem::receive()

{

switch(stage)

{

case StageNone:

{

receiveStageNone();

break;

}

case StageEstablishing:

{

receiveStageEstablishing();

break;

}

case StageEstablished:

{

receiveStageEstablished();

break;

}

case StageTransmitting:

{

receiveStageTransmitting();

break;

}

case StageFinishing:

{

receiveStageFinishing();

break;

}

default:

{

receiveStageFinished();

}

}

}

/**

* @brief  Ymodem transmit.

* @param  None.

* @return None.

*/

void Ymodem::transmit()

{

switch(stage)

{

case StageNone:

{

transmitStageNone();

break;

}

case StageEstablishing:

{

transmitStageEstablishing();

break;

}

case StageEstablished:

{

transmitStageEstablished();

break;

}

case StageTransmitting:

{

transmitStageTransmitting();

break;

}

case StageFinishing:

{

transmitStageFinishing();

break;

}

default:

{

transmitStageFinished();

}

}

}

/**

* @brief  Ymodem abort.

* @param  None.

* @return None.

*/

void Ymodem::abort()

{

timeCount  = 0;

errorCount = 0;

dataCount  = 0;

code       = CodeNone;

stage      = StageNone;

for(txLength = 0; txLength < YMODEM_CODE_CAN_NUMBER; txLength++)

{

txBuffer[txLength] = CodeCan;

}

write(txBuffer, txLength);

}

/**

* @brief  Receives a packet of data.

* @param  None.

* @return Packet type.

*/

Ymodem::Code Ymodem::receivePacket()

{

if(code == CodeNone)

{

if(read(&(rxBuffer[0]), 1) > 0)

{

if(rxBuffer[0] == CodeSoh)

{

uint32_t len = read(&(rxBuffer[1]), YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1);

if(len < (YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - 1))

{

rxLength = len + 1;

code     = CodeSoh;

return CodeNone;

}

else

{

return CodeSoh;

}

}

else if(rxBuffer[0] == CodeStx)

{

uint32_t len = read(&(rxBuffer[1]), YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1);

if(len < (YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - 1))

{

rxLength = len + 1;

code     = CodeStx;

return CodeNone;

}

else

{

return CodeStx;

}

}

else

{

return (Code)(rxBuffer[0]);

}

}

else

{

return CodeNone;

}

}

else

{

if(code == CodeSoh)

{

uint32_t len = read(&(rxBuffer[rxLength]), YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - rxLength);

if(len < (YMODEM_PACKET_SIZE + YMODEM_PACKET_OVERHEAD - rxLength))

{

rxLength += len;

return CodeNone;

}

else

{

code = CodeNone;

return CodeSoh;

}

}

else if(code == CodeStx)

{

uint32_t len = read(&(rxBuffer[rxLength]), YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - rxLength);

if(len < (YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD - rxLength))

{

rxLength += len;

return CodeNone;

}

else

{

code = CodeNone;

return CodeStx;

}

}

else

{

code = CodeNone;

return CodeNone;

}

}

}

/**

* @brief  Receive none stage.

* @param  None.

* @return None.

*/

void Ymodem::receiveStageNone()

{

timeCount   = 0;

errorCount  = 0;

dataCount   = 0;

code        = CodeNone;

stage       = StageEstablishing;

txBuffer[0] = CodeC;

txLength    = 1;

write(txBuffer, txLength);

}

/**

* @brief  Receive establishing stage.

* @param  None.

* @return None.

*/

v

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值