1

So, trying to use the f_findfirst() function in fat_fs by elmChaN. Using R0.11a. I have everything configured for long file names. The one kicker is that after f_findfirst has ran the first character in longFileName[0] is '\0' (as in NULL character). If following my pattern that I gave it correctly it should be 'F'. I've been banging my head against a wall all night over this. Anyone have a clue why this is happening?

SAMPLE CODE:

uint8_t findFirmwareFile(uint8_t driveToMount)
{
    FRESULT result;
    UINT    n_bytes;
    DIR     directorySearchObject;
    FILINFO fileInformation;
    #if _USE_LFN
        char longFileName[_MAX_LFN];
        fileInformation.lfname = longFileName;
        fileInformation.lfsize = sizeof(longFileName);
    #endif
    
    char fnPattern[36];
    sprintf (fnPattern, "%s", FIRMWARE_FILE_NAME_PATTERN);
    
    int versionNumber = -1;
    char msg[128];

    test_drive[0]     = driveToMount + '0';
    
    sprintf(msg, "TIME (ms): %010d || ---->RUNNING FAT FILE SYSTEM.\r\n", getTime());
        UARTWrite(msg);
    
        memset(&fileSystem, 0, sizeof(FATFS));
    
        sprintf(msg, "TIME (ms): %010d || ---->MOUNTING FILE SYSTEM.\r\n", getTime());
        UARTWrite(msg);
    
        result = f_mount(&fileSystem, "0:", 1);
        if (FR_INVALID_DRIVE == result || FR_NOT_READY == result)
        {
            return FATFS_SKIP;
        }   
        
        sprintf(msg, "TIME (ms): %010d || ---->LOOKING FOR FIRMWARE FILES. PATTERN: %s\r\n", getTime(), FIRMWARE_FILE_NAME_PATTERN);
        UARTWrite(msg);
        
        result = f_findfirst(&directorySearchObject, &fileInformation, "", fnPattern);
        
        if (result == FR_OK)
        {
            while (result == FR_OK && longFileName[0])
            {
            #if _USE_LFN
                sprintf(msg, "TIME (ms): %010d || ---->FILE FOUND --> SHORT NAME: %-12s || LONG NAME: %s\r\n", getTime(), fileInformation.fname, fileInformation.lfname);
                UARTWrite(msg);
                char tempNUMBERstr[15];
                int temVersionNum;
                int tempSTRtrace = 0;
                for(int i = 8; i < 27; i++)
                {
                    if (fileInformation.lfname[i] == '.' )
                    {
                        //DO NOTHING
                    }
                    else
                    {
                        tempNUMBERstr[tempSTRtrace] = fileInformation.lfname[i];
                        tempSTRtrace++;
                    }
                }
                
                temVersionNum = atoi(tempNUMBERstr);
                
                if(versionNumber <= temVersionNum)
                {
                    versionNumber = temVersionNum;
                }
                else
                {
                    sprintf(msg, "TIME (ms): %010d || ---->LATEST FIRMWARE FILE FOUND --> NAME: %s", getTime(), fileInformation.lfname);
                    UARTWrite(msg);
                }
            #else
                sprintf(msg, "TIME (ms): %010d || ---->FILE FOUND --> SHORT NAME: %-12s", getTime(), fileInformation.fname);
                UARTWrite(msg);
            #endif
                
                result = f_findnext(&directorySearchObject, &fileInformation);  
            
            }
        }
        
    return FATFS_OK;
}
DDECE88
  • 21
  • 1
  • Does the library code also directly use _USE_LFN during compilation so that it is aware and should use the address of the provided array? Or do you have to somehow either make a configuration call, use a different call for long names, or otherwise let it know what you want? Also, does your compiler generate any initialization code for the longFileName array? Or is it just allocated off the stack with whatever junk was left on the stack? – jonk Dec 28 '22 at 02:41
  • MS-DOS long file names are stored as UTF-16 Unicode, which means each character occupies two bytes. In characters with an ASCII counterpart, the first byte will always be 0, so if the file name were `Foo`, on disk it would be stored as `"\0F\0o\0o\0\0"`. (where `\0` is a byte with the value `0`). – Jerry Coffin Dec 28 '22 at 03:53
  • To Jonk: Yes from what I can tell _USE_LFN is being used in compilation. I'm seeing the string change after being put through the f_findfirst() function. I don't know how to check to see if the longFileName array is allocated off the stack though. To Jerry: I'm pretty sure what you are saying about UTF-16 is not happening. otherwise the other characters in the array would have '\0' between them. The issue only seems to be happening in '**fileInformation.fname**' and any thing associated with '**fileInformation.lfname**'. – DDECE88 Dec 28 '22 at 15:21

0 Answers0