Hi Kan,
This is the function we use to program the flash. I'd like to stress, that it is working appx. 99.99% of the time, as we have programmed the flash hundreds of times on hundreds of units and it got corrupted only twice so far. However we would like to scale up our production and this is becoming an issue, as it is happening on the field (over-the-air firmware update).
//-----------------------------------------------------------------------------
// Copy one bank worth of data from firmware partition to flash
// (Skip the last block of Bank3, as it is used for flash swap indicator)
// part_block: block offset in firmware partition
// bankname: flash bank to write to
static bool WriteBank( uint32_t part_block, const char *bankname ) {
MQX_FILE_PTR flash_file;
bool success = true;
PROG_DEBUG( "Opening %s\n", bankname );
/* open flash device */
if (NULL == ( flash_file = fopen(bankname, NULL) ) ) {
PROG_ERROR( "Couldn't open %s\n", bankname );
return false;
}
uint32_t sector_size;
ioctl( flash_file, FLASH_IOCTL_GET_SECTOR_SIZE, §or_size );
/* Unprotecting the the FLASH might be required */
uint32_t ioctl_param = 0;
ioctl(flash_file, FLASH_IOCTL_WRITE_PROTECT, &ioctl_param);
ioctl(flash_file, FLASH_IOCTL_ENABLE_SECTOR_CACHE, NULL);
char *buf;
if ( NULL == ( buf = ((char *)ddrmalloc( BANK_SIZE ) ) ) ) {
PROG_ERROR( "Couldn't allocate %d bytes of memory\n", BANK_SIZE);
fclose( flash_file );
return false;
}
int sectors;
if (0 == strcmp(bankname, BANK2)) {
sectors = BANK_SIZE / sector_size ;
} else {
// bank3: leave the last one sector intact (used as
// flash indicator)
sectors = (BANK_SIZE / sector_size) - 1;
}
int blocks = BANK_SIZE / PM_SECTOR_SIZE;
success = ReadPartition( buf, part_block, blocks);
if ( success ) {
int bytes_to_write = sectors * sector_size;
if ( bytes_to_write != write( flash_file, buf, bytes_to_write ) ) {
PROG_ERROR( "Couldn't write data to flash\n" );
success = false;
}
}
fclose( flash_file );
free( buf );
return success;
}