Problems with EFFS
Posted: Sat Feb 11, 2023 4:39 pm
I'm having a bizzare issue with reading from an SDCARD and a NANO54415
The objective: Two routines. One picks a random file from the SDCard and opens it. The other reads 1200bytes from the file everytime you execute it. If you reach the end of file, you rewind the file to the beginning. RandomTree is called every couple of minutes and closes any open file while picking a new one. The routine OutputTree reads 1200bytes and puts them in corrected order into an output buffer.
filesel is a global. Any open is kept open across routines ; we don't want to close anything for the minutes that the file is being read. and the enterfs takes place in the usermain.c program at the initialization.
What's happening:
The code reads 1200 bytes once or twice. But every other read afterwords is 0 bytes long, even though the files are a couple Megabytes in length. This 0 byte read doesn't cause EOF though ; that still happens later on. And the Rewind doesn't do anything -- reading more simply causes more EOFs.
The point of all this is to use the SDCard as a massive memory holding patterns of 400 pixels in many files. This data would not fit in any memory of the device. So putting the patterns on an SDCard and just reading it, a) makes a vast memory device b) that can be changed on any pc with a card reader. It sees the directory fine. It even opens and reads a file... one or two times. Then it all goes wonky.
***
/*
* sdcard.cpp
*
* Created on: Dec 23, 2022
* Author: ALLEN
*
* Create an internal directory of all files on an SDCard, and pull ROWS*COLS pixels to the
*/
#include <predef.h>
#include <stdio.h>
#include <stdlib.h>
#include <basictypes.h>
#include <ctype.h>
#include <startnet.h>
//#include <autoupdate.h>
#include <dhcpclient.h>
#include <taskmon.h>
#include <smarttrap.h>
#include <serial.h>
// SDCard
#include <effs_fat/effs_utils.h>
#include <effs_fat/fat.h>
#include "FileSystemUtils.h"
#include <ftpd.h>
#include <networkdebug.h>
#include <nbtime.h>
#include "xmas2011.h"
#include "sdcard.h"
#define SIZEDIR 16
char * filenameRead;
char * fileSelected;
F_FILE * filesel;
char filenames[DIRSSIZE];
int numpatterns; // how many treexx.out patterns are there?
unsigned char Tree[TREECHARS];
unsigned char * ptrTree;
unsigned char * OutTreechar;
unsigned char tempr, tempg, tempb;
int myTreeIndex;
int myTreeStart;
int ii, jj;
unsigned char SDFlag;
int randomFile(int maxout)
{
return rand()%maxout;
}
void InitMYSD()
{
//f_enterFS();
numpatterns=0;
filesel = 0;
SDFlag = 0;
InitExtFlash(); // Initialize the CFC or SD/MMC external flash drive
memset(filenames, 0x00, DIRSSIZE);// clear the directory
}
int GetSDDir(int debug)
{
F_FIND finder; // location to store the information retrieved
/* Find first file or subdirectory in specified directory. First call the
f_findfirst function, and if file was found get the next file with
f_findnext function. Files with the system attribute set will be ignored.
Note: If f_findfirst() is called with "*.*" and the current directory is
not the root directory, the first entry found will be "." - the current
directory.
*/
filenameRead = &filenames[0];
volatile int rc = f_findfirst("*.*", &finder);
if (rc == F_NO_ERROR) // found a file or directory
{
do
{
if (!(finder.attr & F_ATTR_DIR))
{
strcpy(filenameRead, finder.filename);
numpatterns++; // remember this is a global
filenameRead+=SIZEDIR;
if (debug != 0)
iprintf("File [%s] : %lu Bytes\r\n", finder.filename, finder.filesize);
}
} while (!f_findnext(&finder));
}
else
{
numpatterns = 0;
SDFlag = 1;
}
return numpatterns;
}
void SmellFilenames()
{
int i;
if (numpatterns != 0)
{
for(i=0; i<numpatterns; i++)
{
filenameRead = &filenames[i*SIZEDIR];
iprintf("FileMem [%s]\r\n", filenameRead);
}
}
}
int RandomTree(int override)
{
// close current file
if(filesel != 0)
{
f_close(filesel);
filesel = 0;
}
// picks a random tree file unless override is set
if (SDFlag == 0) // no SD fault
{
ii = randomFile(numpatterns);
if ((override != 0) && (override<numpatterns))
ii = override;
ii*=SIZEDIR;
fileSelected = &filenames[ii];
// open new file
filesel = f_open(fileSelected, "r");
if (!filesel)
{
iprintf("%s OPEN ERROR %d \r\n", fileSelected, SDFlag);
return 1; // error opening
}
iprintf("%s reading\r\n", fileSelected);
return 0;
}
iprintf("No SDCard Files\r\n");
return 2;
}
int OutputTree(int startindex) // returns how many pixels were written
{
int numPixels = 0;
int numRead;
if (SDFlag)
{
iprintf("SDFLAG %d\r\n", SDFlag);
return 0;
}
myTreeStart = startindex;
ptrTree = &Tree[0];
// are we at eof, reset if so
if (f_eof(filesel))
{
f_rewind(filesel);
iprintf("rewind\r\n"); // rewinding indication
}
// reads one block of pixels and displays them.
// grab 400*3 chars
numRead = f_read(ptrTree, 1, TREECHARS, filesel);
iprintf(" %d", numRead);
// put them into the outbuffer a pixel at a time
OutTreechar = &Tree[0];
for (ii=TREEROWS-1; ii>=0; ii--)
{
for (jj=0; jj<TREECOLS; jj++)
{
tempr = *OutTreechar++;
tempg = *OutTreechar++;
tempb = *OutTreechar++;
myTreeIndex = (jj*TREEROWS) + ii + myTreeStart;
setlightchar(myTreeIndex, tempr, tempg, tempb);
numPixels +=1;
}
}
return numPixels;
}
The objective: Two routines. One picks a random file from the SDCard and opens it. The other reads 1200bytes from the file everytime you execute it. If you reach the end of file, you rewind the file to the beginning. RandomTree is called every couple of minutes and closes any open file while picking a new one. The routine OutputTree reads 1200bytes and puts them in corrected order into an output buffer.
filesel is a global. Any open is kept open across routines ; we don't want to close anything for the minutes that the file is being read. and the enterfs takes place in the usermain.c program at the initialization.
What's happening:
The code reads 1200 bytes once or twice. But every other read afterwords is 0 bytes long, even though the files are a couple Megabytes in length. This 0 byte read doesn't cause EOF though ; that still happens later on. And the Rewind doesn't do anything -- reading more simply causes more EOFs.
The point of all this is to use the SDCard as a massive memory holding patterns of 400 pixels in many files. This data would not fit in any memory of the device. So putting the patterns on an SDCard and just reading it, a) makes a vast memory device b) that can be changed on any pc with a card reader. It sees the directory fine. It even opens and reads a file... one or two times. Then it all goes wonky.
***
/*
* sdcard.cpp
*
* Created on: Dec 23, 2022
* Author: ALLEN
*
* Create an internal directory of all files on an SDCard, and pull ROWS*COLS pixels to the
*/
#include <predef.h>
#include <stdio.h>
#include <stdlib.h>
#include <basictypes.h>
#include <ctype.h>
#include <startnet.h>
//#include <autoupdate.h>
#include <dhcpclient.h>
#include <taskmon.h>
#include <smarttrap.h>
#include <serial.h>
// SDCard
#include <effs_fat/effs_utils.h>
#include <effs_fat/fat.h>
#include "FileSystemUtils.h"
#include <ftpd.h>
#include <networkdebug.h>
#include <nbtime.h>
#include "xmas2011.h"
#include "sdcard.h"
#define SIZEDIR 16
char * filenameRead;
char * fileSelected;
F_FILE * filesel;
char filenames[DIRSSIZE];
int numpatterns; // how many treexx.out patterns are there?
unsigned char Tree[TREECHARS];
unsigned char * ptrTree;
unsigned char * OutTreechar;
unsigned char tempr, tempg, tempb;
int myTreeIndex;
int myTreeStart;
int ii, jj;
unsigned char SDFlag;
int randomFile(int maxout)
{
return rand()%maxout;
}
void InitMYSD()
{
//f_enterFS();
numpatterns=0;
filesel = 0;
SDFlag = 0;
InitExtFlash(); // Initialize the CFC or SD/MMC external flash drive
memset(filenames, 0x00, DIRSSIZE);// clear the directory
}
int GetSDDir(int debug)
{
F_FIND finder; // location to store the information retrieved
/* Find first file or subdirectory in specified directory. First call the
f_findfirst function, and if file was found get the next file with
f_findnext function. Files with the system attribute set will be ignored.
Note: If f_findfirst() is called with "*.*" and the current directory is
not the root directory, the first entry found will be "." - the current
directory.
*/
filenameRead = &filenames[0];
volatile int rc = f_findfirst("*.*", &finder);
if (rc == F_NO_ERROR) // found a file or directory
{
do
{
if (!(finder.attr & F_ATTR_DIR))
{
strcpy(filenameRead, finder.filename);
numpatterns++; // remember this is a global
filenameRead+=SIZEDIR;
if (debug != 0)
iprintf("File [%s] : %lu Bytes\r\n", finder.filename, finder.filesize);
}
} while (!f_findnext(&finder));
}
else
{
numpatterns = 0;
SDFlag = 1;
}
return numpatterns;
}
void SmellFilenames()
{
int i;
if (numpatterns != 0)
{
for(i=0; i<numpatterns; i++)
{
filenameRead = &filenames[i*SIZEDIR];
iprintf("FileMem [%s]\r\n", filenameRead);
}
}
}
int RandomTree(int override)
{
// close current file
if(filesel != 0)
{
f_close(filesel);
filesel = 0;
}
// picks a random tree file unless override is set
if (SDFlag == 0) // no SD fault
{
ii = randomFile(numpatterns);
if ((override != 0) && (override<numpatterns))
ii = override;
ii*=SIZEDIR;
fileSelected = &filenames[ii];
// open new file
filesel = f_open(fileSelected, "r");
if (!filesel)
{
iprintf("%s OPEN ERROR %d \r\n", fileSelected, SDFlag);
return 1; // error opening
}
iprintf("%s reading\r\n", fileSelected);
return 0;
}
iprintf("No SDCard Files\r\n");
return 2;
}
int OutputTree(int startindex) // returns how many pixels were written
{
int numPixels = 0;
int numRead;
if (SDFlag)
{
iprintf("SDFLAG %d\r\n", SDFlag);
return 0;
}
myTreeStart = startindex;
ptrTree = &Tree[0];
// are we at eof, reset if so
if (f_eof(filesel))
{
f_rewind(filesel);
iprintf("rewind\r\n"); // rewinding indication
}
// reads one block of pixels and displays them.
// grab 400*3 chars
numRead = f_read(ptrTree, 1, TREECHARS, filesel);
iprintf(" %d", numRead);
// put them into the outbuffer a pixel at a time
OutTreechar = &Tree[0];
for (ii=TREEROWS-1; ii>=0; ii--)
{
for (jj=0; jj<TREECOLS; jj++)
{
tempr = *OutTreechar++;
tempg = *OutTreechar++;
tempb = *OutTreechar++;
myTreeIndex = (jj*TREEROWS) + ii + myTreeStart;
setlightchar(myTreeIndex, tempr, tempg, tempb);
numPixels +=1;
}
}
return numPixels;
}