例題(measurement)を見てみると
RT-Linux ver2.x になってかなり変更がありました。
今まで独自にスレッドを管理していましたが、これが
POSIX thread を使うようになりました。

例題をもとに、簡単な HOWTO を(自分の為に)書いてみました。

ヘッダーファイル
------ common.h -------
#define LPT_PORT 0x378
#define LPT_IRQ 7
#define RTC_IRQ 8

#include <rtl_time.h>


struct sample {
        hrtime_t min;
        hrtime_t max;
};
まあ、ヘッダーファイルはこんなもんでしょう。
ここで目を引くのは hrtime_t でしょうか
これは、RT-Linux で使う時間用の変数のタイプです。
typedef long long hrtime_t;
と定義されています。(64ビット符号付の整数)
メインモジュール
/*
 * RTL scheduling accuracy measuring example, user program
 *
 * (C) Michael Barabanov, 1997
 *  (C) FSMLabs  1999. baraban@fsmlabs.com
 *  Released under the GNU GENERAL PUBLIC LICENSE Version 2, June 1991
 *  Any use of this code must include this notice.
 */

#include <stdio.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <rtl_fifo.h>
#include <asm/rt_time.h>
#include "common.h"



int main()
{
        int fd0;
        int n;
        struct sample samp;
        
        if ((fd0 = open("/dev/rtf0", O_RDONLY)) < 0) {
                fprintf(stderr, "Error opening /dev/rtf0\n");
                exit(1);
        }


        while (1) {
                n = read(fd0, &samp, sizeof(samp));
                printf("min: %8d, max: %8d\n", (int) samp.min, (int) samp.max);
                fflush(stdout);
        }
	return 0;
}
メインの方では、FIFOバッファからデータを読んで表示するだけですね
RT-Linux に固有なものは /dev/rtf0 くらいです。
この rtf0 は RT-Linux の FIFOバッファのデバイスです。
この FIFO を通してデータを交換します。
さて、・・・問題なのはリアルタイムで動く以下のモジュールファイルです。
私自身もあまり詳しく無いので、さらりと読んでください(笑)
/*
 * RTL scheduling accuracy measuring example
 *
 * (C) Michael Barabanov, 1997
 *  (C) FSMLabs  1999. baraban@fsmlabs.com
 *  Released under the GNU GENERAL PUBLIC LICENSE Version 2, June 1991
 *  Any use of this code must include this notice.
 */

#include <rtl.h>
#include <rtl_fifo.h>
#include <time.h>
#include <rtl_sched.h>
#include <rtl_sync.h>
#include <pthread.h>
#include <unistd.h>
#include <rtl_debug.h>
#include <errno.h>
#include "common.h"

int ntests=500;
int period=1000000;
int mode=0;
int fifo_size=4000;
int advance=0;

MODULE_PARM(period,"i");
MODULE_PARM(ntests,"i");
MODULE_PARM(mode,"i");
MODULE_PARM(advance,"i");

pthread_t thread;
int fd_fifo;

void *thread_code(void *param) {

        hrtime_t expected;
        hrtime_t diff;
        hrtime_t now;
        hrtime_t min_diff;
        hrtime_t max_diff;
        struct sample samp;
        int i;
        int cnt = 0;
        DECLARE_CPUID(cpu_id);

        rtl_printf ("Measurement task starts on CPU %d\n", cpu_id);
        if (mode) {
                int ret = rtl_setclockmode (rtl_getschedclock(), RTL_CLOCK_MODE_
PERIODIC, period);

                if (ret != 0) {
                        conpr("Setting periodic mode failed\n");
                        mode = 0;
                }
        }

        if (mode) {
                struct timespec resolution;

                /* need to round up the period; should this be done
                 * in pthread_make_periodic? */
                clock_getres (rtl_getschedclock(), &resolution);
                period = timespec_to_ns (&resolution);
        } else {

                rtl_setclockmode (rtl_getschedclock(), RTL_CLOCK_MODE_ONESHOT, 0
);
        }

        expected = clock_gethrtime(rtl_getschedclock()) + 2 * period;

        if (advance) {
                pthread_make_periodic_np (pthread_self(), expected - advance, pe
riod);
        } else {
                pthread_make_periodic_np (pthread_self(), expected, period);
        }


        fd_fifo = open("/dev/rtf0", O_NONBLOCK);
        if (fd_fifo < 0) {
                rtl_printf("/dev/rtf0 open returned %d\n", fd_fifo);
                return (void *) -1;
        }

        if (advance) {
                rtl_stop_interrupts(); /* Be careful with this! The task won't b
e preempted by anything else. This is probably only appropriate for small high-p
riority tasks. */
        }

        do {
                min_diff = 2000000000;
                max_diff = -2000000000;

                for (i = 0; i < ntests; i++) {
                        ++cnt;
                        pthread_wait_np();

                        now = clock_gethrtime(CLOCK_UST);
                        if (advance && !mode) {
                                if (now < expected) {
                                        rtl_delay (expected - now);
                                }
                                now = clock_gethrtime(CLOCK_UST);
                        }
                        diff = now - expected;
                        if (diff < min_diff) {
                                min_diff = diff;
                        }
                        if (diff > max_diff) {
                                max_diff = diff;
                        }

                        expected += period;
                }

                samp.min = min_diff;
                samp.max = max_diff;
                write (fd_fifo, &samp, sizeof(samp));
        } while (1);
        return 0;
}



