Exemplo n.º 1
0
void main(void)
{
  HAL_BOARD_INIT();
#if HAL_OTA_XNV_IS_SPI
  XNV_SPI_INIT();
#endif
  /* This is in place of calling HalDmaInit() which would require init of the
   * other 4 DMA descriptors in addition to just Channel 0.
   */
  HAL_DMA_SET_ADDR_DESC0( &dmaCh0 );

  while (1)
  {
    HalFlashRead(HAL_OTA_CRC_ADDR / HAL_FLASH_PAGE_SIZE,
                 HAL_OTA_CRC_ADDR % HAL_FLASH_PAGE_SIZE,
                 (uint8 *)&OTA_crcControl, sizeof(OTA_crcControl));

    if (OTA_crcControl.crc[0] == OTA_crcControl.crc[1])
    {
      break;
    }
    else if ((OTA_crcControl.crc[0] != 0) && (OTA_crcControl.crc[0] == crcCalc()))
    {
      OTA_crcControl.crc[1] = OTA_crcControl.crc[0];
      HalFlashWrite((HAL_OTA_CRC_ADDR / HAL_FLASH_WORD_SIZE), (uint8 *)OTA_crcControl.crc, 1);
    }
    else
    {
      dl2rc();
    }
  }

  // Simulate a reset for the Application code by an absolute jump to location 0x0800.
  asm("LJMP 0x800\n");
}
Exemplo n.º 2
0
/**************************************************************************************************
 * @fn          checkDL
 *
 * @brief       Check validity of the downloaded image.
 *
 * input parameters
 *
 * None.
 *
 * output parameters
 *
 * None.
 *
 * @return      TRUE or FALSE for image valid.
 **************************************************************************************************
 */
static uint8 checkDL(void)
{
  uint16 crc[2];

  HalFlashRead(OAD_IMG_D_PAGE, OAD_IMG_CRC_OSET, (uint8 *)crc, sizeof(crc));

  if ((crc[0] == 0xFFFF) || (crc[0] == 0x0000))
  {
    return FALSE;
  }

  if (crc[1] == 0xFFFF)
  {
    //P0DIR |= 1;
    //P0_0 = 0;
    //P0_0 = 1;
    //P0_0 = 0;
    //P0_0 = 1;
    //P0_0 = 0;
    //P0_0 = 1;
    crc[1] = crcCalcDLDMA();
    //P0_0 = 0;

#if defined FEATURE_OAD_BIM  // If download image is made to run in-place, enable it here.
    uint16 addr = OAD_IMG_D_PAGE * OAD_FLASH_PAGE_MULT + OAD_IMG_CRC_OSET / HAL_FLASH_WORD_SIZE;
    crc[0] = 0xFFFF;
    HalFlashWrite(addr, (uint8 *)crc, 1);
    HalFlashRead(OAD_IMG_D_PAGE, OAD_IMG_CRC_OSET, (uint8 *)crc, sizeof(crc));
#endif
  }

  return (crc[0] == crc[1]);
}
Exemplo n.º 3
0
/**************************************************************************************************
 * @fn          sbImgValid
 *
 * @brief       Check validity of the run-code image.
 *
 * input parameters
 *
 * None.
 *
 * output parameters
 *
 * None.
 *
 * @return      TRUE or FALSE for image valid.
 **************************************************************************************************
 */
uint8 sbImgValid(void)
{
  uint16 crc[2];


  HalFlashRead(HAL_SB_CRC_ADDR / HAL_FLASH_PAGE_SIZE,
               HAL_SB_CRC_ADDR % HAL_FLASH_PAGE_SIZE,
               (uint8 *)crc, sizeof(crc));

  if ((crc[0] == 0xFFFF) || (crc[0] == 0x0000))
  {
    return FALSE;
  }

  if (crc[0] != crc[1])
  {
    crc[1] = calcCRC();
    HalFlashWrite((HAL_SB_CRC_ADDR / HAL_FLASH_WORD_SIZE), (uint8 *)crc, 1);
    HalFlashRead(  HAL_SB_CRC_ADDR / HAL_FLASH_PAGE_SIZE,
                   HAL_SB_CRC_ADDR % HAL_FLASH_PAGE_SIZE,
                   (uint8 *)crc, sizeof(crc));
  }

  return ((crc[0] == crc[1]) && (crc[0] != 0xFFFF) && (crc[0] != 0x0000));
}
Exemplo n.º 4
0
/**************************************************************************************************
 * @fn          crcCheck
 *
 * @brief       Calculate the image CRC and set it ready-to-run if it is good.
 *
 * input parameters
 *
 * @param       page - Flash page on which to beging the CRC calculation.
 *
 * output parameters
 *
 * None.
 *
 * @return      None, but no return from this function if the CRC check is good.
 **************************************************************************************************
 */
