9 years, 1 month ago.

Why the read time of fprintf() is different?

I checked the read time of fprintf() by using the program. The result is that the time is 55us or 15000us. I want to know the reason why the time is non-constant. And also, I want to know what should I do for writing the data within constant time. If you have an idea, please reply my question.

thanks.

///////IC infomation/////// mbed NXP LPC1768 /media/uploads/M_HORI/2015y03m14d_185426257.jpg

#include "mbed.h"

LocalFileSystem local("local"); 
Serial pc(USBTX, USBRX); // tx, rx ( the usb serial communication )
Timer check;
int begin, end;

char kakutyoushi[5];
char FileName[100];
FILE *fp;

void OpenFile_for_memorize(char *kakutyoushi){
    time_t now = time(NULL);
    struct tm *local = localtime(&now);
    sprintf(FileName,
            "/local/%02d%02d%02d%02d%s", 
            local->tm_mday,
            local->tm_hour,
            local->tm_min,
            local->tm_sec,
            kakutyoushi
            );
        
    fp = fopen(FileName, "w");  
    if (fp == NULL) {
            printf("ERROR : file cannot open");
            exit (1);
            }
    }

int main() {
    check.start(); 
    strcpy(kakutyoushi, ".txt");
    OpenFile_for_memorize(kakutyoushi);
        
    while(1) {
        
        begin = check.read_us();
        fprintf(fp,
                "ADCvalue= 2001 2100 2042 2000 2100 1986 1974 1899 1996 2022 2311 2093 2011 2031 2022 2111 \n"
                
                );
        end = check.read_us();
        
        
        if(pc.readable() == 1){
                fclose(fp);
                pc.printf("\n measurement end\n");
                while(1){
                    if(pc.getc() == 's'){
                        pc.printf("\n measurement restart\n");
                        OpenFile_for_memorize(kakutyoushi);
                        break;
                        }
                    }
                }
                
        pc.printf("Time = %d\n", end - begin); 
        
    }
}


http://i.imgur.com/FU8R5k7.png

Sorry couldn't help myself. But show code by copy pasting and putting it in <<code>> and <</code>> (On seperate lines).

posted by Erik - 14 Mar 2015

1 Answer

9 years, 1 month ago.

I think what you are observing is the effect of data buffering in the local filesystem software. The regular pattern of four or five 55us operations followed by a 15ms operation is the giveaway.

The local filesystem is organised as 512 byte blocks. Each of your fprintf() operations writes about 92 bytes to the output file. So, most of these simply buffer the data in the local filesystem's buffers. These are the 55us ones. Every fifth or sixth operation there is sufficient buffered data to write a block to the local filesystem Flash memory chip. These are the 15ms ones.

The local filesystem is not a high performance one. Writing 512 bytes in 15ms equates to about 34 kB/s. This seems about right. Writing 92 bytes in 55us equates to about 1.7 MB/s. No way!

The only way to make every fprintf() operation take the same time is to flush the local filesystem buffer after each fprintf(). I am not sure if flush() is implemented, so you may have to close and reopen the file. Unfortunately, this will make every operation a 15ms one. I suspect this is not what you want. If high performance is important to you, then I suggest you use an SD card and the SDFileSystem.

Erik is quite right - put your code between <<code>> and <</code>>. That way it is easy for people to copy and paste it into the editor and to run it on their mbed. They can then help you to resolve your problem. Nobody wants to waste their valuable time having to type all your code in again :(.

Dear Paul,

Thanks for your kind reply. I can understand the possible reason you mention. And also, I try a SD card as a method of saving data.

By the way, I have to say sorry for the way of showing my program. This is the first time for me to use this question board, so I didn't know the fact that the visualization will become nice if I write the program code between <<code>> and <</code>>. Now, I learn the way by your suggestion, and next time, I'll do so.

Thanks a lot.

posted by Masataka Hori 16 Mar 2015

You will see a similar pattern with SD cards.

If you need to maintain a regular interval while also writing to a file then run the code that needs to be consistent on an interrupt of some sort (e.g. a Ticker) and have it store the results into a buffer. In the main loop check if there is data in the buffer and if so write it to the SD card.

This way the data collection is de-coupled from the file system writes and so as long as you're buffer is large enough the data comes out completely consistent. The slower the SD card the larger the buffer needs to be but unless memory is an issue there is no harm in making it massive.

posted by Andy A 16 Mar 2015