📄 fsintrnl.c
字号:
(Flash->high_wear - Flash->blocks[b].wear_count));
if (Flash->high_wear >= Flash->blocks[b].wear_count + MAX_WDELTA)
f_b += 65536;
/*-------------------------------------------------------------*/
/* If better candidate, remember it. */
/*-------------------------------------------------------------*/
if (max_f < f_b)
{
max_f = f_b;
max_b = b;
}
}
}
/*-----------------------------------------------------------------*/
/* If candidate block found, place it in set. */
/*-----------------------------------------------------------------*/
if (max_f != -1)
{
Flash->erase_set[i] = max_b; /*lint !e644 */
/*---------------------------------------------------------------*/
/* Temporarily mark block as bad so it's not selected next time */
/* around. */
/*---------------------------------------------------------------*/
Flash->blocks[max_b].bad_block = TRUE;
}
/*-----------------------------------------------------------------*/
/* Else stop and start using free blocks. */
/*-----------------------------------------------------------------*/
else
break;
}
/*-------------------------------------------------------------------*/
/* If not enough non-free blocks to fill set, use free blocks. */
/*-------------------------------------------------------------------*/
for (; i < Flash->set_blocks; ++i)
{
/*-----------------------------------------------------------------*/
/* Select the first free block and get the last sector in block. */
/*-----------------------------------------------------------------*/
free_blck = Flash->free_sect / Flash->block_sects;
last_in_free_block = (free_blck + 1) * Flash->block_sects - 1;
PfAssert(Flash->sect_tbl[last_in_free_block].prev == FFREE_SECT);
/*-----------------------------------------------------------------*/
/* Put the block on the erase set. */
/*-----------------------------------------------------------------*/
Flash->erase_set[i] = (int)free_blck;
/*-----------------------------------------------------------------*/
/* Advance free sector to next free block. */
/*-----------------------------------------------------------------*/
PfAssert(Flash->sect_tbl[last_in_free_block].next != FLAST_SECT);
Flash->free_sect = Flash->sect_tbl[last_in_free_block].next;
PfAssert(Flash->sect_tbl[Flash->free_sect].prev == FFREE_SECT);
/*-----------------------------------------------------------------*/
/* Mark all free sectors in erase set block to dirty. */
/*-----------------------------------------------------------------*/
sect = free_blck * Flash->block_sects + Flash->hdr_sects;
for (j = Flash->hdr_sects; j < Flash->block_sects; ++j, ++sect)
{
if (Flash->sect_tbl[sect].prev == FFREE_SECT)
{
Flash->sect_tbl[sect].prev = FDRTY_SECT;
--Flash->free_sects;
}
}
}
/*-------------------------------------------------------------------*/
/* Turn back to good all blocks in erasable set. */
/*-------------------------------------------------------------------*/
for (i = 0; i < Flash->set_blocks; ++i)
if (Flash->erase_set[i] != -1)
Flash->blocks[Flash->erase_set[i]].bad_block = FALSE;
}
/***********************************************************************/
/* recycle_not_possible: Determine whether there are enough free */
/* sectors to recycle the erase set */
/* */
/* Returns: TRUE if not enough free, FALSE otherwise */
/* */
/***********************************************************************/
static int recycle_not_possible(void)
{
ui32 block_sects, used, ctrl_blocks;
FlashRecycleValues(&ctrl_blocks, &used, &block_sects);
return ctrl_blocks * block_sects + used > Flash->free_sects;
}
/***********************************************************************/
/* erase_set: Write signature bytes and erase erasable set as part */
/* of a recycle operation */
/* */
/* Input: old_set_size = size of erasable set before adjustment */
/* due to write ctrl in recycle_finish() */
/* */
/* Returns: 0 on success, -1 on error */
/* */
/***********************************************************************/
static int erase_set(int old_set_size)
{
int s;
/*-------------------------------------------------------------------*/
/* Erase all blocks in next erasable set. */
/*-------------------------------------------------------------------*/
for (s = 0; s < old_set_size; ++s)
if (Flash->erase_set[s] != -1 &&
FlashEraseBlock((ui32)Flash->erase_set[s]))
return -1;
return 0;
}
/***********************************************************************/
/* in_erase_set: Determine if a block belongs to the erase set */
/* */
/* Input: block = block to look for */
/* */
/* Returns: TRUE if block in set, FALSE otherwise */
/* */
/***********************************************************************/
static int in_erase_set(ui32 block)
{
ui32 s;
/*-------------------------------------------------------------------*/
/* Skip checking during format. */
/*-------------------------------------------------------------------*/
if (Flash->set_blocks == 1)
return FALSE;
for (s = 0; s < Flash->set_blocks; ++s)
if (Flash->erase_set[s] == block)
return TRUE;
return FALSE;
}
/***********************************************************************/
/* choose_free_block: Choose free block to write control info */
/* */
/* Input: action = flag to indicate if in middle of reycles */
/* */
/* Returns: First data sector in block, -1 on error */
/* */
/***********************************************************************/
static ui32 choose_free_block(int action)
{
ui32 i, curr_sect, last_b4_curr = (ui32)-1, last_in_lowest;
/*-------------------------------------------------------------------*/
/* If free sector on block boundary, consider the first block in free*/
/* list, otherwise skip it. */
/*-------------------------------------------------------------------*/
if (Flash->free_sect % Flash->block_sects == Flash->hdr_sects)
curr_sect = Flash->free_sect;
else
{
last_b4_curr = (Flash->free_sect / Flash->block_sects + 1) *
Flash->block_sects - 1;
curr_sect = Flash->sect_tbl[last_b4_curr].next;
}
/*-------------------------------------------------------------------*/
/* Selected free block shouldn't be in erase set. */
/*-------------------------------------------------------------------*/
PfAssert(!in_erase_set(curr_sect / Flash->block_sects));
/*-------------------------------------------------------------------*/
/* If no more free blocks, error. */
/*-------------------------------------------------------------------*/
if (curr_sect == FLAST_SECT)
return (ui32)-1;
/*-------------------------------------------------------------------*/
/* Figure out last sector in free block and check block is free. */
/*-------------------------------------------------------------------*/
last_in_lowest = curr_sect + Flash->block_sects - Flash->hdr_sects - 1;
PfAssert(Flash->sect_tbl[curr_sect].prev == FFREE_SECT &&
Flash->sect_tbl[last_in_lowest].prev == FFREE_SECT);
/*-------------------------------------------------------------------*/
/* Take block out of free list. */
/*-------------------------------------------------------------------*/
if (curr_sect == Flash->free_sect)
{
/*-----------------------------------------------------------------*/
/* If no more free blocks, error. */
/*-----------------------------------------------------------------*/
if (Flash->sect_tbl[last_in_lowest].next == FLAST_SECT)
return (ui32)-1;
Flash->free_sect = Flash->sect_tbl[last_in_lowest].next;
}
else
{
PfAssert(last_b4_curr != (ui32)-1);
Flash->sect_tbl[last_b4_curr].next =
Flash->sect_tbl[last_in_lowest].next;
/*-----------------------------------------------------------------*/
/* Update last free sector if selected block is last block in list.*/
/*-----------------------------------------------------------------*/
if (last_in_lowest == Flash->last_free_sect)
Flash->last_free_sect = last_b4_curr;
}
/*-------------------------------------------------------------------*/
/* Mark all of its sectors as dirty. */
/*-------------------------------------------------------------------*/
for (i = curr_sect; i <= last_in_lowest; ++i)
{
--Flash->free_sects;
PfAssert(Flash->sect_tbl[i].prev == FFREE_SECT);
Flash->sect_tbl[i].prev = FDRTY_SECT;
}
/*-------------------------------------------------------------------*/
/* Return first sector in selected block. */
/*-------------------------------------------------------------------*/
return curr_sect;
}
/***********************************************************************/
/* adjust_set_size: Adjust the erase set size based on control size */
/* */
/* Inputs: adjust_erase = flag to adjust erase set */
/* check_recycle = flag to check recycles */
/* */
/***********************************************************************/
static void adjust_set_size(int adjust_erase, int check_recycle)
{
int s1, set_increase = FALSE, b, max_f, f_b, max_b = 0;
ui32 old_size = Flash->set_blocks, s_optimal, s = 0;
ui32 max_set_blocks = (Flash->max_set_blocks == 1) ? 1 :
Flash->max_set_blocks - 1;
ui32 ctrl_sects, ctrl_inc;
/*-------------------------------------------------------------------*/
/* Compute the control sectors with control increment accounted. */
/*-------------------------------------------------------------------*/
ctrl_inc = (Flash->num_sects - Flash->used_sects - Flash->set_blocks *
Flash->block_sects - Flash->num_blocks * Flash->hdr_sects +
Flash->block_sects - 1) / Flash->block_sects +
Flash->used_sects;
ctrl_sects = (Flash->ctrl_size + 2 * ctrl_inc + Flash->sect_sz - 1) /
Flash->sect_sz;
/*-------------------------------------------------------------------*/
/* Reset the free_sects_used count. */
/*-------------------------------------------------------------------*/
Flash->free_sects_used = 0;
/*-------------------------------------------------------------------*/
/* Determine the erase set size. */
/*-------------------------------------------------------------------*/
for (Flash->set_blocks = 0; Flash->set_blocks < max_set_blocks; ++s)
{
++Flash->set_blocks;
/*-----------------------------------------------------------------*/
/* If size goes up, mark new holder with invalid blocks. */
/*-----------------------------------------------------------------*/
if (s >= old_size)
{
Flash->erase_set[s] = -1;
set_increase = TRUE;
}
/*-----------------------------------------------------------------*/
/* Determine if size is big enough. */
/*-----------------------------------------------------------------*/
if ((ctrl_sects <= Flash->block_sects * Flash->set_blocks /
FLASH_SET_LIMIT ||
Flash->set_blocks >= Flash->num_blocks / 8) &&
Flash->set_blocks >= Flash->max_set_blocks / 40)
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -