Skip to content

Commit

Permalink
Don't load A2L file into memory to provide it for upload
Browse files Browse the repository at this point in the history
  • Loading branch information
RainerZ committed Sep 27, 2024
1 parent aee89e5 commit db62fc0
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 76 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,7 @@ cargo.lock
*.a2h
*.bin
/tmp.a2l
/a2lfile.a2l
/a2lfile.txt
/test.a2l
/xcp_lite.a2l
2 changes: 1 addition & 1 deletion tests/multi_thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ async fn test_multi_thread() {
}

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

info!("Test done. Waiting for tasks to terminate");
for t in v {
Expand Down
2 changes: 1 addition & 1 deletion tests/tokio_multi_thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ async fn test_tokio_multi_thread() {
v.push(t);
}

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

for t in v {
t.join().ok();
Expand Down
116 changes: 42 additions & 74 deletions xcplib/xcpAppl.c
Original file line number Diff line number Diff line change
Expand Up @@ -386,99 +386,63 @@ uint8_t ApplXcpGetCalPageMode(uint8_t segment) {
#endif

/**************************************************************************/
// Provide infos for GET_ID
// The XCP command GET_ID provides different type of identification
// information to the XCP client
// Returns 0, when the information is not available
// Functions for upload of A2L file
/**************************************************************************/

static const char *gXcpA2lName = NULL; // A2L filename
static const char *gXcpA2lName = NULL; // A2L filename (without extension .a2l)

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

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

static uint8_t* gXcpFile = NULL; // A2l file content
static FILE* gXcpFile = NULL; // A2l file content
static uint32_t gXcpFileLength = 0; // A2L file length

BOOL ApplXcpReadA2L(uint8_t size, uint32_t addr, uint8_t* data) {
if (addr + size > gXcpFileLength) return FALSE;
memcpy(data, gXcpFile + addr, size);
return TRUE;
}

// @@@@ ToDo: Implement a way to release the file memory after upload
/*
static void releaseFile(uint8_t* file) {

if (file != NULL) {
free(file);
}
void closeA2lFile() {
assert(gXcpFile != NULL);
fclose(gXcpFile);
gXcpFile = NULL;
DBG_PRINT3("Close A2L file\n");
}
*/

static uint8_t* loadFile(const char* filename, uint32_t* length) {

uint8_t* fileBuf = NULL; // file content
uint32_t fileLen = 0; // file length

DBG_PRINTF3("Load A2L file %s to memory buffer\n", filename);

#if defined(_LINUX) // Linux

FILE* fd;
fd = fopen(filename, "r");
if (fd == NULL) {
DBG_PRINTF_ERROR("ERROR: file %s not found!\n", filename);
return NULL;
}
struct stat fdstat;
stat(filename, &fdstat);
fileBuf = (uint8_t*)malloc((size_t)(fdstat.st_size + 1));
if (fileBuf == NULL) return NULL;
fileLen = (uint32_t)fread(fileBuf, 1, (uint32_t)fdstat.st_size, fd);
fclose(fd);

#elif defined(_WIN) // Windows

wchar_t wcfilename[256] = { 0 };
MultiByteToWideChar(0, 0, filename, (int)strlen(filename), wcfilename, (int)strlen(filename));
HANDLE hFile = CreateFileW((wchar_t*)wcfilename, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
DBG_PRINTF_ERROR("ERROR: file %s not found!\n", filename);
return NULL;
}
fileLen = (uint32_t)GetFileSize(hFile, NULL);
fileBuf = (uint8_t*)malloc(fileLen + 1);
if (fileBuf == NULL) {
DBG_PRINTF_ERROR("ERROR: out of memory!\n");
CloseHandle(hFile);
return NULL;
}
if (!ReadFile(hFile, fileBuf, fileLen, NULL, NULL)) {
DBG_PRINTF_ERROR("ERROR: could not read from %s!\n", filename);
free(fileBuf);
CloseHandle(hFile);
return NULL;
}
fileBuf[fileLen] = 0;
CloseHandle(hFile);

#endif

DBG_PRINTF3(" file %s ready for upload, size=%u\n\n", filename, fileLen);
assert(fileLen > 0);
uint32_t openA2lFile() {
char filename[256];
SNPRINTF((char*)filename, 255, "%s.a2l", gXcpA2lName);
assert(gXcpFile == NULL);
gXcpFile = fopen(filename, "r");
if (gXcpFile == NULL) {
DBG_PRINTF_ERROR("ERROR: file %s not found!\n", filename);
return 0;
}
struct stat fdstat;
stat(filename, &fdstat);
gXcpFileLength = (uint32_t)fdstat.st_size;
assert(gXcpFileLength > 0);
DBG_PRINTF3("A2L file %s ready for upload, size=%u\n\n", filename, gXcpFileLength);
return gXcpFileLength;
}

*length = fileLen;
return fileBuf;
BOOL ApplXcpReadA2L(uint8_t size, uint32_t addr, uint8_t* data) {
if (gXcpFile == NULL) return FALSE;
if (addr + size > gXcpFileLength) return FALSE;
if (size!=fread(data, 1, (uint32_t)size, gXcpFile)) return FALSE;
if (addr + size == gXcpFileLength) closeA2lFile(); // Close file after complete sequential read
return TRUE;
}

#endif
#endif // XCP_ENABLE_IDT_A2L_UPLOAD

/**************************************************************************/
// Provide infos for GET_ID
// The XCP command GET_ID provides different type of identification
// information to the XCP client
// Returns 0, when the information is not available
/**************************************************************************/

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

Expand Down Expand Up @@ -511,10 +475,14 @@ uint32_t ApplXcpGetId(uint8_t id, uint8_t* buf, uint32_t bufLen) {
#ifdef XCP_ENABLE_IDT_A2L_UPLOAD
case IDT_ASAM_UPLOAD:
{
#ifdef XCP_LOAD_A2L_FILE
char filename[256];
SNPRINTF((char*)filename, 255, "%s.a2l", gXcpA2lName);
if (NULL==(gXcpFile=loadFile(filename,&gXcpFileLength))) return 0;
len = gXcpFileLength;
#else
len = openA2lFile();
#endif
}
break;
#endif
Expand Down

0 comments on commit db62fc0

Please sign in to comment.