-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPreprocess_Flash_file.cin
More file actions
252 lines (218 loc) · 6.79 KB
/
Copy pathPreprocess_Flash_file.cin
File metadata and controls
252 lines (218 loc) · 6.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
/*@!Encoding:1252*/
int HexCharToInt(char c)
{
if (c >= '0' && c <= '9') return c - '0';
if (c >= 'A' && c <= 'F') return c - 'A' + 10;
if (c >= 'a' && c <= 'f') return c - 'a' + 10;
return 0;
}
byte ParseHexByte(char str[], int startIndex)
{
return (byte)((HexCharToInt(str[startIndex]) * 16) + HexCharToInt(str[startIndex + 1]));
}
int PreProcessS19ToBin(char filename[])
{
dword inFileHandle;
dword outFileHandle;
char line[1024];
byte lineDataBuffer[512];
int byteCount, dataBytesCount, i;
int ret_status = 0;
totalBytesExtracted = 0;
inFileHandle = openFileRead(filename, 0);
outFileHandle = openFileWrite("payload.bin", 1);
if (inFileHandle != 0 && outFileHandle != 0)
{
testStep("Flash File", "Pre-processing S19 file... please wait.");
while (fileGetString(line, elCount(line), inFileHandle) == 1)
{
// Process only S3 Data Records
if (line[0] == 'S' && line[1] == '3')
{
byteCount = ParseHexByte(line, 2);
// Subtract 4 bytes for the address and 1 byte for the checksum
dataBytesCount = byteCount - 5;
// Extract pure data into our temporary line buffer
for (i = 0; i < dataBytesCount; i++)
{
// S3 payload starts at index 12
lineDataBuffer[i] = ParseHexByte(line, 12 + (i * 2));
}
// Instantly dump this line's data into the binary file
fileWriteBinaryBlock(lineDataBuffer, dataBytesCount, outFileHandle);
totalBytesExtracted += dataBytesCount;
}
}
fileClose(inFileHandle);
fileClose(outFileHandle);
ret_status = 1;
testStep("Flash File", "Pre-processing complete. Extracted %d pure data bytes.", totalBytesExtracted);
}
else
{
testStepWarning("Error", "Could not open input or output file for pre-processing.");
}
return ret_status;
}
int PreProcessHexToBin(char filename[])
{
dword inFileHandle;
dword outFileHandle;
char line[1024];
byte lineDataBuffer[512];
int byteCount, recordType, i;
int ret_status = 0;
totalBytesExtracted = 0;
inFileHandle = openFileRead(filename, 0);
outFileHandle = openFileWrite("payload.bin", 1);
if (inFileHandle != 0 && outFileHandle != 0)
{
testStep("Flash File", "Pre-processing Intel HEX file... please wait.");
while (fileGetString(line, elCount(line), inFileHandle) == 1)
{
// Every valid Intel HEX line starts with a colon
if (line[0] == ':')
{
// 1. Extract Byte Count (at index 1 and 2)
byteCount = ParseHexByte(line, 1);
// 2. Extract Record Type (at index 7 and 8)
recordType = ParseHexByte(line, 7);
// 3. Process only Data Records (Type 00)
if (recordType == 0)
{
// Extract pure data into our temporary line buffer
for (i = 0; i < byteCount; i++)
{
// Data payload in Intel HEX starts at index 9
lineDataBuffer[i] = ParseHexByte(line, 9 + (i * 2));
}
// Instantly dump this line's data into the binary file
fileWriteBinaryBlock(lineDataBuffer, byteCount, outFileHandle);
totalBytesExtracted += byteCount;
}
// 4. Stop reading if we hit the End of File Record (Type 01)
else if (recordType == 1)
{
break;
}
}
}
fileClose(inFileHandle);
fileClose(outFileHandle);
ret_status = 1;
testStep("Flash File", "Pre-processing complete. Extracted %d pure data bytes.", totalBytesExtracted);
}
else
{
testStepWarning("Error", "Could not open input or output file for pre-processing.");
}
return ret_status;
}
int PreProcessFirmwareFile(char filename[])
{
dword fileHandle;
char firstLine[256];
int ret_status = 0;
// Open the file in ASCII mode (0)
fileHandle = openFileRead(filename, 0);
if (fileHandle != 0)
{
// Read first line
if (fileGetString(firstLine, elCount(firstLine), fileHandle) == 1)
{
fileClose(fileHandle); // Close it immediately, the sub-functions will re-open it
// Auto-Detect Logic
if (firstLine[0] == 'S')
{
testStep("Flash File type", "Detected Motorola S-Record format.");
ret_status = PreProcessS19ToBin(filename);
}
else if (firstLine[0] == ':')
{
testStep("Flash File type", "Detected Intel HEX format.");
ret_status = PreProcessHexToBin(filename);
}
else
{
testStepWarning("Error", "Unknown file format. The file must start with 'S' or ':'.");
}
}
else
{
testStepWarning("Error", "The file is empty.");
fileClose(fileHandle);
}
}
else
{
testStepWarning("Error", "Could not open file %s. Check the path.", filename);
}
return ret_status;
}
int StartTransferData()
{
int transferResult = 0;
binaryFileHandle = openFileRead("payload.bin", 1);
if (binaryFileHandle != 0)
{
testStep("Transfer DATA", "Starting 0x36 Data Transfer stream...");
flashState = STATE_TRANSFER_DATA;
blockSequenceCounter = 1;
// Call the newly refactored loop
transferResult = SendAllDataBlocks();
}
else
{
testStepFail("Binary File Processing", "Payload.bin not found!");
}
return transferResult;
}
int SendAllDataBlocks()
{
byte fileDataBuffer[4096];
byte diag_request_byte[4096];
dword bytesRead = 0;
int i;
int total_bytes;
int ret_status = 1;
// The loop runs continuously as long as there is data left in the file
while ((bytesRead = fileGetBinaryBlock(fileDataBuffer, maxDataBytesPerBlock, binaryFileHandle)) > 0)
{
total_bytes = bytesRead + 2;
// Construct the UDS 0x36 message
diag_request_byte[0] = 0x36;
diag_request_byte[1] = blockSequenceCounter;
for (i = 0; i < bytesRead; i++)
{
diag_request_byte[i + 2] = fileDataBuffer[i];
}
// Send to ECU
ret_status = DiagRequest_via_bytes_WithFixedLengthReturnType(diag_request_obj, diag_request_byte, total_bytes);
if(1 == ret_status)
{
testStep("Transfer data", "Sent block 0x%02X (%d bytes of data)", blockSequenceCounter, bytesRead);
// Handle the counter rollover
if (blockSequenceCounter == 0xFF)
{
blockSequenceCounter = 0x00;
}
else
{
blockSequenceCounter++;
}
}
else
{
testStepFail("Transfer data", "Failed to send block 0x%02X. ECU rejected the request.", blockSequenceCounter);
break; // Exit the loop immediately if a block fails
}
}
// Cleanup after the loop finishes (either successfully or via error break)
if (bytesRead == 0 && ret_status == 1)
{
testStep("Transfer data Status", "End of file reached. Transitioning to 0x37 Request Transfer Exit.");
}
fileClose(binaryFileHandle);
flashState = STATE_IDLE;
return ret_status;
}