static void crcCheck(uint8 page, uint16 *crc)
{
  HAL_BOARD_INIT();

  /* This is in place of calling HalDmaInit() which would require init of the other 4 DMA
   * descriptors in addition to just Channel 0.
   */
  //P0DIR |= 1;
  //P0_0 = 0;
  //P0_0 = 1;
  //P0_0 = 0;
  //P0_0 = 1;
  //P0_0 = 0;
  //P0_0 = 1;
  if (crc[0] == crcCalcDMA(page))
  {
    //P0_0 = 0;
    uint16 addr = page * (HAL_FLASH_PAGE_SIZE / HAL_FLASH_WORD_SIZE) +
                                 BIM_CRC_OSET / HAL_FLASH_WORD_SIZE;
    crc[1] = crc[0];
    crc[0] = 0xFFFF;

    HAL_DMA_SET_ADDR_DESC0(&dmaCh0);
    HalFlashWrite(addr, (uint8 *)crc, 1);
    HAL_SYSTEM_RESET();
  }
}
Exemplo n.º 5
0
/*********************************************************************
 * @fn      writeWord
 *
 * @brief   Writes a Flash-WORD to NV.
 *
 * @param   pg - A valid NV Flash page.
 * @param   offset - A valid offset into the page.
 * @param   buf - Pointer to source buffer.
 *
 * @return  none
 */
static void writeWord( uint8 pg, uint16 offset, uint8 *buf )
{
  offset = (offset / HAL_FLASH_WORD_SIZE) +
          ((uint16)pg * (HAL_FLASH_PAGE_SIZE / HAL_FLASH_WORD_SIZE));

  HalFlashWrite(offset, buf, 1);
}
Exemplo n.º 6
0
/*********************************************************************
 * @fn      HalOADWrite
 *
 * @brief   Write to the storage medium according to the image type.
 *
 *  NOTE:   Destructive write on page boundary! When writing to the first flash word
 *          of a page boundary, the page is erased without saving/restoring the bytes not written.
 *          Writes anywhere else on a page assume that the location written to has been erased.
 *
 * @param   oset - Offset into the monolithic image, aligned to HAL_FLASH_WORD_SIZE.
 * @param   pBuf - Pointer to the buffer in from which to write.
 * @param   len - Number of bytes to write. If not an even multiple of HAL_FLASH_WORD_SIZE,
 *                remainder bytes are overwritten with garbage.
 * @param   type - Which image: HAL_OAD_RC or HAL_OAD_DL.
 *
 * @return  None.
 *********************************************************************/
void HalOADWrite(uint32 oset, uint8 *pBuf, uint16 len, image_t type)
{
  if (HAL_OAD_RC != type)
  {
#if HAL_OAD_XNV_IS_INT
    preamble_t preamble;

    HalOADRead(PREAMBLE_OFFSET, (uint8 *)&preamble, sizeof(preamble_t), HAL_OAD_RC);
    //oset += HAL_OAD_RC_START + preamble.len;
    oset += HAL_OAD_RC_START + HAL_OAD_DL_OSET;
#elif HAL_OAD_XNV_IS_SPI
    oset += HAL_OAD_DL_OSET;
    HalSPIWrite(oset, pBuf, len);
    return;
#endif
  }
  else
  {
    oset += HAL_OAD_RC_START;
  }

  if ((oset % HAL_FLASH_PAGE_SIZE) == 0)
  {
    HalFlashErase(oset / HAL_FLASH_PAGE_SIZE);
  }

  HalFlashWrite(oset / HAL_FLASH_WORD_SIZE, pBuf, len / HAL_FLASH_WORD_SIZE);
}
Exemplo n.º 7
0
void persistent_pwrmgmt_set_latest(struct pwrmgmt_data *pwr_ptr)
{
	uint8_t count;
	uint32_t pwr_idx_bits, u32;

	u32 = (uint32)&(((struct persistent_page *)0)->pwr_idx_bits[0]);
    HalFlashRead(pidx, (uint16_t)u32, (uint8_t *)&pwr_idx_bits, 4);
	count = __persistent_get_idx_from_bit_map((uint8_t *)&pwr_idx_bits, 4);
	if (count < PERSISTENT_PWR_MAX) {
		u32 = (uint32)&(((struct persistent_page *)0)->pwr_log[count]);
		HalFlashWrite(pidx, (uint16_t)u32, (uint8_t *)pwr_ptr, sizeof(struct pwrmgmt_data));
		__persistent_mark_bit_map((uint8_t *)&pwr_idx_bits, 4);
		u32 = (uint32)&(((struct persistent_page *)0)->pwr_idx_bits[0]);
		HalFlashWrite(pidx, (uint16_t)u32, (uint8_t *)&pwr_idx_bits, 4);
	} else {
		flash_trigger_refresh_pwr_mgmt_info(pwr_ptr);
	}
}
Exemplo n.º 8
0
// This function does the persistent page overwrite
void persistent_flash_backup_finish(void)
{
	uint32_t buf32[64];
	uint8_t i;

	HalFlashErase(pidx);
	for (i = 0; i < 4; i++) {
		HalFlashRead((pidx + 1), i * 256, (uint8_t *)buf32, 256);
		if (i == 0) {
			buf32[0] = 0xFFFFADDE;
		}
		HalFlashWrite(pidx, i * 256, (uint8_t *)buf32, 256);
	}
	buf32[0] = 0xFFBEADDE;
	HalFlashWrite(pidx, 0, (uint8_t *)buf32, 4);
	HalFlashErase(pidx + 1);
	buf32[0] = 0xEFBEADDE;
	HalFlashWrite(pidx, 0, (uint8_t *)buf32, 4);
}
Exemplo n.º 9
0
void OS_reboot(char flash)
{
 #ifdef FEATURE_OAD_HEADER
  if (flash)
  {
    short zero = 0;
    uint16 addr = OAD_IMG_B_PAGE * (HAL_FLASH_PAGE_SIZE / HAL_FLASH_WORD_SIZE);
    HalFlashWrite(addr, (uint8*)&zero, sizeof(zero));
  }
#else
  VOID flash;
#endif
  SystemReset();
}
Exemplo n.º 10
0
// Input buffer at least 21 bytes (couting tailing zero)
void custom_set_dn(uint8 *dn)
{
    uint8 idx = 0;
    uint8 buf[CUSTOM_DN_MAGIC_LEN + CUSTOM_DN_LEN] = {0};

    for (idx = 0; idx < (CUSTOM_DN_MAGIC_LEN + CUSTOM_DN_LEN); idx++) {
        buf[idx] = 0;
    }
    dn[CUSTOM_DN_LEN] = 0;
    HalFlashErase(CUSTOM_DN_PAGE_IDX);

    osal_memcpy(buf, dn_magic, CUSTOM_DN_MAGIC_LEN);
    osal_memcpy((buf + CUSTOM_DN_MAGIC_LEN), dn, osal_strlen((char *)dn));
    HalFlashWrite((((uint32)CUSTOM_DN_PAGE_IDX * (uint32)2048 + CUSTOM_DN_MGIC_OFFSET) / 4), buf, (CUSTOM_DN_MAGIC_LEN + CUSTOM_DN_LEN) / 4); 
}
Exemplo n.º 11
0
// FIXME: currently only device name
void custom_init(void)
{
    uint8 buf[CUSTOM_DN_MAGIC_LEN + CUSTOM_DN_LEN];
    uint8 idx = 0;

    HalFlashRead(CUSTOM_DN_PAGE_IDX, CUSTOM_DN_MGIC_OFFSET, buf, (CUSTOM_DN_MAGIC_LEN + CUSTOM_DN_LEN));
    if (osal_memcmp(buf, dn_magic, CUSTOM_DN_MAGIC_LEN) != TRUE) {
        HalFlashErase(CUSTOM_DN_PAGE_IDX);
        for (idx = 0; idx < (CUSTOM_DN_MAGIC_LEN + CUSTOM_DN_LEN); idx++) {
            buf[idx] = 0;
        }
        osal_memcpy(buf, dn_magic, CUSTOM_DN_MAGIC_LEN);
        osal_memcpy((buf + CUSTOM_DN_MAGIC_LEN), dn_default, 3);
        HalFlashWrite((((uint32)CUSTOM_DN_PAGE_IDX * (uint32)2048 + CUSTOM_DN_MGIC_OFFSET) / 4), buf, (CUSTOM_DN_MAGIC_LEN + CUSTOM_DN_LEN) / 4);
    }
}
Exemplo n.º 12
0
/**************************************************************************************************
 * @fn          crcCheck
 *
 * @brief       Calculate the image CRC and set it ready-to-run if it is good.
 *
 * input parameters
 *
 * @param       page - Flash page on which to beging the CRC calculation.
 *
 * output parameters
 *
 * None.
 *
 * @return      None, but no return from this function if the CRC check is good.
 **************************************************************************************************
 */
static void crcCheck(uint8 page, uint16 *crc)
{
  HAL_BOARD_INIT();

  if (crc[0] == crcCalcDMA(page))
  {
    //P0_0 = 0;
    uint16 addr = page * (HAL_FLASH_PAGE_SIZE / HAL_FLASH_WORD_SIZE) +
                                 BIM_CRC_OSET / HAL_FLASH_WORD_SIZE;
    crc[1] = crc[0];
    crc[0] = 0xFFFF;

    HAL_DMA_SET_ADDR_DESC0(&dmaCh0);
    HalFlashWrite(addr, (uint8 *)crc, 1);
    HAL_SYSTEM_RESET();
  }
}
Exemplo n.º 13
0
/**************************************************************************************************
 * @fn          sblExec
 *
 * @brief       Act on the SB command and received buffer.
 *
 * @param       pBuf - A pointer to the RPC command buffer received.
 *
 * None.
 *
 * output parameters
 *
 * None.
 *
 * @return      None.
 **************************************************************************************************
 */
static void sblExec(uint8 *pBuf)
{
    uint16 t16 = BUILD_UINT16(pBuf[SBL_REQ_ADDR_LSB],pBuf[SBL_REQ_ADDR_MSB]) + OAD_DONGLE_SBL_IMG_BEG;
    uint8 len = 1;
    uint8 rsp = SBL_SUCCESS;

    switch (pBuf[RPC_POS_CMD1])
    {
    case SBL_WRITE_CMD:
        if ((t16 >= OAD_DONGLE_SBL_IMG_END) || (t16 < OAD_DONGLE_SBL_IMG_BEG))
        {
            rsp = SBL_FAILURE;
            break;
        }
        if ((t16 % SBL_PAGE_SIZE) == 0)
        {
            HalFlashErase(t16 / SBL_PAGE_SIZE);
        }
        HalFlashWrite(t16, (pBuf + SBL_REQ_DAT0), (SBL_RW_BUF_LEN / HAL_FLASH_WORD_SIZE));
        break;

    case SBL_READ_CMD:
        len = SBL_RW_BUF_LEN + SBL_READ_HDR_LEN;
        pBuf[SBL_RSP_ADDR_MSB] = pBuf[SBL_REQ_ADDR_MSB];
        pBuf[SBL_RSP_ADDR_LSB] = pBuf[SBL_REQ_ADDR_LSB];

        HalFlashRead(t16 / SBL_PAGE_SIZE,
                     (t16 % SBL_PAGE_SIZE) << 2, (pBuf + SBL_RSP_DAT0), SBL_RW_BUF_LEN);
        break;

    case SBL_ENABLE_CMD:
        // Bootload master must verify download by read back - no room for CRC checking code in dongle.
        break;

    case SBL_HANDSHAKE_CMD:
        break;

    default:
        rsp = SBL_FAILURE;
        break;
    }

    pBuf[RPC_POS_LEN] = len;
    pBuf[RPC_POS_CMD1] |= SBL_RSP_MASK;
    pBuf[RPC_POS_DAT0] = rsp;
}
Exemplo n.º 14
0
/*********************************************************************
 * @fn      dl2rc
 *
 * @brief   Copy the DL image to the RC image location.
 *
 *  NOTE:   Assumes that DL image ends on a flash word boundary.
 *
 * @param   None.
 *
 * @return  None.
 *********************************************************************/