int init_module(void)
{
        pthread_attr_t attr;
        struct sched_param sched_param;
        int thread_status;
        int fifo_status;

        rtf_destroy(0);
        fifo_status = rtf_create(0, fifo_size);
        if (fifo_status) {
                rtl_printf("RTL measurement test fail. fifo_status=%d\n",fifo_st
atus);
                return -1;
        }


        rtl_printf("RTL measurement module on CPU %d\n",rtl_getcpuid());
        pthread_attr_init (&attr);
        pthread_attr_setcpu_np(&attr, 0 /*!rtl_getcpuid()*/);
        sched_param.sched_priority = 1;
        pthread_attr_setschedparam (&attr, &sched_param);
        rtl_printf("About to thread create\n");
        thread_status = pthread_create (&thread,  &attr, thread_code, (void *)1)
;
        if (thread_status != 0) {
                rtl_printf("failed to create RT-thread; errno=\n", errno);
                return -1;
        } else {
/*              rtl_printf("created RT-thread\n"); */
        }

        return 0;
}


void cleanup_module(void)
{
        rtl_printf ("Removing module on CPU %d\n", rtl_getcpuid());
        pthread_delete_np (thread);
        close(fd_fifo);
/* should be:   pthread_cancel(thread); pthread_join(thread); */
/* or:          rtl_pthread_kill_other_threads(); */
        rtf_destroy(0);
}

このモジュールは以下の3個の関数から出来ています。
  1. void *thread_code(void *param)
  2. int init_module(void)
  3. void cleanup_module(void)
それぞれ、実際に走るスレッド部分、モジュールの初期化、モジュールの終了
となっています。
時間を追って、(簡単に)中を見ていくと

モジュールの初期化
モジュールの初期化は2段階あります、まずデータ入出力のFIFOの確保
次にスレッドの作成です。
  1. FIFO の確保
    rtf_destroy(0);
    使用しようとする FIFOバッファを開放して
    fifo_status = rtf_create(0, fifo_size);
    新しく FIFO バッファを作る
    if (fifo_status) {
    FIFOの確保に失敗したらエラーメッセージを出して -1 を返す
  2. スレッドを作る
    pthread_attr_init (&attr);
    man で出てこない(??)、構造体 pthread_attr_t を初期化する関数です。
    pthread_attr_setcpu_np(&attr, 0 /*!rtl_getcpuid()*/);
    スレッドを実行するCPUを指定します、指定した結果は attr に入っているようです。CPUを指定するときは /proc/cpuinfo の processorの数字を指定します。
    sched_param.sched_priority = 1;
    スレッドスケジュールの優先度を決めます。
    pthread_attr_setschedparam (&attr, &sched_param);
    そして、スレッドアトリビュートに値を設定します。
    thread_status = pthread_create (&thread, &attr, thread_code, (void *)1)
    スレッドを作ります。 pthread_create() はmanで出てこないので予想ですが
    pthread_create(
    スレッドIDを書き込むポインター
    スレッドのアトリビュートへのポインター
    スレッドで走らせる関数へのポインター
    その関数への引き数へのポインター)

    のようです。
    ちなみに、インクルードファイル pthread.h では
    Create a thread with given attributes ATTR (or default attributes if ATTR is NULL),
    and call function START_ROUTINE with given arguments ARG.
    extern int pthread_create __P ((pthread_t *__thread,
    __const pthread_attr_t *__attr,
    void *(*__start_routine) (void *),
    void *__arg));

    と、なっています
    if (thread_status != 0) {
    スレッドの作成でエラーが発生すれば、-1 を返します。
    正常に終了すれば、0を返して初期化を終わります。