http://www.cnblogs.com/mfrbuaa/p/5251628.html

简介:

STM32F051 IAP源代码分享

 

假设不懂IAP的请自己主动脑补或者怒戳这里

http://www.openedv.com/posts/list/11494.htm

 

然后STM32F051的IAP有一点差别也请自己主动脑补 ^_^

 

事实上我仅仅是来分享源代码的:

 

事情是介个样子滴:

 

IAP须要有两个project。第一个是Bootloader。第二个是Application

同一时候将这两份程序放在mcu的flash里的不同位置,启动时自己主动进入bootloader(可选择)进行iap,成功后跳转至application。

 

完整源代码见最后内容,这里先瞎扯一点点:

 

那么IAP问题简化成三个步骤,

Step1:做Bootloaderproject

Step2:做Applicationproject

Step3:烧进Flash的不同位置

 

Step1:须要做这些事情:

1:初始化IAP相关外设

2:下载文件(ymodem协议)

3: 写入Application程序存储空间

鸡:

     IAP_Init();

     SerialDownload();

详细实现:

/**
  *@brief  Initialize the Iap module(leddelay usart and unlock flash)
  *@param  None
  *@retval None
  */
void IAP_Init(void)
{
  uint32_tt;
 LEDInit();                  /*--Set up Led to Output signal  --*/
 SysTickInit();                 /*-- Config System Tick for delay functions --*/
 USART_Configuration();            /*-- Config usart to download .bin --*/
 FLASH_If_Init();                     /*-- Unlock Flash --*/
 for(t = 2000; t > 10; t >>= 1 )        /*-- LED1 blink 3 second indeicate IAPbegin--*/
  {
   LEDTogle(1); delayms(t);
  }
}
 
 
void SerialDownload(void)
{
 uint8_t Number[10] = {0};
 int32_t Size = 0;
 
  SerialPutString("Waitingfor the file to be sent ... (press 'a' to abort)\n\r");
 Size = Ymodem_Receive(&tab_1024[0]);
  if(Size > 0)
  {
   SerialPutString("\n\n\r Programming CompletedSuccessfully!\n\r--------------------------------\r\n Name: ");
   SerialPutString(FileName);
   Int2Str(Number, Size);
   SerialPutString("\n\r Size: ");
   SerialPutString(Number);
   SerialPutString(" Bytes\r\n");
   SerialPutString("-------------------\n");
  }
 else if (Size == -1)
  {
   SerialPutString("\n\n\rThe image size is higher than the allowedspace memory!\n\r");
  }
 else if (Size == -2)
  {
   SerialPutString("\n\n\rVerification failed!\n\r");
  }
 else if (Size == -3)
  {
   SerialPutString("\r\n\nAborted by user.\n\r");
  }
 else
  {
    SerialPutString("\n\rFailedto receive the file!\n\r");
  }
}


 

Step2:须要这样干:

在Applicationproject中程序执行的一開始加上例如以下中断拷贝就可以

void InterruptRemap(void)
{
       u8 i;
       u32 Data;
       u32 Address;
       for(i=1;i<48;i++)
       {
               Data =  *(__IOu32*)(0x08003000+i*4);
               Address = 0x20000000 + (i*4);
                *(__IO u32*)Address= (u32)Data;
       }
       SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);
}


 

Step3:这就样

将两个project分别烧在不同的flash地址段中

A:bootloader

 

1:点Project选项卡,然后点Optionsfor Target选项如图:


2:Target选项卡下有on-chip地址设置,bootloader放在0x8000000开头的0x3000空间内

如图:



然后正常手段烧入flash就可以。

 

B:application

和上述设置手段一样。仅仅只是in-chip的IROM1设置起始地址为0x8003000。Size为mcu的Flash大小减去0x3000就可以(注意是16进制哦)

 

然后就祝你幸福了   0.0

 

 

 

 

 

 

完整源代码:

 

Main.c

 

 

/* Includes------------------------------------------------------------------*/
#include "stm32f0xx.h"
#include "flash.h"
#include "powerAPI.h"
#include "IAP_Bootloader.h"
 
 
/**
  *@brief  Main program.
  *@param  None
  *@retval None
  */
int main(void)
{
 SystemPowerUp();               /*-- PowerUp && LoadSysMsg --*/
 while (1)
  {
   if(FLASH_If_ReadWord((uint32_t)IAP_READY_FLAG_ADDRESS) == FLAG_READY)
    {
     IAP_Init();
     SerialDownload();
     IAP_End_Clear_Flag();
    }
   else
    {
     JumpToApp();
    }
  }
 return 0;
}


 

 

 