static void dl2rc(void)
{
  preamble_t preamble;
  uint32 oset;
  uint16 addr = HAL_OAD_RC_START / HAL_FLASH_WORD_SIZE;
  uint8 buf[4];

  HalOADRead(PREAMBLE_OFFSET, (uint8 *)&preamble, sizeof(preamble_t), HAL_OAD_DL);

  for (oset = 0; oset < preamble.len; oset += HAL_FLASH_WORD_SIZE)
  {
    HalOADRead(oset, buf, HAL_FLASH_WORD_SIZE, HAL_OAD_DL);
    if ((addr % (HAL_FLASH_PAGE_SIZE / HAL_FLASH_WORD_SIZE)) == 0)
    {
      HalFlashErase(addr / (HAL_FLASH_PAGE_SIZE / HAL_FLASH_WORD_SIZE));
    }
    HalFlashWrite(addr++, buf, 1);
  }
}
Exemplo n.º 15
0
uint8 MT_UblCommandProcessing(uint8 *pBuf)
{
  if (pBuf[MT_RPC_POS_CMD1] == MT_UBL_ERASE)
  {
    uint16 crc[2];
    HalFlashRead(UBL_RC_IMG_PG_BEG, UBL_MD_PG_OFFSET, (uint8 *)(crc+1), 2);

    if (crc[1] != 0)
    {
      crc[1] ^= 0xFFFF;  // Only write to zero bits that are not already zero.
      crc[0] = 0xFFFF;
      HalFlashWrite((UBL_MD_ADDR - 2) / HAL_FLASH_WORD_SIZE, (uint8 *)crc, 1);
    }

    Onboard_soft_reset();
  }

  return MT_RPC_ERR_COMMAND_ID;
}
Exemplo n.º 16
0
void persistent_record_error(uint8_t error_idx, uint32_t error_info)
{
	uint8_t idx;
	uint32_t offset;
	struct error_record rcd;

	if (error_idx > PERSISTENT_ERROR_MAX) {
		persistent_record_error(PERSISTENT_ERROR_INTERNAL, 0);
		return;
	}

	offset = (uint32)&(((struct persistent_page *)0)->error_log[error_idx]);
	HalFlashRead(pidx, (uint16_t)offset, (uint8_t *)&rcd, sizeof(rcd));
	idx = __persistent_mark_bit_map((uint8_t *)&(rcd.count_bit), 4);
	if (idx < PERSISTENT_ERROR_ENTRY) {
		rcd.error_info[idx] = error_info;
	}

	// Write back
	HalFlashWrite(pidx, (uint16_t)offset, (uint8_t *)&rcd, sizeof(rcd));
}
Exemplo n.º 17
0
/******************************************************************************
 * @fn      dl2rc
 *
 * @brief   Copy the DL image to the RC image location.
 *
 *  NOTE:   Assumes that DL image ends on a flash word boundary.
 *
 * @param   None.
 *
 * @return  None.
 */
