sysmobts: Cache the eeprom_Cfg_t for reading tx/rx calib data

The current code has 26 fseek/fread. Only the minority really results
in a call to read. Nevertheless the time for reading during the bootstrap
can take up to 7.82 seconds. Caching the header (which is already done
by fopen/fread) will result in one call to fseek/fread and only
consumes 0.784 seconds.
This commit is contained in:
Holger Hans Peter Freyther
2013-07-01 11:42:38 +02:00
parent 89582f7e77
commit 481f14d87f

View File

@@ -260,6 +260,7 @@ typedef struct
static int eeprom_read( int addr, int size, char *pBuff ); static int eeprom_read( int addr, int size, char *pBuff );
static int eeprom_write( int addr, int size, const char *pBuff ); static int eeprom_write( int addr, int size, const char *pBuff );
static uint16_t eeprom_crc( uint8_t *pu8Data, int len ); static uint16_t eeprom_crc( uint8_t *pu8Data, int len );
static eeprom_Cfg_t *eeprom_cached_config(void);
/**************************************************************************** /****************************************************************************
@@ -649,29 +650,20 @@ eeprom_Error_t eeprom_WriteRfClockCal( const eeprom_RfClockCal_t *pRfClockCal )
eeprom_Error_t eeprom_ReadTxCal( int iBand, eeprom_TxCal_t *pTxCal ) eeprom_Error_t eeprom_ReadTxCal( int iBand, eeprom_TxCal_t *pTxCal )
{ {
int i; int i;
int err;
int size; int size;
int nArfcn; int nArfcn;
eeprom_Cfg_t ee; eeprom_Cfg_t *ee = eeprom_cached_config();
eeprom_SID_t sId; eeprom_SID_t sId;
eeprom_CfgTxCal_t *pCfgTxCal = NULL; eeprom_CfgTxCal_t *pCfgTxCal = NULL;
// Get a copy of the EEPROM header // Get a copy of the EEPROM header
err = eeprom_read( EEPROM_CFG_START_ADDR, sizeof(ee.hdr), (char *)&ee.hdr ); if (!ee)
if ( err != sizeof(ee.hdr) )
{ {
PERROR( "Error while reading the EEPROM content (%d)\n", err ); PERROR( "Reading cached content failed.\n" );
return EEPROM_ERR_DEVICE; return EEPROM_ERR_DEVICE;
} }
// Validate the header magic ID switch ( ee->hdr.u16Version )
if ( ee.hdr.u32MagicId != EEPROM_CFG_MAGIC_ID )
{
PERROR( "Invalid EEPROM format\n" );
return EEPROM_ERR_INVALID;
}
switch ( ee.hdr.u16Version )
{ {
case 1: case 1:
{ {
@@ -680,40 +672,32 @@ eeprom_Error_t eeprom_ReadTxCal( int iBand, eeprom_TxCal_t *pTxCal )
case 0: case 0:
nArfcn = 124; nArfcn = 124;
sId = EEPROM_SID_GSM850_TXCAL; sId = EEPROM_SID_GSM850_TXCAL;
pCfgTxCal = &ee.cfg.v1.gsm850TxCal; pCfgTxCal = &ee->cfg.v1.gsm850TxCal;
size = sizeof(ee.cfg.v1.gsm850TxCal) + sizeof(ee.cfg.v1.__gsm850TxCalMem); size = sizeof(ee->cfg.v1.gsm850TxCal) + sizeof(ee->cfg.v1.__gsm850TxCalMem);
break; break;
case 1: case 1:
nArfcn = 194; nArfcn = 194;
sId = EEPROM_SID_GSM900_TXCAL; sId = EEPROM_SID_GSM900_TXCAL;
pCfgTxCal = &ee.cfg.v1.gsm900TxCal; pCfgTxCal = &ee->cfg.v1.gsm900TxCal;
size = sizeof(ee.cfg.v1.gsm900TxCal) + sizeof(ee.cfg.v1.__gsm900TxCalMem); size = sizeof(ee->cfg.v1.gsm900TxCal) + sizeof(ee->cfg.v1.__gsm900TxCalMem);
break; break;
case 2: case 2:
nArfcn = 374; nArfcn = 374;
sId = EEPROM_SID_DCS1800_TXCAL; sId = EEPROM_SID_DCS1800_TXCAL;
pCfgTxCal = &ee.cfg.v1.dcs1800TxCal; pCfgTxCal = &ee->cfg.v1.dcs1800TxCal;
size = sizeof(ee.cfg.v1.dcs1800TxCal) + sizeof(ee.cfg.v1.__dcs1800TxCalMem); size = sizeof(ee->cfg.v1.dcs1800TxCal) + sizeof(ee->cfg.v1.__dcs1800TxCalMem);
break; break;
case 3: case 3:
nArfcn = 299; nArfcn = 299;
sId = EEPROM_SID_PCS1900_TXCAL; sId = EEPROM_SID_PCS1900_TXCAL;
pCfgTxCal = &ee.cfg.v1.pcs1900TxCal; pCfgTxCal = &ee->cfg.v1.pcs1900TxCal;
size = sizeof(ee.cfg.v1.pcs1900TxCal) + sizeof(ee.cfg.v1.__pcs1900TxCalMem); size = sizeof(ee->cfg.v1.pcs1900TxCal) + sizeof(ee->cfg.v1.__pcs1900TxCalMem);
break; break;
default: default:
PERROR( "Invalid GSM band specified (%d)\n", iBand ); PERROR( "Invalid GSM band specified (%d)\n", iBand );
return EEPROM_ERR_INVALID; return EEPROM_ERR_INVALID;
} }
// Get a copy of the EEPROM section
err = eeprom_read( EEPROM_CFG_START_ADDR + ((uint32_t)pCfgTxCal - (uint32_t)&ee), size, (char *)pCfgTxCal );
if ( err != size )
{
PERROR( "Error while reading the EEPROM content (%d)\n", err );
return EEPROM_ERR_DEVICE;
}
// Validate the ID // Validate the ID
if ( pCfgTxCal->u16SectionID != sId ) if ( pCfgTxCal->u16SectionID != sId )
{ {
@@ -920,29 +904,20 @@ eeprom_Error_t eeprom_WriteTxCal( int iBand, const eeprom_TxCal_t *pTxCal )
eeprom_Error_t eeprom_ReadRxCal( int iBand, int iUplink, eeprom_RxCal_t *pRxCal ) eeprom_Error_t eeprom_ReadRxCal( int iBand, int iUplink, eeprom_RxCal_t *pRxCal )
{ {
int i; int i;
int err;
int size; int size;
int nArfcn; int nArfcn;
eeprom_Cfg_t ee; eeprom_Cfg_t *ee = eeprom_cached_config();
eeprom_SID_t sId; eeprom_SID_t sId;
eeprom_CfgRxCal_t *pCfgRxCal = NULL; eeprom_CfgRxCal_t *pCfgRxCal = NULL;
// Get a copy of the EEPROM header
err = eeprom_read( EEPROM_CFG_START_ADDR, sizeof(ee.hdr), (char *)&ee.hdr ); if (!ee)
if ( err != sizeof(ee.hdr) )
{ {
PERROR( "Error while reading the EEPROM content (%d)\n", err ); PERROR( "Reading cached content failed.\n" );
return EEPROM_ERR_DEVICE; return EEPROM_ERR_DEVICE;
} }
// Validate the header magic ID switch ( ee->hdr.u16Version )
if ( ee.hdr.u32MagicId != EEPROM_CFG_MAGIC_ID )
{
PERROR( "Invalid EEPROM format\n" );
return EEPROM_ERR_INVALID;
}
switch ( ee.hdr.u16Version )
{ {
case 1: case 1:
{ {
@@ -953,14 +928,14 @@ eeprom_Error_t eeprom_ReadRxCal( int iBand, int iUplink, eeprom_RxCal_t *pRxCal
if ( iUplink ) if ( iUplink )
{ {
sId = EEPROM_SID_GSM850_RXUCAL; sId = EEPROM_SID_GSM850_RXUCAL;
pCfgRxCal = &ee.cfg.v1.gsm850RxuCal; pCfgRxCal = &ee->cfg.v1.gsm850RxuCal;
size = sizeof(ee.cfg.v1.gsm850RxuCal) + sizeof(ee.cfg.v1.__gsm850RxuCalMem); size = sizeof(ee->cfg.v1.gsm850RxuCal) + sizeof(ee->cfg.v1.__gsm850RxuCalMem);
} }
else else
{ {
sId = EEPROM_SID_GSM850_RXDCAL; sId = EEPROM_SID_GSM850_RXDCAL;
pCfgRxCal = &ee.cfg.v1.gsm850RxdCal; pCfgRxCal = &ee->cfg.v1.gsm850RxdCal;
size = sizeof(ee.cfg.v1.gsm850RxdCal) + sizeof(ee.cfg.v1.__gsm850RxdCalMem); size = sizeof(ee->cfg.v1.gsm850RxdCal) + sizeof(ee->cfg.v1.__gsm850RxdCalMem);
} }
break; break;
case 1: case 1:
@@ -968,14 +943,14 @@ eeprom_Error_t eeprom_ReadRxCal( int iBand, int iUplink, eeprom_RxCal_t *pRxCal
if ( iUplink ) if ( iUplink )
{ {
sId = EEPROM_SID_GSM900_RXUCAL; sId = EEPROM_SID_GSM900_RXUCAL;
pCfgRxCal = &ee.cfg.v1.gsm900RxuCal; pCfgRxCal = &ee->cfg.v1.gsm900RxuCal;
size = sizeof(ee.cfg.v1.gsm900RxuCal) + sizeof(ee.cfg.v1.__gsm900RxuCalMem); size = sizeof(ee->cfg.v1.gsm900RxuCal) + sizeof(ee->cfg.v1.__gsm900RxuCalMem);
} }
else else
{ {
sId = EEPROM_SID_GSM900_RXDCAL; sId = EEPROM_SID_GSM900_RXDCAL;
pCfgRxCal = &ee.cfg.v1.gsm900RxdCal; pCfgRxCal = &ee->cfg.v1.gsm900RxdCal;
size = sizeof(ee.cfg.v1.gsm900RxdCal) + sizeof(ee.cfg.v1.__gsm900RxdCalMem); size = sizeof(ee->cfg.v1.gsm900RxdCal) + sizeof(ee->cfg.v1.__gsm900RxdCalMem);
} }
break; break;
case 2: case 2:
@@ -983,14 +958,14 @@ eeprom_Error_t eeprom_ReadRxCal( int iBand, int iUplink, eeprom_RxCal_t *pRxCal
if ( iUplink ) if ( iUplink )
{ {
sId = EEPROM_SID_DCS1800_RXUCAL; sId = EEPROM_SID_DCS1800_RXUCAL;
pCfgRxCal = &ee.cfg.v1.dcs1800RxuCal; pCfgRxCal = &ee->cfg.v1.dcs1800RxuCal;
size = sizeof(ee.cfg.v1.dcs1800RxuCal) + sizeof(ee.cfg.v1.__dcs1800RxuCalMem); size = sizeof(ee->cfg.v1.dcs1800RxuCal) + sizeof(ee->cfg.v1.__dcs1800RxuCalMem);
} }
else else
{ {
sId = EEPROM_SID_DCS1800_RXDCAL; sId = EEPROM_SID_DCS1800_RXDCAL;
pCfgRxCal = &ee.cfg.v1.dcs1800RxdCal; pCfgRxCal = &ee->cfg.v1.dcs1800RxdCal;
size = sizeof(ee.cfg.v1.dcs1800RxdCal) + sizeof(ee.cfg.v1.__dcs1800RxdCalMem); size = sizeof(ee->cfg.v1.dcs1800RxdCal) + sizeof(ee->cfg.v1.__dcs1800RxdCalMem);
} }
break; break;
case 3: case 3:
@@ -998,14 +973,14 @@ eeprom_Error_t eeprom_ReadRxCal( int iBand, int iUplink, eeprom_RxCal_t *pRxCal
if ( iUplink ) if ( iUplink )
{ {
sId = EEPROM_SID_PCS1900_RXUCAL; sId = EEPROM_SID_PCS1900_RXUCAL;
pCfgRxCal = &ee.cfg.v1.pcs1900RxuCal; pCfgRxCal = &ee->cfg.v1.pcs1900RxuCal;
size = sizeof(ee.cfg.v1.pcs1900RxuCal) + sizeof(ee.cfg.v1.__pcs1900RxuCalMem); size = sizeof(ee->cfg.v1.pcs1900RxuCal) + sizeof(ee->cfg.v1.__pcs1900RxuCalMem);
} }
else else
{ {
sId = EEPROM_SID_PCS1900_RXDCAL; sId = EEPROM_SID_PCS1900_RXDCAL;
pCfgRxCal = &ee.cfg.v1.pcs1900RxdCal; pCfgRxCal = &ee->cfg.v1.pcs1900RxdCal;
size = sizeof(ee.cfg.v1.pcs1900RxdCal) + sizeof(ee.cfg.v1.__pcs1900RxdCalMem); size = sizeof(ee->cfg.v1.pcs1900RxdCal) + sizeof(ee->cfg.v1.__pcs1900RxdCalMem);
} }
break; break;
default: default:
@@ -1013,14 +988,6 @@ eeprom_Error_t eeprom_ReadRxCal( int iBand, int iUplink, eeprom_RxCal_t *pRxCal
return EEPROM_ERR_INVALID; return EEPROM_ERR_INVALID;
} }
// Get a copy of the EEPROM section
err = eeprom_read( EEPROM_CFG_START_ADDR + ((uint32_t)pCfgRxCal - (uint32_t)&ee), size, (char *)pCfgRxCal );
if ( err != size )
{
PERROR( "Error while reading the EEPROM content (%d)\n", err );
return EEPROM_ERR_DEVICE;
}
// Validate the ID // Validate the ID
if ( pCfgRxCal->u16SectionID != sId ) if ( pCfgRxCal->u16SectionID != sId )
{ {
@@ -1322,12 +1289,17 @@ int eeprom_dump( int addr, int size, int hex )
} }
static FILE *g_file; static FILE *g_file;
static eeprom_Cfg_t *g_cached_cfg;
void eeprom_free_resources(void) void eeprom_free_resources(void)
{ {
if (g_file) if (g_file)
fclose(g_file); fclose(g_file);
g_file = NULL; g_file = NULL;
/* release the header */
free(g_cached_cfg);
g_cached_cfg = NULL;
} }
/** /**
@@ -1352,6 +1324,42 @@ static int eeprom_read( int addr, int size, char *pBuff )
return n; return n;
} }
static void eeprom_cache_cfg(void)
{
int err;
free(g_cached_cfg);
g_cached_cfg = malloc(sizeof(*g_cached_cfg));
if (!g_cached_cfg)
return;
err = eeprom_read( EEPROM_CFG_START_ADDR, sizeof(*g_cached_cfg), (char *) g_cached_cfg );
if ( err != sizeof(*g_cached_cfg) )
{
PERROR( "Error while reading the EEPROM content (%d)\n", err );
goto error;
}
if ( g_cached_cfg->hdr.u32MagicId != EEPROM_CFG_MAGIC_ID )
{
PERROR( "Invalid EEPROM format\n" );
goto error;
}
return;
error:
free(g_cached_cfg);
g_cached_cfg = NULL;
}
static eeprom_Cfg_t *eeprom_cached_config(void)
{
if (!g_cached_cfg)
eeprom_cache_cfg();
return g_cached_cfg;
}
/** /**
* Write up to 'size' bytes of data to the EEPROM starting at offset 'addr'. * Write up to 'size' bytes of data to the EEPROM starting at offset 'addr'.