You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm using Filex with LevelX nor flash driver. I found that when writing a lot of data, _lx_nor_flash_logical_sector_find costs a lot of time(about 50ms each write), making LevelX write quite slow (about 5kb/s).
I checked the source code of LevelX, this while block costs the most of the time. Is there anyway to improve the write speed of LevelX?
while (total_blocks--)
{
/* Setup the block word pointer to the first word of the search block. */block_word_ptr= (nor_flash->lx_nor_flash_base_address+ (i*nor_flash->lx_nor_flash_words_per_block));
/* Determine if the minimum and maximum logical sector values are present in the block header. If these are present, we can quickly skip blocks that don't have our sector. *//* Read the minimum and maximum logical sector values in this block. */#ifdefLX_DIRECT_READ/* Read the word directly. */min_logical_sector=*(block_word_ptr+LX_NOR_FLASH_MIN_LOGICAL_SECTOR_OFFSET);
#elsestatus=_lx_nor_flash_driver_read(nor_flash, block_word_ptr+LX_NOR_FLASH_MIN_LOGICAL_SECTOR_OFFSET, &min_logical_sector, 1);
/* Check for an error from flash driver. Drivers should never return an error.. */if (status)
{
/* Call system error handler. */_lx_nor_flash_system_error(nor_flash, status);
/* Return the error. */return(status);
}
#endif#ifdefLX_DIRECT_READ/* Read the word directly. */max_logical_sector=*(block_word_ptr+LX_NOR_FLASH_MAX_LOGICAL_SECTOR_OFFSET);
#elsestatus=_lx_nor_flash_driver_read(nor_flash, block_word_ptr+LX_NOR_FLASH_MAX_LOGICAL_SECTOR_OFFSET, &max_logical_sector, 1);
/* Check for an error from flash driver. Drivers should never return an error.. */if (status)
{
/* Call system error handler. */_lx_nor_flash_system_error(nor_flash, status);
/* Return the error. */return(status);
}
#endif/* Are the values valid? */if ((min_logical_sector!=LX_ALL_ONES) && (max_logical_sector!=LX_ALL_ONES))
{
/* Now let's check to see if the search sector is within this range. */if ((logical_sector<min_logical_sector) || (logical_sector>max_logical_sector))
{
/* Move to the next block. */i++;
/* Determine if we have wrapped. */if (i >= nor_flash->lx_nor_flash_total_blocks)
{
/* Yes, we have wrapped, set to block 0. */i=0;
}
/* Start at the first sector in the next block. */j=0;
/* No point in looking further into this block, just continue the loop. */continue;
}
}
/* Setup the total number of sectors. */total_sectors=nor_flash->lx_nor_flash_physical_sectors_per_block;
/* Remember the start of the search. */search_start=j;
/* Now search through the sector list to find a match. */while (total_sectors--)
{
/* Setup a pointer to the mapped list. */list_word_ptr=block_word_ptr+nor_flash->lx_nor_flash_block_physical_sector_mapping_offset+j;
/* Read in the mapped list for this block. */#ifdefLX_DIRECT_READ/* Read the word directly. */list_word=*(list_word_ptr);
#elsestatus=_lx_nor_flash_driver_read(nor_flash, list_word_ptr, &list_word, 1);
/* Check for an error from flash driver. Drivers should never return an error.. */if (status)
{
/* Call system error handler. */_lx_nor_flash_system_error(nor_flash, status);
/* Return the error. */LOGE("sector find costs: %d", tx_time_get() -s);
return(status);
}
#endif/* Determine if the entry hasn't been used. */if (list_word==LX_NOR_PHYSICAL_SECTOR_FREE)
{
/* Since the mapping is done sequentially in the block, we know nothing else exists after this point. *//* Determine if the search started at the beginning of the block. */if (search_start==0)
{
/* Yes, we started at the beginning of the block. We are now done with this block. */break;
}
else
{
/* Setup the new total to the search start. */total_sectors=search_start;
/* Clear search start. */search_start=0;
/* Start search over. */j=0;
continue;
}
}
/* Is this entry valid? */if ((list_word& (LX_NOR_PHYSICAL_SECTOR_VALID | LX_NOR_PHYSICAL_SECTOR_MAPPING_NOT_VALID)) ==LX_NOR_PHYSICAL_SECTOR_VALID)
{
/* Decrement the number of mapped sectors. */mapped_sectors--;
/* Do we have a valid sector match? */if ((list_word&LX_NOR_LOGICAL_SECTOR_MASK) ==logical_sector)
{
/* Determine if we care about the superceded bit. */if (superceded_check==LX_FALSE)
{
/* Prepare the return information. */*physical_sector_map_entry=list_word_ptr;
*physical_sector_address=block_word_ptr+nor_flash->lx_nor_flash_block_physical_sector_offset+ (j*LX_NOR_SECTOR_SIZE);
/* Determine if the sector mapping cache is enabled. */if (nor_flash->lx_nor_flash_sector_mapping_cache_enabled)
{
/* Yes, update the cache with the sector mapping. *//* Move all the cache entries down so the oldest is at the bottom. */*(sector_mapping_cache_entry_ptr+3) =*(sector_mapping_cache_entry_ptr+2);
*(sector_mapping_cache_entry_ptr+2) =*(sector_mapping_cache_entry_ptr+1);
*(sector_mapping_cache_entry_ptr+1) =*(sector_mapping_cache_entry_ptr);
/* Setup the new sector information in the cache. */sector_mapping_cache_entry_ptr->lx_nor_sector_mapping_cache_logical_sector= (logical_sector | LX_NOR_SECTOR_MAPPING_CACHE_ENTRY_VALID);
sector_mapping_cache_entry_ptr->lx_nor_sector_mapping_cache_physical_sector_map_entry=*physical_sector_map_entry;
sector_mapping_cache_entry_ptr->lx_nor_sector_mapping_cache_physical_sector_address=*physical_sector_address;
}
/* Remember the last found block for next search. */nor_flash->lx_nor_flash_found_block_search=i;
/* Remember the last found sector. */nor_flash->lx_nor_flash_found_sector_search=j+1;
/* Has this wrapped around? */if (nor_flash->lx_nor_flash_found_sector_search >= nor_flash->lx_nor_flash_physical_sectors_per_block)
{
/* Reset to the beginning sector. */nor_flash->lx_nor_flash_found_sector_search=0;
}
/* Return success! */LOGI("sector find costs: %d", tx_time_get() -s);
return(LX_SUCCESS);
}
/* Check for the superceded bit being clear, which means the sector was superceded. */elseif (list_word&LX_NOR_PHYSICAL_SECTOR_SUPERCEDED)
{
/* Prepare the return information. */*physical_sector_map_entry=list_word_ptr;
*physical_sector_address=block_word_ptr+nor_flash->lx_nor_flash_block_physical_sector_offset+ (j*LX_NOR_SECTOR_SIZE);
/* No need to update the cache here, since this condition only happens during initialization. *//* Remember the last found block for next search. */nor_flash->lx_nor_flash_found_block_search=i;
/* Remember the last found sector. */nor_flash->lx_nor_flash_found_sector_search=j+1;
/* Has this wrapped around? */if (nor_flash->lx_nor_flash_found_sector_search >= nor_flash->lx_nor_flash_physical_sectors_per_block)
{
/* Reset to the beginning sector. */nor_flash->lx_nor_flash_found_sector_search=0;
}
/* Return success! */LOGI("sector find costs: %d", tx_time_get() -s);
return(LX_SUCCESS);
}
}
}
/* Move to the next list entry. */j++;
/* Check for wrap around. */if (j >= nor_flash->lx_nor_flash_physical_sectors_per_block)
{
/* Yes, wrap around, go back to the beginning. */j=0;
}
}
/* Determine if there are any more mapped sectors. */if (mapped_sectors==0)
break;
/* Move to the next block. */i++;
/* Determine if we have wrapped. */if (i >= nor_flash->lx_nor_flash_total_blocks)
{
/* Yes, we have wrapped, set to block 0. */i=0;
}
/* Start at the first sector in the next block. */j=0;
}
The text was updated successfully, but these errors were encountered:
Hi @HaoboGu, in version 6.3.0, there are two new options that may improve the write speed: LX_NOR_ENABLE_MAPPING_BITMAP and LX_NOR_ENABLE_OBSOLETE_COUNT_CACHE. Enable these two options and provide cache memory to the LevelX by calling lx_nor_flash_extended_cache_enable. The memory size should be one bit for each sector plus one byte for each block.
I'm using Filex with LevelX nor flash driver. I found that when writing a lot of data, _lx_nor_flash_logical_sector_find costs a lot of time(about 50ms each write), making LevelX write quite slow (about 5kb/s).
I checked the source code of LevelX, this while block costs the most of the time. Is there anyway to improve the write speed of LevelX?
The text was updated successfully, but these errors were encountered: