📄 fdi_pckt.c
字号:
### For ERR_PARAM cheking, validate for non-NULL
### pointer and that it is word-aligned.
### size: Size of the buffer to be written, in bytes.
### For ERR_PARAM checking, validate it is non-zero,
### a word-multiple and not greater than size of a packet.
### FDI_Pckt: Check ID and InProg for ensuring in packet data processing,
### and ensure that size must not be greater than FragSize
###
### OUT:
###
###
### RETURNS:
### ERR_NONE ERR_SYSTEM ERR_PARAM ERR_WRITE
###
#############################################################################
*/
ERR_CODE
FDI_WritePacket(volatile WORD_PTR flash_p, WORD_PTR buf_p, WORD size)
{
return (ERR_CODE)FlashDevWritePacket((BYTE_PTR) buf_p, (DWORD) flash_p, (DWORD) size);
}
/*
#############################################################################
### FDI_InitPacket()
###
### DESCRIPTION:
### This function reclaim adequate Flash space in preparation for 'count'
### writes whose packet size is 'size' or less. Once Flash space is
### available, the function reserve this space for 'count' packets by
### invoking multiple FDI_Write. Background task performs reservation and
### stores the flash data fragment pointers in a taf-RAM referenced by
### 'buf_p'. The object to be written is represented by 'identifier' and
### 'type'. A global structure FDI_Pckt is used for sharing variables.
###
###
### PARAMETERS:
### IN:
### buf_p: pointer to tag-RAM, which will be loaded with an
### array of Flash data fragment pointers. For ERR_PARAM
### checking, validate it's a non-NULL pointer. This
### pointer is stored in the FDI_Pckt structure.
###
### size: maximum size of the flash packets, in bytes. For
### ERR_PARAM checking, validate that it is a multiple
### of unit granularity not greater than MAX_UNITS_PER_FRAG.
### This value represents the data fragment size and is
### stored in the FDI_Pckt structure.
###
### count: number of packets to be written for the object and is
### stored in the FDI_Pckt structure. For ERR_PARAM checking,
### validate it is non-zero.
###
### identifier: the user identifier of the object to be written. If
### the identifier exists, it is deleted and recreated.
### For ERR_PARAM checking, validate appropriate range.
### The value is stored in the FDI_Pckt structure.
###
### type: the user type of the object to be written. For
### ERR_PARAM checking, validate appropriate range.
###
### OUT:
### error: a descriptive error code
### FDI_Pckt: a global structure to be accessed by the API,
### Background and Reclaim tasks.
###
### RETURNS:
### ERR_NONE ERR_INIT ERR_PARAM ERR_OPEN ERR_FLASH_FULL
### ERR_SYSTEM
###
#############################################################################
*/
ERR_CODE
FDI_InitPacket(WORD_PTR *buf_p,
WORD fragsize,
WORD count,
WORD_PTR id,
BYTE type
)
{
BYTE queuestatus;
DWORD TotalPacketObjSize; /* total size of this packet object */
DWORD b_needed_Space; /* space needed by this packet object */
DWORD cur_count; /* used as dirtyspace's stub in FDI_Statistics
and for multiple FDI_Write calls */
DWORD MaxWriteBytes;
DWORD freespace;
/* DWORD oldfreespace; */
COMMAND_CONTROL cmd_cntrl;
ERR_CODE status;
WORD grp_entries; /* used to count the sequence table number */
WORD g_needed_grpsize; /* the last GRP header's size */
WORD identifier = *id;
#ifdef TIMING
/* Get timestamp for start of update */
COMM_getTimestamp((COMM_TIMESTAMP *) & Pckt_Start);
#endif
/*
* Check for completion of Initialization and if not yet complete return
* the proper error code.
*/
if (FDI_InitComplete != TRUE)
return ERR_INIT;
#if (PARAM_CHECK == TRUE)
/*
* Check to see if the passed in parameters (buf_p count size) are valid.
* Otherwise return proper error code. Here only check its range and in
* FDI_Write check in detailed.
*/
if ( buf_p == NULL || count == 0 ||
fragsize > (MAX_NUM_UNITS_PER_FRAG * UNIT_GRANULARITY) ||
((fragsize % UNIT_GRANULARITY) != 0) || (fragsize == 0))
return ERR_PARAM;
/*
* Check to see if the passed in parameters ( identifier and type) are valid.
* Otherwise return proper error code. Here only check its range and in
* FDI_Write check in detailed.
*/
if (((identifier >= NUM_PARMS[type]) && (identifier != NEW_DATA_STREAM_ID))||
(type > MAX_TYPE))
{
return ERR_PARAM;
}
#endif
/* lock the SEM_APIMutexSemaphore */
SEM_MTX_WAIT(SEM_APIMutexSemaphore);
/*
* Check the FDI_OPEN_PACKET structure only has one instance. If ID is not
* WORDMAX, then FDI_Pckt is being used by former caller.
*/
if (FDI_Pckt.ID != WORDMAX )
{
SEM_MTX_POST(SEM_APIMutexSemaphore);
return ERR_OPEN;
}
/* Initilize the PacketData Command */
cmd_cntrl.identifier = identifier ;
cmd_cntrl.type = type ;
cmd_cntrl.priority = FDI_PACKETDATA_PRIORITY ;
TotalPacketObjSize = count * fragsize ;
b_needed_Space = count * ( fragsize + sizeof(UNIT_HEADER) );
/* need to add sequence table and GRP table and invalided GRP header */
grp_entries = TO_SIZE (count,MAX_SEQ_ENTRY);
/* add the sequence table occupied space */
b_needed_Space += (grp_entries*(UNIT_GRANULARITY+sizeof(UNIT_HEADER)));
g_needed_grpsize = TO_SIZE (grp_entries,MAX_SEQ_ENTRY);
/* add the group table occupied space(include dirtied GRP) */
/* in fact, we can skip the dirtied space due to auto-reclaim,
but it can only save less space and we have BKGD_CheckForSpace to do
more accurancy, so in 2.5 we don't conside it */
/* we have changed the BKGD_CheckForSpace and now it can gurantee that
every time the FDI_Write will only need 1 more granularity for GRP
table, so the dirtied GRP can be reclaimed.
for (cur_count=1; cur_count<=g_needed_grpsize; cur_count++) {
b_needed_Space += (cur_count*UNIT_GRANULARITY+sizeof(UNIT_HEADER));
}
*/
b_needed_Space += (g_needed_grpsize*UNIT_GRANULARITY+sizeof(UNIT_HEADER));
/*
* Verify the Packetdata with the same identifier and type exists. If
* existing, Delete it.
*/
status = DataFind(identifier, type, GET_MATCHED);
if ( status == ERR_NONE)
{
/*
* Check FDI Queue status. If Queue status is empty, then continue;
* or else wait for Queue become empty using the TaskDelay function in
* Tornado lib.
*/
/* to prevent FDI_Delete encounter ERR_Q_FULL */
FDI_WAIT_FORQUEUE_EMPTY(queuestatus);
/*
* Parameters needed for FDI_Delete:
* cmd_cntrl.identifier
* cmd_cntrl.type
* cmd_cntrl.priority
*/
status = FDI_Delete(&cmd_cntrl);
if (status != ERR_NONE)
{
/* Unlock the SEM_APIMutexSemaphore. */
SEM_MTX_POST(SEM_APIMutexSemaphore);
return status;
}
}
/*
* Check FDI Queue status. If Queue status is empty, then continue;
* or else wait for Queue become empty using the TaskDelay function in
* Tornado lib.
*/
FDI_WAIT_FORQUEUE_EMPTY(queuestatus);
/* may have reclaim task actived by background task , wait for its done*/
FDI_WAIT_FORRECLM_DONE;
/*
* Check if has enough space for PacketData to write. If not, reclaim and
* check again. If not available space to reclaim, then return ERR_FLASH_FULL.
*/
FDI_Statistics(&freespace, &cur_count);
if ( freespace + cur_count < b_needed_Space )
{
/* Unlock the SEM_APIMutexSemaphore. */
SEM_MTX_POST(SEM_APIMutexSemaphore);
return ERR_FLASH_FULL;
}
/* invoke the FDI_open */
cmd_cntrl.sub_command = OPEN_CREATE ;
cmd_cntrl.aux = FALSE ;
/* force DATA_STREAMING = TRUE, for loose threshold decision in BKGD_Task */
/*
* Parameters needed for FDI_Open:
* cmd_cntrl.identifier
* cmd_cntrl.type
* cmd_cntrl.sub_command
*/
status = FDI_Open(&cmd_cntrl);
if (status != ERR_NONE)
{
/* Unlock the SEM_APIMutexSemaphore. */
SEM_MTX_POST(SEM_APIMutexSemaphore);
return status;
}
/* Initilize the FDI_Pckt structure */
FDI_Pckt.ID = cmd_cntrl.identifier ;
FDI_Pckt.type = cmd_cntrl.type;
FDI_Pckt.FragSize = fragsize ;
FDI_Pckt.TagRAMp = buf_p ;
FDI_Pckt.Count = 0 ;
*id = cmd_cntrl.identifier;
/* Add WRITE_RSRVPCKT subcommand into queue to let background task to execute */
/*
* Parameters needed for FDI_Write:
* cmd_cntrl.identifier
* cmd_cntrl.type
* cmd_cntrl.sub_command
* cmd_cntrl.buffer_ptr
* cmd_cntrl.count
* cmd_cntrl.offset
* cmd_cntrl.priority
*/
/* call FDI_Write several times for allocating space for packet object greater than 64KB */
cmd_cntrl.sub_command = WRITE_RSRVPCKT ;
cmd_cntrl.buffer_ptr = NULL ;
cmd_cntrl.offset = 0 ;
/* Writing Packetdata always start at the begining of Packetdata */
MaxWriteBytes = FDI_ONEGRANGRP_MAX_FRAGS * FDI_Pckt.FragSize;
if ( MaxWriteBytes > FDI_MAX_RSRV_BYTES_PER_ITEM )
{
MaxWriteBytes = (FDI_MAX_RSRV_BYTES_PER_ITEM / FDI_Pckt.FragSize)
* FDI_Pckt.FragSize;
}
do
{
if (TotalPacketObjSize > MaxWriteBytes)
cur_count = MaxWriteBytes;
else
cur_count = TotalPacketObjSize;
cmd_cntrl.count = cur_count;
for (;;)
{
FDI_WAIT_FORQUEUE_EMPTY(queuestatus);
status = FDI_Write(&cmd_cntrl); /* may cause reclaim here */
if ( status == ERR_NONE )
{
mDEBUG_PCKT_PLR_RETURN_ERROR()
}
#ifdef PCKTDBG_INJECTION_1
/***** simulate write error to see if DeletePcktData has
successfully process the acc_free/acc_dirty *******/
if ( TotalPacketObjSize == cur_count )
{
status = ERR_WRITE;
}
/**********************************************************/
#endif
if ( status != ERR_Q_FULL )
{
/* write command finished or error */
break;
}
}
if ( status != ERR_NONE )
{
/* may have ERR_FLASH_FULL, ERR_SYSTEM */
DeletePcktData (identifier,type);
FDI_Pckt.ID = WORDMAX;
/* Unlock the SEM_APIMutexSemaphore. */
FDI_Close(&cmd_cntrl);
SEM_MTX_POST(SEM_APIMutexSemaphore);
return status;
}
cmd_cntrl.offset += cur_count; /* increment the offset */
TotalPacketObjSize -= cur_count;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -