📄 db_fs.c
字号:
#include <string.h>
#include "db_defs.h"
#include "db_fmgr.h"
#include "db_dram.h"
#include "db_defs.h"
//#include "dvb_msg.h"
#include "dvb_flash.h"
#include "dvb_sys.h"
#define DATAPOOL_FLAG_MASK 0xE0000000
#define DATAPOOL_AVALIABLE_FLAG 0xE0000000
#define DATAPOOL_WRITING_FLAG 0x60000000
#define DATAPOOL_DATA_FLAG 0x20000000
#define DATAPOOL_DEL_FLAG 0x00000000
#if defined(WIN32)
#define IAT_SUB_ID_MASK 0x0000F000
#define IAT_AVAILABLE_FLAG 0x0000F000
#else
#define IAT_SUB_ID_MASK 0xF0000000
#define IAT_AVAILABLE_FLAG 0xF0000000
#endif
/*******************************************************************************************/
#define FS_MSG(p) printf p
#if 1
#define FS_DBG(p)
#else
#define FS_DBG(p) printf p
#endif
/*******************************************************************************************/
typedef struct DB_TableInfo
{
EN_DB_TABLE_TYPE enTableType;
u8 u8TableSubID;
u8 u8BankID;
u16 u16Address;
u8 u8ItemSize;
u16 u16NumOfItem;
}DB_TableInfo;
bool8 b8relation_update = FALSE;
static DB_TableInfo stTableInfo;
static u32 u32buffer;
static u32 u32temp;
static u16 u16temp;
static u8 u8temp;
static u8 au8DBFS_record_buffer[DB_SRV_POOL_ITEM_SIZE];
static CTOS_SEMAPHORE stDBFSSemaphore;
/*******************************************************************************************/
DB_TableInfo const astTableLoc[]=
{
{EN_RELATION_TABLE, 0, 1, BANK_DATA_START_ADDRESS, 1, DB_RELATION_SIZE}, // relation table must be always here
{EN_TP_TABLE, 0, 1, BANK_DATA_START_ADDRESS+DB_RELATION_SIZE, DB_TP_POOL_ITEM_SIZE, DB_TP_NUM_IN_ONE_BANK},
{EN_SAT_TABLE, 0, 1, BANK_DATA_START_ADDRESS+DB_RELATION_SIZE+DB_TP_INFO_TABLE_SIZE, DB_SAT_POOL_ITEM_SIZE, DB_SAT_NUM_IN_ONE_BANK},
{EN_GENERAL_FILE, 0, 1, BANK_DATA_START_ADDRESS+DB_RELATION_SIZE+DB_TP_INFO_TABLE_SIZE+DB_SAT_INFO_TABLE_SIZE, DB_FILE_POOL_ITEM_SIZE, DB_FILE_BLOCK_NUM_IN_ONE_BANK},
#if (DB_DATA_BANK==1)
{EN_SRV_TABLE, 0, 1, BANK_DATA_START_ADDRESS+DB_RELATION_SIZE+DB_TP_INFO_TABLE_SIZE+DB_SAT_INFO_TABLE_SIZE+DB_FILE_SIZE, DB_SRV_POOL_ITEM_SIZE, DB_SRV_NUM_IN_ONE_BANK},
#endif
#if (DB_DATA_BANK>1)
{EN_SRV_TABLE, 0, 2, BANK_DATA_START_ADDRESS, DB_SRV_POOL_ITEM_SIZE, DB_SRV_NUM_IN_ONE_BANK},
#endif
#if (DB_DATA_BANK>2)
{EN_SRV_TABLE, 1, 3, BANK_DATA_START_ADDRESS, DB_SRV_POOL_ITEM_SIZE, DB_SRV_NUM_IN_ONE_BANK},
#endif
#if (DB_DATA_BANK>3)
{EN_SRV_TABLE, 2, 4, BANK_DATA_START_ADDRESS, DB_SRV_POOL_ITEM_SIZE, DB_SRV_NUM_IN_ONE_BANK},
#endif
#if (DB_DATA_BANK>4)
{EN_SRV_TABLE, 3, 5, BANK_DATA_START_ADDRESS, DB_SRV_POOL_ITEM_SIZE, DB_SRV_NUM_IN_ONE_BANK},
#endif
{0xff,0,0,0,0,0}
};
/*******************************************************************************************/
#if 0 //test table location
DB_TableInfo const astRelationLoc[]=
{
{EN_RELATION_TABLE, 0, 1, BANK_DATA_START_ADDRESS, 1, DB_RELATION_SIZE}, // relation table must be always here
{0xff,0,0,0,0,0}
};
DB_TableInfo const astTpPoolLoc[]=
{
{EN_TP_TABLE, 0, 1, BANK_DATA_START_ADDRESS+DB_RELATION_SIZE, DB_TP_POOL_ITEM_SIZE, DB_TP_NUM_IN_ONE_BANK},
{0xff,0,0,0,0,0}
};
DB_TableInfo const astSatPoolLoc[]=
{
{EN_SAT_TABLE, 0, 1, BANK_DATA_START_ADDRESS+DB_RELATION_SIZE+DB_TP_INFO_TABLE_SIZE, DB_SAT_POOL_ITEM_SIZE, DB_SAT_NUM_IN_ONE_BANK},
{0xff,0,0,0,0,0}
};
#if 0
DB_TableInfo const astSrvPoolLoc[]=
{
{EN_SRV_TABLE, 0, 1, BANK_DATA_START_ADDRESS+DB_RELATION_SIZE+DB_TP_INFO_TABLE_SIZE+DB_SAT_INFO_TABLE_SIZE, DB_SRV_POOL_ITEM_SIZE, DB_SRV_NUM_IN_ONE_BANK},
{0xff,0,0,0,0,0}
};
#else
DB_TableInfo const astSrvPoolLoc[]=
{
{EN_SRV_TABLE, 0, 2, BANK_DATA_START_ADDRESS, DB_SRV_POOL_ITEM_SIZE, DB_SRV_NUM_IN_ONE_BANK},
{EN_SRV_TABLE, 1, 3, BANK_DATA_START_ADDRESS, DB_SRV_POOL_ITEM_SIZE, DB_SRV_NUM_IN_ONE_BANK},
{EN_SRV_TABLE, 2, 4, BANK_DATA_START_ADDRESS, DB_SRV_POOL_ITEM_SIZE, DB_SRV_NUM_IN_ONE_BANK},
{0xff,0,0,0,0,0}
};
#endif
#endif
// BANK INFO TABLE(BIT)============================================================================
bool8 _bit_search_table(EN_DB_TABLE_TYPE enTable, u8 u8sub_id, DB_TableInfo* pstTableInfo)
{
u8 u8idx;
#if 0 //test table location
switch(enTable)
{
case EN_RELATION_TABLE:
pstTableLoc = (DB_TableInfo*)&astRelationLoc[0];
break;
case EN_SRV_TABLE:
pstTableLoc = (DB_TableInfo*)&astSrvPoolLoc[0];
break;
case EN_TP_TABLE:
pstTableLoc = (DB_TableInfo*)&astTpPoolLoc[0];
break;
case EN_SAT_TABLE:
pstTableLoc = (DB_TableInfo*)&astSatPoolLoc[0];
break;
default:
return FALSE;
}
#endif
for(u8idx=0; astTableLoc[u8idx].enTableType!=0xff; u8idx++)
{
if( (astTableLoc[u8idx].enTableType==enTable) &&
(astTableLoc[u8idx].u8TableSubID==u8sub_id) )
{
*pstTableInfo = astTableLoc[u8idx];
return TRUE;
}
}
return FALSE;
}
/*******************************************************************************************/
bool8 _bit_get_table_in_bank(u8 u8bank_id, u8 u8table_idx, DB_TableInfo* pstTableInfo)
{
u8 u8idx;
u8idx=0;
while( astTableLoc[u8idx].enTableType!=0xff )
{
if(astTableLoc[u8idx].u8BankID==u8bank_id)
{
if(u8table_idx==0)
{
*pstTableInfo = astTableLoc[u8idx];
return TRUE;
}
else
{
u8table_idx--;
}
}
u8idx++;
}
#if 0 //test table location
u8idx=0;
while( astRelationLoc[u8idx].enTableType!=0xff )
{
if(astRelationLoc[u8idx].u8BankID==u8bank_id)
{
if(u8table_idx==0)
{
*pstTableInfo = astRelationLoc[u8idx];
return TRUE;
}
else
{
u8table_idx--;
}
}
u8idx++;
}
u8idx=0;
while( astTpPoolLoc[u8idx].enTableType!=0xff )
{
if(astTpPoolLoc[u8idx].u8BankID==u8bank_id)
{
if(u8table_idx==0)
{
*pstTableInfo = astTpPoolLoc[u8idx];
return TRUE;
}
else
{
u8table_idx--;
}
}
u8idx++;
}
u8idx=0;
while( astSatPoolLoc[u8idx].enTableType!=0xff )
{
if(astSatPoolLoc[u8idx].u8BankID==u8bank_id)
{
if(u8table_idx==0)
{
*pstTableInfo = astSatPoolLoc[u8idx];
return TRUE;
}
else
{
u8table_idx--;
}
}
u8idx++;
}
u8idx=0;
while( astSrvPoolLoc[u8idx].enTableType!=0xff )
{
if(astSrvPoolLoc[u8idx].u8BankID==u8bank_id)
{
if(u8table_idx==0)
{
*pstTableInfo = astSrvPoolLoc[u8idx];
return TRUE;
}
else
{
u8table_idx--;
}
}
u8idx++;
}
#endif
return FALSE;
}
/*******************************************************************************************/
void _bit_dump(void)
{
for(u8temp=1; u8temp<DB_TOTAL_BANK_ID; u8temp++)
{
FS_DBG(( "\nDump BankID %hx Info:\n", u8temp));
u16temp = 0;
while( _bit_get_table_in_bank( u8temp, u16temp, &stTableInfo)==TRUE )
{
switch( stTableInfo.enTableType )
{
case EN_RELATION_TABLE:
FS_DBG(( "Type: Rel"));
break;
case EN_SRV_TABLE:
FS_DBG(( "Type: Srv"));
break;
case EN_TP_TABLE:
FS_DBG(( "Type: Tp "));
break;
case EN_SAT_TABLE:
FS_DBG(( "Type: Sat"));
break;
case EN_GENERAL_FILE:
FS_DBG(( "Type: File"));
break;
default:
break;
}
#if (DB_DRAM_IMAGE==1)
FS_DBG(("-%hx, BAdd: %04lx~%04lx, DAdd: %08lx~%08lx\n", stTableInfo.u8TableSubID,
(u32)stTableInfo.u16Address, (u32)(stTableInfo.u16Address+(stTableInfo.u8ItemSize*stTableInfo.u16NumOfItem)),
(DB_CACHE_DRAM_START+(u8temp-1)*0x10000+stTableInfo.u16Address), (DB_CACHE_DRAM_START+(u8temp-1)*0x10000+stTableInfo.u16Address+(stTableInfo.u8ItemSize*stTableInfo.u16NumOfItem)) ));
#else
FS_DBG(("-%hx, BAdd: %04lx~%04lx\n", stTableInfo.u8TableSubID,
(u32)stTableInfo.u16Address, (u32)(stTableInfo.u16Address+(stTableInfo.u8ItemSize*stTableInfo.u16NumOfItem)) ));
#endif
u16temp++;
}
}
}
/*******************************************************************************************/
void DBFS_CheckDBConfig(void)
{
EN_DB_TABLE_TYPE enTable;
#if (DB_DRAM_IMAGE==0)
if( (DB_CACHE_DRAM_START+0x10000)>=DB_DRAM_END)
{
FS_DBG(( "DB_CFG: Dram is not enough.\n"));
while(1);
}
#endif
// check db configuration
for( enTable=0; enTable<MAX_TABLE_NUMBER; enTable++)
{
u8temp = 0;
while(_bit_search_table(enTable, u8temp, &stTableInfo)==TRUE)
{
u32temp = stTableInfo.u8ItemSize*stTableInfo.u16NumOfItem;
u32temp += stTableInfo.u16Address;
// FS_DBG(( "DB_CFG: table end address, t:%hx sid:%hx add:%lx\n", enTable, u8temp, u32temp));
if(u32temp>0xff80)
{
_bit_dump();
FS_DBG(( "DB_CFG: bank address overflow, t:%hx sid:%hx add:%lx\n", enTable, u8temp, u32temp));
while(1);
}
if(stTableInfo.u8BankID>DB_DATA_BANK)
{
_bit_dump();
FS_DBG(( "DB_CFG: error bank id, t:%hx sid:%hx bid%hx\n", enTable, u8temp, stTableInfo.u8BankID));
while(1);
}
#if (DB_DRAM_IMAGE==1)
if( (DB_CACHE_DRAM_START+(stTableInfo.u8BankID-1)*0x10000+stTableInfo.u16Address+(stTableInfo.u8ItemSize*stTableInfo.u16NumOfItem))
>=DB_DRAM_END)
{
FS_DBG(( "DB_CFG: Dram is not enough.\n"));
while(1);
}
#endif
u8temp++;
}
if(enTable==EN_SRV_TABLE)
{
if(stTableInfo.u8BankID<DB_DATA_BANK)
{
_bit_dump();
FS_DBG(( "DB_CFG: data bank unused.\n"));
while(1);
}
if( (DB_SRV_NUM_IN_ONE_BANK*u8temp)<(MAX_NUM_OF_SRV+MAX_NUM_OF_SRV/10) )
{
_bit_dump();
FS_DBG(("DB_CFG: service datapool is too small, %d/%d\n"
, (int)(MAX_NUM_OF_SRV+MAX_NUM_OF_SRV/10), (int)(DB_SRV_NUM_IN_ONE_BANK*u8temp) ));
while(1);
}
}
}
// _bit_dump();
FS_DBG(( "Check DB configuration OK.\n"));
}
/*******************************************************************************************/
// BANK INFO TABLE(BIT)============================================================================
// GARBAGE RECYCLE=================================================================================
void _garbage_recycle(u8 u8bank_id)
{
u16 u16current_record_idx, u16remainder_item;
u32 u32flag;
DB_TableInfo stTableInfo;
u8 u8idx, u8idx2;
FS_DBG(( "Start garbage recycle, bank id %hx...\n", u8bank_id));
if( FMgr_CheckAvailable( u8bank_id)==FALSE )
{
// read bank will fill 0xff to dram if it is deleted.
FMgr_ReadBank( u8bank_id);
return;
}
for( u8idx=0;
_bit_get_table_in_bank( u8bank_id, u8idx, &stTableInfo)==TRUE;
u8idx++)
{
if(stTableInfo.enTableType==EN_RELATION_TABLE)
{
continue;
}
for(u8idx2=0; u8idx2<2; u8idx2++)
{
u16current_record_idx = 0;
if(u8idx2==0)
{
u32flag = DATAPOOL_DEL_FLAG;
}
else
{
u32flag = DATAPOOL_WRITING_FLAG;
}
while(1)
{
u16remainder_item = stTableInfo.u16NumOfItem-u16current_record_idx;
u16temp = FMgr_Search( stTableInfo.u8BankID,
stTableInfo.u16Address+(u16current_record_idx*stTableInfo.u8ItemSize),
stTableInfo.u8ItemSize,
u16remainder_item,
DATAPOOL_FLAG_MASK,
u32flag);
if(u16temp==u16remainder_item)
{
break;
}
else
{
u16current_record_idx+=u16temp;
memset(au8DBFS_record_buffer,0xff,stTableInfo.u8ItemSize);
#if (DB_DRAM_IMAGE==0)
DVB_DramWrite(DB_CACHE_DRAM_START+
stTableInfo.u16Address+(u16current_record_idx*stTableInfo.u8ItemSize),
au8DBFS_record_buffer, stTableInfo.u8ItemSize);
#else
DVB_DramWrite(DB_CACHE_DRAM_START+
(stTableInfo.u8BankID-1)*0x10000+
stTableInfo.u16Address+(u16current_record_idx*stTableInfo.u8ItemSize),
au8DBFS_record_buffer, stTableInfo.u8ItemSize);
#endif
}
}
}
}
}
/*******************************************************************************************/
// GARBAGE RECYCLE=================================================================================
// DATAPOOL========================================================================================
static u8 au8last_available_sub_id[MAX_TABLE_NUMBER];
void _datapool_init(void)
{
for(u8temp=0; u8temp<MAX_TABLE_NUMBER; u8temp++)
au8last_available_sub_id[u8temp]=0;
}
/*******************************************************************************************/
void _datapool_clean(void)
{
for(u8temp=0; u8temp<MAX_TABLE_NUMBER; u8temp++)
au8last_available_sub_id[u8temp]=0;
}
/*******************************************************************************************/
void _datapool_read_record(EN_DB_TABLE_TYPE enTable, u8 u8sub_id, u16 u16record_idx, u8* pu8buffer, u8 u8length)
{
_bit_search_table(enTable, u8sub_id, &stTableInfo);
FMgr_Read(stTableInfo.u8BankID, stTableInfo.u16Address+stTableInfo.u8ItemSize*u16record_idx+DB_POOL_ITEM_HEADER,
pu8buffer, u8length);
}
/*******************************************************************************************/
void _datapool_write_record(EN_DB_TABLE_TYPE enTable, u8 u8sub_id, u16 u16record_idx, u8* pu8buffer, u8 u8length)
{
_bit_search_table(enTable, u8sub_id, &stTableInfo);
// set dirty bit
#if defined(WIN32)
pu8buffer[3]=0x7f;
#else
pu8buffer[0]=0x7f;
#endif
// write data
FMgr_Write(stTableInfo.u8BankID, stTableInfo.u16Address+(stTableInfo.u8ItemSize*u16record_idx), pu8buffer, u8length);
// set avaliable bit
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -