need help using fopen on a wav file, while using RTOS threads

02 Mar 2012

Whenever I try to use fopen to read a file from the USB filesystem, while using RTOS threading, the mbed immediately goes to siren lights.

I would use the internal filesystem, but I need to stream audio, and when I used fopen on a file on the internal filesystem, the program would just hang. If there is a workaround to either problem, please let me know.

Thanks

02 Mar 2012

Hello, I have similiar problem with CMSIS RTOS and SD card library. My attempt was to have thread which add line of data to file on SD card each 1 second. It is as kind of log for logging data. Sometimes ( I think dependent on placement of FILE *fp = fopen("/sd/_log/_log_001.txt", "a"); statement - in thread or in main)

Here is my very testing code

#include "mbed.h"
#include "cmsis_os.h"
#include "SDFileSystem.h"

DigitalOut led1(LED1);
DigitalOut led2(LED2);
SDFileSystem sd(p5, p6, p7, p8, "sd");


// FILE *fp;


void save_fake_data() {
    FILE *fp = fopen("/sd/_log/_log_001.txt", "a");
    fseek (fp, 0, SEEK_END);
    fprintf(fp, "\nVoltage:  V\n\r");
    fclose (fp);
}



void led2_thread(void const *argument) {
    while (true) {
        led2 = !led2;
        osDelay(1000);
    }
}




void write_SD_thread(void const *argument) {
    while (true) {
        led1 = !led1;
        save_fake_data();
    
        // osDelay(1000);

    }
}


osThreadDef(led2_thread, osPriorityNormal, 1, DEFAULT_STACK_SIZE);
osThreadDef(write_SD_thread, osPriorityNormal, 1, DEFAULT_STACK_SIZE);



int main (void) {



    osThreadCreate(osThread(write_SD_thread), NULL);
    osThreadCreate(osThread(led2_thread), NULL);




                // wait(1);
                // FILE *fp = fopen("/sd/_rec/_rec_001.txt", "a");
               
                // if (fp == NULL) {
                // printf("Could not open file for write\n");
                // }
                //
                // while (!fopen());


                // mkdir("/sd/_log", 0777);
                // fclose (fp);

                // fseek ( fp , 0 , SEEK_END );
                // fprintf(fp, "\nVoltage:  V\n\r");
                // fprintf(fp, "\n\r Current:  A \n\r");
                // fprintf(fp, "Number of cycles: U\n\r");
                // printf("Current: A\n\r");


}

In one case after restart all leds started flashing in pairs like runtime error but data was written - only once but written.

In second case there was no flashing leds but no data was written.

Please can anybody point me to right direction? Is it fprintf()? and I would write data to file char by char with say fputc()?

Can this happen because SD card library and fat filesystem library isn't made for use with RTOS?

Thank You for any help.

02 Mar 2012

Please, can anybody point me idea why writing data to SD card by thread in CMSIS RTOS does not work?

Thank You very much.

02 Mar 2012

Hi Alexander,

Alexander Smith wrote:

Whenever I try to use fopen to read a file from the USB filesystem, while using RTOS threading, the mbed immediately goes to siren lights.

I would use the internal filesystem, but I need to stream audio, and when I used fopen on a file on the internal filesystem, the program would just hang. If there is a workaround to either problem, please let me know.

As a first test I am just writing a file in the local file system and I am simply blinking a LED in another thread. This is working as expected:

#include "mbed.h"
#include "rtos.h"

DigitalOut led1(LED1);

void led2_thread(void const *argument) {
    LocalFileSystem local("local");
    
    FILE *f = fopen("/local/out.txt", "w");
    for (int i=0; i<30; i++) {
        fprintf(f, "%d\n", i);
        Thread::wait(100);
    }
    fclose(f);
}

int main() {
    Thread t(led2_thread);
    
    while (true) {
        led1 = !led1;
        Thread::wait(1000);
    }
}

I will now try to see what goes wrong with the other libraries (USB and SD).

Cheers, Emilio

