1. 程式人生 > >RTAI的使用者空間程式設計(四)——程式碼基礎框架

RTAI的使用者空間程式設計(四)——程式碼基礎框架

前面先準備三個檔案:
1. Makefile

TARGET = periodic_task  
SRCS = periodic_task.c 
prefix := $(shell rtai-config --prefix)
ifeq ($(prefix),)
$(error Please add <rtai-install>/bin to your PATH variable)
endif
OBJECTS = $(SRCS:.c=.o)
CC = $(shell rtai-config --cc)
LXRT_CFLAGS = $(shell rtai-config --lxrt-cflags)
LXRT_LDFLAGS = $(
shell rtai-config --lxrt-ldflags all: $(TARGET) %.o: %.c $(CC) -c $(LXRT_CFLAGS) $< $(TARGET) : $(OBJECTS) $(CC) -o $(TARGET) $(LXRT_LDFLAGS) -llxrt $(OBJECTS) clean: rm -f *.o *~ core.* $(TARGET) .PHONY: clean

2. run
實際上是呼叫rtai-load來執行的.

${DESTDIR}/usr/realtime/bin/rtai-load

3. .runinfo
隱藏檔案rtai-load根據這個來執行

prog_name:lxrt+sem+mbx+msg+fifos:!./prog_name; popall:control_c

(2 、3步驟可以簡化成另一種方式,直接進入RTAI安裝目錄,然後insmod rtai_hal.ko insmod rtai_sched.ko insmod rtai_lxrt.ko……,然後執行程式./prog_name 就行了)

4. 程式碼框架

  • 單觸發模式
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h> #include <sys/types.h> #include <sys/mman.h> #include <sys/stat.h> //#include <sys/time.h> //#include <signal.h> #include <fcntl.h> #include <sched.h> #include <rtai_lxrt.h> //#include <rtai_sem.h> //#include <rtai_msg.h> static int thread0; static void *fun0(void *arg) { RT_TASK *task; task = rt_task_init_schmod(nam2num("TASK0"), 0, 0, 0, SCHED_FIFO, 0xF); mlockall(MCL_CURRENT | MCL_FUTURE); //設定優先順序和排程演算法 這裡他用SCHED_FIFO,而SCHED_OTHER(基於時間片)優先會低些,這個Name就是實時任務的標識 nam2num 是把名字轉為name id 以免命名衝突 // 進入硬實時模式,無此語句時,預設的是軟實時 //rt_make_hard_real_time(); //此處新增程式碼,如下語句 //rt_printk("Hello World!\n"); //將實時任務或者執行緒返回到標準linux的狀態 rt_make_soft_real_time(); //刪除任務 rt_task_delete(task); return 0; } int main(void) { RT_TASK *task; // make main thread LXRT soft realtime task = rt_task_init_schmod(nam2num("MYTASK"), 9, 0, 0, SCHED_FIFO, 0xF); mlockall(MCL_CURRENT | MCL_FUTURE); // start realtime timer and scheduler rt_set_oneshot_mode(); start_rt_timer(0); // create a linux thread thread0 = rt_thread_create(fun0, NULL, 10000); // wait for end of program printf("TYPE <ENTER> TO TERMINATE\n"); getchar(); // cleanup stuff stop_rt_timer(); return 0; }

- 週期模式

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <rtai_lxrt.h>
#include <sys/io.h>

#define TICK_TIME 1000000
#define CPUMAP 0x1

static RT_TASK *main_Task;
static RT_TASK *loop_Task;
int keep_on_running = 1;
static pthread_t main_thread;
static RTIME expected;
static RTIME sampling_interval;

static void *main_loop()
{
    if (!(loop_Task = rt_task_init_schmod(nam2num("RTAI01"), 2, 0, 0, SCHED_FIFO, CPUMAP))) 
    {
        printf("CANNOT INIT PERIODIC TASK\n");
        exit(1); 
    } 

    //mlockall(MCL_CURRENT | MCL_FUTURE);(原始碼沒有,…?)
    expected = rt_get_time() + 100*sampling_interval;
    rt_task_make_periodic(loop_Task, expected, sampling_interval); 

    rt_make_hard_real_time();

    while (keep_on_running)
    {
        //insert your main periodic loop here
        rt_task_wait_period();//
        //set keep_on_running to 0 if you want to exit
    } 

    rt_task_delete(loop_Task);
    return 0;
}

int main(void)
{
    RT_TASK *Main_Task;
    if (!(Main_Task = rt_task_init_schmod(nam2num("MNTSK"), 0, 0, 0, SCHED_FIFO, 0xF))) 
    {
        printf("CANNOT INIT MAIN TASK\n");
        exit(1);
    } 

    //mlockall(MCL_CURRENT | MCL_FUTURE); 
    if ((hard_timer_running = rt_is_hard_timer_running()))
    {
        printf("Skip hard real_timer setting...\n");
        sampling_interval = nano2count(TICK_TIME);
    }
    else
    {
        printf("Starting real time timer...\n");
        rt_set_oneshot_mode();
        start_rt_timer(0);// 啟動計時器 記得用完要關掉
    } 

    sampling_interval = nano2count(TICK_TIME);
    pthread_create(&main_thread, NULL, main_loop, NULL);
    while (keep_on_running)
        sampling_interval = sampling_interval; //do nothing!

    rt_task_delete(Main_Task);
    return 0;
}