📄 sysenv.c
字号:
{ /* Neither free nor in use: file FLASH is corrupted ! */ return( ERROR_SYSENV_FLASH_INVALID ) ; } } /* validate the free file FLASH area */ pf = SYSENV_file_flash_start + SYSENV_next_free * sizeof(t_SYSENV_elem) ; for ( i = SYSENV_next_free; i < SYSENV_max_records; i++) { for ( j=0; j<(sizeof(t_SYSENV_elem)/sizeof(UINT32)); j++, pf+= sizeof(UINT32) ) { if ( *(UINT32*)pf != 0xffffffff ) { /* This is an error, file FLASH is corrupted ! */ return( ERROR_SYSENV_FLASH_INVALID ) ; } } } /* Set SYSENV state = 'OK' */ SYSENV_state = SYSENV_STATE_OK ; return(OK) ;}/************************************************************************ * * SYSENV_read * Description : * ------------- * * Read a system environment variable. Unformatted data are read from * a data array, accessed via an 'index'. Data are not copied, just * a pointer reference is being returned to the data array and the * actual size of the data, which have been stored. * * * Parameters : * ------------ * * 'var', INOUT, data are not copied * * Return values : * --------------- * * 'OK'(=0), returned parameter value and size are valid. * * ************************************************************************/INT32 SYSENV_read( t_user_environment_var *var ){ INT32 header; UINT8 *pf ; if (SYSENV_state != SYSENV_STATE_OK) { return( ERROR_SYSENV_FLASH_INVALID ) ; } if ( var->index > SYS_USER_ENVIRONMENT_MAX_INDEX ) { return( ERROR_SYSENV_INVALID_INDEX ) ; } /* index OK, just try and get the context */ pf = SYSENV_lookup[ var->index ].flash_record ; if ( pf == NULL ) { return ( ERROR_SYSENV_NO_VARIABLE ) ; /* empty index */ } /* OK, there is a environment variable */ /* verify inuse record */ if ( SYSENV_check_inuse_record( pf, var->index ) == OK ) { header = *(UINT32*)pf; var->size = REGFIELD(header,SYSENV_HEADER_SIZE); var->data_inout = (void*)(pf + SYSENV_HEADER_SIZE) ; } else { var->size = 0 ; var->data_inout = NULL ; } if (var->size == 0) { /* Record has been deleted */ return ( ERROR_SYSENV_NO_VARIABLE ) ; } return( OK ) ;}/************************************************************************ * * SYSENV_write * Description : * ------------- * * Write data to a system environment variable. Unformatted data are * written to a data array, accessed via an 'index'. Data are copied, * into non-volatile memory (FLASH) and a pointer reference is * returned to the data-array of this variable in FLASH. The actual * size is stored too, to be returned in a 'read' for this variable. * A system variable is being created with the first 'write' operation * to this variable and deleted, if any succeeding 'write' to * this 'index' contains a 'size' parameter of '0'. * * * Parameters : * ------------ * * 'var', INOUT, data are copied into non-volatile memory * and the storage-pointer for this memory * is being returned in the 'data_inout' * parameter of the parameter block. * * Return values : * --------------- * * 'OK'(=0), returned parameter value and size are valid. * * ************************************************************************/INT32 SYSENV_write( t_user_environment_var *var ){ int i ; INT32 completion, rcode = OK ; UINT32 header; UINT8 *pf ; UINT8 *pdata ; UINT8 checksum ; t_FLASH_write_descriptor flash_write ; t_FLASH_ctrl_descriptor flash_ctrl ; if (SYSENV_state != SYSENV_STATE_OK) { return( ERROR_SYSENV_FLASH_INVALID ) ; } /* validate user parameters */ if ( var->index > SYS_USER_ENVIRONMENT_MAX_INDEX ) { /* Index is out of valid range */ return( ERROR_SYSENV_INVALID_INDEX ) ; } if ( var->size > SYS_USER_ENVIRONMENT_DATA_SIZE ) { /* Size is too big */ return( ERROR_SYSENV_ENV_VAR_TOO_BIG ) ; } /* Index and size is OK, just try and store the context */ if (SYSENV_next_free < SYSENV_max_records) { /* normal case */ completion = OK ; } else { /* This is the garbage collection case */ completion = SYSENV_collect_garbage() ; if (completion != ERROR_SYSENV_UPDATE_READ_REFS) { return(completion) ; } } /* format buffer */ pdata = var->data_inout ; checksum = 0 ; for (i=0; i<var->size; i++) { checksum += pdata[i] ; } /* Header is independent of endianess */ REGP(SYSENV_write_buffer,SYSENV_HEADER) = (SYSENV_RECORD_IN_USE << SYSENV_HEADER_CONTROL_SHF) | (var->index << SYSENV_HEADER_ID_SHF) | (checksum << SYSENV_HEADER_CHKSUM_SHF) | (var->size << SYSENV_HEADER_SIZE_SHF); memcpy( &SYSENV_write_buffer[ SYSENV_HEADER_SIZE ], var->data_inout , var->size ) ; /* get pointer to file flash record */ pf = SYSENV_file_flash_start + (SYSENV_next_free * sizeof(t_SYSENV_elem)) ; /* store record in file flash */ flash_write.adr = PHYS(pf) ; flash_write.length = var->size + SYSENV_HEADER_SIZE ; flash_write.buffer = SYSENV_write_buffer ; flash_ctrl.command = FLASH_CTRL_WRITE_FILEFLASH ; flash_ctrl.wr_param = &flash_write ; rcode = IO_ctrl( SYS_MAJOR_FLASH_STRATA, 0, &flash_ctrl ) ; if (rcode != OK) { SYSENV_state = SYSENV_STATE_ERROR ; return(rcode) ; } /* update lookup table */ SYSENV_lookup[ var->index ].flash_record = pf ; /* update user reference */ var->data_inout = (void*)(pf + SYSENV_HEADER_SIZE) ; /* Paranoid checking.. */ header = *(UINT32*)pf; rcode = SYSENV_check_inuse_record( pf, REGFIELD(header,SYSENV_HEADER_ID) ) ; if (rcode != OK) { return(rcode) ; } /* advance to next free record in file flash */ SYSENV_next_free++ ; return( completion ) ;}/************************************************************************ * Implementation : Static functions ************************************************************************//************************************************************************ * * SYSENV_collect_garbage * Description : * ------------- * * Execute garbage collection. * * * * * Parameters : * ------------ * * - * * * Return values : * --------------- * * 'ERROR_SYSENV_UPDATE_READ_REFS', all references for env variables must be re-read. * ************************************************************************/static INT32 SYSENV_collect_garbage( void ){ int i ; INT32 rcode ; UINT32 header; t_SYSENV_elem *pf ; t_SYSENV_elem *pr ; t_FLASH_ctrl_descriptor flash_ctrl ; t_FLASH_write_descriptor flash_write ; /* cache any variable in RAM */ for ( i = 0; i <= SYS_USER_ENVIRONMENT_MAX_INDEX ; i++ ) { pf = SYSENV_lookup[ i ].flash_record ; pr = SYSENV_lookup[ i ].ram_record ; if ( pf != NULL ) { /* copy flash data to RAM */ header = *(UINT32*)pf; memcpy( pr, pf, REGFIELD(header,SYSENV_HEADER_SIZE) + SYSENV_HEADER_SIZE ) ; /* delete reference */ SYSENV_lookup[i].flash_record = NULL ; } else { /* set size to '0' to delete record */ REGP(pr,SYSENV_HEADER) &= ~SYSENV_HEADER_SIZE_MSK; } } /* delete file flash */ flash_ctrl.command = FLASH_CTRL_ERASE_FILEFLASH ; rcode = IO_ctrl( SYS_MAJOR_FLASH_STRATA, 0, &flash_ctrl ) ; if (rcode != OK) { return(rcode) ; } /* reset context */ SYSENV_next_free = 0 ; /* copy cached data back into flash */ for ( i = 0; i <= SYS_USER_ENVIRONMENT_MAX_INDEX ; i++ ) { pr = SYSENV_lookup[ i ].ram_record ; header = *(UINT32*)pr; if (REGFIELD(header,SYSENV_HEADER_SIZE) != 0) { /* store cached data in flash */ pf = SYSENV_file_flash_start + (SYSENV_next_free * sizeof(t_SYSENV_elem)) ; pr = SYSENV_lookup[ i ].ram_record ; flash_write.adr = PHYS(pf) ; flash_write.length = REGFIELD(header,SYSENV_HEADER_SIZE) + SYSENV_HEADER_SIZE ; flash_write.buffer = (UINT8*)pr; flash_ctrl.command = FLASH_CTRL_WRITE_FILEFLASH ; flash_ctrl.wr_param = &flash_write ; rcode = IO_ctrl( SYS_MAJOR_FLASH_STRATA, 0, &flash_ctrl ) ; if (rcode != OK) { return(rcode) ; } /* update reference */ SYSENV_lookup[i].flash_record = pf ; /* advance to next free record in file flash */ SYSENV_next_free++ ; } else { /* update reference */ SYSENV_lookup[i].flash_record = NULL ; } } return(ERROR_SYSENV_UPDATE_READ_REFS) ;}/************************************************************************ * * SYSENV_error_lookup * Description : * ------------- * Lookup error code to error string(s) * * * Parameters : * ------------ * * 'p_param', INOUT, variable of type, t_sys_error_string. * * * Return values : * --------------- * * 'OK' = 0x00: * * ************************************************************************/staticINT32 SYSENV_error_lookup( t_sys_error_string *p_param ){ UINT32 t, i ; i = 0 ; p_param->count = 0 ; t = SYSERROR_ID( p_param->syserror ) ; /* check for recognized error code */ if (t < sizeof(sysenv_error_string)/sizeof(char*) ) { /* fill in mandatory error message string */ p_param->strings[SYSCON_ERRORMSG_IDX] = sysenv_error_string[t] ; i++ ; /* check for hint message */ if ( sysenv_error_hint_string[t] != NULL) { /* fill in optional hint message string */ p_param->strings[SYSCON_HINTMSG_IDX] = sysenv_error_hint_string[t] ; i++ ; } } p_param->count = i ; return(OK) ;}/************************************************************************ * * SYSENV_check_inuse_record * Description : * ------------- * Check referenced record * * * Parameters : * ------------ * * 'ph', INOUT, environment flash record. * 'index', INOUT, environment flash record index. * * * Return values : * --------------- * * 'ERROR_SYSENV_FLASH_INVALID': Environment is corrupted. * 'OK' = 0x00: * * ************************************************************************/staticINT32 SYSENV_check_inuse_record( UINT8 *ph, UINT8 index ){ UINT32 i ; UINT32 header ; UINT32 size ; UINT8 checksum ; UINT8 *pf ; header = *(UINT32*)ph; /* check control */ if ( REGFIELD(header,SYSENV_HEADER_CONTROL) == SYSENV_RECORD_IN_USE ) { /* check index */ if ( REGFIELD(header,SYSENV_HEADER_ID) == index ) { /* check size: */ size = REGFIELD(header,SYSENV_HEADER_SIZE) ; pf = ph + SYSENV_HEADER_SIZE ; if ( size <= SYS_USER_ENVIRONMENT_DATA_SIZE ) { /* calculate checksum */ for (checksum = 0; size > 3; size -= 4, pf += 4) { i = *(UINT32*)pf; checksum += (i>>24) + (i>>16) + (i>>8) + i; } if (size > 0) { i = *(UINT32*)pf; switch (size) { case 3: checksum += i >> 16; /* fall through */ case 2: checksum += i >> 8; /* fall through */ case 1: checksum += i; } } /* check checksum */ if ( checksum == REGFIELD(header,SYSENV_HEADER_CHKSUM) ) { /* OK, header is valid */ return( OK ) ; } } } } /* This is an error, file FLASH is corrupted ! */ /* Set SYSENV state = 'ERROR' */ SYSENV_state = SYSENV_STATE_ERROR ; return( ERROR_SYSENV_FLASH_INVALID ) ;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -