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

📄 xmodem_receive.c

📁 实现单片机与GPRS模块的Xmodem协议文件传输
💻 C
字号:
static unsigned char xmodem_buff[128+4];
static unsigned char xmodem_block_number;
static int xmodem_index = -1;

static int get_xmodem_frame(void)    //接受数据子函数
{
    TIMER timeout;
    int index;
    int c;

    xmodem_index = -1;

    //set_timer(&timeout, ONE_SECOND*10 );
    Delay(1000);

    do {
        c = getchar();
       } while(c < 0 && ! timer_expired(&timeout));

    if(c < 0)    return -1;                                   //返回值如果小于0则为原则性错误,停止传输

    if(c != XMODEM_SOH && c != XMODEM_EOT && c != XMODEM_CAN) //如果是开始、结束或者停止标志位返回
    {
       Delay(1000);
       do {
            c = getchar();
            if(c >= 0)  Delay(1000);
        } while( ! timer_expired(&timeout));
       return -1;  //返回值如果小于0则为原则性错误,停止传输
      }

    index = 0;
    xmodem_buff[index++] = c;    //接受开始SOH数据

    if(c == XMODEM_EOT || c == XMODEM_CAN)  return 0;        //返回值如果为0则为终止或者结束标志

    while(index < sizeof(xmodem_buff))
     {

       Delay(1000);

       do {
           c = getchar();
          } while(c < 0 && ! timer_expired(&timeout));

       if(c < 0)    return -1;  //返回值如果小于0则为原则性错误,停止传输

       xmodem_buff[index++] = c;  //接受数据DATA
      }

    xmodem_index = 0;             //接受完毕
    return 0;
 }


static int xmodem_verify_frame(void) //校验子函数累加和
{
   int i;
   unsigned char checksum;

   //检测数据包的SOH、包号和包号的补码
   if(xmodem_buff[0] != XMODEM_SOH)                        return -1; //原则性错误
   if(xmodem_buff[1] != xmodem_block_number)               return -1;
   if(xmodem_buff[2] != ((~xmodem_block_number) & 0xff))   return -1;
   //检测累加和
   checksum = 0;

   for(i = 3; i < sizeof(xmodem_buff)-1; i++)  checksum += xmodem_buff[i];

   if(checksum != xmodem_buff[sizeof(xmodem_buff)-1])      return -1; //校验和不对

   return 0; //成功
  }

static int xmodem_get_more(void)                     //获得更多数据包
{
   int err;
   int err_retry_count;

   xmodem_block_number++;
   err_retry_count = 0;

   while(err_retry_count < XMODEM_ERR_RETRY_COUNT)
    {

       if(xmodem_index < 0)    putchar(XMODEM_NAK); //发出重发信号
       err = get_xmodem_frame();//得到下一组数据

       if(err == 0)
       {
          if(xmodem_buff[0] == XMODEM_SOH)
           {
              if( xmodem_verify_frame() == 0)       //校验码成功
               {
                 putchar(XMODEM_ACK);               //传输成功
                 xmodem_index = 3;
                 return 0;
                }
              else if(xmodem_buff[1] == xmodem_block_number -1)
                  putchar(XMODEM_ACK);             //uart_sendchar

              else {
                   xmodem_index = -1;
                  }
              err_retry_count++;
              continue;
             }
           else if(xmodem_buff[0] == XMODEM_EOT)
              {
                 putchar(XMODEM_ACK);
                 xmodem_index = -1;
                 return -1;
               }
        }

       xmodem_index = -1;
       err_retry_count++;
      }

    xmodem_index = -1;
    return -2;
  }

static int xmodem_eof(void)
{
   int i;

   if(xmodem_index < 0)   return 1;

   for( i = xmodem_index; i < sizeof(xmodem_buff) -1; i++)
     {
       if(xmodem_buff[i] != XMODEM_EOF)    return 0;
       }
   if(peekchar() != XMODEM_EOT)   return 0;

   return 1;
 }

int xmodem_start(void)
{
    xmodem_index = sizeof(xmodem_buff)-1;
    xmodem_block_number = 0;

    return 0;
  }

int xmodem_finish(void)
{
    int c;

    do {
       c = xmodem_getchar();
      } while(c >= 0);

    return 0;
  }


int xmodem_abort(void)
{
    int i;

    for(i=0; i<8; i++)
       putchar(XMODEM_CAN);

    xmodem_finish();

    return 0;
  }

/****************************************************************
 * This is the user api call for xmodem transfers.
 *
 *
 */

int xmodem_getchar(void)
{
    int err;
    int c;
    if(xmodem_index < 0)   return -1;

    if(xmodem_index >= sizeof(xmodem_buff)-1)
     {
        err = xmodem_get_more();

        if(err < 0)    return err;
      }

    c = xmodem_buff[xmodem_index];
    xmodem_index++;

    if(c == XMODEM_EOF) {
       if( xmodem_eof() ) {
          xmodem_finish();
          xmodem_index = -1;
          return -1;
         }
      }

    return c;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -