Linux RT(1)-硬实时Linux(RT-Preempt Patch)在PC上的编译、使用和测试
by @宋宝华Barry
Linux kernel在spinlock、irq上下文方面无法抢占,因此高优先级任务被唤醒到得以执行的时间并不能完全确定。同时,Linux kernel本身也不处理优先级反转。RT-Preempt Patch是在Linux社区kernel的基础上,加上相关的补丁,以使得Linux满足硬实时的需求。本文描述了该patch在PC上的实践。我们的测试环境为Ubuntu 10.10,默认情况下使用Ubuntu 10.10自带的kernel:
RT-Preempt Patch试用运行同样的测试cyclictest benchmark工具,结果迥异:
#include <stdlib.h>#include <stdio.h>#include <time.h>#include <sched.h>#include <sys/mman.h>#include <string.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 = 50000; /* 50us*/ /* Declare ourself as a real time task */ param.sched_priority = MY_PRIORITY; if(sched_setscheduler(0, SCHED_FIFO, ?m) == -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++; while(1) { /* wait until next shot */ clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &t, NULL); /* do the stuff */ /* calculate next shot */ t.tv_nsec += interval; while (t.tv_nsec >= NSEC_PER_SEC) { t.tv_nsec -= NSEC_PER_SEC; t.tv_sec++; } }}编译之:gcc -o test_rt test_rt.c -lrt。本节就到这里,后续我们会有一系列博文来描述RT-Preempt Patch对kernel的主要改动,以及其工作原理。