예제 #1
0
/**
 * Store parameters of object dictionary into flash memory.
 * \param[in] FlashAddress Use CO_OD_Flash_Adress for the normal parameter
 *                         block and CO_OD_Flash_Default_Param for the
 *                         default parameters
 */
static CO_SDO_abortCode_t storeParameters(cyg_flashaddr_t FlashAddress,
	uint8_t ParametersSub)
{
	CO_DBG_PRINT("Store parameters\n");

	cyg_flashaddr_t ErrorAddress;

	//unlock flash
#ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING
	int Result = cyg_flash_unlock(FlashAddress, sizeof(struct sCO_OD_ROM),
		&ErrorAddress);
	CHECK_FLASH_RESULT(Result);
	if (CYG_FLASH_ERR_OK != Result)
	{
		return CO_SDO_AB_HW;
	}
#endif

	// erase block
	Result = cyg_flash_erase(FlashAddress, sizeof(struct sCO_OD_ROM),
		&ErrorAddress);
	CHECK_FLASH_RESULT(Result);
	if (CYG_FLASH_ERR_OK != Result)
	{
		return CO_SDO_AB_HW;
	}

	// program data into flash
	Result = cyg_flash_program(FlashAddress, &CO_OD_ROM,
		sizeof(CO_OD_ROM), &ErrorAddress);
	CHECK_FLASH_RESULT(Result);
	if (CYG_FLASH_ERR_OK != Result)
	{
		return CO_SDO_AB_HW;
	}

	return CO_SDO_AB_NONE;
}
예제 #2
0
void SpiFlash::eraseCmd(cTerm & t,int argc,char *argv[])
{
	if (argc > 1)
	{
		cyg_uint32 addr = (cyg_uint32)strtoul(argv[1],NULL,16);

		int error = cyg_flash_erase(addr, 1, 0);

		if (!error)
		{
			t<<t.format(GREEN("Erased serial flash sector at address 0x%08X\n"), addr);
		}
		else
		{
			t<<(RED("Error erasing serial flash!\n"));
			printfError(error);
		}
	}
	else
	{
		t<<"You need to supply an address in a sector to erase\n";
	}

}
예제 #3
0
__externC int
cyg_flash_erase(cyg_flashaddr_t flash_base,
                size_t len,
                cyg_flashaddr_t *err_address)
{
  cyg_flashaddr_t block, end_addr;
  struct cyg_flash_dev * dev;
  size_t erase_count;
  int stat = CYG_FLASH_ERR_OK;
  HAL_FLASH_CACHES_STATE(d_cache, i_cache);

  dev = find_dev(flash_base, &stat);
  if (!dev) return stat;

  CHECK_SOFT_WRITE_PROTECT(flash_base, len);

  LOCK(dev);

  // Check whether or not we are going past the end of this device, on
  // to the next one. If so the next device will be handled by a
  // recursive call later on.
  if (len > (dev->end + 1 - flash_base)) {
      end_addr = dev->end;
  } else {
      end_addr = flash_base + len - 1;
  }
  // erase can only happen on a block boundary, so adjust for this
  block         = flash_block_begin(flash_base, dev);
  erase_count   = (end_addr + 1) - block;

  CHATTER(dev, "... Erase from %p-%p: ", (void*)block, (void*)end_addr);

  HAL_FLASH_CACHES_OFF(d_cache, i_cache);
  FLASH_Enable(flash_base, end_addr);
  while (erase_count > 0) {
    int i;
    unsigned char *dp;
    bool erased = false;
    size_t block_size = flash_block_size(dev, block);

    // Pad to the block boundary, if necessary
    if (erase_count < block_size) {
        erase_count = block_size;
    }

    // If there is a read function it probably means the flash
    // cannot be read directly.
    if (!dev->funs->flash_read) {
      erased = true;
      dp = (unsigned char *)block;
      for (i = 0;  i < block_size;  i++) {
        if (*dp++ != (unsigned char)0xFF) {
          erased = false;
          break;
        }
      }
    }
    if (!erased) {
      FLASH_WATCHDOG_RESET;
      stat = dev->funs->flash_erase_block(dev,block);
    }
    if (CYG_FLASH_ERR_OK != stat) {
        if (err_address)
            *err_address = block;
        break;
    }
    block       += block_size;
    erase_count -= block_size;
    CHATTER(dev, ".");
  }
  FLASH_Disable(flash_base, end_addr);
  HAL_FLASH_CACHES_ON(d_cache, i_cache);
  CHATTER(dev, "\n");
  UNLOCK(dev);
  if (stat != CYG_FLASH_ERR_OK) {
    return stat;
  }

  // If there are multiple flash devices in series the erase operation
  // may touch successive devices. This can be handled by recursion.
  // The stack overheads should be minimal because the number of
  // devices will be small.
  if (len > (dev->end + 1 - flash_base)) {
    return cyg_flash_erase(dev->end+1,
                           len - (dev->end + 1 - flash_base),
                           err_address);
  }
  return CYG_FLASH_ERR_OK;
}
예제 #4
0
파일: flash2.c 프로젝트: KarenHung/ecosgit
void cyg_user_start(void)
{
    int ret;
    cyg_flashaddr_t flash_start=0, flash_end=0;
    cyg_flash_info_t info;
    cyg_uint32 i=0;
    cyg_uint32 j;
    int block_size=0, blocks=0;
    cyg_flashaddr_t prog_start;
    unsigned char * ptr;

    CYG_TEST_INIT();
  
    cyg_flash_set_global_printf((cyg_flash_printf *)&diag_printf);
    ret=cyg_flash_init(NULL);
    
    CYG_TEST_PASS_FAIL((ret == CYG_FLASH_ERR_OK),"flash_init");

    do {
      ret = cyg_flash_get_info(i, &info);
      if (ret == CYG_FLASH_ERR_OK) {
        diag_printf("INFO: Nth=%d, start=%p, end=%p\n",
                    i, (void *) info.start, (void *) info.end);
        if (i == 0) {
          flash_start = info.start;
          flash_end = info.end;
          block_size = info.block_info[0].block_size;
          blocks = info.block_info[0].blocks;
        }
        for (j=0;j < info.num_block_infos; j++) {
          diag_printf("INFO:\t block_size %zd, blocks %u\n",
                      info.block_info[j].block_size,
                      info.block_info[j].blocks);
        }
      }
      i++;
    } while (ret != CYG_FLASH_ERR_INVALID);
    
    /* Erase the whole flash. Not recommended on real hardware since this
     will probably erase the bootloader etc!!! */
    ret=cyg_flash_erase(flash_start,block_size * blocks,NULL);
    CYG_TEST_PASS_FAIL((ret == CYG_FLASH_ERR_OK),"flash_erase1");

    /* check that its actually been erased, and test the mmap area */
    for (ptr=(unsigned char *)flash_start,ret=0; 
         ptr <= (unsigned char *)flash_end; ptr++) {
        if (*ptr != 0xff) {
            ret++;
        }
    }
  
    CYG_TEST_PASS_FAIL((ret == 0),"flash empty check");

    ret = cyg_flash_program(flash_start,&copyright,sizeof(copyright),NULL);
    CYG_TEST_PASS_FAIL((ret == CYG_FLASH_ERR_OK),"flash_program1");
  
    /* Check the contents made it into the flash */
    CYG_TEST_PASS_FAIL(!strncmp((void *)flash_start,
                                copyright,sizeof(copyright)),
                       "flash program contents");

    /* .. and check nothing else changed */
    for (ptr=(unsigned char *)flash_start+sizeof(copyright),ret=0; 
         ptr < (unsigned char *)flash_end; ptr++) {
        if (*ptr != 0xff) {
            ret++;
        }
    }
  
    CYG_TEST_PASS_FAIL((ret == 0),"flash program overrun check");

    /* Program over a block boundary */
    prog_start = flash_start + block_size - sizeof(copyright)/2;
    ret = cyg_flash_program(prog_start,&copyright,sizeof(copyright),NULL);
    CYG_TEST_PASS_FAIL((ret == CYG_FLASH_ERR_OK),"flash_program2");
  
    /* Check the first version is still OK */
    CYG_TEST_PASS_FAIL(!strncmp((void *)flash_start,
                                copyright,
                                sizeof(copyright)),
                       "Original contents");
  
    CYG_TEST_PASS_FAIL(!strncmp((void *)prog_start,
                                copyright,
                                sizeof(copyright)),
                       "New program contents");

    /* Check the bit in between is still erased */
    for (ptr=(unsigned char *)flash_start+sizeof(copyright),ret=0; 
         ptr < (unsigned char *)prog_start; ptr++) {
        if (*ptr != 0xff) {
            ret++;
        }
    }
    CYG_TEST_PASS_FAIL((ret == 0),"flash erase check1");
  
    /* Erase the second block and make sure the first is not erased */
    ret=cyg_flash_erase(flash_start+block_size,block_size,NULL);
    CYG_TEST_PASS_FAIL((ret == CYG_FLASH_ERR_OK),"flash_erase2");

    /* Check the erase worked */
    for (ptr=(unsigned char *)flash_start+block_size,ret=0; 
         ptr < (unsigned char *)flash_start+block_size*2; 
         ptr++) {
        if (*ptr != 0xff) {
            ret++;
        }
    }

    CYG_TEST_PASS_FAIL((ret == 0), "flash erase check2");
  
    /* Lastly check the first half of the copyright message is still there */
    CYG_TEST_PASS_FAIL(!strncmp((void *)prog_start,
                                copyright,
                                sizeof(copyright)/2),
                       "Block 1 OK");

#if 0
    /* This test is be fatal! Its not run by default!
     Check the flash is read only, by trying to write to it. We expect
     to get an exception */

    *(char *)flash_start = 'a';
#endif

    CYG_TEST_PASS_FINISH("flash2");
}