02 Mar 2012

Just to keep you updated. I managed to reproduce the problem. There seems to be some sort of incompatibility between the "FATFileSystem" library (used by USBMSDHost and SDFileSystem) and the "RTOS" library. I will investigate it.

02 Mar 2012

Hello Emilio,

thank You for Your interest and investigations in using RTOS and SD/local filesystem. This is far above my experience to figure out what can be wrong.

I am very interested in RTOS because i see it as future benefit to have implemented RTOS with USB device/host, network, SD/local filesystem and serial,SPI...

So my question is if is possible to use above libraries like USB device, serial or network with CMSIS RTOS library or do I have to check each one for compatibility?

I tried to match code to write SD card to Your code for local system and adapted to CMSIS RTOS thread example:

#include "mbed.h"
#include "cmsis_os.h"
#include "SDFileSystem.h"

DigitalOut led1(LED1);
DigitalOut led2(LED2);

void write_SD_thread(void const *argument) {
   SDFileSystem sd(p5, p6, p7, p8, "sd");
    
    FILE *f = fopen("/sd/_log/_log_001.txt", "w");
    for (int i=0; i<30; i++) {
        fprintf(f, "%d\n", i);
       osDelay(100);
    }
    fclose(f);
}


void led2_thread(void const *argument) {
    while (true) {
        led2 = !led2;
        osDelay(1000);
    }
}

osThreadDef(write_SD_thread, osPriorityNormal, 1, DEFAULT_STACK_SIZE);
osThreadDef(led2_thread, osPriorityNormal, 1, DEFAULT_STACK_SIZE);

int main (void) {

    osThreadCreate(osThread(write_SD_thread), NULL);
    osThreadCreate(osThread(led2_thread), NULL);

}

After restart all leds starts flashing in pairs like runtime error? No data are written.

02 Mar 2012

Now I will try SD HC library to see if the result will be the same.

02 Mar 2012

As I see SD HC use the same #include "FATFileSystem.h" so I expect the resul will be the same.

02 Mar 2012

Okay. Thanks for helping, Emilio. I had a feeling the problem was something along those lines, but I couldn't test it due to my limited knowledge of C++ functions.

Also, a correction in my first post. After more testing, I found it was the wave_player function wave.play() that hung up using the localfilesystem, not the action of fopen.

07 Mar 2012

The SDFileSystem + FATFileSystem call stack is pretty deep. The stack of the thread writing to the SD card has to be set about 2.25 times the default stack size:

Thread t(sd_thread, NULL, osPriorityNormal, (DEFAULT_STACK_SIZE * 2.25));

This is an example program with such a thread:

Import programSDThread

Simple RTOS example with a thread writing to an SD card, requiring custom stack size

Cheers, Emilio

31 May 2012

Hello:

I have the same problem, but I need to use the internal filesystem. My test code without threads works ok. Then I simply added the RTOS library and recompile, but the program hangs.

The code is fairly simple:

#include "mbed.h"

AnalogOut signal(p18);
LocalFileSystem local("local");
Serial pc(USBTX, USBRX); // tx, rx

int main() {
    pc.printf("Open\n");
    FILE *file = fopen("/local/ringin.bit", "r");

    // count characters in file
    pc.printf("Count\n");
    int i;
    for(i=0; 1; i++) if(fgetc(file) == EOF) break;

    // return file position pointer to start of file
    pc.printf("Bytes: %d \n", i);
    pc.printf("Seek\n");
    fseek(file, 0, SEEK_SET);

    //allocate a pointer to hold contents of file
    pc.printf("Allocate\n");
    char *out = (char*) malloc(sizeof(char) * i + 1); //+1 to hold the end of string

    // copy contents to pointer
    pc.printf("Read\n");
    fscanf(file, "%s", out);

    //close file pointer
    pc.printf("Close\n");
    fclose(file);
                   
    pc.printf("End\n");
}

Could someone please help me with this? Thanks, Gonzalo

-------

Forget it, I managed to make it work.