Hi Hervé
I checked this out and found that the FTP module doesn't actually know that it is working with a user file. It also doesn't need to know this since the general solution is to allow files to be read from user files as they are read from uFileSystem files.
I adapted some code in uFile.c to allows this to work - it required a little more than expected but maintains compatibility and allows general access without the header problem.
To give it a try make the following changes:
1) In uFile.c add a new local routine (add it just below the existing uGetFileLength())
#ifdef INTERNAL_USER_FILES // {19}
// Local copy of the routine uGetFileLength which adjusts the file header if the file is not a user file
//
static MAX_FILE_LENGTH uGetFileLength_variable_header(MEMORY_RANGE_POINTER ptrfile, unsigned char *ptrHeaderLength)
{
MAX_FILE_LENGTH FileLength;
#if defined INTERNAL_USER_FILES
FileLength = fnFilterUserFileLength(ptrfile);
if (FileLength != 0) {
return FileLength;
}
#endif
fnGetParsFile(ptrfile, (unsigned char *)&FileLength, sizeof(MAX_FILE_LENGTH));
*ptrHeaderLength = FILE_HEADER; // adjust the length since it is a uFileSystem file
if (FileLength == 0) { // protect against corrupted file so that it can be deleted
return _FILE_GRANULARITY; // the size of a file block
}
if (FileLength == (MAX_FILE_LENGTH)(-1)) { // check for blank FLASH memory
return 0; // no length so empty
}
// if a (corrupted) length should be too large, we limit it to end of the file system
if (((CAST_EXTENDED_POINTER_ARITHMETIC)((MEMORY_RANGE_POINTER)(uFILE_START + FILE_SYSTEM_SIZE - FILE_HEADER)) - (CAST_EXTENDED_POINTER_ARITHMETIC)ptrfile) < FileLength) {
FileLength = (MAX_FILE_LENGTH)((CAST_EXTENDED_POINTER_ARITHMETIC)(MEMORY_RANGE_POINTER)(uFILE_START + FILE_SYSTEM_SIZE - FILE_HEADER) - (CAST_EXTENDED_POINTER_ARITHMETIC)ptrfile); // the space remaining
}
return FileLength;
}
#endif
2) Now modify the routine uGetFileData() with the code below (the changes are only used when INTERNAL_USER_FILES is active)
extern MAX_FILE_LENGTH uGetFileData(MEMORY_RANGE_POINTER ptrFile, MAX_FILE_SYSTEM_OFFSET FileOffset, unsigned char *ucData, MAX_FILE_LENGTH DataLength)
{
#ifdef INTERNAL_USER_FILES // {19}
#if defined _WINDOWS
extern int iFetchingInternalMemory;
#endif
unsigned char ucFileHeaderLength = 0;
MAX_FILE_SYSTEM_OFFSET RemainingLength = uGetFileLength_variable_header(ptrFile, &ucFileHeaderLength);
#else
MAX_FILE_SYSTEM_OFFSET RemainingLength = uGetFileLength(ptrFile);
#endif
if (RemainingLength) {
RemainingLength -= FileOffset; // this is remaining length in file from this position
if (RemainingLength != 0) {
if (RemainingLength >= DataLength) {
RemainingLength = DataLength;
}
#ifdef INTERNAL_USER_FILES // {19}
#if defined _WINDOWS
if (!ucFileHeaderLength) {
iFetchingInternalMemory = 1; // mark that the file in in code memory for simulation use
}
#endif
fnGetParsFile((ptrFile + FileOffset + ucFileHeaderLength), ucData, (MAX_FILE_LENGTH)RemainingLength);
#else
fnGetParsFile((ptrFile + FileOffset + FILE_HEADER), ucData, (MAX_FILE_LENGTH)RemainingLength);
#endif
}
}
return ((MAX_FILE_LENGTH)RemainingLength); // return the length copied
}
This works on the target and on the simulator and so allows user files embedded in code to be extracted to a file via FTP (or other methods).
Tell me if it solves your requirements.
Regards
Mark