コード例 #1
0
/*******************************************************************************
 * @fn      SensorTag_saveFactoryImage
 *
 * @brief   Save the current image to external flash as a factory image
 *
 * @return  none
 */
static bool SensorTag_saveFactoryImage(void)
{
  bool success;

  success = extFlashOpen();

  if (success)
  {
    uint32_t address;

    // Erase external flash
    for (address= 0; address<EFL_FLASH_SIZE; address+=EFL_PAGE_SIZE)
    {
      extFlashErase(address,EFL_PAGE_SIZE);
    }

    // Install factory image
    for (address=0; address<EFL_SIZE_RECOVERY && success; address+=EFL_PAGE_SIZE)
    {
      success = extFlashErase(EFL_ADDR_RECOVERY+address, EFL_PAGE_SIZE);
      if (success)
      {
        size_t offset;
        static uint8_t buf[256]; // RAM storage needed due to SPI/DMA limitation

        for (offset=0; offset<EFL_PAGE_SIZE; offset+=sizeof(buf))
        {
          const uint8_t *pIntFlash;

          // Copy from internal to external flash
          pIntFlash = (const uint8_t*)address + offset;
          memcpy(buf,pIntFlash,sizeof(buf));
          success = extFlashWrite(EFL_ADDR_RECOVERY+address+offset,
                                  sizeof(buf), buf);

          // Verify first few bytes
          if (success)
          {
            extFlashRead(EFL_ADDR_RECOVERY+address+offset, sizeof(buf), buf);
            success = buf[2] == pIntFlash[2] && buf[3] == pIntFlash[3];
          }
        }
      }
    }

    extFlashClose();
  }

  return success;
}
コード例 #2
0
/*******************************************************************************
 * @fn      saveImageInfo
 *
 * @brief   Save image information in the meta-data area
 *
 * @return  none
 */
void saveImageInfo(void)
{
  uint32_t addr;
 
  if (imgInfo.imgType == EFL_OAD_IMG_TYPE_APP)
  {
    addr = EFL_IMAGE_INFO_ADDR_APP;
  }
  else
  {
    addr = EFL_IMAGE_INFO_ADDR_BLE;
  }
  
  // Erase old meta data.
  extFlashErase(addr, HAL_FLASH_PAGE_SIZE);
  
  // Set status so that bootloader pull in the new image.
  imgInfo.status = 0xFF;
  
  // Write new meta data.
  extFlashWrite(addr, sizeof(ExtImageInfo_t),
                (uint8_t*)&imgInfo);
}
コード例 #3
0
/*********************************************************************
 * @fn      OADTarget_imgBlockWrite
 *
 * @brief   Process the Image Block Write.
 *
 * @param   connHandle - connection message was received on
 * @param   pValue - pointer to data to be written
 *
 * @return  status
 */
bStatus_t OADTarget_imgBlockWrite(uint16_t connHandle, uint8_t *pValue)
{
  volatile uint16_t blkNum;
 
  blkNum  = BUILD_UINT16(pValue[0], pValue[1]);

  // First block of OAD which included image header and CRC and CRC shadow
  // values. Do a sanity check on the received image header
  if (blkNum == 0)
  {
    img_hdr_t ImgHdr;
    uint16_t blkTot;
   
    blkTot = BUILD_UINT16(pValue[8], pValue[9]) / 
                                  (OAD_BLOCK_SIZE / HAL_FLASH_WORD_SIZE);

    // Read out running image's header.
    uint8_t *flashAddr = (uint8_t *)(APP_IMAGE_START + OAD_IMG_HDR_OSET);
    memcpy(&ImgHdr,flashAddr,sizeof(img_hdr_t));

    // Note:  if additional customer criteria was checked in the Image
    // Identification step, it may be important to check again here.
    if ((oadBlkNum != blkNum) || (oadBlkTot != blkTot) )
    {
      // Cancel download
      OADTarget_rejectImage(connHandle, &ImgHdr);

      // NB! This is meaningless for a WriteNoResp operation
      return (ATT_ERR_WRITE_NOT_PERMITTED);
    }
#ifdef POWER_SAVING
    Power_setConstraint(Power_SB_DISALLOW);
#endif
  }

  // Check that this is the expected block number.
  if (oadBlkNum == blkNum && flashOk)
  {
    uint32_t addr;
   
    // Calculate address to write as (start of OAD range) + (offset)
    addr = APP_IMAGE_START + oadBlkNum * OAD_BLOCK_SIZE;

    // If address starts a new page, erase that page first.
    if ((addr % HAL_FLASH_PAGE_SIZE) == 0)
    {
      flashOk = extFlashErase(addr, HAL_FLASH_PAGE_SIZE);
    }

    // Write a 16 byte block to Flash.
    if (flashOk)
    {
      flashOk = extFlashWrite(addr, OAD_BLOCK_SIZE, pValue+2);
    
      // Increment received block count.
      if (flashOk)
        oadBlkNum++;
    }

    // Toggle Green LED for every 8th block
    if ( (oadBlkNum % 8) == 0)
    {
      GPIO_toggle(Board_LED2);
    }
  }
  else
  {
    img_hdr_t ImgHdr;
    
     // Toggle RED LED and sound buzzer when overflow
     GPIO_toggle(Board_LED1);
     GPIO_toggle(Board_BUZZER);
#ifdef POWER_SAVING
    Power_releaseConstraint(Power_SB_DISALLOW);
#endif     
    
    // Cancel download
    ImgHdr.len = 0; // Don't care content
    OADTarget_rejectImage(connHandle, &ImgHdr);
  }
  
  // Check if the OAD Image is complete.
  if (oadBlkNum == oadBlkTot)
  {
    extFlashClose();
    
    // Run CRC check on new image.
    if (checkDL())
    {
      HAL_SYSTEM_RESET();
    }
    else
    {
      GPIO_toggle(Board_LED1);
    }
#ifdef POWER_SAVING
    Power_releaseConstraint(Power_SB_DISALLOW);
#endif     
  }
  else
  {
    // Request the next OAD Image block.
    OADTarget_getNextBlockReq(connHandle, oadBlkNum);
  }

  return (SUCCESS);
}
コード例 #4
0
/*********************************************************************
 * @fn      OADTarget_eraseFlash
 *
 * @brief   Erase selected flash page.
 *
 * @param   page - the page to erase.
 *
 * @return  None.
 */
void OADTarget_eraseFlash(uint8_t page)
{
  extFlashErase(FLASH_ADDRESS(page,0), HAL_FLASH_PAGE_SIZE);
}