/**
 ******************************************************************************
  *@file      bootloader.c
  *@brief     IAP module function
  *@CPU       STM32F051
  *@compiler  Keil uVision V4.74
  *@author    MetalSeed
  *@version   V1.0.0
  *@date      18-Sept-2014
  *@modifydate20-Sept-2014
 ******************************************************************************
  *@attention
  */
#include "stm32f0xx.h" 
#include "IAP_Bootloader.h"
#include "uart.h"
#include "led.h"
#include "delay.h"
#include "flash.h"
#include "ymodem.h"
 
/*================================================================
        APPLICATION_ADDRESS   =   (uint32_t)0x08003000
                        defined in flash
================================================================*/
 
extern uint32_t IapReady;
uint8_t tab_1024[1024] ={ 0 };
uint8_t FileName[FILE_NAME_LENGTH];
 
 
 
 
/*================================================================
                            About Jump             
================================================================*/
typedef void (*pFunction)(void); /*-- define a function type --*/
 
uint32_t JumpAddress; /*-- define the usrapp's address --*/
 
pFunction JumpToApplication; /*-- definethe function pointer which direct to usr app --*/
 
 
/**
  *@brief  Jump to application
  *@retval None
  */
void JumpToApp(void)
{
   if (((*(__IO uint32_t*)APPLICATION_ADDRESS) & 0x2FFE0000 ) ==0x20000000)/*-- check whether stack pointer legal --*/
    {
     
     JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);
     JumpToApplication = (pFunction) JumpAddress;
     
     __set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS); /*-- initialize theheap & stack pointer --*/
 
     JumpToApplication();
    }
}
 
 
 
 
/*================================================================
                    About IAP Download
================================================================*/
/**
  *@brief  Initialize the Iap module(leddelay usart and unlock flash)
  *@param  None
  *@retval None
  */
void IAP_Init(void)
{
 uint32_t t;
 LEDInit();                  /*--Set up Led to Output signal  --*/
 SysTickInit();                 /*-- Config System Tick for delay functions --*/
 USART_Configuration();             /*-- Config usart to download .bin --*/
 FLASH_If_Init();                     /*-- Unlock Flash --*/
 for(t = 2000; t > 10; t >>= 1 )        /*-- LED1 blink 3 second indeicate IAPbegin--*/
  {
   LEDTogle(1); delayms(t);
  }
}
 
 
/**
  *@brief  IAP end, Clear Iap ready flag andoutput success signal
  *@retval None
  */
void IAP_End_Clear_Flag()
{
 uint32_t i;
 if(FLASH_If_WriteWord(IAP_READY_FLAG_ADDRESS, FLAG_UNREADY)  == 0)/*-- clear iap ready flag --*/
  {
   for(i = 0; i < 50; ++i) /*-- IAP end, Led1 and Led2 blink in turnlast 2.5 second --*/
    {
     LEDTogle(1); delayms(50); LEDTogle(2);
    }
  }
 LED1ON;                  /*-- IAPend, Led1 and Led2 turn ON last 3 second --*/
 LED2ON;
 delayms(3000);
}
 
 
/**
  *@brief  In App Program by Serial
  *@retval None
  */
void SerialDownload(void)
{
 uint8_t Number[10] = {0};
 int32_t Size = 0;
 
 SerialPutString("Waiting for the file to be sent ... (press 'a' toabort)\n\r");
 Size = Ymodem_Receive(&tab_1024[0]);
  if(Size > 0)
  {
   SerialPutString("\n\n\r Programming CompletedSuccessfully!\n\r--------------------------------\r\n Name: ");
   SerialPutString(FileName);
   Int2Str(Number, Size);
   SerialPutString("\n\r Size: ");
   SerialPutString(Number);
   SerialPutString(" Bytes\r\n");
   SerialPutString("-------------------\n");
  }
 else if (Size == -1)
  {
   SerialPutString("\n\n\rThe image size is higher than the allowedspace memory!\n\r");
  }
 else if (Size == -2)
  {
   SerialPutString("\n\n\rVerification failed!\n\r");
  }
 else if (Size == -3)
  {
   SerialPutString("\r\n\nAborted by user.\n\r");
  }
 else
  {
   SerialPutString("\n\rFailed to receive the file!\n\r");
  }
}
 
 
/**
  *@brief  Upload a file via serial port.
  *@param  None
  *@retval None
  */
void SerialUpload(void)
{
 uint8_t status = 0 ;
 
 SerialPutString("\n\n\rSelect Receive File\n\r");
 
  if(GetKey() == CRC16)
  {
   /* Transmit the flash image through ymodem protocol */
   status = Ymodem_Transmit((uint8_t*)APPLICATION_ADDRESS, (constuint8_t*)"UploadedFlashImage.bin", USER_FLASH_SIZE);
 
   if (status != 0)
    {
     SerialPutString("\n\rError Occurred while TransmittingFile\n\r");
    }
   else
    {
     SerialPutString("\n\rFile uploaded successfully \n\r");
    }
  }
}


 

 

 

 

FLASH.c
/**
 ******************************************************************************
  *@file      flash.c
  *@brief     XXX function
  *@CPU       STM32F051
  *@compiler  Keil uVision V4.74
  *@author    MetalSeed
  *@version    V1.0.0
  *@date      18-Sept-2014
  *@modifydate20-Sept-2014
 ******************************************************************************
  *@attention
  */
 
/* Includes ------------------------------------------------------------------*/
 
#include "stm32f0xx.h"
#include "flash.h"
#include "uart.h"
 
/** @addtogroup STM32F0xx_IAP
  *@{
  */
 
/**
  *@brief  Unlocks Flash for write access
  *@param  None
  *@retval None
  */
void FLASH_If_Init(void)
{
  /*Unlock the Program memory */
 FLASH_Unlock();
 
  /*Clear all FLASH flags */ 
 FLASH_ClearFlag(FLASH_FLAG_EOP|FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR |FLASH_FLAG_BSY);  
}
 
/**
  *@brief  This function does an erase of alluser flash area
  *@param  StartSector: start of user flasharea
  *@retval 0: user flash area successfully erased
 *         1: error occurred
  */
uint32_t FLASH_If_Erase(uint32_tStartSector)
{
 uint32_t flashaddress;
 
 flashaddress = StartSector;
 
 while (flashaddress <= (uint32_t) USER_FLASH_LAST_PAGE_ADDRESS)
  {
   if (FLASH_ErasePage(flashaddress) == FLASH_COMPLETE)
    {
     flashaddress += FLASH_PAGE_SIZE;
    }
   else
    {
     /* Error occurred while page erase */
     return (1);
    }
  }
 return (0);
}
 
/**
  *@brief  Read uint32_t int
  *@param  FlashAddress: address to be read
  *@retval Read value 
  */
uint32_t FLASH_If_ReadWord(__IO uint32_tFlashAddress)
{
 return *(uint32_t*)FlashAddress;
}
 
/**
  *@brief  Erase flash by one page
  *@param  SectorNum: page number
  *@retval None
  */
uint32_t FLASH_If_ErasePage(uint32_tSectorNum)
{
 uint32_t flashaddress;
 
 flashaddress = SectorNum;
  if(FLASH_ErasePage(flashaddress) == FLASH_COMPLETE)
  {
   return 0;
  }
 else
  {
   /* Error occurred while page erase */
   return (1);
  }
}
 
/**
  *@brief  Write uint32_t int
  *@param  FlashAddress: address to write
  *@param  Data: data to be write
  *@retval 0: Write success 
  *@retval 1: Write error 
  *@retval 2: read error 
  */
uint32_t FLASH_If_WriteWord(uint32_tFlashAddress, uint32_t Data)
{
  if(FLASH_ProgramWord(FlashAddress, Data) == FLASH_COMPLETE)
  {
   /*Check the written value */
   if (*(uint32_t*)FlashAddress != Data)
    {
     /* Flash content doesn't match SRAM content */
     return(2);
    }
   return 0;
  }
 else
  {
   /* Error occurred while writing data in Flash memory */
   return (1);
  }
}
 
 
/**
  *@brief  This function writes a databuffer in flash (data are 32-bit aligned).
  *@note   After writing data buffer, theflash content is checked.
  *@param  FlashAddress: start address forwriting data buffer
  *@param  Data: pointer on data buffer
  *@param  DataLength: length of data buffer(unit is 32-bit word)  
  *@retval 0: Data successfully written to Flash memory
 *         1: Error occurred whilewriting data in Flash memory
 *         2: Written Data in flashmemory is different from expected one
  */
 
uint32_t FLASH_If_Write(__IO uint32_t*FlashAddress, uint32_t* Data ,uint16_t DataLength)  //ÐèÒª½«Á½¸öµØÖ·¸³Öµ¹ýÀ´¡£°´Êý¾Ý³¤¶È½«Êý¾ÝдÈëflash
{
 uint32_t i = 0;
  for(i = 0; (i < DataLength) && (*FlashAddress <=(USER_FLASH_END_ADDRESS-4)); i++)
  {
   /* the operation will be done by word */
   if (FLASH_ProgramWord(*FlashAddress, *(uint32_t*)(Data+i)) ==FLASH_COMPLETE)
    {
    /* Check the written value */
     if (*(uint32_t*)*FlashAddress != *(uint32_t*)(Data+i))
     {
       /* Flash content doesn't match SRAM content */
       return(2);
     }
     /* Increment FLASH destination address */
     *FlashAddress += 4;
    }
   else
    {
     /* Error occurred while writing data in Flash memory */
     return (1);
    }
  }
 
 return (0);
}
/**
  *@brief  Disables the write protection ofuser desired pages
  *@param  None
  *@retval 0: Write Protection successfully disabled
 *         1: Error: Flash writeunprotection failed
 *         2: Flash memory is not writeprotected
  */
