⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmodem.c

📁 XMODEM串口下载代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    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 + -