kendryte-freertos-sdk icon indicating copy to clipboard operation
kendryte-freertos-sdk copied to clipboard

size limitation in filesystem_file_read?

Open Moo2017 opened this issue 5 years ago • 5 comments

Hi All, I am trying to read a file ( file size is 300kb) from sdcard using filesystem_file_read function. I tried to read in 1000bytes blocks but it doesn't work properly and after reading some blocks it doesn't respond anymore. I'd appreciate if you can help me with that.

Moo2017 avatar Mar 15 '19 15:03 Moo2017

such small and arbitrary limitation is highly unlikely. Please check if there is any other problems in your program (e.g. stack overflow).

Anyway, we will need a small standalone reproduction case to be able to diagnose the problem.

minux avatar Mar 15 '19 19:03 minux

I have tested the code under Kendryte standalone sdk and it works fine but the same code doesn’t work in FreeRtos sdk.There is no stack overflowing and I am using the example sd card code in FreeRtos demo repository and just did a little change to get the size of file and then read it. If size iz higher than 1000, it try to read in 1000 bytes block ( In the standalone sdk I was able to read 65535 bytes in each reading).However, I’ll attach the code here by Monday.

Moo2017 avatar Mar 16 '19 13:03 Moo2017

Hi @minux @sunnycase Here is the code:


int main() { printf("Hello sd\n"); char msg[]="k233333333333333333"; char buffer[200]; handle_t sd0 = install_sdcard(); configASSERT(sd0); configASSERT(filesystem_mount("/fs/0/", sd0) == 0); io_close(sd0);

FIL file; FRESULT ret = FR_OK;

char *path = "DCIM/100VIG/VPH_00001.BMP";

//printf("/sd read write test/\n"); uint32_t v_ret_len = 0; uint8_t mm=0; FILINFO v_fileinfo; if((ret = f_stat(path, &v_fileinfo)) == FR_OK) { printf("%s length is %lld\n", path,(long long int) v_fileinfo.fsize); } else { printf("%s fstat err [%d]\n", path, ret); }

if((ret = f_open(&file, path, FA_READ)) == FR_OK) { uint8_t *v_buf = (uint8_t *) malloc (v_fileinfo.fsize); if (!v_buf) { printf("v_buf allocate problem \n"); } else { uint32_t len=0 ;

 while (v_fileinfo.fsize)
 {
   mm++;
   if (v_fileinfo.fsize>512)
     len = 512;
   else len = v_fileinfo.fsize;
   ret = f_read(&file, (void *)v_buf, len, &v_ret_len);
   if(ret != FR_OK)
   {
       printf("Read %s err[%d]\n", path, ret);
   }
   else
   {
     vTaskDelay(pdMS_TO_TICKS(1));
      // printf("Read :> %02x %d bytes lenth\n", *v_buf, v_ret_len);
   }
   v_fileinfo.fsize-=len;
   v_buf+=len;
 }

printf("DONE mm%d ,len=%u\n",mm,len);

}

 f_close(&file);

} else printf("ret = %d\n",ret ); f_close(&file);

while (1);


I should mention that if I remove " vTaskDelay(pdMS_TO_TICKS(1));" in the else statement it doesn't work fine but with this delay I was able to read the file . Also If try to read in 1024 bytes block it won't work fine either. As I mentioned before , I tested this code in K210-SDK standalone and I was able to read it in 65535 bytes block without any problem. VPH_00001.BMP is a 300kb files.

Moo2017 avatar Mar 18 '19 13:03 Moo2017

Hi @minux @sunnycase Here is the code:

int main() { printf("Hello sd\n"); char msg[]="k233333333333333333"; char buffer[200]; handle_t sd0 = install_sdcard(); configASSERT(sd0); configASSERT(filesystem_mount("/fs/0/", sd0) == 0); io_close(sd0);

FIL file; FRESULT ret = FR_OK;

char *path = "DCIM/100VIG/VPH_00001.BMP";

//printf("/sd read write test/\n"); uint32_t v_ret_len = 0; uint8_t mm=0; FILINFO v_fileinfo; if((ret = f_stat(path, &v_fileinfo)) == FR_OK) { printf("%s length is %lld\n", path,(long long int) v_fileinfo.fsize); } else { printf("%s fstat err [%d]\n", path, ret); }

if((ret = f_open(&file, path, FA_READ)) == FR_OK) { uint8_t *v_buf = (uint8_t *) malloc (v_fileinfo.fsize); if (!v_buf) { printf("v_buf allocate problem \n"); } else { uint32_t len=0 ;

 while (v_fileinfo.fsize)
 {
   mm++;
   if (v_fileinfo.fsize>512)
     len = 512;
   else len = v_fileinfo.fsize;
   ret = f_read(&file, (void *)v_buf, len, &v_ret_len);
   if(ret != FR_OK)
   {
       printf("Read %s err[%d]\n", path, ret);
   }
   else
   {
     vTaskDelay(pdMS_TO_TICKS(1));
      // printf("Read :> %02x %d bytes lenth\n", *v_buf, v_ret_len);
   }
   v_fileinfo.fsize-=len;
   v_buf+=len;
 }

printf("DONE mm%d ,len=%u\n",mm,len);

}

 f_close(&file);

} else printf("ret = %d\n",ret ); f_close(&file);

while (1);

I should mention that if I remove " vTaskDelay(pdMS_TO_TICKS(1));" in the else statement it doesn't work fine but with this delay I was able to read the file . Also If try to read in 1024 bytes block it won't work fine either. As I mentioned before , I tested this code in K210-SDK standalone and I was able to read it in 65535 bytes block without any problem. VPH_00001.BMP is a 300kb files.

Hello.I cannot get your problem.you can test my code or give the whole test code to me. /***********************************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <devices.h> #include <filesystem.h> #include <storage/sdcard.h> #include "project_cfg.h" #include <sys/stat.h> #include <unistd.h>

handle_t install_sdcard() { handle_t spi, gpio; configASSERT(spi = io_open("/dev/spi0")); configASSERT(gpio = io_open("/dev/gpio0")); handle_t sd0 = spi_sdcard_driver_install(spi, gpio, 7); io_close(spi); io_close(gpio); return sd0; }

int main() { printf("Hello sd\r\n"); char msg[]="k233333333333333333"; char buffer[200]; handle_t sd0 = install_sdcard(); configASSERT(sd0); configASSERT(filesystem_mount("/fs/0/", sd0) == 0); io_close(sd0);

FILE *stream;
struct stat buf;

if((stream=fopen("/fs/0/sdtest.bmp","r"))==NULL)
{
    fprintf(stderr,"Can not open file.\r\n");
    exit(-1);
}

int fd = fileno(stream);
fstat(fd, &buf);
printf("length is %ld\n", buf.st_size);

uint32_t count = buf.st_size;
uint32_t len=0 ;
uint32_t ret = 0;
uint32_t i = 0;
uint8_t *v_buf = (uint8_t *)malloc(count);
if (!v_buf)
{
    printf("v_buf allocate problem \n");
}
while (count)
{
    if (count > 65535)
        len = 65535;
    else
        len = count;
    ret = fread(v_buf, 1, len, stream);
    if(ret != len)
    {
        printf("Read err[%d]\n", ret);
    }
    else
    {
        printf("Read [%d]:> %02x %d bytes lenth\n", i, *v_buf, ret);
    }
    count -= len;
    v_buf += len;
    i++;
}
fclose(stream);
while (1)
    ;

} /***********************************************/

xiangbingj avatar Apr 08 '19 08:04 xiangbingj

Hi @minux Problem it's resolved since you have updated the branch ( I've seen that with old develop branch , then I've noticed that you have done some changes in SPI and then I updated my FREERTOS around two weeks ago and problem was resolved, however still for writing on sd card I need to break down the file into 512 bytes block otherwise doesn't work fine with large files and can't write. Have you tried to write large files? I wan't able to use fwrite even with breaking down to small blocks , However f_write can store the large files if it's broken down to 512bytes block.

Moo2017 avatar Apr 08 '19 13:04 Moo2017