uint32_tFLASH_If_DisableWriteProtection(void)
{
 uint32_t UserMemoryMask = 0, WRPR = 0;
 FLASH_Status status = FLASH_BUSY;
 
  /*Clear all FLASH flags */ 
 FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR |FLASH_FLAG_BSY);
 
  /*Get Write protection */
 WRPR = FLASH_OB_GetWRP();
 
  /*Test if user memory is write protected */
  if(FLASH_If_GetWriteProtectionStatus() != 0x00)
  {
    /* Enable the FLASH option byte access */
   FLASH_OB_Unlock(); 
 
   /* Erase option bytes */
   status = FLASH_OB_Erase();
 
   /* Compute the User_Mask */
   UserMemoryMask = FLASH_PROTECTED_PAGES | WRPR;
   
   if (UserMemoryMask != 0xFFFFFFFF)
    {
   /* Disable Write protection */
   status = FLASH_OB_EnableWRP((uint32_t)~UserMemoryMask);
    }
   
   if (status == FLASH_COMPLETE)
    {
     /* Write Protection successfully disabled */
     return (0);
    }
   else
    {
     /* Error: Flash write unprotection failed */
     return (1);
    }
  }
 else
  {
    /* Flash memory is not write protected */
    return(2);
  }
}
 
/**
  *@brief  Returns the write protectionstatus of user flash area.
  *@param  None
  *@retval If the sector is write-protected, the corresponding bit in returned
 *         value is set.
 *         If the sector isn'twrite-protected, the corresponding bit in returned
 *         value is reset.
  */
uint32_t FLASH_If_GetWriteProtectionStatus(void)
{
 return(~FLASH_OB_GetWRP() & FLASH_PROTECTED_PAGES);
}
 
 
/**
  *@}
  */
 
 
/************************ (C) COPYRIGHTSTMicroelectronics *****END OF FILE****/
 


 

 

 

Ymodem.c

 

 

 

/**
 ******************************************************************************
  *@file    STM32F0xx_IAP/src/ymodem.c
  *@author  MCD Application Team
  *@version V1.0.0
  *@date    29-May-2012
  *@brief   Main program body
 ******************************************************************************
  *@attention
  *
  *<h2><center>&copy; COPYRIGHT 2012STMicroelectronics</center></h2>
  *
  *Licensed under MCD-ST Liberty SW License Agreement V2, (the"License");
  *You may not use this file except in compliance with the License.
  *You may obtain a copy of the License at:
  *
 *       http://www.st.com/software_license_agreement_liberty_v2
  *
  *Unless required by applicable law or agreed to in writing, software
  *distributed under the License is distributed on an "AS IS" BASIS,
  *WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  *See the License for the specific language governing permissions and
  *limitations under the License.
  *
 ******************************************************************************
  */
/* Includes------------------------------------------------------------------*/
 
#include "ymodem.h"
#include "uart.h"
#include "string.h"
#include "flash.h"
 
 
/** @addtogroup STM32F0xx_IAP
  *@{
  */
 
/* Private typedef-----------------------------------------------------------*/
/* Private define------------------------------------------------------------*/
/* Private macro-------------------------------------------------------------*/
/* Private variables---------------------------------------------------------*/
extern uint8_t FileName[];
 
/* Private function prototypes-----------------------------------------------*/
/* Private functions---------------------------------------------------------*/
 
/**
  *@brief  Receive byte from sender
  *@param  c: Character
  *@param  timeout: Timeout
  *@retval 0: Byte received
 *         -1: Timeout
  */
static int32_t Receive_Byte (uint8_t *c, uint32_t timeout)
{
 while (timeout-- > 0)
  {
   if (SerialKeyPressed(c) == 1)
    {
     return 0;
    }
  }
 return -1;
}
 
/**
  *@brief  Send a byte
  *@param  c: Character
  *@retval 0: Byte sent
  */
static uint32_t Send_Byte (uint8_t c)
{
 SerialPutChar(c);
 return 0;
}
 
/**
  *@brief  Update CRC16 for input byte
  *@param  CRC input value
  *@param  input byte
  *@retval Updated CRC value
  */
uint16_t UpdateCRC16(uint16_t crcIn,uint8_t byte)
{
 uint32_t crc = crcIn;
 uint32_t in = byte|0x100;
 
  do
  {
   crc <<= 1;
   in <<= 1;
 
   if(in&0x100)
    {
      ++crc;
    }
   
   if(crc&0x10000)
    {
     crc ^= 0x1021;
    }
 }while(!(in&0x10000));
 
 return (crc&0xffffu);
}
 
/**
  *@brief  Cal CRC16 for YModem Packet
  *@param  data
  *@param  length
  *@retval CRC value
  */
uint16_t Cal_CRC16(const uint8_t* data,uint32_t size)
{
 uint32_t crc = 0;
 const uint8_t* dataEnd = data+size;
 
 while(data<dataEnd)
  {
   crc = UpdateCRC16(crc,*data++);
  }
  crc= UpdateCRC16(crc,0);
  crc= UpdateCRC16(crc,0);
 
 return (crc&0xffffu);
}
 
/**
  *@brief  Cal Check sum for YModem Packet
  *@param  data
  *@param  length
  *@retval None
  */
uint8_t CalChecksum(const uint8_t* data,uint32_t size)
{
 uint32_t sum = 0;
 const uint8_t* dataEnd = data+size;
 
 while(data < dataEnd)
  {
   sum += *data++;
  }
 
 return (sum&0xffu);
}
 
/**
  *@brief  Receive a packet from sender
  *@param  data
  *@param  length
  *@param  timeout
 *          0: end of transmission
 *          -1: abort by sender
 *          >0: packet length
  *@retval 0: normally return
 *         -1: timeout or packeterror
 *         1: abort by user
  */
static int32_t Receive_Packet (uint8_t*data, int32_t *length, uint32_t timeout)
{
 uint16_t i, packet_size, computedcrc;
 uint8_t 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 CA:
     if ((Receive_Byte(&c, timeout) == 0) && (c == CA))
     {
       *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;
  }
 
  /*Compute the CRC */
 computedcrc = Cal_CRC16(&data[PACKET_HEADER],(uint32_t)packet_size);
  /*Check that received CRC match the already computed CRC value
    data[packet_size+3]<<8) | data[packet_size+4] contains thereceived CRC
    computedcrc contains the computed CRC value */
  if(computedcrc != (uint16_t)((data[packet_size+3]<<8) |data[packet_size+4]))
  {
   /* CRC error */
   return -1;
  }
 
 *length = packet_size;
 return 0;
}
 
/**
  *@brief  Receive a file using the ymodemprotocol
  *@param  buf: Address of the first byte
  *@retval The size of the file
  */
int32_t Ymodem_Receive (uint8_t *buf)
{
 uint8_t packet_data[PACKET_1K_SIZE + PACKET_OVERHEAD],file_size[FILE_SIZE_LENGTH], *file_ptr, *buf_ptr;
 int32_t i, packet_length, session_done, file_done, packets_received,errors, session_begin, size = 0;
 uint32_t flashdestination, ramsource;
 
  /*Initialize flashdestination variable */
 flashdestination = APPLICATION_ADDRESS;
 
  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)
         {
           /* Abort by sender */
           case - 1:
              Send_Byte(ACK);
              return 0;
           /* End of transmission */
           case 0:
              Send_Byte(ACK);
              file_done = 1;
              break;
           /* Normal packet Õý³£Çé¿öϵİü*/
           default:
              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 hasvalid data */
                    for (i = 0, file_ptr =packet_data + PACKET_HEADER; (*file_ptr != 0) && (i <FILE_NAME_LENGTH);)
                    {
                      FileName[i++] =*file_ptr++;
                    }
                    FileName[i++] = '\0';
                    for (i = 0, file_ptr ++;(*file_ptr != ' ') && (i < (FILE_SIZE_LENGTH - 1));)
                    {
                      file_size[i++] =*file_ptr++;
                    }
                    file_size[i++] = '\0';
                    Str2Int(file_size,&size);
 
                    /* Test the size of theimage to be sent */
                    /* Image size is greaterthan Flash size */
                    if (size >(USER_FLASH_SIZE + 1))
                    {
                      /* End session */
                      Send_Byte(CA);
                      Send_Byte(CA);
                      return -1;
                    }
                    /* erase user applicationarea */
                    FLASH_If_Erase(APPLICATION_ADDRESS);
                    Send_Byte(ACK); // ACK  and 'C' ?
                    Send_Byte(CRC16);
                  }
                  /* Filename packet is empty,end session */
                  else
                  {
                    Send_Byte(ACK);
                    file_done = 1;
                    session_done = 1;
                    break;
                  }
                }
                /* Data packet */
                else   //Õý³£Çé¿öϽøÈë
                {
                  memcpy(buf_ptr, packet_data +PACKET_HEADER, packet_length);
                  ramsource =(uint32_t)buf;   //bufÊÇÒ»¸öÖ¸Õë
 
                  /* Write received data inFlash */
                  if(FLASH_If_Write(&flashdestination, (uint32_t*) ramsource, (uint16_t)packet_length/4)  == 0)  //½«Êý¾ÝдÈëflash
                  {
                    Send_Byte(ACK);  //дÍêÒ»Ö¡Êý¾ÝÖ®ºó·¢ËÍÏìÓ¦
                  }
                  else /* An error occurredwhile writing to Flash memory */
                  {
                    /* End session */
                    Send_Byte(CA);
                    Send_Byte(CA);
                    return -2;
                  }
                }
                packets_received ++;  //°üÊý+1
                session_begin = 1;
              }
         }
         break;
       case 1:
         Send_Byte(CA);
         Send_Byte(CA);
         return -3;
       default:
         if (session_begin > 0) //½ÓÊÕÒѾ­¿ªÊ¼£¬µ«ÊÇReceive_Packet(packet_data, &packet_length,NAK_TIMEOUT)¸Ãº¯Êý·µ»Ø´íÎó¡£
         {
           errors ++;
         }
         if (errors > MAX_ERRORS)
         {
           Send_Byte(CA);
           Send_Byte(CA);
           return 0;
         }
         Send_Byte(CRC16); // the start C!!
         break;
     }
     if (file_done != 0)
     {
       break;
     }
    }
   if (session_done != 0)
    {
     break;
    }
  }
 return (int32_t)size;
}
 
/**
  *@brief  check response using the ymodemprotocol
  *@param  buf: Address of the first byte
  *@retval The size of the file
  */
int32_t Ymodem_CheckResponse(uint8_t c)
{
 return 0;
}
 
/**
  *@brief  Prepare the first block
  *@param  timeout
  *@retval None
  */
void Ymodem_PrepareIntialPacket(uint8_t*data, const uint8_t* fileName, uint32_t *length)
{
 uint16_t i, j;
 uint8_t file_ptr[10];
 
  /*Make first three packet */
 data[0] = SOH;
 data[1] = 0x00;
 data[2] = 0xff;
 
  /*Filename packet has valid data */
  for(i = 0; (fileName[i] != '\0') && (i < FILE_NAME_LENGTH);i++)
  {
    data[i + PACKET_HEADER] = fileName[i];
  }
 
 data[i + PACKET_HEADER] = 0x00;
 
 Int2Str (file_ptr, *length);
  for(j =0, i = i + PACKET_HEADER + 1; file_ptr[j] != '\0' ; )
  {
    data[i++] = file_ptr[j++];
  }
 
  for(j = i; j < PACKET_SIZE + PACKET_HEADER; j++)
  {
   data[j] = 0;
  }
}
 
/**
  *@brief  Prepare the data packet
  *@param  timeout
  *@retval None
  */
void Ymodem_PreparePacket(uint8_t*SourceBuf, uint8_t *data, uint8_t pktNo, uint32_t sizeBlk)
{
 uint16_t i, size, packetSize;
 uint8_t* file_ptr;
 
  /*Make first three packet */
 packetSize = sizeBlk >= PACKET_1K_SIZE ? PACKET_1K_SIZE :PACKET_SIZE;
 size = sizeBlk < packetSize ? sizeBlk :packetSize;
  if(packetSize == PACKET_1K_SIZE)
  {
    data[0] = STX;
  }
 else
  {
    data[0] = SOH;
  }
 data[1] = pktNo;
 data[2] = (~pktNo);
 file_ptr = SourceBuf;
 
  /*Filename packet has valid data */
  for(i = PACKET_HEADER; i < size + PACKET_HEADER;i++)
  {
    data[i] = *file_ptr++;
  }
  if( size  <= packetSize)
  {
   for (i = size + PACKET_HEADER; i < packetSize + PACKET_HEADER; i++)
    {
     data[i] = 0x1A; /* EOF (0x1A) or 0x00 */
    }
  }
}
 
/**
  *@brief  Transmit a data packet using theymodem protocol
  *@param  data
  *@param  length
  *@retval None
  */
void Ymodem_SendPacket(uint8_t *data,uint16_t length)
{
 uint16_t i;
  i =0;
 while (i < length)
  {
   Send_Byte(data[i]);
   i++;
  }
}
 
/**
  *@brief  Transmit a file using the ymodemprotocol
  *@param  buf: Address of the first byte
  *@retval The size of the file
  */
uint8_t Ymodem_Transmit (uint8_t *buf,const uint8_t* sendFileName, uint32_t sizeFile)
{
 uint8_t packet_data[PACKET_1K_SIZE + PACKET_OVERHEAD];
 uint8_t FileName[FILE_NAME_LENGTH];
 uint8_t *buf_ptr, tempCheckSum ;
 uint16_t tempCRC, blkNumber;
 uint8_t receivedC[2], CRC16_F = 0, i;
 uint32_t errors = 0, ackReceived = 0, size = 0, pktSize;
 
  for(i = 0; i < (FILE_NAME_LENGTH - 1); i++)
  {
   FileName[i] = sendFileName[i];
  }
 CRC16_F = 1;
 
  /*Prepare first block */
 Ymodem_PrepareIntialPacket(&packet_data[0], FileName,&sizeFile);
 
  do
  {
   /* Send Packet */
   Ymodem_SendPacket(packet_data, PACKET_SIZE + PACKET_HEADER);
   
   /* Send CRC or Check Sum based on CRC16_F */
   if (CRC16_F)
    {
      tempCRC = Cal_CRC16(&packet_data[3], PACKET_SIZE);
      Send_Byte(tempCRC >> 8);
      Send_Byte(tempCRC & 0xFF);
    }
   else
    {
      tempCheckSum = CalChecksum (&packet_data[3], PACKET_SIZE);
      Send_Byte(tempCheckSum);
    }
 
    /*Wait for Ack and 'C' */
   if (Receive_Byte(&receivedC[0], 1000000) == 0) 
    {
     if (receivedC[0] == ACK)
     {
       /* Packet transfered correctly */
       ackReceived = 1;
     }
    }
   else
    {
       errors++;
    }
 }while (!ackReceived && (errors < 0x0A));
 
  if(errors >=  0x0A)
  {
   return errors;
  }
 buf_ptr = buf;
 size = sizeFile;
 blkNumber = 0x01;
 
  /*Here 1024 bytes package is used to send the packets */
 while (size)
  {
   /* Prepare next packet */
   Ymodem_PreparePacket(buf_ptr, &packet_data[0], blkNumber, size);
   ackReceived = 0;
   receivedC[0]= 0;
   errors = 0;
   do
    {
     /* Send next packet */
     if (size >= PACKET_1K_SIZE)
     {
       pktSize = PACKET_1K_SIZE;
       
     }
     else
     {
       pktSize = PACKET_SIZE;
     }
     Ymodem_SendPacket(packet_data, pktSize + PACKET_HEADER);
     /* Send CRC or Check Sum based on CRC16_F */
     if (CRC16_F)
     {
        tempCRC = Cal_CRC16(&packet_data[3], pktSize);
        Send_Byte(tempCRC >> 8);
        Send_Byte(tempCRC & 0xFF);
     }
     else
     {
       tempCheckSum = CalChecksum (&packet_data[3], pktSize);
       Send_Byte(tempCheckSum);
     }
     
     /* Wait for Ack */
     if (Receive_Byte(&receivedC[0], 1000000) == 0) 
     {    if (receivedC[0] == ACK)
     {
       ackReceived = 1; 
       if (size > pktSize)
       {
          buf_ptr += pktSize; 
          size -= pktSize;
          if (blkNumber == (USER_FLASH_SIZE/1024))
          {
            return 0xFF; /*  error */
          }
          else
          {
              blkNumber++;
          }
       }
       else
       {
          buf_ptr += pktSize;
          size = 0;
       }
     }
     }
     else
     {
       errors++;
     }
   }while(!ackReceived && (errors < 0x0A));
   
   /* Resend packet if NAK  for acount of 10 else end of commuincation */
   if (errors >=  0x0A)
    {
     return errors;
    }
   
  }
 ackReceived = 0;
 receivedC[0] = 0x00;
 receivedC[1] = 0x00;
 errors = 0;
  do
  {
   Send_Byte(EOT);  
   /* Send (EOT); */
   /* Wait for Ack */
   receivedC[0] = USART_ReceiveData(USART1);
   if (receivedC[0] == ACK)
    {
     ackReceived = 1;
     }
   
   else
    {
     errors++;
    }
   /* Clear Overrun flag of the USART2 */
   USART_ClearFlag(USART1, USART_FLAG_ORE);
 }while (!ackReceived && (errors < 0x0A));
   
  if(errors >=  0x0A)
  {
   return errors;
  }
 
  /*Last packet preparation */
 ackReceived = 0;
 receivedC[0] = 0x00;
 receivedC[1] = 0x00;
 errors = 0;
 
 packet_data[0] = SOH;
 packet_data[1] = 0;
 packet_data [2] = 0xFF;
 
  for(i = PACKET_HEADER; i < (PACKET_SIZE + PACKET_HEADER); i++)
  {
    packet_data [i] = 0x00;
  }
 
  do
  {
   /* Send Packet */
   Ymodem_SendPacket(packet_data, PACKET_SIZE + PACKET_HEADER);
 
   /* Send CRC or Check Sum based on CRC16_F */
    tempCRC = Cal_CRC16(&packet_data[3],PACKET_SIZE);
   Send_Byte(tempCRC >> 8);
   Send_Byte(tempCRC & 0xFF);
 
   /* Wait for Ack and 'C' */
   if (Receive_Byte(&receivedC[1], 1000000) == 0) 
    {
     if (receivedC[1] == ACK)
     {
       /* Packet transfered correctly */
       ackReceived = 1;
     }
    }
   else
    {
     errors++;
    }
 }while (!ackReceived && (errors < 0x0A));
 
  /*Resend packet if NAK  for a count of10  else end of commuincation */
  if(errors >=  0x0A)
  {
   return errors;
 } 
 receivedC[0] = 0x00;
  do
  {
   Send_Byte(EOT);  
   /* Send (EOT); */
   /* Wait for Ack */
   if ((Receive_Byte(&receivedC[0], 1000000) == 0)  && receivedC[0] == ACK)
    {
     ackReceived = 1; 
    }
   
   else
    {
     errors++;
    }
   /* Clear Overrun flag of the USART2 */
   USART_ClearFlag(USART1, USART_FLAG_ORE);
 }while (!ackReceived && (errors < 0x0A));
   
  if(errors >=  0x0A)
  {
   return errors;
  }
 return 0; /* file trasmitted successfully */
}
 
/**
  *@}
  */
 
/************************ (C) COPYRIGHTSTMicroelectronics *****END OF FILE****/


 

 

然后就没有然后了。假设你还要然后能够博客下载完整project看看。。。

还要再然后的话能够博客留言联系。






本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/5251533.html,如需转载请自行联系原作者

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务&nbsp;ACK 容器服务&nbsp;Kubernetes&nbsp;版(简称&nbsp;ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情:&nbsp;https://www.aliyun.com/product/kubernetes
相关文章
|
15天前
|
Java
java原生发送http请求
java原生发送http请求
|
23天前
|
网络协议 Linux iOS开发
推荐:实现RTSP/RTMP/HLS/HTTP协议的轻量级流媒体框架,支持大并发连接请求
推荐:实现RTSP/RTMP/HLS/HTTP协议的轻量级流媒体框架,支持大并发连接请求
50 1
|
1月前
|
编解码 测试技术 索引
性能工具之 Jmeter 使用 HTTP 请求编写 HLS 脚本
在我们简要介绍了 HLS 协议的基础知识,接下来我们详细介绍一种使用 Jmeter 编写压测 HLS 协议脚本的方法。
72 1
性能工具之 Jmeter 使用 HTTP 请求编写 HLS 脚本
|
1月前
|
JSON 数据格式
第三方系统或者工具通过 HTTP 请求发送给 ABAP 系统的数据,应该如何解析试读版
第三方系统或者工具通过 HTTP 请求发送给 ABAP 系统的数据,应该如何解析试读版
27 0
|
1月前
|
Java Spring
用spring发送http请求
用spring发送http请求
|
5天前
|
安全 Java 网络安全
Servlet 教程 之 Servlet 客户端 HTTP 请求 2
Servlet教程介绍了如何在Servlet中处理HTTP请求,包括获取Cookie、头信息、参数、Session等。方法如:`getCookies()`、`getAttributeNames()`、`getHeaderNames()`、`getParameterNames()`等。还能获取身份验证类型、字符编码、MIME类型、请求方法、远程用户信息、URL路径、安全通道状态以及请求内容长度等。此外,可通过`getSession()`创建或获取Session,并以`Map`形式获取参数。
20 8
|
1天前
|
JSON 测试技术 API
Python的Api自动化测试使用HTTP客户端库发送请求
【4月更文挑战第18天】在Python中进行HTTP请求和API自动化测试有多个库可选:1) `requests`是最流行的选择,支持多种请求方法和内置JSON解析;2) `http.client`是标准库的一部分,适合需要低级别控制的用户;3) `urllib`提供URL操作,适用于复杂请求;4) `httpx`拥有类似`requests`的API,提供现代特性和异步支持。根据具体需求选择,如多数情况`requests`已足够。
7 3
|
8天前
|
安全 网络安全 开发工具
对象存储oss使用问题之flutter使用http库进行post请求文件上传返回400如何解决
《对象存储OSS操作报错合集》精选了用户在使用阿里云对象存储服务(OSS)过程中出现的各种常见及疑难报错情况,包括但不限于权限问题、上传下载异常、Bucket配置错误、网络连接问题、跨域资源共享(CORS)设定错误、数据一致性问题以及API调用失败等场景。为用户降低故障排查时间,确保OSS服务的稳定运行与高效利用。
24 1
|
1月前
|
JSON 前端开发 数据格式
糊涂工具类真是场景下请求http接口的案例
糊涂工具类真是场景下请求http接口的案例
21 0