📄 loader.c
字号:
}
if ( (type == '2') || (type == '8') )
{
offset_data = OFFSET_DATA_S28; /* Only relevant for S2/S8 records */
}
if ( (type == '1') || (type == '9') )
{
offset_data = OFFSET_DATA_S19; /* Only relevant for S1/S9 records */
}
checksum = 0;
/* Convert line */
odd = TRUE ;
while (TRUE)
{
/* get next character */
ch = sdata[sid++] ;
odd = !odd;
/* convert character */
ch_val = char2val[ch] ;
/* check for invalid chars */
if ( ch_val == INVALID_CHAR )
{
// printf("1 %d\n", ch) ;
*raw_error = ERROR_LOAD_ILLEGAL_CHARACTER ;
return ERROR_LOAD_ILLEGAL_CHARACTER ;
}
/* check for valid "space" chars to terminate */
if ( ch_val == VALID_SPACE )
{
if( odd )
{
// printf("2 %d\n", ch) ;
*raw_error = ERROR_LOAD_ILLEGAL_FORMAT ;
return ERROR_LOAD_ILLEGAL_FORMAT;
}
/* check rest of line, must contain VALID_SPACE only */
do
{
/* get char */
ch = sdata[sid++] ;
ch_val = char2val[ch] ;
/* check for invalid format */
if ( ch_val != VALID_SPACE )
{
// printf("3 %d\n", ch) ;
*raw_error = ERROR_LOAD_ILLEGAL_FORMAT ;
return ERROR_LOAD_ILLEGAL_FORMAT;
}
} while( ch ) ;
break;
}
if( odd )
{
/* Store value */
val <<= 4;
val |= ch_val ;
data[offset++] = val;
checksum += val;
}
else
{
val = ch_val ;
}
}
/* Do various checks (don't perform checks for S0/S5 since
* they are discarded anyway.
*/
if( (type != '0') && (type != '5') )
{
/* Check that enough data is available */
if( offset < offset_data + 1 )
{
/* Something missing */
// printf("4 %d\n", type) ;
*raw_error = ERROR_LOAD_ILLEGAL_FORMAT ;
return ERROR_LOAD_ILLEGAL_FORMAT;
}
/* Check count */
if( offset - (OFFSET_COUNT + 1) != data[OFFSET_COUNT] )
{
// printf("5 %d\n", offset) ;
*raw_error = ERROR_LOAD_ILLEGAL_FORMAT ;
return ERROR_LOAD_ILLEGAL_FORMAT;
}
/* Check checksum */
if( checksum != 0xFF)
{
*raw_error = ERROR_LOAD_CHECKSUM ;
return ERROR_LOAD_CHECKSUM ;
}
}
/* Address */
if ( (type == '3') || (type == '7') )
{
/* 4-byte address is kept in 4-7 */
addr[0] = (void *)(*(UINT32 *)(&data[OFFSET_ADDRESS]));
}
if ( (type == '2') || (type == '8') )
{
/* 3-byte address is kept in 4-6 */
data[0] = 0 ;
data[1] = data[OFFSET_ADDRESS+0] ;
data[2] = data[OFFSET_ADDRESS+1] ;
data[3] = data[OFFSET_ADDRESS+2] ;
addr[0] = (void *)(*(UINT32 *)(&data[0]));
}
if ( (type == '1') || (type == '9') )
{
/* 2-byte address is kept in 4-5 */
data[0] = 0 ;
data[1] = 0 ;
data[2] = data[OFFSET_ADDRESS+0] ;
data[3] = data[OFFSET_ADDRESS+1] ;
addr[0] = (void *)(*(UINT32 *)(&data[0]));
}
#ifdef EL
addr[0] = (void *)SWAPEND32( (UINT32)(addr[0]) );
#endif
/* Decode line */
/* Set offset to the number of data bytes */
offset -= (offset_data + 1);
switch( type )
{
case '1' :
case '2' :
case '3' :
/**** S1, S2 or S3 record ****/
if(offset)
{
/* Write data to RAM/FLASH
*
* dst addr = (UINT32)*addr
* bytecount = offset
* src addr = &data[offset_data]
*/
/* check range context to return this at load end */
if ( (UINT32)addr[0] < (UINT32)addr[1] )
(UINT32)addr[1] = (UINT32)addr[0] ;
if ( ((UINT32)addr[0]+offset-1) > (UINT32)addr[2] )
(UINT32)addr[2] = (UINT32)addr[0]+offset-1 ;
/* Validate address */
rc = sys_validate_range(
(UINT32)addr[0],
offset,
sizeof(UINT8),
TRUE );
if (rc != OK)
{
*raw_error = rc;
return rc;
}
flash_write.adr = (UINT32)addr[0];
flash_write.length = offset ;
flash_write.buffer = &data[offset_data] ;
//printf(" adr=%08x\n", flash_write.adr ) ;
rc = IO_write( SYS_MAJOR_FLASH_STRATA, 0, &flash_write ) ;
if (rc != OK)
{
*raw_error = rc ;
return ERROR_LOAD_STORE;
}
/* PBUpdate indicate address in alpha-display */
/* DISP( (UINT32)addr[0] ) ; */
}
break;
case '7' :
case '8' :
case '9' :
/* S7, S8 or S9 record (end record) */
*raw_error = ERROR_LOAD_NONE ;
if (offset != 0 )
{
// printf("6 %d\n", offset) ;
*raw_error = ERROR_LOAD_ILLEGAL_FORMAT ;
}
if( port == PORT_NET )
{
/* This just to guarantee proper report */
printf("\n") ;
}
return offset ? ERROR_LOAD_ILLEGAL_FORMAT : ERROR_LOAD_NONE;
break;
default : /* Ignore S0/S5 records */
break;
}
}
else
{
// printf("7 %d\n", type) ;
*raw_error = ERROR_LOAD_ILLEGAL_FORMAT ;
return ERROR_LOAD_ILLEGAL_FORMAT;
}
/* read next line */
*raw_error = loader_readline( port ) ;
*error_pos = failing_line_no ;
if ( *raw_error != OK ) return( *raw_error ) ;
ch = sdata[sid++] ;
if( ch != 'S' )
{
// printf("8 %d\n", ch) ;
*raw_error = ERROR_LOAD_ILLEGAL_FORMAT ;
return ERROR_LOAD_ILLEGAL_FORMAT;
}
}
}
/************************************************************************
* loader_readline
************************************************************************/
static UINT32 loader_readline( UINT32 port )
{
bool empty_line ;
signed char ch ;
/* set default */
empty_line = TRUE ;
/* adjust line number counter */
failing_line_no = failing_line_no - failing_line_no_adjust ;
/* do read lines until any not empty found */
while ( empty_line )
{
/* clear actual line */
sid = 0 ;
do
{
while( !GETCHAR( port, &ch ) )
{
/* check for user break */
if (port != DEFAULT_PORT )
{
if (GETCHAR_CTRLC( DEFAULT_PORT ))
return( ERROR_LOAD_BREAK ) ;
}
}
/* check for user break */
if ( ch == CTRL_C )
return( ERROR_LOAD_BREAK ) ;
if ( ch == EOF_SREC )
{
/* check for End Of File; used by TFTP */
sid = 0 ; /* clear current line */
sdata[0] = 0 ;
return ERROR_LOAD_NO_S7_RECORD ;
}
if ( ch == UART_ERROR )
{
/* UART communication error */
failing_line_no++ ;
sdata[sid] = 0 ;
return ERROR_LOAD_UART_COMM_ERROR ;
}
/* check line size */
if (sid < MAX_LINE_SIZE)
{
/* save character, in upper case */
sdata[sid++] = toupper(ch) ;
}
else
{
/* terminate line and return error */
failing_line_no++ ;
sdata[sid] = 0 ;
return ERROR_LOAD_LINE_TOO_LONG;
}
/* check until any none space character found */
if ( empty_line )
{
if ( ( ch != SP ) && ( ch != TAB ) && ( ch != CR ) && ( ch != LF ) )
empty_line = FALSE ;
}
}
while( (ch != LF) && (ch != CR) ) ;
/* adjust line counter */
if (ch == LF)
{
if (!line_termination_is_linefeed)
{
/* Toggle termination criteria */
line_termination_is_linefeed = TRUE ;
/* Reset line count */
failing_line_no = 0 ;
}
/* Count line */
failing_line_no++ ;
}
else
{
if (!line_termination_is_linefeed)
{
/* Count line */
failing_line_no++ ;
}
}
}
if (line_termination_is_linefeed)
{
if (ch != LF)
{
failing_line_no_adjust = 1 ;
failing_line_no++ ;
}
else
{
failing_line_no_adjust = 0 ;
}
}
sdata[sid] = 0 ; /* remember to allocate space for the NUL-termination */
sid = 0 ;
return(OK) ;
}
static
INT32 loader_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(loader_error_string)/sizeof(char*) )
{
/* fill in mandatory error message string */
p_param->strings[SYSCON_ERRORMSG_IDX] = loader_error_string[t] ;
i++ ;
/* check for diagnose message */
if ( sdata[0] != 0 )
{
/* fill in optional diagnose message string */
sprintf( loader_diag_msg,"Line %d, %s", failing_line_no, sdata ) ;
p_param->strings[SYSCON_DIAGMSG_IDX] = loader_diag_msg ;
i++ ;
}
/* check for hint message */
if ( loader_error_hint_string[t] != NULL)
{
/* fill in optional hint message string */
p_param->strings[SYSCON_HINTMSG_IDX] = loader_error_hint_string[t] ;
i++ ;
}
}
p_param->count = i ;
/* delete context */
loader_last_error = OK ;
return(OK) ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -