• STM32F051 IAP源代码分享


    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)
    
    ");
     Size = Ymodem_Receive(&tab_1024[0]);
      if(Size > 0)
      {
       SerialPutString("
    
    
     Programming CompletedSuccessfully!
    
    --------------------------------
     Name: ");
       SerialPutString(FileName);
       Int2Str(Number, Size);
       SerialPutString("
    
     Size: ");
       SerialPutString(Number);
       SerialPutString(" Bytes
    ");
       SerialPutString("-------------------
    ");
      }
     else if (Size == -1)
      {
       SerialPutString("
    
    
    The image size is higher than the allowedspace memory!
    
    ");
      }
     else if (Size == -2)
      {
       SerialPutString("
    
    
    Verification failed!
    
    ");
      }
     else if (Size == -3)
      {
       SerialPutString("
    
    Aborted by user.
    
    ");
      }
     else
      {
        SerialPutString("
    
    Failedto receive the file!
    
    ");
      }
    }


    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)
    
    ");
     Size = Ymodem_Receive(&tab_1024[0]);
      if(Size > 0)
      {
       SerialPutString("
    
    
     Programming CompletedSuccessfully!
    
    --------------------------------
     Name: ");
       SerialPutString(FileName);
       Int2Str(Number, Size);
       SerialPutString("
    
     Size: ");
       SerialPutString(Number);
       SerialPutString(" Bytes
    ");
       SerialPutString("-------------------
    ");
      }
     else if (Size == -1)
      {
       SerialPutString("
    
    
    The image size is higher than the allowedspace memory!
    
    ");
      }
     else if (Size == -2)
      {
       SerialPutString("
    
    
    Verification failed!
    
    ");
      }
     else if (Size == -3)
      {
       SerialPutString("
    
    Aborted by user.
    
    ");
      }
     else
      {
       SerialPutString("
    
    Failed to receive the file!
    
    ");
      }
    }
     
     
    /**
      *@brief  Upload a file via serial port.
      *@param  None
      *@retval None
      */
    void SerialUpload(void)
    {
     uint8_t status = 0 ;
     
     SerialPutString("
    
    
    Select Receive File
    
    ");
     
      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("
    
    Error Occurred while TransmittingFile
    
    ");
        }
       else
        {
         SerialPutString("
    
    File uploaded successfully 
    
    ");
        }
      }
    }


    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++] = '';
                        for (i = 0, file_ptr ++;(*file_ptr != ' ') && (i < (FILE_SIZE_LENGTH - 1));)
                        {
                          file_size[i++] =*file_ptr++;
                        }
                        file_size[i++] = '';
                        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] != '') && (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] != '' ; )
      {
        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看看。。。

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

  • 相关阅读:
    贪婪匹配
    洛谷P1219 [USACO1.5]八皇后 Checker Challenge【搜索回溯】
    【数据结构笔记】栈
    数据结构课堂笔记
    DAY1
    小记2020.1.10
    c++复习
    c++用流控制成员函数输出数据
    c++用控制符控制输出格式
    "中国东信杯"广西大学第二届程序设计竞赛E Antinomy与红玉海(二分)
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/5251533.html
Copyright © 2020-2023  润新知