Chinaunix首页 | 论坛 | 博客
  • 博客访问: 92550
  • 博文数量: 34
  • 博客积分: 1410
  • 博客等级: 上尉
  • 技术积分: 275
  • 用 户 组: 普通用户
  • 注册时间: 2007-10-13 23:05
文章分类

全部博文(34)

文章存档

2011年(1)

2010年(7)

2009年(26)

我的朋友

分类: 嵌入式

2010-03-13 11:13:12

Hex文件格式分析
    嵌入式里面最后生成的文件最多的就是Hex文件, 由intel定义, 现在广泛使用在编程器,调试器, 用于向系统的存储写入。
   
文件:Hexfrmt.pdf
大小:18KB
下载:下载

    根据这个文件和网上的说明, 做了一个hex文件查看器。 暂时还没有做地址识别。 效率太低了现在。

viewhex.c


#include <stdio.h>
#include "hex.h"
#include "mylibc.h"


void usage()
{
    printf("viewhex: a tool to view the intel hex format file\n");
    printf("usage: viewhex filename.hex\n");
    printf("where the filename.hex is the hex file you want to view\n");
}
void printData(char* line, int lineLength)
{
    int iCount = 0;
    for(iCount = 9; iCount < lineLength-2; iCount++)
        putchar(line[iCount]);
    printf("; Dec = %d", ahex2int(line+9, 8) );
}
int main(int argc, char* argv[])
{
    unsigned char line[MAX_LINE_LENGTH];
    FILE* fp;
    int retLength = 0;
    int lineNumber = 0;

    if(2 != argc) {
        usage();
        return -1;
    }

    fp = fopen(argv[1], "r");
    if(NULL == fp) {
        printf("fail open file %s", argv[1]);
        return -1;
    }
    lineNumber = 0;
    while((retLength = fgetline(fp, line, MAX_LINE_LENGTH)) > 0 ) {
        lineNumber++;
        if( retLength == 1 ) {
            printf("Line:%d empty\n", lineNumber);
            continue;
        }
        if( retLength < 12 ) {
            printf("error record length %d at line %d\n", retLength, lineNumber);
            continue;
        }
            
        if( checkValidHexRecord(line, retLength - 1) ) {
            switch( getRecordType(line, retLength - 1) ) {
            case 0:
                printf("Line:%d Type: Data, DataLen = %d, Data = ",lineNumber, ahex2int(line+1, 2));
                printData(line, retLength-1);
                printf("\n");
                break;
            case 1:
                printf("Line:%d Type: End, End of File Record\n", lineNumber);
                break;
            case 2:
                printf("Line:%d Type: Extended Segment Address, USBA = 0x", lineNumber);
                printData(line, retLength-1);
                printf("\n");
                break;
            case 3:
                printf("Line:%d Type: Start Segment Address , CS/IP = 0x", lineNumber);
                printData(line, retLength-1);
                printf("\n");
                break;
            case 4:
                printf("Line:%d Type: Extended Linear Address , ULBA = 0x", lineNumber);
                printData(line, retLength-1);
                printf("\n");
                break;
            case 5:
                printf("Line:%d Type: Start Linear Address , EIP = 0x", lineNumber);
                printData(line, retLength-1);
                printf("\n");
                break;
            default:
                printf("error record Type at line %d\n", lineNumber);
                break;
            }
        }
        else
            printf("not valid record at line %d\n", lineNumber);
    }
    if(retLength < 0)
        printf("Too long at line: %d\n", lineNumber);
    fclose(fp);
    return 0;
}


mylib.c

#include "mylibc.h"
//return the number of ansii code from fp to the end of the line

//return 0: eof

//         -1: too long

//         positive: the length including the '\n' char

int fgetline(FILE* fp, char* line, int maxLength)
{
    int iCount = 0;
    char c = 0;
    while( EOF != (c = fgetc(fp)) ) {
        #ifdef __GNU_C //skip the nonsense char '\r' in __GNU_C

        if( '\r' == c )
            continue;
        #endif
        iCount++;
        *line++ = c;
        if('\n' == c)
        {
            return iCount;
        }
        if( iCount >= maxLength )
            return -1;
    }
    return iCount;
}

mylib.h


#ifndef __MYLIBC_H
#define __MYLIBC_H

int fgetline(FILE* fp, char* line, int maxLength);

#endif

hex.h


#ifndef __HEX_H
#define __HEX_H

#include "defs.h"

#define FILENAME_LEN 100
#define MAX_LINE_LENGTH 1+2+4+2+255*2+2 // ==521

#define MIN_LINE_LENGTH 1+2+4+2+2     // ==11



//function convert ANSII Hex to interger

// make sure byte[0--bytesNum-1] is between '0'--'9' or 'A'--'F'

// using checkContent()

// case sensitive

unsigned int ahex2int(char* bytes, int bytesNum)
{
    int retVal = 0;
    int iCount = 0;
    if(bytesNum <= 0)
        return -1;
    while( bytesNum --)    {
        retVal <<= 4;
        if(bytes[iCount] >= 'A' && bytes[iCount] <= 'F')
            retVal += bytes[iCount] - 'A' + 10;
        if(bytes[iCount] >= '0' && bytes[iCount] <= '9')
            retVal += bytes[iCount] - '0';
        iCount++;
    }
    return retVal;
}


int inline getRecordType(char* line, int lineLength)
{
    return ahex2int(line+7, 2);
}

bool checkContent(char* line, int lineLength)
{
    int iCount = 0;
    if(line[0] != ':')
        return false;
    for(iCount = 1; iCount <lineLength; iCount++) {
        if( (line[iCount] < '0') ||
            ( (line[iCount] > '9' ) && (line[iCount] < 'A') ) ||
            (line[iCount] > 'F') )
            return false;
    }
    return true;
}
bool inline checkLength(char* line,unsigned int lineLength)
{
    return ( (2 * ahex2int(line+1, 2) + 1 + 2 + 4 + 2 + 2) == lineLength );
}
bool inline checkType(char* line, int lineLength)
{
    return ( ahex2int(line+7, 2) <= 6 ) && ( ahex2int(line+7, 2) >= 0 );
}
bool inline checkNonDataType(char* line, int lineLength)
{
    if(ahex2int(line+7, 2) != 0) {
        if( ahex2int(line+3, 4) == 0 )
            return true;
        else
            return false;
    }
    return true;
}
bool inline checkSum(char* line, int lineLength)
{
    int iCount = 0;
    int checksum = 0;
    for(iCount = 1; iCount <lineLength; iCount+=2)
        checksum += ahex2int(line+iCount, 2);
    if((checksum %256) != 0)
        return false;
    return true;
}
bool checkValidHexRecord(char* line, int lineLength)
{
    if( !checkContent(line, lineLength) )
        return false;
    if( !checkLength(line, lineLength) )
        return false;
    if( !checkType(line, lineLength) )
        return false;
    if( !checkNonDataType(line, lineLength) )
        return false;
    if( !checkSum(line, lineLength) )
        return false;
    return true;
}


#endif

defs.h


#ifndef __DEFS_H
#define __DEFS_H

typedef int bool;
#define true 1
#define false 0
#define inline __inline

#endif


阅读(1689) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~