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

📄 ymodem.c

📁 一个很不错的Ymodem协议编程范例程序
💻 C
字号:
/******************** (C) COPYRIGHT 2006 STMicroelectronics ********************
* File Name          : ymodem.c
* Author             : MCD Application Team
* Date First Issued  : 10/25/2004
* Description        : This file provides all the software functions related to
*                      the ymodem protocol.
********************************************************************************
* History:
*  02/01/2006 : IAP Version 2.0
*  11/24/2004 : IAP Version 1.0
********************************************************************************
THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH
CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A 
RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR 
CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT OF SUCH 
SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN
IN CONNECTION WITH THEIR PRODUCTS.
********************************************************************************/
#include "common.h"

//#define Flash_Offset   0x40003000  /* Flash user program offset */
#define Flash_Offset   0x40004000 

char file_name[FILE_NAME_LENGTH];
u32 Flash_Destination = Flash_Offset;                     
u32 Ram_Source;

/*******************************************************************************
* Function Name  : Receive_Byte
* Description    : Receive byte from sender
* Input 1        : Character
* Input 2        : Timeout
* Return         :  0   --      Byte received                           
*                : -1   --      Timeout   
*******************************************************************************/
static s32 Receive_Byte (char *c, u32 timeout)
{
  while (timeout-- > 0)
  {
    if (SerialKeyPressed(c) == 1)
    {
      return 0;
    }
  }
  return -1;
}

/*******************************************************************************
* Function Name  : Send_Byte
* Description    : Send a byte 
* Input          : Character
* Return         :  0   --      Byte sent                           
*******************************************************************************/
static u32 Send_Byte (char c)
{
  SerialPutChar(c);
  return 0;
}

/*******************************************************************************
* Function Name  : Receive_Packet
* Description    : Receive a packet from sender 
* Input 1        : Data
* Input 2        : Length
* Input 3        : Timeout
* Return         :   0  --      normally return                         
*                :  -1  --      timeout or packet error                 
*                :   1  --      abort by user                           
*                : *length:                                                
*                :   0  --      end of transmission                    
*                :  -1  --      abort by sender                         
*                :  >0  --      packet length                                      
*******************************************************************************/
static s32 Receive_Packet (char *data, s32 *length, u32 timeout)
{
  int i, packet_size;
  char c;
  *length = 0;
  if (Receive_Byte(&c, timeout) != 0)
  {
    return -1;
  }
  switch (c)
  {
    case SOH:
      packet_size = PACKET_SIZE;
      break;
    case STX:
      packet_size = PACKET_1K_SIZE;
      break;
    case EOT:
      return 0;
    case CAN:
      if ((Receive_Byte(&c, timeout) == 0) && (c == CAN))
      {
        *length = -1;
        return 0;
      }
      else
      {
        return -1;
      }
    case ABORT1:
    case ABORT2:
      return 1;
    default:
      return -1;
  }
  *data = c;
  for (i = 1; i < (packet_size + PACKET_OVERHEAD); i ++)
  {
    if (Receive_Byte(data + i, timeout) != 0)
    {
      return -1;
    }
  }
  if (data[PACKET_SEQNO_INDEX] != ((data[PACKET_SEQNO_COMP_INDEX] ^ 0xff) & 0xff))
  {
    return -1;
  }
  *length = packet_size;
  return 0;
}
/*******************************************************************************
* Function Name  : Ymodem_Receive
* Description    : Receive a file using the ymodem protocol 
* Input          : Address of the first byte 
* Return         : The size of the file                                                               
*******************************************************************************/
u8 sector[10]={0,0};
u8 s_index=0;

s32 Ymodem_Receive (char *buf)
{

  
  
  char packet_data[PACKET_1K_SIZE + PACKET_OVERHEAD], file_size[FILE_SIZE_LENGTH], *file_ptr, *buf_ptr;
  s32 i, j, packet_length, session_done, file_done, packets_received, errors, session_begin, size = 0;
  u32 Sector_Mask = 0;  
  for (session_done = 0, errors = 0, session_begin = 0; ;)
  {
    for (packets_received = 0, file_done = 0, buf_ptr = buf; ;)
    {
      switch (Receive_Packet(packet_data, &packet_length, NAK_TIMEOUT))
      {
        case 0:
          errors = 0;
           switch (packet_length)
           {
             case -1:    /* Abort by sender */
               Send_Byte(ACK);
               return 0;
             case 0:     /* End of transmission */
               Send_Byte(ACK);
               file_done = 1;
               break;
             default:    /* Normal packet */
               if ((packet_data[PACKET_SEQNO_INDEX] & 0xff) != (packets_received & 0xff))
               {
                 Send_Byte(NAK);
               }
               else
               {
                 if (packets_received == 0)   /* Filename packet */
                 {
                   if (packet_data[PACKET_HEADER] != 0)    /* Filename packet has valid data */
                   {
                     for (i = 0, file_ptr = packet_data + PACKET_HEADER; (*file_ptr != 0) && (i < FILE_NAME_LENGTH);)
                     {
                       file_name[i++] = *file_ptr++;
                     }
                     file_name[i++] = '\0';
                     for (i = 0, file_ptr ++; (*file_ptr != ' ') && (i < FILE_SIZE_LENGTH);)
                     {
                       file_size[i++] = *file_ptr++;
                     }
                     file_size[i++] = '\0';
                     Str2Int(file_size, &size);
                     
                     /* Test the size of the image to be sent */
                     if (size > 0x3E000)
                     {
                       /* End session */
                       Send_Byte(CAN);
                       Send_Byte(CAN);
                       return -1;
                     }
                     /* Erase the needed sectors */
                     Sector_Mask = FLASH_SectorMask(size);
                     
                     sector[s_index++]=Sector_Mask;
                     
                     FLASH_SectorErase(Sector_Mask);

                     
                     GPIO1->PD  |= 0x0010; // p1.4 turn on
                     
                     
                     Send_Byte(ACK);
                     Send_Byte(CRC16);
                   }
                   else   /* Filename packet is empty; end session */
                   {
                     Send_Byte(ACK);
                     file_done = 1;
                     session_done = 1;
                     break;
                   }
                 }
                 else    /* Data packet */
                 {
                   memcpy(buf_ptr, packet_data + PACKET_HEADER, packet_length);
                   Ram_Source = 0x20002000;
                   for (j=0;(j<packet_length)&&(Flash_Destination < Flash_Offset + size);j+=4)
                   {
                     /* Program the data received into Flash */
                     FLASH_WordWrite(Flash_Destination,*(u32*)Ram_Source);
                     if(*(u32*)Flash_Destination != *(u32*)Ram_Source)
                     {
                       GPIO1->PD  |= 0x0020; // p1.5 turn on
                       /* End session */
                       Send_Byte(CAN);
                       Send_Byte(CAN);
                       return -2;
                     }
                     Flash_Destination += 4;                     
                     Ram_Source+=4;
                   }                   

                   Send_Byte(ACK);
                 }
                 packets_received ++;
                 session_begin = 1;
               }
             }
             break;
           case 1:
             Send_Byte(CAN);
             Send_Byte(CAN);
             return -3;
           default:
             if (session_begin > 0)
             {
               errors ++;
             }
             if (errors > MAX_ERRORS)
             {
               Send_Byte(CAN);
               Send_Byte(CAN);
               return 0;
             }
             Send_Byte(CRC16);
             break;
         }
         if (file_done != 0)
         {
         break;
       }
     }
     if (session_done != 0)
     {
       break;
     }
  }  
  
  GPIO1->PD  &= 0xffef;  // p1.4 turn off
  GPIO1->PD  &= 0xffdf;  // p1.5 turn off
  
  return (s32)size;
}
/*******************(C)COPYRIGHT 2006 STMicroelectronics *****END OF FILE****/

⌨️ 快捷键说明

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