读取十六进制 (Intel) C 中的扩展线性地址记录
Read Extended Linear Address Records in Hex (Intel) C
我有三个 Intel 十六进制行,看起来像这样:
:02 0000 04 FFFF FC // 04 means Extended Linear Address Record
:0B 0010 00 6164647265737320676170 A7 // 00 means Data
:00 0000 01 FF // 01 means EOF
我故意添加了空格以使其更具可读性,但它通常是一个单独的部分。示例和解释来自 Intel HEX Wikipedia page.
我的目的是编写一个函数来提取数据部分,在本例中为 6164647265737320676170
。
到目前为止我是这样想的;首先两个字符,数据大小,会这样使用:
int getSize(char* intelHex)
{
return intelHex[1]*16 + intelHex[2]; // Skip colon and compute only data's size
}
在我的例子中 物理地址 四个字符 部分,第二行是 0010
是已知的,所以我忽略它。在两个字符上指定类型的部分应始终是04
、00
然后是01
,所以我会这样检查:
getline(file, hexLine); // Fill hexLine with first line
if (hexLine[7] != '0' ||hexLine[8] != '4') // First line need "04" as type
puts("Error, Extended Linear Address Record type is expected.\n"); //
else {
// Process first line
}
getline(file, hexLine); // Fill hexLine with second line
if (hexLine[7] != '0' || hexLine[8] != '0') // Second line need "00" as type
puts("Error, Data type is expected.\n");
else {
// Process second line, extract data
// for example
int size = getSize(hexLine);
char data[size];
for (int i = 9; i < 9 + size; i++)
data[i - 9] = hexLine[i]; // Each data part's hexadecimal number is stored
}
getline(file, hexLine); // Fill hexLine with third and last line
if (strcmp(hexLine, ":00000001FF") != 0) // EOF is always the same so we check the whole line instead of just the type
puts("Error, EOF type is expected.\n");
我不明白也无法想象如何计算是第一行的数据部分,这里FFFF
以及如何检查CheckSum部分,也就是最后两个字符.
引自ARM Information Center Hex File Format:
Extended linear address records are also known as 32-bit address records and HEX386 records. These records contain the upper 16 bits (bits 16-31) of the data address. The extended linear address record always has two data bytes.
在我的特定情况下,这部分等于 1FFF
尽管第二行的数据部分完全包含我希望提取的数据。那是什么意思呢?还是我应该忽略它?
至于校验和,再次引用 Intel HEX 维基百科页面:
For example, in the case of the record :0300300002337A1E, the sum of the decoded byte values is 03 + 00 + 30 + 00 + 02 + 33 + 7A = E2. The two's complement of E2 is 1E, which is the checksum byte appearing at the end of the record.
我想我需要一个从E2
中找到1E
的函数,但我不知道怎么写。
关于这些部分的任何提示、新信息或可能的解释,尤其是如何处理它们,将是一种祝福。如果有任何混淆,我很乐意进一步解释自己。
我使用过这样的结构:
struct HexIntel {
size_t m_len;
unsigned char m_addr[8];
unsigned char m_data[255];
unsigned char m_checkSum;
bool m_endOfFile;
bool m_success; // Only set true after checking the EOF, the checksums etc.
};
两个非常有用的枚举来避免幻数:
类型一个
enum HEX_INTEL_TYPE {
DATA = 0, HEX_EOF = 1, EXTENDED_SEGMENT_ADDRESS = 2, START_SEGMENT_ADDRESS = 3,
EXTENDED_LINEAR_ADDRESS = 4, START_LINEAR_ADDRESS = 5
}; // In fact initializing those values is useless since the default values are the same
还有一个来命名选项卡的每个值:
enum HEX_INTEL_RECORD {
LEN_MSB = 0, LEN_LSB = 1, ADDR_MSB = 2, ADDR_MSB2 = 3, ADDR_LSB2 = 4, ADDR_LSB = 5,
TYPE_MSB = 6, TYPE_LSB = 7, DATA_START = 8
};
并且在使用以下函数将每一行解析为一个 int 选项卡之后:
unsigned char hexCharToInt(char c)
{
const unsigned char ERROR = 16;
const int asciiNumberBetweenDigitAndAlpha = 7; // In ASCII, 7 ponctuations marks separate digits from uppercase alphabetical character
if (c > '/' && c < ':') // In ASCII, '0' is after '/' and ':' after '9'
return c - '0'; // In ASCII '0' = 48; '1' = 49..
else if (c > '@' && c < 'G') // In ASCII, 'A' is after '@'
return c - '0' - asciiNumberBetweenDigitAndAlpha;
else
{
fprintf(stderr, "Not hexadecimal character, can't be parsed into a int.\n");
return ERROR;
}
}
我刚刚根据正在阅读的行类型初始化了结构。
检查一行校验和的函数如下:
bool checkSum(const int* hexTab, const size_t sizeOfTab)
{
unsigned char checkSum = 0;
for (size_t i = 0; i + 1 < sizeOfTab - 2; i += 2) // Byte by byte until checksum
{
unsigned char currentByteValue = hexTab[i] * 16 + hexTab[i + 1];
if (currentByteValue + checkSum < 256)
checkSum += currentByteValue;
else
{
while (currentByteValue != 0)
{
if (checkSum == 255)
checkSum = 0;
else
checkSum++;
currentByteValue--;
}
}
}
const unsigned char twoComplement = 256 - checkSum;
const unsigned char tabCheckSum = hexTab[sizeOfTab - 2] * 16 + hexTab[sizeOfTab - 1];
if (twoComplement == tabCheckSum)
return true;
else
return false;
}
我一开始并不打算分享这个,但认为它可以提供帮助。不是完整的解决方案,而是帮助构建解决方案的主要功能。如果可以添加任何改进,请不要犹豫,分享它们。
我有三个 Intel 十六进制行,看起来像这样:
:02 0000 04 FFFF FC // 04 means Extended Linear Address Record
:0B 0010 00 6164647265737320676170 A7 // 00 means Data
:00 0000 01 FF // 01 means EOF
我故意添加了空格以使其更具可读性,但它通常是一个单独的部分。示例和解释来自 Intel HEX Wikipedia page.
我的目的是编写一个函数来提取数据部分,在本例中为 6164647265737320676170
。
到目前为止我是这样想的;首先两个字符,数据大小,会这样使用:
int getSize(char* intelHex)
{
return intelHex[1]*16 + intelHex[2]; // Skip colon and compute only data's size
}
在我的例子中 物理地址 四个字符 部分,第二行是 0010
是已知的,所以我忽略它。在两个字符上指定类型的部分应始终是04
、00
然后是01
,所以我会这样检查:
getline(file, hexLine); // Fill hexLine with first line
if (hexLine[7] != '0' ||hexLine[8] != '4') // First line need "04" as type
puts("Error, Extended Linear Address Record type is expected.\n"); //
else {
// Process first line
}
getline(file, hexLine); // Fill hexLine with second line
if (hexLine[7] != '0' || hexLine[8] != '0') // Second line need "00" as type
puts("Error, Data type is expected.\n");
else {
// Process second line, extract data
// for example
int size = getSize(hexLine);
char data[size];
for (int i = 9; i < 9 + size; i++)
data[i - 9] = hexLine[i]; // Each data part's hexadecimal number is stored
}
getline(file, hexLine); // Fill hexLine with third and last line
if (strcmp(hexLine, ":00000001FF") != 0) // EOF is always the same so we check the whole line instead of just the type
puts("Error, EOF type is expected.\n");
我不明白也无法想象如何计算是第一行的数据部分,这里FFFF
以及如何检查CheckSum部分,也就是最后两个字符.
引自ARM Information Center Hex File Format:
Extended linear address records are also known as 32-bit address records and HEX386 records. These records contain the upper 16 bits (bits 16-31) of the data address. The extended linear address record always has two data bytes.
在我的特定情况下,这部分等于 1FFF
尽管第二行的数据部分完全包含我希望提取的数据。那是什么意思呢?还是我应该忽略它?
至于校验和,再次引用 Intel HEX 维基百科页面:
For example, in the case of the record :0300300002337A1E, the sum of the decoded byte values is 03 + 00 + 30 + 00 + 02 + 33 + 7A = E2. The two's complement of E2 is 1E, which is the checksum byte appearing at the end of the record.
我想我需要一个从E2
中找到1E
的函数,但我不知道怎么写。
关于这些部分的任何提示、新信息或可能的解释,尤其是如何处理它们,将是一种祝福。如果有任何混淆,我很乐意进一步解释自己。
我使用过这样的结构:
struct HexIntel {
size_t m_len;
unsigned char m_addr[8];
unsigned char m_data[255];
unsigned char m_checkSum;
bool m_endOfFile;
bool m_success; // Only set true after checking the EOF, the checksums etc.
};
两个非常有用的枚举来避免幻数:
类型一个
enum HEX_INTEL_TYPE {
DATA = 0, HEX_EOF = 1, EXTENDED_SEGMENT_ADDRESS = 2, START_SEGMENT_ADDRESS = 3,
EXTENDED_LINEAR_ADDRESS = 4, START_LINEAR_ADDRESS = 5
}; // In fact initializing those values is useless since the default values are the same
还有一个来命名选项卡的每个值:
enum HEX_INTEL_RECORD {
LEN_MSB = 0, LEN_LSB = 1, ADDR_MSB = 2, ADDR_MSB2 = 3, ADDR_LSB2 = 4, ADDR_LSB = 5,
TYPE_MSB = 6, TYPE_LSB = 7, DATA_START = 8
};
并且在使用以下函数将每一行解析为一个 int 选项卡之后:
unsigned char hexCharToInt(char c)
{
const unsigned char ERROR = 16;
const int asciiNumberBetweenDigitAndAlpha = 7; // In ASCII, 7 ponctuations marks separate digits from uppercase alphabetical character
if (c > '/' && c < ':') // In ASCII, '0' is after '/' and ':' after '9'
return c - '0'; // In ASCII '0' = 48; '1' = 49..
else if (c > '@' && c < 'G') // In ASCII, 'A' is after '@'
return c - '0' - asciiNumberBetweenDigitAndAlpha;
else
{
fprintf(stderr, "Not hexadecimal character, can't be parsed into a int.\n");
return ERROR;
}
}
我刚刚根据正在阅读的行类型初始化了结构。
检查一行校验和的函数如下:
bool checkSum(const int* hexTab, const size_t sizeOfTab)
{
unsigned char checkSum = 0;
for (size_t i = 0; i + 1 < sizeOfTab - 2; i += 2) // Byte by byte until checksum
{
unsigned char currentByteValue = hexTab[i] * 16 + hexTab[i + 1];
if (currentByteValue + checkSum < 256)
checkSum += currentByteValue;
else
{
while (currentByteValue != 0)
{
if (checkSum == 255)
checkSum = 0;
else
checkSum++;
currentByteValue--;
}
}
}
const unsigned char twoComplement = 256 - checkSum;
const unsigned char tabCheckSum = hexTab[sizeOfTab - 2] * 16 + hexTab[sizeOfTab - 1];
if (twoComplement == tabCheckSum)
return true;
else
return false;
}
我一开始并不打算分享这个,但认为它可以提供帮助。不是完整的解决方案,而是帮助构建解决方案的主要功能。如果可以添加任何改进,请不要犹豫,分享它们。