STM32F051 IAP源码分享

来源:互联网 发布:msdb数据库置疑 编辑:程序博客网 时间:2024/05/16 06:13

STM32F051 IAP源码分享

 

如果不懂IAP的请自动脑补或者怒戳这里

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

 

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

 

其实我只是来分享源码的:

 

事情是介个样子滴:

 

IAP需要有两个工程,第一个是Bootloader,第二个是Application

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

 

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

 

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

Step1:做Bootloader工程

Step2:做Application工程

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:需要这样干:

在Application工程中程序运行的一开始加上如下中断拷贝即可

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:这就样

将两个工程分别烧在不同的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****/


 

 

然后就没有然后了,如果你还要然后可以博客下载完整工程看看。。。还要再然后的话可以博客留言联系。。

3 0
原创粉丝点击