📄 env.c
字号:
}/************************************************************************ * access_var ************************************************************************/static UINT32access_var( char *name, char **value, UINT8 attr, char *default_value, t_env_decode decode ){ t_env_var *env_var; 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 voidset_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 boollookup_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 intcompare( UINT32 *x, UINT32 *y ){ return strcmp( env_vars[*x].name, env_vars[*y].name );}/************************************************************************ * remove_var ************************************************************************/static UINT32remove_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; 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 */ i = (sizeof(UINT32) - (disk_env_var.size % sizeof(UINT32))) % sizeof(UINT32); disk_env_var.size += i;#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; case ERROR_SYSENV_UPDATE_READ_REFS : /* Flash was rearranged, so re-read */ re_init(); *index_flash = INDEX_REARRANGED; return OK; default : *index_flash = INDEX_NONE; return rc; }}/************************************************************************ * 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) );} #ifdef EB/************************************************************************ * convert_endianness ************************************************************************/static voidconvert_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] ); }}#endif/************************************************************************ * 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]; 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) );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -