OpenCores
URL https://opencores.org/ocsvn/light52/light52/trunk

Subversion Repositories light52

[/] [light52/] [trunk/] [tools/] [b51/] [src/] [util/] [ihex.c] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 ja_rd
/*
2
 *  ihex.c
3
 *  Utility functions to create, read, write, and print Intel HEX8 binary records.
4
 *
5
 *  Written by Vanya A. Sergeev <vsergeev@gmail.com>
6
 *  Version 1.0.5 - February 2011
7
 *
8
 */
9
 
10
#include "ihex.h"
11
 
12
/* Initializes a new IHexRecord structure that the paramater ihexRecord points to with the passed
13
 * record type, 16-bit integer address, 8-bit data array, and size of 8-bit data array. */
14
int New_IHexRecord(int type, uint16_t address, const uint8_t *data, int dataLen, IHexRecord *ihexRecord) {
15
        /* Data length size check, assertion of ihexRecord pointer */
16
        if (dataLen < 0 || dataLen > IHEX_MAX_DATA_LEN/2 || ihexRecord == NULL)
17
                return IHEX_ERROR_INVALID_ARGUMENTS;
18
 
19
        ihexRecord->type = type;
20
        ihexRecord->address = address;
21
        memcpy(ihexRecord->data, data, dataLen);
22
        ihexRecord->dataLen = dataLen;
23
        ihexRecord->checksum = Checksum_IHexRecord(ihexRecord);
24
 
25
        return IHEX_OK;
26
}
27
 
28
/* Utility function to read an Intel HEX8 record from a file */
29
int Read_IHexRecord(IHexRecord *ihexRecord, FILE *in) {
30
        char recordBuff[IHEX_RECORD_BUFF_SIZE];
31
        /* A temporary buffer to hold ASCII hex encoded data, set to the maximum length we would ever need */
32
        char hexBuff[IHEX_ADDRESS_LEN+1];
33
        int dataCount, i;
34
 
35
        /* Check our record pointer and file pointer */
36
        if (ihexRecord == NULL || in == NULL)
37
                return IHEX_ERROR_INVALID_ARGUMENTS;
38
 
39
        if (fgets(recordBuff, IHEX_RECORD_BUFF_SIZE, in) == NULL) {
40
                        /* In case we hit EOF, don't report a file error */
41
                        if (feof(in) != 0)
42
                                return IHEX_ERROR_EOF;
43
                        else
44
                                return IHEX_ERROR_FILE;
45
        }
46
        /* Null-terminate the string at the first sign of a \r or \n */
47
        for (i = 0; i < (int)strlen(recordBuff); i++) {
48
                if (recordBuff[i] == '\r' || recordBuff[i] == '\n') {
49
                        recordBuff[i] = 0;
50
                        break;
51
                }
52
        }
53
 
54
 
55
        /* Check if we hit a newline */
56
        if (strlen(recordBuff) == 0)
57
                return IHEX_ERROR_NEWLINE;
58
 
59
        /* Size check for start code, count, addess, and type fields */
60
        if (strlen(recordBuff) < (unsigned int)(1+IHEX_COUNT_LEN+IHEX_ADDRESS_LEN+IHEX_TYPE_LEN))
61
                return IHEX_ERROR_INVALID_RECORD;
62
 
63
        /* Check the for colon start code */
64
        if (recordBuff[IHEX_START_CODE_OFFSET] != IHEX_START_CODE)
65
                return IHEX_ERROR_INVALID_RECORD;
66
 
67
        /* Copy the ASCII hex encoding of the count field into hexBuff, convert it to a usable integer */
68
        strncpy(hexBuff, recordBuff+IHEX_COUNT_OFFSET, IHEX_COUNT_LEN);
69
        hexBuff[IHEX_COUNT_LEN] = 0;
70
        dataCount = strtol(hexBuff, (char **)NULL, 16);
71
 
72
        /* Copy the ASCII hex encoding of the address field into hexBuff, convert it to a usable integer */
73
        strncpy(hexBuff, recordBuff+IHEX_ADDRESS_OFFSET, IHEX_ADDRESS_LEN);
74
        hexBuff[IHEX_ADDRESS_LEN] = 0;
75
        ihexRecord->address = strtol(hexBuff, (char **)NULL, 16);
76
 
77
        /* Copy the ASCII hex encoding of the address field into hexBuff, convert it to a usable integer */
78
        strncpy(hexBuff, recordBuff+IHEX_TYPE_OFFSET, IHEX_TYPE_LEN);
79
        hexBuff[IHEX_TYPE_LEN] = 0;
80
        ihexRecord->type = strtol(hexBuff, (char **)NULL, 16);
81
 
82
        /* Size check for start code, count, address, type, data and checksum fields */
83
        if (strlen(recordBuff) < (unsigned int)(1+IHEX_COUNT_LEN+IHEX_ADDRESS_LEN+IHEX_TYPE_LEN+dataCount*2+IHEX_CHECKSUM_LEN))
84
                return IHEX_ERROR_INVALID_RECORD;
85
 
86
        /* Loop through each ASCII hex byte of the data field, pull it out into hexBuff,
87
         * convert it and store the result in the data buffer of the Intel HEX8 record */
88
        for (i = 0; i < dataCount; i++) {
89
                /* Times two i because every byte is represented by two ASCII hex characters */
90
                strncpy(hexBuff, recordBuff+IHEX_DATA_OFFSET+2*i, IHEX_ASCII_HEX_BYTE_LEN);
91
                hexBuff[IHEX_ASCII_HEX_BYTE_LEN] = 0;
92
                ihexRecord->data[i] = strtol(hexBuff, (char **)NULL, 16);
93
        }
94
        ihexRecord->dataLen = dataCount;
95
 
96
        /* Copy the ASCII hex encoding of the checksum field into hexBuff, convert it to a usable integer */
97
        strncpy(hexBuff, recordBuff+IHEX_DATA_OFFSET+dataCount*2, IHEX_CHECKSUM_LEN);
98
        hexBuff[IHEX_CHECKSUM_LEN] = 0;
99
        ihexRecord->checksum = strtol(hexBuff, (char **)NULL, 16);
100
 
101
        if (ihexRecord->checksum != Checksum_IHexRecord(ihexRecord))
102
                return IHEX_ERROR_INVALID_RECORD;
103
 
104
        return IHEX_OK;
105
}
106
 
107
/* Utility function to write an Intel HEX8 record to a file */
108
int Write_IHexRecord(const IHexRecord *ihexRecord, FILE *out) {
109
        int i;
110
 
111
        /* Check our record pointer and file pointer */
112
        if (ihexRecord == NULL || out == NULL)
113
                return IHEX_ERROR_INVALID_ARGUMENTS;
114
 
115
        /* Check that the data length is in range */
116
        if (ihexRecord->dataLen > IHEX_MAX_DATA_LEN/2)
117
                return IHEX_ERROR_INVALID_RECORD;
118
 
119
        /* Write the start code, data count, address, and type fields */
120
        if (fprintf(out, "%c%2.2X%2.4X%2.2X", IHEX_START_CODE, ihexRecord->dataLen, ihexRecord->address, ihexRecord->type) < 0)
121
                return IHEX_ERROR_FILE;
122
 
123
        /* Write the data bytes */
124
        for (i = 0; i < ihexRecord->dataLen; i++) {
125
                if (fprintf(out, "%2.2X", ihexRecord->data[i]) < 0)
126
                        return IHEX_ERROR_FILE;
127
        }
128
 
129
        /* Calculate and write the checksum field */
130
        if (fprintf(out, "%2.2X\r\n", Checksum_IHexRecord(ihexRecord)) < 0)
131
                return IHEX_ERROR_FILE;
132
 
133
        return IHEX_OK;
134
}
135
 
136
/* Utility function to print the information stored in an Intel HEX8 record */
137
void Print_IHexRecord(const IHexRecord *ihexRecord) {
138
        int i;
139
        printf("Intel HEX8 Record Type: \t%d\n", ihexRecord->type);
140
        printf("Intel HEX8 Record Address: \t0x%2.4X\n", ihexRecord->address);
141
        printf("Intel HEX8 Record Data: \t{");
142
        for (i = 0; i < ihexRecord->dataLen; i++) {
143
                if (i+1 < ihexRecord->dataLen)
144
                        printf("0x%02X, ", ihexRecord->data[i]);
145
                else
146
                        printf("0x%02X", ihexRecord->data[i]);
147
        }
148
        printf("}\n");
149
        printf("Intel HEX8 Record Checksum: \t0x%2.2X\n", ihexRecord->checksum);
150
}
151
 
152
/* Utility function to calculate the checksum of an Intel HEX8 record */
153
uint8_t Checksum_IHexRecord(const IHexRecord *ihexRecord) {
154
        uint8_t checksum;
155
        int i;
156
 
157
        /* Add the data count, type, address, and data bytes together */
158
        checksum = ihexRecord->dataLen;
159
        checksum += ihexRecord->type;
160
        checksum += (uint8_t)ihexRecord->address;
161
        checksum += (uint8_t)((ihexRecord->address & 0xFF00)>>8);
162
        for (i = 0; i < ihexRecord->dataLen; i++)
163
                checksum += ihexRecord->data[i];
164
 
165
        /* Two's complement on checksum */
166
        checksum = ~checksum + 1;
167
 
168
        return checksum;
169
}
170
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.