📄 env.c
字号:
t_env_var_info *info;
UINT32 index;
UINT32 index_flash;
UINT32 rc;
char old_data[SYS_USER_ENVIRONMENT_DATA_SIZE];
if( strlen(name) > ENV_VAR_MAXLEN_NAME )
{
return ERROR_ENV_VAR_NAME_LEN;
}
/* Check length of data for buffer (name + value + 2 * '\0') */
if( strlen(name) + strlen(*value) + 2 > SYS_USER_ENVIRONMENT_DATA_SIZE )
{
return ERROR_ENV_VAR_VAL_LEN;
}
if( lookup_env( name, &index ) )
{
/* Found */
env_var = &env_vars[index];
info = &env_var_info[index];
switch( info->attr )
{
case ENV_ATTR_RO :
if( !ext_priviliges )
return ERROR_ENV_VAR_RO;
/**** Fall through ****/
case ENV_ATTR_RW :
case ENV_ATTR_USER :
if( strcmp( env_var->val, *value ) != 0 )
{
/* new value, check validity of data */
if( info->decode &&
!info->decode( *value, NULL, 0 ) )
{
return ERROR_ENV_VAR_VALUE;
}
/* Store old value */
strcpy( old_data, env_var->val );
/* Generate new data */
strcpy( env_var->val, *value );
/* Write to flash */
rc = env_to_flash( index, &index_flash );
if( rc != OK )
{
/* Could not write, restore old data */
strcpy( env_var->val, old_data );
return rc;
}
}
if( info->attr == ENV_ATTR_USER )
{
info->default_value = default_value;
info->decode = decode;
info->attr = attr;
}
break;
default :
/* Ignore */
break;
}
}
else
{
/* Not found, so create it */
if( env_var_count == SYS_USER_ENVIRONMENT_MAX_INDEX + 1 )
{
/* Too many */
return ERROR_ENV_VAR_OVERFLOW;
}
else
{
/* Allocate variable */
index = env_var_count;
env_var = &env_vars[index];
info = &env_var_info[index];
strcpy( info->data, name );
set_env_var( env_var, info );
if( *value )
strcpy( env_var->val, *value );
else
*env_var->val = '\0';
info->index = INDEX_NONE;
info->default_value = default_value;
info->decode = decode;
info->attr = attr;
/* Write to flash */
rc = env_to_flash( index, &index_flash );
if( rc != OK )
{
/* Could not write */
return rc;
}
else if( index_flash != INDEX_REARRANGED )
{
/* Write OK, store index */
env_var_info[index].index = index_flash;
env_var_count++;
/* New NULL var */
env_vars[env_var_count].name = NULL;
env_vars[env_var_count].val = NULL;
}
}
}
return OK;
}
/************************************************************************
* set_env_var
************************************************************************/
static void
set_env_var(
t_env_var *env_var,
t_env_var_info *info )
{
env_var->name = info->data;
env_var->val = &info->data[strlen(env_var->name) + 1];
}
/************************************************************************
* lookup_env
************************************************************************/
static bool
lookup_env(
char *name,
UINT32 *index )
{
/* Find variable */
for( *index = 0;
(*index < env_var_count) &&
(strcmp( env_vars[*index].name, name ) != 0);
(*index)++ );
return ( *index == env_var_count ) ? FALSE : TRUE;
}
/************************************************************************
* compare
************************************************************************/
static int
compare(
UINT32 *x,
UINT32 *y )
{
return strcmp( env_vars[*x].name, env_vars[*y].name );
}
/************************************************************************
* remove_var
************************************************************************/
static UINT32
remove_var(
UINT32 index,
bool user,
bool system,
bool error_on_ro )
{
t_env_var_info *info;
UINT32 rc;
info = &env_var_info[index];
switch( env_var_info[index].attr )
{
case ENV_ATTR_RW :
if( system )
{
/* Set to default value */
rc = access_var( env_vars[index].name,
&info->default_value, ENV_ATTR_RW,
info->default_value, NULL );
if( rc != OK )\
return rc;
}
break;
case ENV_ATTR_USER :
if( user )
{
/* Remove from flash */
env_remove_from_flash( env_var_info[index].index );
/* Move last record to the empty position */
env_var_info[index] = env_var_info[env_var_count - 1];
set_env_var( &env_vars[index], &env_var_info[index] );
/* New NULL */
env_var_count--;
env_vars[env_var_count].name = NULL;
env_vars[env_var_count].val = NULL;
}
break;
case ENV_ATTR_RO :
default :
/* Ignore request */
if( error_on_ro )
{
return ERROR_ENV_VAR_RO;
}
break;
}
return OK;
}
/************************************************************************
* env_to_flash
************************************************************************/
static UINT32
env_to_flash(
UINT32 index_local,
UINT32 *index_flash )
{
t_user_environment_var disk_env_var;
char s[SYS_USER_ENVIRONMENT_DATA_SIZE];
UINT32 len_name;
UINT32 i;
INT32 rc;
char *val;
UINT32 align;
t_env_var *env_var = &env_vars[index_local];
t_env_var_info *info = &env_var_info[index_local];
*index_flash = info->index;
len_name = strlen(env_var->name);
val = env_var->val ? env_var->val : "\0";
disk_env_var.size = len_name + strlen(val) + 2;
if( disk_env_var.size > SYS_USER_ENVIRONMENT_DATA_SIZE )
{
*index_flash = INDEX_NONE;
return ERROR_ENV_VAR_VAL_LEN;
}
strcpy( s, env_var->name );
strcpy( &s[len_name + 1], val );
#ifdef EB
convert_endianness( s );
/* Round size up to a whole multiplum of words */
align = (sizeof(UINT32) - (disk_env_var.size % sizeof(UINT32))) %
sizeof(UINT32);
disk_env_var.size += align;
#endif
disk_env_var.data_inout = (void *)s;
if( *index_flash == INDEX_NONE )
{
/* Find free index */
*index_flash = 0;
do
{
for( i=0;
(i<env_var_count) && (env_var_info[i].index != *index_flash);
i++ );
if( i == env_var_count ) /* Found free index */
break;
else /* Not free */
(*index_flash)++;
}
while( *index_flash <= SYS_USER_ENVIRONMENT_MAX_INDEX );
if( *index_flash > SYS_USER_ENVIRONMENT_MAX_INDEX )
{
/* Should not happen */
*index_flash = INDEX_NONE;
return ERROR_ENV_VAR_OVERFLOW;
}
}
disk_env_var.index = *index_flash;
rc = SYSCON_write(
SYSCON_DISK_ENVIRONMENT_ID,
(void *)&disk_env_var,
sizeof(t_user_environment_var) );
switch( rc )
{
case 0 :
return OK;
break;
case ERROR_SYSENV_UPDATE_READ_REFS :
/* Flash was rearranged, so re-read */
re_init();
*index_flash = INDEX_REARRANGED;
return OK;
break;
default :
*index_flash = INDEX_NONE;
return rc;
break;
}
}
/************************************************************************
* env_remove_from_flash
************************************************************************/
static void
env_remove_from_flash(
UINT32 index )
{
t_user_environment_var env_var;
env_var.index = index;
env_var.size = 0;
env_var.data_inout = NULL;
SYSCON_write(
SYSCON_DISK_ENVIRONMENT_ID,
(void *)&env_var,
sizeof(t_user_environment_var) );
}
/************************************************************************
* convert_endianness
************************************************************************/
static void
convert_endianness(
char *s )
{
UINT32 i;
UINT32 *data = (UINT32 *)s;
for(i=0; i<SYS_USER_ENVIRONMENT_DATA_SIZE / 4; i++ )
{
data[i] = SWAPEND32( data[i] );
}
}
/************************************************************************
* re_init
************************************************************************/
static void
re_init( void )
{
/* Flash was rearranged, so indices must be updated */
t_user_environment_var env_var;
UINT32 index;
UINT32 i;
for( i=0; i<= SYS_USER_ENVIRONMENT_MAX_INDEX; i++ )
{
env_var.index = i;
if( SYSCON_read(
SYSCON_DISK_ENVIRONMENT_ID,
(void *)&env_var,
sizeof(t_user_environment_var) ) == OK )
{
/* Found variable */
if( lookup_env(
(char *)env_var.data_inout,
&index) )
{
/* lookup_env should never fail in this case */
env_var_info[index].index = env_var.index;
}
}
}
}
/************************************************************************
* Implementation : Public functions
************************************************************************/
/************************************************************************
*
* env_init
* Description :
* -------------
*
* Init ENV module (create System environment variables)
*
* Return values :
* ---------------
*
* None
*
************************************************************************/
void
env_init(void)
{
t_user_environment_var env_var;
UINT32 i, t, count;
char *s;
bool default_switch;
char *raw;
char msg[40];
UINT32 error;
t_sys_error_lookup_registration registration;
/* Register error handling function */
registration.prefix = SYSERROR_DOMAIN( ERROR_ENV );
registration.lookup = error_lookup;
SYSCON_write( SYSCON_ERROR_REGISTER_LOOKUP_ID,
®istration,
sizeof( registration ) );
env_var_count = 0;
env_corrupted = FALSE;
/* Read environment variables */
for( i=0; i<= SYS_USER_ENVIRONMENT_MAX_INDEX; i++ )
{
env_var.index = i;
if( SYSCON_read(
SYSCON_DISK_ENVIRONMENT_ID,
(void *)&env_var,
sizeof(t_user_environment_var) ) == OK )
{
env_var_info[env_var_count].index = env_var.index;
env_var_info[env_var_count].attr = ENV_ATTR_USER;
env_var_info[env_var_count].decode = NULL;
/* Make local copy of data */
s = env_var_info[env_var_count].data;
memcpy( s,
(char *)env_var.data_inout,
SYS_USER_ENVIRONMENT_DATA_SIZE );
#ifdef EB
convert_endianness( s );
#endif
/* Check that data contains two \0 terminations */
for( t=0, count = 0; t< SYS_USER_ENVIRONMENT_DATA_SIZE; t++ )
{
if( s[t] == '\0' )
count++;
}
if( count >= 2 )
{
/* Setup name and value */
env_vars[env_var_count].name = s;
env_vars[env_var_count].val = &s[strlen(s) + 1];
env_var_count++;
}
else
{
env_corrupted = TRUE;
}
}
}
env_vars[env_var_count].name = NULL;
env_vars[env_var_count].val = NULL;
/* Setup system environment variables if this was not done
* at a previous run.
*/
SYSCON_read( SYSCON_BOARD_USE_DEFAULT_ID,
(void *)&default_switch,
sizeof(UINT32) );
SYSCON_read( SYSCON_CPU_CACHE_CONFIGURABLE_ID,
(void *)&cache_configurable,
sizeof(UINT32) );
SYSCON_read( SYSCON_CPU_MMU_CONFIGURABLE_ID,
(void *)&mmu_configurable,
sizeof(UINT32) );
SYSCON_read( SYSCON_CPU_CP0_CONFIG_RESET_ID,
(void *)&config_init,
sizeof(UINT32) );
ext_priviliges = TRUE;
/* Size of RAM */
sprintf( msg, "0x%08x", sys_ramsize );
if( (error = env_set( "memsize", msg, ENV_ATTR_RO, NULL, hex_s2num )) != OK )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -