📄 xmodem.c
字号:
return RETURN_NO_ERR;
}
/******************************************************************************
* 函数名称: CRC(void) *
* 功能 : 由于xModem协议面向字符的,本函数完成对CRC字段的接收 *
******************************************************************************/
unsigned long XMODEM_Crc( void )
{
unsigned char data;
unsigned short CRC;
unsigned char sec;
unsigned short CRC2;
unsigned char *p;
unsigned long i, k;
struct reltime time;
RTC_GetTime( &time );
sec = time.second;
for( k = 0; k < 2; k++ )
{
for( i = 0 ; i < BIOS_CLI_TERM_TIME; )
{
RTC_GetTime( &time );
if( sec != time.second )
{
i++;
sec = time.second;
}
if( UART_kbhit( COM0 ))
{
data = (unsigned char)UART_getchar( COM0 );
break;
}
}
if( i >= BIOS_CLI_TERM_TIME )
{
UART_putchar( COM0, NAK );
g_dwDownLoadState = START_OF_HEADER;
return RETURN_NO_ERR;
}
g_SXModemPacket.CRC[ k ] = data;
}
p = (unsigned char*)&CRC;
*p++ = g_SXModemPacket.CRC[1];
*p = g_SXModemPacket.CRC[0];
CRC2 = XMODEM_CalCRC ( g_SXModemPacket.Data, DATA_NUM_PER_PACKET );
if ( CRC != CRC2 )
{
XMODEM_Purge();
UART_putchar( COM0, NAK );
}
else
{
UART_putchar( COM0, ACK );
g_ucLastSeqNo = g_SXModemPacket.SeqNo;
for( i = 0; i < DATA_NUM_PER_PACKET; i++ )
{
*XMODEM_LoadBuffer++ = g_SXModemPacket.Data[ i ];
}
g_LoadLength += DATA_NUM_PER_PACKET;
if( g_LoadLength > g_dwAllowedMaxLength )
{
return 0xffffffff;
}
}
g_dwDownLoadState = START_OF_HEADER;
return RETURN_NO_ERR;
}
/******************************************************************************
* 函数名称: XModemPurge(void) *
* 功能 : 清空串口接收缓冲BUFFER中的信息 *
******************************************************************************/
void XMODEM_Purge ( void )
{
unsigned char data;
for(;;)
{
if( UART_kbhit(COM0) )
data = (unsigned char)UART_getchar( COM0 );
else
break;
}
return;
}
void XMODEM_LeaveProcess( void )
{
UART_putchar( COM0, CAN );
UART_putchar( COM0, CAN );
XMODEM_Purge();
}
/*****************************************************************************/
/* 函数名称: XModemDump() */
/* 功能 : 完成xModem协议的发送功能,从而实现DUMP功能。 */
/*****************************************************************************/
unsigned long XMODEM_Dump( unsigned char *src_add, unsigned long ulSendDataLength )
{
unsigned char ucXModemPacket[ XMODEM_PAKET_LENGTH ];
unsigned long all_frame_num; //帧数
unsigned long last_frame_len; //最后一帧长度
unsigned long current_order;
unsigned char *source_ptr;
unsigned char current_state;
unsigned char EOT_sended;
unsigned char recv_ch;
unsigned long i;
unsigned char ucData;
// 初始化变量
source_ptr = src_add;
current_state = NOTSTART;
EOT_sended = FALSE;
current_order = 0;
// 获取要发送的数据的总长度
i = ulSendDataLength;
if (i % 128)
{
all_frame_num = i / 128 + 1;
last_frame_len = i % 128;
}
else
{
all_frame_num = i/128;
last_frame_len = 128;
}
ucData = (unsigned char)UART_getchar( COM0 );
for(;;)
{
ucData = (unsigned char)UART_getchar( COM0 );
switch ( recv_ch )
{
case 'C' :
if(STARTED == current_state)
break;
source_ptr = src_add;
current_order = 1;
current_state = STARTED;
EOT_sended = FALSE;
// XMODEM_ProduceSendString(source_ptr, ucXModemPacket,current_order, all_frame_num, last_frame_len);
current_order ++;
// g_ulXmodemSeq = current_order;
source_ptr += 128;
for ( i = 0; i < XMODEM_PAKET_LENGTH; i++ )
{
UART_putchar( COM0, ucXModemPacket[i] );
}
// 启动定时器
continue;
case NAK :
if( STARTED == current_state )
{
for ( i = 0; i < XMODEM_PAKET_LENGTH; i++ )
{
UART_putchar( COM0, ucXModemPacket[i] );
}
// 启动定时器
}
continue;
case ACK :
if( STARTED == current_state )
{
if( current_order == all_frame_num+1)
{// 最后一帧的确认
if (!EOT_sended)
{
UART_putchar( COM0, EOT );
// 启动定时器
EOT_sended = TRUE;
}
else
{
return RETURN_NO_ERR;
}
}
else
{// 发送下一帧
// XmodemProduceSendString(source_ptr, ucXModemPacket,current_order, all_frame_num, last_frame_len);
current_order ++;
source_ptr += 128;
for ( i = 0; i < XMODEM_PAKET_LENGTH; i++ )
{
UART_putchar( COM0, ucXModemPacket[i] );
}
// 启动定时器
}
continue;
}
break;
case CAN :
XMODEM_LeaveProcess();
return 1;
default :
// 完善xmodem本端的处理
XMODEM_LeaveProcess();
return 1;
}
/* {
{ // 超时
if (current_state == NOTSTART)
{
// 未曾收到 'C'
// if( g_ulSendRepeatTime > MAX_REPEAT_TIME_C )
{
XmodemLeaveProcess();
return 1;
}
}
else
{
// if( g_ulSendRepeatTime > MAX_REPEAT_TIME_ACK )
{
XmodemLeaveProcess();
return 1;
}
// else
{
// 重发
if(EOT_sended)
{
UART_putchar( COM0, EOT );
}
else
{
for ( i = 0; i < XMODEM_PAKET_LENGTH; i++ )
{
UART_putchar( COM0, ucXModemPacket[i] );
}
}
}
}
}
}
*/
}
}
/*****************************************************************************/
/* 函数名称: ProduceSendString() */
/* 功能 : 将要发送的信息打成xModem协议包。 */
/*****************************************************************************/
void XMODEM_ProduceSendString( unsigned char *source_ptr, unsigned char *target_ptr, unsigned long order,
unsigned long all_frame_num, unsigned char size )
{
unsigned char *tmp_ptr = source_ptr;
unsigned short temp_crc;
unsigned char *ret_ptr;
unsigned char ucTempOrder = (unsigned char)order;
unsigned char i;
ret_ptr = target_ptr;
*ret_ptr = SOH;
ret_ptr ++;
*ret_ptr = ucTempOrder;
ret_ptr ++;
*ret_ptr = (unsigned char)(MAX_SEQ_NO - ucTempOrder);
ret_ptr ++;
if (order == all_frame_num)
{
for( i = 0; i < size; i++ )
{
ret_ptr[i] = tmp_ptr[i];
}
for ( i = (unsigned char)size; i < DATA_NUM_PER_PACKET; i++ )
{
ret_ptr[i] = 26; // ^Z
}
}
else
{
for( i = 0; i < DATA_NUM_PER_PACKET; i++ )
{
ret_ptr[i] = tmp_ptr[i];
}
}
temp_crc = XMODEM_CalCRC( ret_ptr, DATA_NUM_PER_PACKET );
ret_ptr += 128;
*(unsigned short*)ret_ptr = temp_crc;
ret_ptr += 2;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -