趣味的なIT・ネットの話題

Raspberry PiでIoTなシステム開発:リアルタイムタスクと非リアルタイムタスクとの違い:波形生成

リアルタイムタスクと非リアルタイムタスクの性能差を確認すべく、Raspbbery Piに矩形波を生成させ、ストレスをかけてみました。使用したコードは以下の通り。

#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <sched.h>
#include <sys/mman.h>
#include <string.h>

#include <wiringPi.h>

#define MY_PRIORITY (49) /* we use 49 as the PRREMPT_RT use 50
                            as the priority of kernel tasklets
                            and interrupt handler by default */

#define MAX_SAFE_STACK (8*1024) /* The maximum stack size which is
                                   guaranteed safe to access without
                                   faulting */

#define NSEC_PER_SEC    (1000000000) /* The number of nsecs per sec. */

void stack_prefault(void) {

        unsigned char dummy[MAX_SAFE_STACK];

        memset(dummy, 0, MAX_SAFE_STACK);
        return;
}

int main(int argc, char* argv[])
{
        struct timespec t;
        struct sched_param param;
//        int interval = 500000000; /* 500ms*/
        int interval = 50000; /* 50us*/

        /* Declare ourself as a real time task */


        param.sched_priority = MY_PRIORITY;
        if(sched_setscheduler(0, SCHED_FIFO, &param) == -1) {
                perror("sched_setscheduler failed");
                exit(-1);
        }

        /* Lock memory */

        if(mlockall(MCL_CURRENT|MCL_FUTURE) == -1) {
                perror("mlockall failed");
                exit(-2);
        }

        /* Pre-fault our stack */

        stack_prefault();

        clock_gettime(CLOCK_MONOTONIC ,&t);
        /* start after one second */
        t.tv_sec++;

        wiringPiSetup () ;
          pinMode (7, OUTPUT) ;

        while(1) {
                /* wait until next shot */
                clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &t, NULL);

                /* do the stuff */
//                printf("hello\n");
                digitalWrite (7, HIGH) ;

                /* calculate next shot */
                t.tv_nsec += interval;

                while (t.tv_nsec >= NSEC_PER_SEC) {
                       t.tv_nsec -= NSEC_PER_SEC;
                        t.tv_sec++;
                }

                /* wait until next shot */
                clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &t, NULL);

                /* do the stuff */
//                printf("good night\n");
                digitalWrite (7, LOW) ;

                /* calculate next shot */
                t.tv_nsec += interval;

                while (t.tv_nsec >= NSEC_PER_SEC) {
                       t.tv_nsec -= NSEC_PER_SEC;
                        t.tv_sec++;
                }

   }
}

公式のサンプルにWiringPiでのピンのアップダウンを加えただけです。これがhigh_priorityの方。

        param.sched_priority = MY_PRIORITY;
        if(sched_setscheduler(0, SCHED_FIFO, &param) == -1) {
                perror("sched_setscheduler failed");
                exit(-1);
        }

low_priorityはhigh_priorityの上記の優先度設定部分をコメントアウトしたものです。

ストレスはstressコマンドでかけました。low_priorityは起動直後は良いのですが、stressで負荷をかけた途端ぐちゃぐちゃになります。一方high_priorityはそのまま。よく見るとstressをかけない状態でもhigh_priorityの方が波形が安定している様に見えます。

デフォルトカーネルもconfig_preemptは入っているので、それとの比較をすべきなのですが、手元に環境が無いのでそれはまたいつか。

 

 


Facebooktwitterpinterestlinkedinmail
納得したらすぐにシェア!