6 years, 1 month ago.

Unsolved ERROR for synchronised tasks and interrupts conflicts

Hello, my program include timers (tickers, timer to measure periods time), spi to read (without DMA), fatfs and USBHOST

I want to call a function each 250 µs periodically using a ticker, this function read data and put it in buffer1, while storing buffer2 in an external USB memory using fatfs of Igor Skochinsky. Once the buffer1 is filled and buffer2 is stored, we reverse them (double buffering).

The data is read and stored fine but The issue is that the ticker counts the double of the expected period (i.e. As said, i want a period of 250us, but got 500us). It sounds like one interrupt is lost, the next interrupt is handled, the next is lost, the next is handled, the next,... But if it's really a ticker/fatfs interrupts conflict, where it came from, and how to solve it?!

I made systick_irq (i.e. it handles write-to-usb interrupt) lower prioritised than timers and vice versa, but didn't work. I also made a ticker based on timer0 with MR0, but still the double period. I guess the fatfs is blocking the timers interrupt, but it should exist a way to deal with this.

double buffer SPI read and usb storage

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include ...
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
Timer t;  //we use timer class, based on timer3, to mesure time.
Ticker tic;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
void my_periodic_func(void) {
{
begin=t.read();
//my_periodic_func_code
end=t.read();
//save period=end-begin
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
int main(void){
//init code
fp = fopen( ... , "wb");
t.start();

tic.attach_us(&my_periodic_func, 250);

while (1){
//store
}

}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

I've been trying for a while ago to solve this issue, and now looking for your ideas Thanks.

1 Answer

6 years, 1 month ago.

Hello Saad,

The period = end -begin you calculate in ISR tells you how much time it takes to complete its execution rather than the period at which it's getting called. Nevertheless, if that value is greater than 250us then the ISR itself (aka my_periodic_func) is causing the missing interrupts because no new interrupts are handled until it's execution has been finished . To solve it, try to optimize (make it as short as possible) the my_periodic_func until it takes less than 250us to complete its execution.

Thank you Zoltan for your precised and rapid answer ! For the the call beginning instant info, I use the variable begin which is supposed to be something like 250us, 500us, 750us ... but I got something like 250us, 750us, 1250us, 1750us, ... Which's means, only the first call that takes 250us, but all the next calls takes 500us.

For the my_periodic_func , we calculated its calls execution time using the variable period for one hour, and found as expected that the execution time for every call is only 18us or 19 us with no exception.

That's why I'm confused, because even if it's a interrupt conflict with filesystem, it must exist a way to deal with it that I still be trying hard to find. Thanks again !

posted by saad essasky 28 Mar 2018

Below is a simplified version of your program which is using an SD card for data storage.
I have tested it on a LPC1768 board with promising results.

#include "mbed.h"
#include "SDBlockDevice.h"
#include "FATFileSystem.h"
#include "errno.h"

Timer           t;
Ticker          tic;
int             callPeriod[10];
int             duration[10];
volatile int    i = 0;
volatile int    last;
volatile bool   dataAvailable = false;
AnalogIn        input(p15);
volatile int    value;
uint16_t        data[10];
SDBlockDevice   bd(p5, p6, p7, p8); // SD card SPI driver pins: mosi, miso, sclk, cs
FATFileSystem   fs("sd");

void my_periodic_func(void)
{
    int begin = t.read_us();
    if (i < 10)
    {
        callPeriod[i] = begin - last;
        last = begin;
        value = input.read_u16();
        data[i] = value;
        dataAvailable = true;
        duration[i] = t.read_us() - begin;
        i++;
    }
}

int main(void)
{
    int err = fs.mount(&bd);
    if (err)
        return err;

    FILE*   fp = fopen("/sd/sdtest.txt", "w+");

    if (!fp)
    {
        fp = fopen("/sd/sdtest.txt", "w+");
        if (!fp)
        {
            error("error: %s (%d)\r\n", strerror(errno), -errno);
            return errno;
        }
    }

    t.start();

    tic.attach_us(&my_periodic_func, 250);
    last = t.read_us();

    while (1)
    {
        if (dataAvailable)
        {
            dataAvailable = false;
            err = fprintf(fp, "%d\r\n", value);
            if (err < 0)
            {
                printf("Fail :(\r\n");
                error("error: %s (%d)\r\n", strerror(errno), -errno);
                return err;
            }
        }

        if (i == 10)
        {
            err = fclose(fp);
            if (err)
                return err;

            for (int j = 0; j < i; j++)
            {
                printf("callPeriod[%d] = %3d us\r\n", j, callPeriod[j]);
                printf("duration[%d]   = %3d us\r\n", j, duration[j]);
            }

            fp = fopen("/sd/sdtest.txt", "r");
            if (err)
                return err;
        
            printf("data:\n");
            while (!feof(fp)) {
                int c = fgetc(fp);
                printf("%c", c);
            }

            
            err = fclose(fp);
            if (err)
                return err;

            i++;
        }
    }
}
posted by Zoltan Hudak 28 Mar 2018

I appreciate so much your help Zoltan ! I'm using the published program MSCFileSystem for USB mass storage. Can I know which lib you used to include Fatfilesystem.h and sdblockdevice.h? I'm using USB mass storage. I need just to use promising libraries so as to make sure that the program I'm using is not bugged, because once I remove the storage loop, it works fine. Thanks again!

posted by saad essasky 29 Mar 2018

Since both FATFileSystem and SDBlockDevice are part of mbed-os they look pretty perspective.

posted by Zoltan Hudak 29 Mar 2018

@Zoltan Yes! could find them in last versions of mbed-os, thanks. I tried to find whether these lib are also included in mbed 2.0 (not OS), but didn't find them. mbed-os is an os, but I should use mbed 2.0 because I need to control the program execution as more as possible. When I update mbed, I got erreur of my filesystem. the file system I'm using was in 2011. I need to try a new filesystem, but there is no example for usb device, but only sd

posted by saad essasky 31 Mar 2018

I noticed also that you declared the main-ISR shared variables as volatile, so I just did it too. but I think that you should make an atomic access to those variables. I still wonder why the filesystem in your example didn't block the ticker interrupts ??

posted by saad essasky 01 Apr 2018