在实时linux中调度任务的运行时错误?

时间:2014-04-01 10:09:18

标签: c linux timer real-time interrupt

#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;
}

我创建了一个调度程序,用于每2毫秒(毫秒),10毫秒和100毫秒调度任务。上面的代码正在编译并运行。运行一段时间后,调度程序将停止执行任务。有三个任务,由调度程序每2ms,10和100ms调用一次。任务是打印hi,hi1和hi3

问题:为什么上面的代码不能打印hi3 100ms? 为什么它会在一定时间后停止?

1 个答案:

答案 0 :(得分:1)

问题1) TASK3未执行,因为您没有调用它。在两个if语句之后调用TASK2

问题2) if(tasks_execution_time大于2ms:MS_to_US(2) - tasks_execution_time将为负数,而usleep将等待很长时间。我建议在usleep之前使用'else',因为if已经在检查这个。