📄 fdi_recl.c
字号:
void RECL_SetState(RECL_STATES a)
{
RECL_State = a;
}
#else
#define RECL_SetState(a) \
{ \
RECL_State = a; \
}
#endif
/*############################################################################
*### RECL_GetState
*###
*### DESCRIPTION:
*### Function returns the current state of the reclaim process
*###
*### PARAMETERS:
*### IN: void
*### OUT:
*###
*### RETURNS:
*### RECL_STATES
*###*/
RECL_STATES
RECL_GetState(void)
{
RECL_STATES current_state;
current_state = RECL_State;
return current_state;
}
/*############################################################################
*### RECL_GetBlock
*###
*### DESCRIPTION:
*### Function returns the Physical Block number of the block being reclaimed.
*###
*### PARAMETERS:
*### IN: void
*### OUT:
*###
*### RETURNS:
*### a byte containing the physical block number
*###*/
WORD
RECL_GetBlock(void)
{
return RECL_ReclaimBlock;
}
/*############################################################################
*### setBitMask
*###
*### DESCRIPTION:
*###
*### PARAMETERS:
*### IN:
*### mask_ptr - pointer to the array to be modified
*### count - number of bit in the array to set
*### OUT:
*###
*### RETURNS:
*###*/
static void
setBitMask(BYTE_PTR mask_ptr, WORD count)
{
*(mask_ptr + (count / BITS_PER_BYTE)) |= (1 << (count % BITS_PER_BYTE));
} /* END of setBitMask */
/*############################################################################
*### countBitMask
*###
*### DESCRIPTION:
*###
*### PARAMETERS:
*### IN:
*### mask_ptr - pointer to the array
*### stop_count - the last header count
*### OUT:
*###
*### RETURNS:
*### num_valids - number of bits valid in the array
*###*/
static WORD
countBitMask(const BYTE * mask_ptr, WORD stop_count)
{
WORD num_valids = 0;
WORD each_byte;
BYTE each_bit;
for (each_byte = 0; stop_count; each_byte++)
{
for (each_bit = 0; each_bit < BITS_PER_BYTE && stop_count; each_bit++)
{
if (*(mask_ptr + each_byte) & (1 << each_bit))
num_valids++;
stop_count--;
}
}
return num_valids;
} /* END of countBitMask */
/*############################################################################
*### RECL_Init
*###
*### DESCRIPTION:
*### Initializes the three semaphores used to control the reclamation
*### process and spawns the reclamation task that runs in the background.
*###
*### PARAMETERS:
*### IN: void
*### OUT:
*###
*### RETURNS:
*### Returns the following errors codes:
*### BKGD_ERR_NONE
*### BKGD_ERR_SEMAPHORE
*###*/
HW_ERROR
RECL_Init(void)
{
HW_ERROR status = HW_ERR_NONE;
#ifdef TESTING
/* Make task safe during plr testing to ensure TID is updated
* prior to preemption during power loss emulation.
*/
taskSafe();
#endif
#if(SEM_CREATE_DESTROY == TRUE)
/* E.5.0.596 START */
if ((RECL_Request == SEM_NULL) &&
/* E.5.0.596 END */
/* create a binary semaphore for the global ReclaimRequest */
((RECL_Request = SEM_BIN_CREATE()) == SEM_NULL))
{
status = HW_ERR_PARAM;
}
/* E.5.0.596 START */
else if ((RECL_Enable == SEM_NULL) &&
/* E.5.0.596 END */
/* create a binary semaphore for the global ReclaimEnable */
((RECL_Enable = SEM_BIN_CREATE()) == SEM_NULL))
{
SEM_DESTROY(RECL_Request);
status = HW_ERR_PARAM;
}
/* E.5.0.596 START */
else if ((RECL_Done == SEM_NULL) &&
/* E.5.0.596 END */
/* create a binary semaphore for the global ReclaimDone */
((RECL_Done = SEM_BIN_CREATE()) == SEM_NULL))
{
SEM_DESTROY(RECL_Request);
SEM_DESTROY(RECL_Enable);
status = HW_ERR_PARAM;
}
/* E.5.0.596 START */
else if ((SEM_ReclaimInProg == SEM_NULL) &&
/* E.5.0.596 END */
/* create a mutex semaphore for the reclaim copy process */
((SEM_ReclaimInProg = SEM_MTX_CREATE()) == SEM_NULL))
{
SEM_DESTROY(RECL_Request);
SEM_DESTROY(RECL_Enable);
SEM_DESTROY(RECL_Done);
status = HW_ERR_PARAM;
}
#endif /* SEM_CREATE_DESTROY */
/*E.5.0.602.START*/
#if(TASK_CREATE_DESTROY == TRUE)
/* spawn the reclamation task */
/* else if ((RECL_TaskId = SPAWN("tFDIreclm", RECL_PRIORITY, TASK_OPTIONS,
RECL_STACK_SIZE, RECL_Task)) == SPAWN_ERROR) */ /* commented by jjs */
else if ((RECL_TaskId = SPAWN("tFDIreclm", RECL_PRIORITY, TASK_OPTIONS,
RECL_STACK_SIZE, (DWORD)RECL_Task)) == SPAWN_ERROR) /* added by jjs */
{
#if(SEM_CREATE_DESTROY == TRUE)
SEM_DESTROY(RECL_Request);
SEM_DESTROY(RECL_Enable);
SEM_DESTROY(RECL_Done);
SEM_MTX_DESTROY(SEM_ReclaimInProg);
#endif /* SEM_CREATE_DESTROY */
status = HW_ERR_PARAM;
}
#endif /* TASK_CREATE_DESTROY */
/*E.5.0.602.END*/
#ifdef TESTING
taskUnsafe();
#endif
return status;
} /* END RECL_Init */
/*############################################################################
*### RECL_Terminate
*###
*### DESCRIPTION:
*### Terminates the three semaphores used to control the reclamation
*### process and the reclamation task that runs in the background.
*###
*### PARAMETERS:
*### IN: void
*### OUT:
*###
*### RETURNS:
*### Returns the following errors codes:
*### BKGD_ERR_NONE
*### BKGD_ERR_SEMAPHORE
*###*/
HW_ERROR
RECL_Terminate(void)
{
#ifdef TESTING
/* Make task safe during plr testing to ensure TID is updated
prior to preemption during power loss emulation. */
taskSafe();
#endif
#if(TASK_CREATE_DESTROY == TRUE)
/* destroy the reclamation task */
if (RECL_TaskId != 0)
{
TASK_DESTROY(RECL_TaskId);
}
#endif /* TASK_CREATE_DESTROY */
#if(SEM_CREATE_DESTROY == TRUE)
/* destroy binary semaphore for the global ReclaimRequest */
if (RECL_Request != SEM_NULL)
{
SEM_DESTROY(RECL_Request);
}
/* destroy binary semaphore for the global ReclaimEnable */
if (RECL_Enable != SEM_NULL)
{
SEM_DESTROY(RECL_Enable);
}
/* destroy binary semaphore for the global ReclaimDone */
if (RECL_Done != SEM_NULL)
{
SEM_DESTROY(RECL_Done);
}
/* destroy mutex semaphore for the reclaim copy process */
if (SEM_ReclaimInProg != SEM_NULL)
{
SEM_MTX_DESTROY(SEM_ReclaimInProg);
}
#endif /* SEM_CREATE_DESTROY */
#ifdef TESTING
taskUnsafe();
#endif
Rip.recl_in_prog_flag = FALSE;
MemorySet(Rip.recl_header_mask, 0, HDR_MASK_SIZE);
Rip.reclaim_block_addr = DWORDMAX;
Rip.spare_block_addr = DWORDMAX;
Rip.reclaim_header_offset = FIRST_HEADER_OFFSET;
Rip.spare_header_offset = FIRST_HEADER_OFFSET;
Rip.spare_free = 0;
Rip.spare_dirty = 0;
RECL_SetState(RECL_DONE); /* initialize state flag */
RECL_ReclaimBlock = WORDMAX;
return HW_ERR_NONE;
} /* END RECL_Init */
/*############################################################################
*### RECL_Task
*###
*### DESCRIPTION:
*### Reclamation is the process used to make invalid regions of flash memory
*### available for reuse for parameter storage. The FDI system uses a spare
*### block for reclaiming valid headers and data. This spare is not used for
*### parameter storage but is used for reclamation only. When there is no
*### more room to write updated or new data, the system finds a block with
*### the greatest amount of invalid space and finds the spare block.
*###
*### Transfer of valid data and headers from the block being reclaimed to
*### the spare block is the next step. The status of the spare block
*### indicates the valid data is being transferred.
*###
*### Upon completion of the data transfer the next step is to prepare the
*### spare block to logically take the original block抯 place. The FDI
*### writes the original block抯 logical block number to the spare block抯
*### block information structure. For power off recovery purposes the status
*### of the spare block indicates the original block is about to be erased.
*### The old block begins to erase after all valid data exists in the spare
*### block.
*###
*### When the erase of the original block completes, the status of the spare
*### block changes to indicate that the block is now a writable block. All
*### of the valid data and headers have been transferred successfully and
*### the old locations have been erased.
*###
*### PARAMETERS:
*### IN: void
*### OUT: void
*### GLOBALS:
*### RECL_ReclaimBLock
*### FDI_LogicalBlockTable[]
*###
*### RETURNS: void
*###
*###*/
void
RECL_Task(void)
{
BLOCK_INFO block_info; /* contains block information */
UNIT_HEADER header; /* contains unit header information */
DWORD least_erased_count; /* track this count for wearleveling */
DWORD most_erased_count; /* track this count for wearleveling */
DWORD reclaim_block_addr; /* local address for searching */
DWORD spare_block_addr;
BYTE index;
union words
{
DWORD this_count; /* track the block's erase count */
WORD unit_size; /* track the reclaimed unit size */
} reclaim;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -