RTAI的使用者空間程式設計(四)——程式碼基礎框架
阿新 • • 發佈:2019-01-30
前面先準備三個檔案:
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;
}