spectasaurus
Active member
I am using the uSDFS-master library to write data to the SD card on T3.6. It works for the most part, but I am noticing that occasionally I get very long delays in writing data. As a test, I am writing 32768 byes to an open file. Usually, this process takes about 3000us, but sometimes will take over 650000us. I am unsure why. I have set the Teensy at various speeds and it's always the same result.
My test code is attached. All it does is open a file for writing, then write 32768 bytes to the file, and repeats this process TotalLoops times. It measures the time it takes for each write.
Output looks like the following:
My test code is attached. All it does is open a file for writing, then write 32768 bytes to the file, and repeats this process TotalLoops times. It measures the time it takes for each write.
Code:
#include <Arduino.h>
#include <sys/stat.h>
#include "ff.h"
#define NbrEvents 8192
#define BufferSize 32768 // 32768 bytes per read tends to be optimal for SDHC access
#define TotalLoops 50
static uint32_t event_data[NbrEvents];
void die(char *str, FRESULT rc);
FRESULT rc; /* Result code */
FATFS fatfs; /* File system object */
FIL fil; /* File object */
DIR dir; /* Directory object */
FILINFO fno; /* File information object */
FATFS *fs;
uint32_t count=0;
uint32_t ifn=0;
uint32_t isFileOpen=0;
char filename[80];
TCHAR wfilename[80];
uint32_t t0=0;
uint32_t t1=0;
UINT wr;
char text[80];
extern "C" {
int _write(int fd, const char *ptr, int len) {
int j;
for (j = 0; j < len; j++) {
if (fd == 1)
Serial.write(*ptr++);
else if (fd == 2)
Serial3.write(*ptr++);
}
return len;
}
int _read(int fd, char *ptr, int len) {
if (len > 0 && fd == 0) {
while (!Serial.available());
*ptr = Serial.read();
return 1;
}
return 0;
}
int _fstat(int fd, struct stat *st) {
memset(st, 0, sizeof (*st));
st->st_mode = S_IFCHR;
st->st_blksize = 1024;
return 0;
}
int _isatty(int fd) {
return (fd < 3) ? 1 : 0;
}
}
void die(char *str, FRESULT rc)
{ printf_P("%s: Failed with rc=%u.\n", str, rc); for (;;) delay(100); }
TCHAR * char2tchar( char * charString, size_t nn, TCHAR * tcharString)
{ int ii;
for(ii = 0; ii<nn; ii++) tcharString[ii] = (TCHAR) charString[ii];
return tcharString;
}
char * tchar2char( TCHAR * tcharString, size_t nn, char * charString)
{ int ii;
for(ii = 0; ii<nn; ii++) charString[ii] = (char) tcharString[ii];
return charString;
}
void setup() {
uint32_t wt;
uint32_t start1, start2, end1, end2, start3, end3;
uint32_t ii;
uint32_t ib;
uint32_t event;
uint8_t TransferBuffer[BufferSize];
uint32_t TotalBytes=0;
float bpms;
for (ii=0; ii < NbrEvents; ii++) {
event_data[ii] = (uint32_t) (random(1000))/1000;
}
while (!Serial);
printf_P(PSTR("\r\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nStart\r\n"));
Serial.flush();
delay(1);
f_mount (&fatfs, (TCHAR *)_T("/"), 0);
sprintf(filename,"Proj_Data_%d.dat",ib);
char2tchar(filename,80,wfilename);
rc = f_open(&fil, wfilename, FA_WRITE | FA_CREATE_ALWAYS);
if (rc) die("open", rc);
printf_P("Filename: %s\n",filename);
start3 = micros();
for (ib=0;ib<TotalLoops;ib++) {
start1 = micros();
while (start1 == micros());
for (ii=NbrEvents; ii > 0LU; ii--) {
// Simulate the data acquisition process here with a 1us delay
delayMicroseconds(1);
}
end1 = micros();
wt = (end1 - start1) - 1;
bpms = (float)NbrEvents / (float) wt;
start2 = micros();
rc = f_write(&fil, event_data, 4*NbrEvents, &wr);
if (rc) die("write", rc);
end2 = micros();
bpms = float(4*NbrEvents)/((end2-start2)-1);
printf_P(PSTR("Time to write %lu bytes to SD: %lu us (%f MBps) \n"), 4*NbrEvents, (end2-start2)-1, bpms);
bpms = float(NbrEvents)/((end2-start1)-1);
delay(1);
}
rc = f_close(&fil);
if (rc) die("close", rc);
end3 = micros();
bpms = float(TotalLoops*NbrEvents)/((end3-start3)-1);
printf_P("Total time to transfer %u events = %u us (%f events/second)\n",TotalLoops*NbrEvents, (end3-start3), bpms*1000000),
delay (2000);
rc = f_opendir(&dir, (TCHAR*)_T(""));
if (rc) die("Dir",rc);
printf_P("Directory listing...\n");
for (;;) {
rc = f_readdir(&dir, &fno); /* Read a directory item */
if (rc || !fno.fname[0]) break; /* Error or end of dir */
if (fno.fattrib & AM_DIR) {
printf_P(" <dir> %s\r\n", tchar2char(fno.fname,80,text));
} else {
printf_P("%8d %s\r\n", (int)fno.fsize, tchar2char(fno.fname,80,text)); // fsize is QWORD for exFAT
}
}
printf_P("\n\n");
if (rc) die("Listing",rc);
// Read File size
rc = f_open(&fil, wfilename, FA_READ);
if (rc) die("Opening", rc);
printf_P("Sending file %s\n", filename);
start1 = micros();
// Send file in chunks of XX bytes
for (ii=fno.fsize/BufferSize; ii > 0LU; ii--) {
rc = f_read(&fil, TransferBuffer, BufferSize, &wr);
if (rc) die("Reading", rc);
// printf_P("Read %d bytes\n", BufferSize);
TotalBytes+=BufferSize;
}
if (TotalBytes != fno.fsize) {
rc = f_read(&fil, TransferBuffer, (uint32_t)(fno.fsize)-TotalBytes, &wr);
if (rc) die("Reading", rc);
}
end1 = micros();
printf_P("Done in %u s\n\n", ((end1-start1)-1)/1000000);
rc = f_close(&fil);
if (rc) die("close", rc);
}
void loop() {
}
Output looks like the following:
Code:
Start
Filename: Proj_Data_0.dat
Time to write 32768 bytes to SD: 3758 us (8.719532 MBps)
Time to write 32768 bytes to SD: 3989 us (8.214590 MBps)
Time to write 32768 bytes to SD: 4126 us (7.941832 MBps)
Time to write 32768 bytes to SD: 3997 us (8.198149 MBps)
Time to write 32768 bytes to SD: 4068 us (8.055064 MBps)
Time to write 32768 bytes to SD: 4001 us (8.189953 MBps)
Time to write 32768 bytes to SD: 4149 us (7.897807 MBps)
Time to write 32768 bytes to SD: 3922 us (8.354921 MBps)
Time to write 32768 bytes to SD: 4177 us (7.844865 MBps)
Time to write 32768 bytes to SD: 4067 us (8.057044 MBps)
Time to write 32768 bytes to SD: 4373 us (7.493254 MBps)
Time to write 32768 bytes to SD: 3516 us (9.319681 MBps)
Time to write 32768 bytes to SD: 3031 us (10.810953 MBps)
Time to write 32768 bytes to SD: 3041 us (10.775403 MBps)
Time to write 32768 bytes to SD: 3031 us (10.810953 MBps)
Time to write 32768 bytes to SD: 3041 us (10.775403 MBps)
Time to write 32768 bytes to SD: 3030 us (10.814522 MBps)
Time to write 32768 bytes to SD: 3042 us (10.771861 MBps)
Time to write 32768 bytes to SD: 3032 us (10.807388 MBps)
Time to write 32768 bytes to SD: 3104 us (10.556701 MBps)
Time to write 32768 bytes to SD: 3031 us (10.810953 MBps)
Time to write 32768 bytes to SD: 3040 us (10.778948 MBps)
Time to write 32768 bytes to SD: 3031 us (10.810953 MBps)
Time to write 32768 bytes to SD: 3041 us (10.775403 MBps)
Time to write 32768 bytes to SD: 3030 us (10.814522 MBps)
Time to write 32768 bytes to SD: 3042 us (10.771861 MBps)
Time to write 32768 bytes to SD: 681527 us (0.048080 MBps)
Time to write 32768 bytes to SD: 15418 us (2.125308 MBps)
Time to write 32768 bytes to SD: 3492 us (9.383735 MBps)
Time to write 32768 bytes to SD: 3590 us (9.127577 MBps)
Time to write 32768 bytes to SD: 3653 us (8.970161 MBps)
Time to write 32768 bytes to SD: 3503 us (9.354268 MBps)
Time to write 32768 bytes to SD: 8725 us (3.755645 MBps)
Time to write 32768 bytes to SD: 6004 us (5.457695 MBps)
Time to write 32768 bytes to SD: 3493 us (9.381048 MBps)
Time to write 32768 bytes to SD: 3445 us (9.511756 MBps)
Time to write 32768 bytes to SD: 3426 us (9.564507 MBps)
Time to write 32768 bytes to SD: 3463 us (9.462316 MBps)
Time to write 32768 bytes to SD: 3445 us (9.511756 MBps)
Time to write 32768 bytes to SD: 3454 us (9.486972 MBps)
Time to write 32768 bytes to SD: 3464 us (9.459584 MBps)
Time to write 32768 bytes to SD: 3412 us (9.603751 MBps)
Time to write 32768 bytes to SD: 3423 us (9.572889 MBps)
Time to write 32768 bytes to SD: 3441 us (9.522813 MBps)
Time to write 32768 bytes to SD: 3485 us (9.402582 MBps)
Time to write 32768 bytes to SD: 3451 us (9.495219 MBps)
Time to write 32768 bytes to SD: 3520 us (9.309091 MBps)
Time to write 32768 bytes to SD: 3474 us (9.432355 MBps)
Time to write 32768 bytes to SD: 3523 us (9.301164 MBps)
Time to write 32768 bytes to SD: 3475 us (9.429640 MBps)
Total time to transfer 409600 events = 1357090 us (301822.500000 events/second)
Directory listing...
1638400 Proj_Data_0.dat
Sending file Proj_Data_0.dat
Done in 0 s