static void dl2rc(void)
{
  uint32 oset;
  OTA_SubElementHdr_t subElement;
  OTA_ImageHeader_t header;
  uint16 addr = HAL_OTA_RC_START / HAL_FLASH_WORD_SIZE;
  uint8 buf[4];

  // Determine the length and starting point of the upgrade image
  HalOTARead(0, (uint8 *)&header, sizeof(OTA_ImageHeader_t), HAL_OTA_DL);
  HalOTARead(header.headerLength, (uint8*)&subElement, OTA_SUB_ELEMENT_HDR_LEN, HAL_OTA_DL);

  for (oset = 0; oset < subElement.length; oset += HAL_FLASH_WORD_SIZE)
  {
    HalOTARead(oset + header.headerLength + OTA_SUB_ELEMENT_HDR_LEN, buf, HAL_FLASH_WORD_SIZE, HAL_OTA_DL);
    if ((addr % (HAL_FLASH_PAGE_SIZE / HAL_FLASH_WORD_SIZE)) == 0)
    {
      HalFlashErase(addr / (HAL_FLASH_PAGE_SIZE / HAL_FLASH_WORD_SIZE));
    }
    HalFlashWrite(addr++, buf, 1);
  }
}
Exemplo n.º 18
0
/**************************************************************************************************
 * @fn          appForceBoot
 *
 * @brief       Force the boot loader to run.
 *
 * input parameters
 *
 * None.
 *
 * output parameters
 *
 * None.
 *
 * @return      None.
 */
void appForceBoot(void)
{
    uint16 crc[2];

    // Make sure SBL is present.
    HalFlashRead(UBL_PAGE_FIRST, UBL_MD_PG_OFFSET, (uint8 *)crc, 4);

    if ((crc[0] == 0xFFFF) || (crc[0] == 0x0000) ||
            (crc[1] == 0xFFFF) || (crc[1] == 0x0000) ||
            (crc[1] != crc[0]))
    {
        return;
    }

    HAL_DISABLE_INTERRUPTS();

    crc[1] ^= 0xFFFF;  // Only write to zero bits that are not already zero.
    crc[0] = 0xFFFF;
    HalFlashWrite(((uint16)&_ublMetaData) / HAL_FLASH_WORD_SIZE, (uint8 *)crc, 1);

    HAL_SYSTEM_RESET();
}
Exemplo n.º 19
0
void main(void)
{
  uint16 crc[2];

  HAL_BOARD_INIT();
#if HAL_OAD_XNV_IS_SPI
  XNV_SPI_INIT();
#endif
  /* This is in place of calling HalDmaInit() which would require init of the other 4 DMA
   * descriptors in addition to just Channel 0.
   */
  HAL_DMA_SET_ADDR_DESC0( &dmaCh0 );
  HalFlashInit();

  HalFlashRead(HAL_OAD_CRC_ADDR / HAL_FLASH_PAGE_SIZE,
               HAL_OAD_CRC_ADDR % HAL_FLASH_PAGE_SIZE,
               (uint8 *)crc, sizeof(crc));

  if (crc[0] != crc[1])
  {
    // If the CRC is erased or the RC code fails a sanity check, instantiate the DL code (again).
    if ((crc[0] == 0) || (crc[0] != crcCalc()))
    {
      dl2rc();

      /* If dl2rc() fails, a flawed image is allowed to run - 
       * maybe the damage is not fatal to OTA ops?
       */
    }
    else
    {
      crc[1] = crc[0];
      HalFlashWrite((HAL_OAD_CRC_ADDR / HAL_FLASH_WORD_SIZE), (uint8 *)crc, 1);
    }
  }

  // Simulate a reset for the Application code by an absolute jump to location 0x0800.
  asm("LJMP 0x800\n");
}
Exemplo n.º 20
0
/******************************************************************************
 * @fn      HalOTAWrite
 *
 * @brief   Write to the storage medium according to the image type.
 *
 *  NOTE:   Destructive write on page boundary! When writing to the first flash word
 *          of a page boundary, the page is erased without saving/restoring the bytes not written.
 *          Writes anywhere else on a page assume that the location written to has been erased.
 *
 * @param   oset - Offset into the monolithic image, aligned to HAL_FLASH_WORD_SIZE.
 * @param   pBuf - Pointer to the buffer in from which to write.
 * @param   len - Number of bytes to write. If not an even multiple of HAL_FLASH_WORD_SIZE,
 *                remainder bytes are overwritten with garbage.
 * @param   type - Which image: HAL_OTA_RC or HAL_OTA_DL.
 *
 * @return  None.
 */
