Это "выдержка" из работающей программы
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)

миниатюрный аудио-видеорекордер mAVR

Отправлено Сидоргек 15 марта 2004 г. 13:59
В ответ на: Всезнающие!!! подскажите плиз, как распаковывать INTEL . HEX файл, может кто в с ети находил отправлено Degrees 15 марта 2004 г. 13:49

// Загрузка из HEX - файла
// Интерпретирую HEX, как массив байт
// Использовал текст из: hex2bin converts an Intel hex file to binary.
// Copyright (C) 1998,1999 Jacques Pelletier
bool CProgFile::LoadHex(void)
{
/* line inputted from file */
char Line[MAX_LINE_SIZE];

/* flag that a file was read */
boolean Fileread;
boolean Enable_Checksum_Error = FALSE;
boolean Status_Checksum_Error = FALSE;

/* cmd-line parameter # */
char /**c,*/*p;

unsigned int Param;
unsigned int i;

/* Application specific */

unsigned int Nb_Bytes;
unsigned int First_Word, Address, Segment, Upper_Address;
unsigned int Lowest_Address, Highest_Address, Starting_Address = 0;
unsigned int Phys_Addr, Type;
unsigned int temp;

/* We will assume that when one type of addressing is selected, it will be valid for all the
current file. Records for the other type will be ignored. */
unsigned int Seg_Lin_Select = NO_ADDRESS_TYPE_SELECTED;

boolean Starting_Address_Setted = FALSE;

int temp2;

byte Data_Str[MAX_LINE_SIZE];
byte Checksum;

/* This will hold binary codes translated from hex file. */
// byte *Memory_Block;

// fprintf (stdout,"hex2bin v1.0.1, Copyright (C) 1999 Jacques Pelletier\n");

// if (argc == 1)
// usage();

// strcpy(Extension, "bin"); /* default is for binary file extension */

/* read file */
Param = 1;

/*
for (Param = 1; Param < argc; Param++)
{
c = p = argv[Param];
#ifdef __linux__
// We don't accept an option beginning with a '/' because it could be a file name.
if(*c == '-')
#else
if((*c == '-') || (*c == '/'))
#endif
{
p = c + 2;
// Parameter may follow immediately after option
// Skips after parameter to next option
if (*p == '\0')
p = argv[++Param];

switch(tolower (*(++c)))
{
case 'e':
// Last parameter was -E, so this parameter is the filename extension.
if (strlen(p) > MAX_EXTENSION_SIZE)
usage();

// Check to see if the user put a period in the filename extension
if (strchr(p, '.') == NULL)
strcpy(Extension, p);
else
strcpy(Extension, p+1);
break;

case 'c':
Enable_Checksum_Error = TRUE;
break;
case 's':
sscanf(p,"%x",&Starting_Address);
Starting_Address_Setted = TRUE;
break;
case 'h':
usage();
break;
default:
usage();
} // switch
} else
break;
// if option

} // for Param
*/
/* when user enters input file name */

/* Assume last parameter is filename */
// strcpy(Filename,argv[argc -1]);

/* Just a normal file name */
// NoFailOpenInputFile (Filename);
// PutExtension(Filename, Extension);
// NoFailOpenOutputFile(Filename);
Fileread = TRUE;

/* allocate a buffer */
// Memory_Block = (byte *) malloc(MEMORY_SIZE);

/* For EPROM or FLASH memory types, fill unused bytes with FF */
// memset (Memory_Block,0xFF,MEMORY_SIZE);

/* To begin, assume the lowest address is at the end of the memory.
subsequent addresses will lower this number. At the end of the input
file, this value will be the lowest address. */
Segment = 0;
Upper_Address = 0;
Lowest_Address = MEMORY_SIZE - 1;
Highest_Address = 0;

/* Now read the file & process the lines. */
do /* repeat until EOF(Filin) */
{
/* Read a line from input file. */
//fgets(Line,MAX_LINE_SIZE,Filin);
ReadString(Line, MAX_LINE_SIZE);

/* Remove carriage return/line feed at the end of line. */
i = (unsigned int)strlen(Line)-1;

if (Line[i] == '\n') Line[i] = '\0';

/* Scan the first two bytes and nb of bytes.
The two bytes are read in First_Word since it's use depend on the
record type: if it's an extended address record or a data record.
*/
sscanf (Line, ":%2x%4x%2x%s",&Nb_Bytes,&First_Word,&Type,Data_Str);

Checksum = Nb_Bytes + (First_Word >> 8) + (First_Word & 0xFF) + Type;

p = (char *)Data_Str;

/* If we're reading the last record, ignore it. */
switch (Type)
{
/* Data record */
case 0:
Address = First_Word;

if (Seg_Lin_Select == SEGMENTED_ADDRESS)
Phys_Addr = ((Segment << 4) & ADDRESS_MASK) + Address;
else
/* LINEAR_ADDRESS or NO_ADDRESS_TYPE_SELECTED
Upper_Address = 0 as specified in the Intel spec. until an extended address
record is read. */
Phys_Addr = ((Upper_Address << 16) & ADDRESS_MASK) + Address;

/* Check that the physical address stays in the buffer's range. */
if ((Phys_Addr + Nb_Bytes) <= MEMORY_SIZE -1)
{
/* Set the lowest address as base pointer. */
if (Phys_Addr < Lowest_Address)
Lowest_Address = Phys_Addr;

/* Same for the top address. */
temp = Phys_Addr + Nb_Bytes -1;

if (temp > Highest_Address)
Highest_Address = temp;

/* Read the Data bytes. */
/* Bytes are written in the Memory block even if checksum is wrong. */
for (i= Nb_Bytes; i > 0; i--)
{
sscanf (p, "%2x",&temp2);
p += 2;

CPrgAddr pa;
pa.a = Phys_Addr;
pa.d = temp2;
m_Data.Add(pa);

/*Memory_Block[*/Phys_Addr++/*] = temp2*/;
Checksum = (Checksum + temp2) & 0xFF;
};

/* Read the Checksum value. */
sscanf (p, "%2x",&temp2);

/* Verify Checksum value. */
Checksum = (Checksum + temp2) & 0xFF;

if ((Checksum != 0) && Enable_Checksum_Error)
{
Status_Checksum_Error = TRUE;
}
}
else
{
if (Seg_Lin_Select == SEGMENTED_ADDRESS)
TRACE("Data record skipped at %4X:%4X\n",Segment,Address);
else
TRACE("Data record skipped at %8X\n",Phys_Addr);
}

break;

/* End of file record */
case 1:
/* Simply ignore checksum errors in this line. */
break;

/* Extended segment address record */
case 2:
/* First_Word contains the offset. It's supposed to be 0000 so
we ignore it. */

/* First extended segment address record ? */
if (Seg_Lin_Select == NO_ADDRESS_TYPE_SELECTED)
Seg_Lin_Select = SEGMENTED_ADDRESS;

/* Then ignore subsequent extended linear address records */
if (Seg_Lin_Select == SEGMENTED_ADDRESS)
{
sscanf (p, "%4x%2x",&Segment,&temp2);

/* Update the current address. */
Phys_Addr = (Segment << 4) & ADDRESS_MASK;

/* Verify Checksum value. */
Checksum = (Checksum + (Segment >> 8) + (Segment & 0xFF) + temp2) & 0xFF;

if ((Checksum != 0) && Enable_Checksum_Error)
Status_Checksum_Error = TRUE;
}
break;

/* Start segment address record */
case 3:
/* Nothing to be done since it's for specifying the starting address for
execution of the binary code */
break;

/* Extended linear address record */
case 4:
/* First_Word contains the offset. It's supposed to be 0000 so
we ignore it. */

/* First extended linear address record ? */
if (Seg_Lin_Select == NO_ADDRESS_TYPE_SELECTED)
Seg_Lin_Select = LINEAR_ADDRESS;

/* Then ignore subsequent extended segment address records */
if (Seg_Lin_Select == LINEAR_ADDRESS)
{
sscanf (p, "%4x%2x",&Upper_Address,&temp2);

/* Update the current address. */
Phys_Addr = (Upper_Address << 16) & ADDRESS_MASK;

/* Verify Checksum value. */
Checksum = (Checksum + (Upper_Address >> 8) + (Upper_Address & 0xFF) + temp2)
& 0xFF;

if ((Checksum != 0) && Enable_Checksum_Error)
Status_Checksum_Error = TRUE;
}
break;

/* Start linear address record */
case 5:
/* Nothing to be done since it's for specifying the starting address for
execution of the binary code */
break;
default:
break;
}
}
while (GetPosition() < GetLength() - 1);
/*-----------------------------------------------------------------------------*/

TRACE("Lowest address = %08X\n",Lowest_Address);
TRACE("Highest address = %08X\n",Highest_Address);

/* This starting address is for the binary file,

ex.: if the first record is :nn010000ddddd...
the data supposed to be stored at 0100 will start at 0000 in the binary file.

Specifying this starting address will put FF bytes in the binary file so that
the data supposed to be stored at 0100 will start at the same address in the
binary file.
*/

if(Starting_Address_Setted)
{
Lowest_Address = Starting_Address;
}

/* write binary file */
// fwrite (&Memory_Block[Lowest_Address],
// 1,
// Highest_Address - Lowest_Address +1,
// Filout);

// free (Memory_Block);

//#ifdef USE_FILE_BUFFERS
// free (FilinBuf);
// free (FiloutBuf);
//#endif

// fclose (Filin);
// fclose (Filout);

if (Status_Checksum_Error & Enable_Checksum_Error)
{
TRACE("Checksum error detected.\n");
return false;
}

// if (!Fileread)
// usage();
return true;
}

Составить ответ  |||  Конференция  |||  Архив

Ответы



Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание  |||  Без кадра

E-mail: info@telesys.ru