cancel
Showing results for 
Search instead for 
Did you mean: 

How to better show file structure with FatFS and TouchGFX?

EEuge
Senior

Hello!

I have code, working with FatFS in system area of my project.

main.c

res = f_opendir(&dir, "0:/");
while(1)
	{
           res = f_readdir(&dir, &fileInfo);
          if (res==FR_OK && fileInfo.fname[0])
          {
            fn = fileInfo.fname;
           // ... some code
	}
       else break;
     }
    f_closedir(&dir);

And I have scrollList widget, where I want to show filelist.

How can I send list of filenames to widget by Model->Presenter->View ?

  1. Create array filelist[65535][256] , and send it to view - is not good idea...
  2. Step by step sending command from View to System which everytime calls " res = f_readdir(&dir, &fileInfo); ", gets filename, and asks next filename again - is better, but still not good.
  3. Can I call res = f_opendir(&dir, "0:/"), and send variable "dir" to view?
  4. May be I can #include "fatfs.h" in STORAGE_SCREENView.cpp and work with FatFS from View?

What can you advise for me?

1 ACCEPTED SOLUTION

Accepted Solutions

no you need use

typedef struct {
    FATFS*  fs;         /* Pointer to the owner file system object */
    WORD    id;         /* Owner file system mount ID */
    WORD    index;      /* Index of directory entry to start to search next */
    DWORD   sclust;     /* Table start cluster (0:Root dir) */
    DWORD   clust;      /* Current cluster */
    DWORD   sect;       /* Current sector */
    BYTE*   dir;        /* Pointer to the current SFN entry in the win[] */
    BYTE*   fn;         /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
#if _USE_LFN
    WCHAR*  lfn;        /* Pointer to the LFN working buffer */
    WORD    lfn_idx;    /* Index of last matched LFN entry (0xFFFF:No LFN) */
#endif
} DIR;

your code here

void STORAGE_SCREENView::setupScreen()
{
 if (f_mount(&fileSystem,  "", 0) == FR_OK)
  {
    res = f_opendir(&dir, "0:/");
files_found=0;
 while(1)
 {
    res = f_readdir(&dir, &fileInfo);
    if (res==FR_OK && fileInfo.fname[0])
    {
       files_found++;
    }
 else break;
 }
   }
scrollList1.setNumberOfItems( files_found);
}
 
void STORAGE_SCREENView::scrollList1UpdateItem(FileList_Container& item, int16_t itemIndex)
{
files_found=0;
 while(1)
 {
    res = f_readdir(&dir, &fileInfo);
    if (res==FR_OK && fileInfo.fname[0])
    {
       if (files_found==itemIndex)    break;
    }
 files_found++;
 }
item.SetItemFName(fileInfo.fname);
}

View solution in original post

26 REPLIES 26
Error while parsing Rich Text Content

What?????

MM..1
Chief II

You send nothing. In main or screensetup create array as you write and fill it with names.

Create next one global variable listvalid aka count.

In screen code extern this two memory and use it.

More complicated is when you plan browse more directories...

You don't understand me.

I need to output the contents of the folder in the custom container.Theoretically, the files in it can be 65536 and the name length is up to 256 bytes. Creating a variable (as you advised me in the next topic) is not rational because of the large amount of memory. Therefore, I want to do this - read the file name using FatFs, output it to the custom container, and when selecting a file, read the value of the text placed in the custom container.

At the moment, I put in view #include " paths.h" and read the folder structure at the start of the window. Immediately assign file names to the custom container elements. But is it rational?

When you plan use 65536 files then you need too plan sdram memory and you dont have problem, But you have right, this isnt effective.

You dont explain your code. But simply screen have une special method to update list items then you dont need store anything.

In ::setupScreen() get count of files and call scrollList1.setNumberOfItems(xx)

for quick operation in setup too create dir handle and leave it opened, close in tear...

void ScreenxView::scrollList1UpdateItem(MenuItem& item, int16_t itemIndex)
{
 only semantic
use dir handle
set file on itemindex pos
get filename
set to item
}

when you choice list item system give you itemIndex, then you repeat and get name. This process have no memory overload...

thanks.

dir handle - you think I must make it global and use with external directive? Good idea

But I'm afraid of this... I have to open DIR handle and then, after reading it, close it. i open and close in main. c, and i send read commands from screenview. But main. c and screenview are independent systems. And if for some reason the command to close ( f_closedir(&dir);) does not pass , there will be a disaster in memory.

Now this code works

void STORAGE_SCREENView::setupScreen()
{
    STORAGE_SCREENViewBase::setupScreen();
		scrollList1.setNumberOfItems(10);
		//scrollList1.setWindowSize(7);
	  scrollList1.setItemPressedCallback(scrollList1ItemPressedCallback);
 
	 if(f_mount(&fileSystem,  "", 0) == FR_OK)
  {
    unsigned int fc=0;
		res = f_opendir(&dir, "0:/");
    
		while(1)
		{
     res = f_readdir(&dir, &fileInfo);
     if (res==FR_OK && fileInfo.fname[0])
      {
        fn = fileInfo.fname;
				
 
				if(strlen(fn)) 
				{	
				
					(*(FileList_Container*)scrollList1ListItems.getDrawable(fc)).SetItemFName(fileInfo.fname);
				}	
					else 
					{	
					
					}	
      
  				if(fileInfo.fattrib&AM_DIR)
						{
													(*(FileList_Container*)scrollList1ListItems.getDrawable(fc)).SetItemFName(fileInfo.fname);
            }
						  
			}
       else break;
			fc++;
     }
     f_closedir(&dir);
		
	   
  }
	
}

no dir handle is private and all operation is created and closed in screen in my example.

Seems your code is fixed to 10 items and you dont understand how scrolllist works. Isnt filled in setup.