void HalOTAWrite(uint32 oset, uint8 *pBuf, uint16 len, image_t type)
{
  if (HAL_OTA_RC != type)
  {
#if HAL_OTA_XNV_IS_INT
    oset += HAL_OTA_RC_START + HAL_OTA_DL_OSET;
#elif HAL_OTA_XNV_IS_SPI
    oset += HAL_OTA_DL_OSET;
    HalSPIWrite(oset, pBuf, len);
    return;
#endif
  }
  else
  {
    oset += HAL_OTA_RC_START;
  }

  if ((oset % HAL_FLASH_PAGE_SIZE) == 0)
  {
    HalFlashErase(oset / HAL_FLASH_PAGE_SIZE);
  }

  HalFlashWrite(oset / HAL_FLASH_WORD_SIZE, pBuf, len / HAL_FLASH_WORD_SIZE);
}
Exemplo n.º 21
0
/*********************************************************************
 * @fn      oadImgBlockWrite
 *
 * @brief   Process the Image Block Write.
 *
 * @param   connHandle - connection message was received on
 * @param   pValue - pointer to data to be written
 *
 * @return  status
 */
static bStatus_t oadImgBlockWrite( uint16 connHandle, uint8 *pValue )
{
  uint16 blkNum = BUILD_UINT16( pValue[0], pValue[1] );

  // make sure this is the image we're expecting
  if ( blkNum == 0 )
  {
    img_hdr_t ImgHdr;
    uint16 ver = BUILD_UINT16( pValue[6], pValue[7] );
    uint16 blkTot = BUILD_UINT16( pValue[8], pValue[9] ) / (OAD_BLOCK_SIZE / HAL_FLASH_WORD_SIZE);

    HalFlashRead(OAD_IMG_R_PAGE, OAD_IMG_HDR_OSET, (uint8 *)&ImgHdr, sizeof(img_hdr_t));

    if ( ( oadBlkNum != blkNum ) ||
         ( oadBlkTot != blkTot ) ||
         ( OAD_IMG_ID( ImgHdr.ver ) == OAD_IMG_ID( ver ) ) )
    {
      return ( ATT_ERR_WRITE_NOT_PERMITTED );
    }
  }

  if (oadBlkNum == blkNum)
  {
    uint16 addr = oadBlkNum * (OAD_BLOCK_SIZE / HAL_FLASH_WORD_SIZE) +
                              (OAD_IMG_D_PAGE * OAD_FLASH_PAGE_MULT);
    oadBlkNum++;

#if defined FEATURE_OAD_SECURE
    if (blkNum == 0)
    {
      // Stop attack with crc0==crc1 by forcing crc1=0xffff.
      pValue[4] = 0xFF;
      pValue[5] = 0xFF;
    }
#endif

#if defined HAL_IMAGE_B
    // Skip the Image-B area which lies between the lower & upper Image-A parts.
    if (addr >= (OAD_IMG_B_PAGE * OAD_FLASH_PAGE_MULT))
    {
      addr += OAD_IMG_B_AREA * OAD_FLASH_PAGE_MULT;
    }
#endif
    if ((addr % OAD_FLASH_PAGE_MULT) == 0)
    {
      HalFlashErase(addr / OAD_FLASH_PAGE_MULT);
    }

    HalFlashWrite(addr, pValue+2, (OAD_BLOCK_SIZE / HAL_FLASH_WORD_SIZE));
  }

  if (oadBlkNum == oadBlkTot)  // If the OAD Image is complete.
  {
#if defined FEATURE_OAD_SECURE
    HAL_SYSTEM_RESET();  // Only the secure OAD boot loader has the security key to decrypt.
#else
    if (checkDL())
    {
#if !defined HAL_IMAGE_A
      // The BIM always checks for a valid Image-B before Image-A,
      // so Image-A never has to invalidate itself.
      uint16 crc[2] = { 0x0000, 0xFFFF };
      uint16 addr = OAD_IMG_R_PAGE * OAD_FLASH_PAGE_MULT + OAD_IMG_CRC_OSET / HAL_FLASH_WORD_SIZE;
      HalFlashWrite(addr, (uint8 *)crc, 1);
#endif
      HAL_SYSTEM_RESET();
    }
#endif
  }
  else  // Request the next OAD Image block.
  {
    oadImgBlockReq(connHandle, oadBlkNum);
  }

  return ( SUCCESS );
}
Exemplo n.º 22
0
/******************************************************************************
 * @fn      HalOTAInvRC
 *
 * @brief   Invalidate the active image so that the boot code will instantiate
 *          the DL image on the next reset.
 *
 * @param   None.
 *
 * @return  None.
 */
