Skip to content

Commit db62fc0

Browse files
committed
Don't load A2L file into memory to provide it for upload
1 parent aee89e5 commit db62fc0

File tree

4 files changed

+48
-76
lines changed

4 files changed

+48
-76
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,7 @@ cargo.lock
2626
*.a2h
2727
*.bin
2828
/tmp.a2l
29+
/a2lfile.a2l
30+
/a2lfile.txt
31+
/test.a2l
32+
/xcp_lite.a2l

tests/multi_thread.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ async fn test_multi_thread() {
212212
}
213213

214214
thread::sleep(Duration::from_millis(250)); // Wait to give all threads a chance to initialize and enter their loop
215-
test_executor(xcp, test_executor::TestMode::MultiThreadDAQ, "test_multi_thread.a2l", false).await; // Start the test executor XCP client
215+
test_executor(xcp, test_executor::TestMode::MultiThreadDAQ, "test_multi_thread.a2l", true).await; // Start the test executor XCP client
216216

217217
info!("Test done. Waiting for tasks to terminate");
218218
for t in v {

tests/tokio_multi_thread.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ async fn test_tokio_multi_thread() {
185185
v.push(t);
186186
}
187187

188-
test_executor(xcp, test_executor::TestMode::MultiThreadDAQ, "test_tokio_multi_thread.a2l", false).await; // Start the test executor XCP client
188+
test_executor(xcp, test_executor::TestMode::MultiThreadDAQ, "test_tokio_multi_thread.a2l", true).await; // Start the test executor XCP client
189189

190190
for t in v {
191191
t.join().ok();

xcplib/xcpAppl.c

+42-74
Original file line numberDiff line numberDiff line change
@@ -386,99 +386,63 @@ uint8_t ApplXcpGetCalPageMode(uint8_t segment) {
386386
#endif
387387

388388
/**************************************************************************/
389-
// Provide infos for GET_ID
390-
// The XCP command GET_ID provides different type of identification
391-
// information to the XCP client
392-
// Returns 0, when the information is not available
389+
// Functions for upload of A2L file
393390
/**************************************************************************/
394391

395-
static const char *gXcpA2lName = NULL; // A2L filename
392+
static const char *gXcpA2lName = NULL; // A2L filename (without extension .a2l)
396393

397-
// This is used by the Rust ffi bindings only
394+
// This is used by the Rust ffi to set the A2L name generated by the registry
398395
void ApplXcpSetA2lName(const char *name) {
399396
DBG_PRINTF3("Set A2L name to '%s'\n", name);
400397
gXcpA2lName = (char*)name; // must be static lifetime
401398
}
402399

403400
#ifdef XCP_ENABLE_IDT_A2L_UPLOAD // Enable GET_ID A2L content upload to host
404401

405-
static uint8_t* gXcpFile = NULL; // A2l file content
402+
static FILE* gXcpFile = NULL; // A2l file content
406403
static uint32_t gXcpFileLength = 0; // A2L file length
407404

408-
BOOL ApplXcpReadA2L(uint8_t size, uint32_t addr, uint8_t* data) {
409-
if (addr + size > gXcpFileLength) return FALSE;
410-
memcpy(data, gXcpFile + addr, size);
411-
return TRUE;
412-
}
413-
414-
// @@@@ ToDo: Implement a way to release the file memory after upload
415-
/*
416-
static void releaseFile(uint8_t* file) {
417405

418-
if (file != NULL) {
419-
free(file);
420-
}
406+
void closeA2lFile() {
407+
assert(gXcpFile != NULL);
408+
fclose(gXcpFile);
409+
gXcpFile = NULL;
410+
DBG_PRINT3("Close A2L file\n");
421411
}
422-
*/
423-
424-
static uint8_t* loadFile(const char* filename, uint32_t* length) {
425-
426-
uint8_t* fileBuf = NULL; // file content
427-
uint32_t fileLen = 0; // file length
428-
429-
DBG_PRINTF3("Load A2L file %s to memory buffer\n", filename);
430-
431-
#if defined(_LINUX) // Linux
432-
433-
FILE* fd;
434-
fd = fopen(filename, "r");
435-
if (fd == NULL) {
436-
DBG_PRINTF_ERROR("ERROR: file %s not found!\n", filename);
437-
return NULL;
438-
}
439-
struct stat fdstat;
440-
stat(filename, &fdstat);
441-
fileBuf = (uint8_t*)malloc((size_t)(fdstat.st_size + 1));
442-
if (fileBuf == NULL) return NULL;
443-
fileLen = (uint32_t)fread(fileBuf, 1, (uint32_t)fdstat.st_size, fd);
444-
fclose(fd);
445-
446-
#elif defined(_WIN) // Windows
447-
448-
wchar_t wcfilename[256] = { 0 };
449-
MultiByteToWideChar(0, 0, filename, (int)strlen(filename), wcfilename, (int)strlen(filename));
450-
HANDLE hFile = CreateFileW((wchar_t*)wcfilename, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
451-
if (hFile == INVALID_HANDLE_VALUE) {
452-
DBG_PRINTF_ERROR("ERROR: file %s not found!\n", filename);
453-
return NULL;
454-
}
455-
fileLen = (uint32_t)GetFileSize(hFile, NULL);
456-
fileBuf = (uint8_t*)malloc(fileLen + 1);
457-
if (fileBuf == NULL) {
458-
DBG_PRINTF_ERROR("ERROR: out of memory!\n");
459-
CloseHandle(hFile);
460-
return NULL;
461-
}
462-
if (!ReadFile(hFile, fileBuf, fileLen, NULL, NULL)) {
463-
DBG_PRINTF_ERROR("ERROR: could not read from %s!\n", filename);
464-
free(fileBuf);
465-
CloseHandle(hFile);
466-
return NULL;
467-
}
468-
fileBuf[fileLen] = 0;
469-
CloseHandle(hFile);
470-
471-
#endif
472412

473-
DBG_PRINTF3(" file %s ready for upload, size=%u\n\n", filename, fileLen);
474-
assert(fileLen > 0);
413+
uint32_t openA2lFile() {
414+
char filename[256];
415+
SNPRINTF((char*)filename, 255, "%s.a2l", gXcpA2lName);
416+
assert(gXcpFile == NULL);
417+
gXcpFile = fopen(filename, "r");
418+
if (gXcpFile == NULL) {
419+
DBG_PRINTF_ERROR("ERROR: file %s not found!\n", filename);
420+
return 0;
421+
}
422+
struct stat fdstat;
423+
stat(filename, &fdstat);
424+
gXcpFileLength = (uint32_t)fdstat.st_size;
425+
assert(gXcpFileLength > 0);
426+
DBG_PRINTF3("A2L file %s ready for upload, size=%u\n\n", filename, gXcpFileLength);
427+
return gXcpFileLength;
428+
}
475429

476-
*length = fileLen;
477-
return fileBuf;
430+
BOOL ApplXcpReadA2L(uint8_t size, uint32_t addr, uint8_t* data) {
431+
if (gXcpFile == NULL) return FALSE;
432+
if (addr + size > gXcpFileLength) return FALSE;
433+
if (size!=fread(data, 1, (uint32_t)size, gXcpFile)) return FALSE;
434+
if (addr + size == gXcpFileLength) closeA2lFile(); // Close file after complete sequential read
435+
return TRUE;
478436
}
479437

480-
#endif
438+
#endif // XCP_ENABLE_IDT_A2L_UPLOAD
481439

440+
/**************************************************************************/
441+
// Provide infos for GET_ID
442+
// The XCP command GET_ID provides different type of identification
443+
// information to the XCP client
444+
// Returns 0, when the information is not available
445+
/**************************************************************************/
482446

483447
uint32_t ApplXcpGetId(uint8_t id, uint8_t* buf, uint32_t bufLen) {
484448

@@ -511,10 +475,14 @@ uint32_t ApplXcpGetId(uint8_t id, uint8_t* buf, uint32_t bufLen) {
511475
#ifdef XCP_ENABLE_IDT_A2L_UPLOAD
512476
case IDT_ASAM_UPLOAD:
513477
{
478+
#ifdef XCP_LOAD_A2L_FILE
514479
char filename[256];
515480
SNPRINTF((char*)filename, 255, "%s.a2l", gXcpA2lName);
516481
if (NULL==(gXcpFile=loadFile(filename,&gXcpFileLength))) return 0;
517482
len = gXcpFileLength;
483+
#else
484+
len = openA2lFile();
485+
#endif
518486
}
519487
break;
520488
#endif

0 commit comments

Comments
 (0)