Search code examples
clinuxtimerreal-timeinterrupt

runtime error in scheduling the tasks in realtime linux?


#define _POSIX_C_SOURCE 200809L
#define _XOPEN_SOURCE   500

#include <sched.h>  /* for sched_setsched */
#include <unistd.h> /* for usleep */
#include <time.h>   /* for clock_gettime */
#include <string.h> /* for memset */
#include <stdio.h>

#define MS_to_US(x) ((x)*1000)

void TASK1()
{
    printf("hi \n");
}

void TASK2()
{
    printf("hi2 \n");
}

void TASK3()
{
    printf("hi3 \n");
}

useconds_t delta_t_us(struct timespec const *a, struct timespec const *b)
{
    time_t const delta_sec  = b->tv_sec  - a->tv_sec;
    long   const delta_nsec = b->tv_nsec - a->tv_nsec;

    /* this might actually overflow for "long" time intervalls"
     * should be safe for a delta_t < 2ms though */
    return delta_sec * 1000000 + delta_nsec / 1000;
}

void rastertask()
{
    struct sched_param sparm;
    memset(&sparm, 0, sizeof(sparm));
    sparm.sched_priority = 10; /* 0 = lowest, 99 = highest */

    sched_setscheduler(
        0 /* pid, 0 ==> this process */,
        SCHED_RR /* policy */,
        &sparm);

    unsigned int n_loop;
    for(n_loop=0;;n_loop++) {
        struct timespec ts_start, ts_end;
        clock_gettime(CLOCK_REALTIME, &ts_start);

        TASK1(); /* gets called every 2ms */
        if( (n_loop % 5) == 0) {
            TASK2(); /* get called every 5 * 2ms = 10ms */
        }
        if( (n_loop % 50) == 0) {
            TASK2(); /* get called every 50 * 2ms = 100ms */
        }

        if( (n_loop % 250) == 0 ) {
            /* reset loop counter when smallest common
             * multiple of timing grid has been reached */
            n_loop = 0;
        }

        clock_gettime(CLOCK_REALTIME, &ts_end);
        useconds_t const tasks_execution_time = delta_t_us(&ts_start, &ts_end);

        if( tasks_execution_time >= MS_to_US(2) ) {
            /* report an error that tasks took longer than 2ms to execute */
        }

        /* wait for 2ms - task_execution_time so that tasks get called in
         * a close 2ms timing grid */
        usleep( MS_to_US(2) - tasks_execution_time );
    }
}

int main()
{
    rastertask();
    return 1;
}

I created a scheduler for scheduling the task for every 2ms (milli second), 10ms and 100ms. The above code is compiling and also running. After running for a certain amount of time then the scheduler will stop executing the tasks. There are three Tasks and called by the scheduler for every 2ms, 10 and 100ms. The tasks are printing hi, hi1 and hi3

questions : why the above code is not printing hi3 for 100ms ?? why it will stop after certain amount of time ??


Solution

  • Question 1) TASK3 isn't executed because your are not calling it. TASK2 is called after both if statements

    Question 2) if (tasks_execution_time is bigger than 2ms: MS_to_US(2) - tasks_execution_time will be negative and usleep will wait very long. I suggest an 'else' just before usleep, as the if is already checking for this.