void HalOTAInvRC(void)
{
  uint16 crc[2] = {0,0xFFFF};
  HalFlashWrite((HAL_OTA_CRC_ADDR / HAL_FLASH_WORD_SIZE), (uint8 *)crc, 1);
}
Exemplo n.º 23
0
/**************************************************************************************************
 * @fn          sbCmnd
 *
 * @brief       Act on the SB command and received buffer.
 *
 * input parameters
 *
 * None.
 *
 * output parameters
 *
 * None.
 *
 * @return      TRUE to indicate that the SB_ENABLE_CMD command was successful; FALSE otherwise.
 **************************************************************************************************
 */
static uint8 sbCmnd(void)
{
  uint16 tmp = BUILD_UINT16(sbBuf[SB_DATA_STATE], sbBuf[SB_DATA_STATE+1]) + SB_IMG_OSET;
  uint16 crc[2];
  uint8 len = 1;
  uint8 rsp = SB_SUCCESS;
  uint8 rtrn = FALSE;

  switch (sbCmd2)
  {
  case SB_HANDSHAKE_CMD:
    break;

  case SB_WRITE_CMD:
    if ((tmp % SB_WPG_SIZE) == 0)
    {
      HalFlashErase(tmp / SB_WPG_SIZE);
    }

    HalFlashWrite(tmp, sbBuf+SB_DATA_STATE+2, SB_RW_BUF_LEN / HAL_FLASH_WORD_SIZE);
    break;

  case SB_READ_CMD:
#if !MT_SYS_OSAL_NV_READ_CERTIFICATE_DATA
    if ((tmp / (HAL_FLASH_PAGE_SIZE / 4)) >= HAL_NV_PAGE_BEG)
    {
      rsp = SB_FAILURE;
      break;
    }
#endif
    HalFlashRead(tmp / (HAL_FLASH_PAGE_SIZE / 4),
                 (tmp % (HAL_FLASH_PAGE_SIZE / 4)) << 2,
                 sbBuf + SB_DATA_STATE + 3, SB_RW_BUF_LEN);
    sbBuf[SB_DATA_STATE+2] = sbBuf[SB_DATA_STATE+1];
    sbBuf[SB_DATA_STATE+1] = sbBuf[SB_DATA_STATE];
    len = SB_RW_BUF_LEN + 3;
    break;
  
  case SB_ENABLE_CMD:
    HalFlashRead(HAL_SB_CRC_ADDR / HAL_FLASH_PAGE_SIZE,
                 HAL_SB_CRC_ADDR % HAL_FLASH_PAGE_SIZE,
                 (uint8 *)crc, sizeof(crc));

    // Bootload master must have verified extra checks to be issuing the SB_ENABLE_CMD.
    //if ((crc[0] != crc[1]) && (crc[0] != 0xFFFF) && (crc[0] != 0x0000))
    if (crc[1] != crc[0])
    {
      crc[1] = crc[0];
      HalFlashWrite((HAL_SB_CRC_ADDR / HAL_FLASH_WORD_SIZE), (uint8 *)crc, 1);
      HalFlashRead(  HAL_SB_CRC_ADDR / HAL_FLASH_PAGE_SIZE,
                     HAL_SB_CRC_ADDR % HAL_FLASH_PAGE_SIZE,
                     (uint8 *)crc, sizeof(crc));
    }

    // Bootload master must have verified extra checks to be issuing the SB_ENABLE_CMD.
    //if ((crc[0] == crc[1]) && (crc[0] != 0xFFFF) && (crc[0] != 0x0000))
    if (crc[0] == crc[1])
    {
      rtrn = TRUE;
    }
    else
    {
      rsp = SB_VALIDATE_FAILED;
    }
    break;
    
  default:
    break;
  }
  
  sbResp(rsp, len);
  return rtrn;
}