How to list the NAND Flash files in MQX 4.2 without Shell

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to list the NAND Flash files in MQX 4.2 without Shell

1,554 Views
MAPC
Senior Contributor I

Hello,

My customer is using K70 as the MCU and MQX4.2 and CodeWarrior v. 10.6.4 as development plattforms.

In his application, he needs to store some parameters in a NAND Flash, like the one mounted in TWR-K70F120M and send the list of files present in NAND Flash out to the CAN bus in order to be received by the assigned nodes in the network.

The only function that seems to do it is "Shell_dir", but we have to add code to copy buffer content to a matrix.  We don't want and don't need a Shell in our application.

Is there an easier way to do it?

Thanks!

Marco Coelho

Labels (1)
11 Replies

1,013 Views
MAPC
Senior Contributor I

Another thing I had to do to make it work and avoid a build error was to change:

From: extern void     *_mem_alloc(_mem_size);

To:  extern char       *_mem_alloc(_mem_size);

In mqx.h file

0 Kudos

1,013 Views
oliviachristyva
Contributor III

Hi,

This is really useful. I was looking for a solution to this same problem .

Thank you so much

Olivia

0 Kudos

1,013 Views
MAPC
Senior Contributor I

After long hours of struggling, I have finally found the correct functions to do what I need. After installing the apropriate drivers and a file system, I just called "_io_get_first_valid_fs" to get a valid file system pointer, alloc a memory space for the buffer which receives the files names, open the directory, check if the file system pointer is valid, read the directory content and save the files names into vectors. Then, I close the directory.

I made a smal test in mfs_nandflash_twrk70f120m demo project: I added some code to "shell_task" and I would like to share it. Maybe somebody may find it useful:

void shell_task(uint32_t temp)

{

    MQX_FILE_PTR         fs_ptr;

    char             *path_ptr, *mode_ptr;

    void                *dir_ptr;

    char    str[100] = "0123456789A";

    /* Run the shell on the serial port */

    printf("This is the Flash File System example, type help for list of available commands\n");

    printf("If this is the first time you use the demo, you should run \"nanderasechip\" command first.\n");

    if (_io_nandflash_wl_install(&_bsp_nandflash_wl_init, FFS_DEVICE) != MQX_OK)

    {

        printf("Can't install FFS!\n");

        _task_block();

    }

   

    mfs_nandflash_wl_open();

   

    fd = fopen("a:/FILE1.TXT", "a");

    if(fd){

    fputs(str,fd);

    fflush(fd);

        fclose(fd);

    }

   

    fd = fopen("a:/FILE2.TXT", "a");

    if(fd){

    fputs(str,fd);

    fflush(fd);

        fclose(fd);

    }

   

    fd = fopen("a:/FILE3.TXT", "a");

    if(fd){

    fputs(str,fd);

    fflush(fd);

        fclose(fd);

    }

   

    fd = fopen("a:/FILE4.TXT", "a");

    if(fd){

    fputs(str,fd);

    fflush(fd);

        fclose(fd);

    }

   

    path_ptr  ="*.*";

    mode_ptr = "m";

    fs_ptr = _io_get_first_valid_fs();

    temp_buffer = _mem_alloc(BUFFER_SIZE);

    dir_ptr = _io_mfs_dir_open(fs_ptr, path_ptr, mode_ptr );

    a=0;

    b=0;

    while ((_io_is_fs_valid(fs_ptr)) && (_io_mfs_dir_read(dir_ptr, temp_buffer, BUFFER_SIZE) > 0)) {

       printf(temp_buffer);

       while(temp_buffer[a]!=' '){

      temp_arquivo[b][a++]=temp_buffer[a++];

       }

       a=0;

       b++;

    }

    _io_mfs_dir_close(dir_ptr);

    for(;;)

    {

        Shell(Shell_commands, NULL);

        printf("Shell exited, restarting...\n");

    }

}

My vector receives the files names, as desired:

pastedImage_5.png

pastedImage_8.png

pastedImage_11.png

pastedImage_14.png

Now I can read the directory and I don't need to run a Shell.

0 Kudos

1,013 Views
MAPC
Senior Contributor I

Hi, Scott

That's the point! I don't want to use Shell. In the mfs_nandflash_twrk70f120m demo, "Shell" function waits for a command entered on Terminal.

But I want to call those functions without Shell. But I don't know how to initialize a file system pointer (fs_ptr) and pass the right parameters to "_io_mfs_dir_open" and "_io_is_fs_valid" to make them work without "Shell" function.

Thank you very much for your tips.

Marco Coelho

0 Kudos

1,013 Views
scottm
Senior Contributor II

You don't need the shell functions.  I was trying to illustrate where that file system pointer comes from.  Look at the flashx example.  I'm pretty sure the file pointer returned when you initially open the flash device is the one you want to pass to the _io_mfs_dir_open function.  The shell code does a lot of shuffling around its own context data structure, but you don't need it.

0 Kudos

1,013 Views
dshimizu
NXP Employee
NXP Employee

Hello Marco,

MQX 4.2 has a filesystem for NAND memories on the folder: C:\Freescale\Freescale_MQX_4_2\ffs\examples\mfs_nandflash

Is your customer using it?

Denis

0 Kudos

1,013 Views
MAPC
Senior Contributor I

Hello, Denis

Thanks for your help.

Actually we took a look at this demo. But, the demo is based on a Shell, that waits for commands entered in a Terminal. There are functions independent from Shell to open the driver, NAND_Flash and file system, as well as the functions to open, write, read, remove and clode files, but we didn't find a specific function to read the list of files in the current directory and save it in a variable.

Shell_dir function does exactly what we need, but we have to add code to the fucntion in order to save files names into a variable (vectors). Besides it, this function uses Shell and a lot of structures tied to Shell. And we would like to break free from Shell.

Is there a way to do it without Shell?

Thanks,

Marco Coelho

0 Kudos

1,013 Views
scottm
Senior Contributor II

I just found app note AN3907 and it at least mentions the _io_mfs_dir_read command.  That means it's been there since at least 2009 and hasn't found its way into the user's guide yet.  I'm having second thoughts about using MFS at all if this is what I can expect - FatFS is better documented and easier to implement.

Scott

0 Kudos

1,013 Views
MAPC
Senior Contributor I

Hello, Scott

Thanks for help.

Actually, there are 3 essential functions at my point of view: "_io_mfs_dir_open", "_io_is_fs_valid" and "_io_mfs_dir_close". We can see it in "Shell_dir" function, which is called in "mfs_nandflash_twrk70f120m" MQX 4.2 demo.

In the demo, "_io_mfs_dir_open" and "_io_is_fs_valid" receive "fs_ptr" as one of their parameters. But "fs_ptr" is obtained by the value returned by "Shell_get_current_filesystem", which is in turn a Shell function.

If you take a look at "Shell_get_current_filesystem" function, it calls several other Shell functions. So, I'm struggling to understand how "fs_ptr" was initialized by Shell functions, to break free from Shell. It is too complex and as you, I also haven't found a clear documentation explaning those functions!

I hope anybody have experienced the same problem as me and can throw some light on it or somebody from NXP can give us a helping hand.

Thanks and regards!

Marco Coelho

0 Kudos

1,013 Views
scottm
Senior Contributor II

I just skimmed through the shell code and I think I see how it works.  Those shell commands all take a pointer to the shell context data structure, which stores the current file system.  The file system is first set in Shell():

#if SHELLCFG_USES_MFS

   // initialize current fs ptr, fs name and path

   Shell_set_current_filesystem((void *)shell_ptr,NULL);

#endif //SHELLCFG_USES_MFS

When it gets to Shell_init_current_filesystem() and sees that it's null, it just pulls the first valid fs out of the fs table.  It looks like file systems are either explicitly registered (see the HVAC demo USB code) or they're opened when they're first referenced.  In the case of the flashx demo you can see this:

    /* Open the flash device */

    flash_file = fopen(FLASH_NAME, NULL);

Previously in that file you see something like this:

#define         FLASH_NAME "flashx:bank0"

That, in turn, is defined in init_bsp.c:

#if BSPCFG_ENABLE_FLASHX

    _io_flashx_install("flashx:", &_bsp_flashx_init);

#endif

So to recap, your BSP installs the driver with the name flashx: and use fopen() to open a flash: path, and fopen() returns a file pointer that you can use with the directory commands.  Haven't tried it myself yet, but that's how it looks to me.

Scott

1,013 Views
scottm
Senior Contributor II

Hi Marco,

I'm new to MFS myself, but I think the functions you're looking for are _io_mfs_dir_open, _io_mfs_dir_read, and _io_mfs_dir_close.  None of which are listed in the MQX 4.2 MFS user's guide, for some reason.  And if you read the comments in dir_read.c there's no help either - it says it's the partition manager.  There are exactly two comments in that file and no instructions on usage.

Surely this must be documented somewhere, but I haven't found it yet.

Scott

0 Kudos