一、基于抢占优先级的任务调度
Xenomai的默认调度策略是基于抢占优先级的FIFO(先进先出)调度。就是说,当高优先级准备好执行时,低优先级任务的执行被中断。当具有相同优先级的多个进程准备好运行时,默认情况下,首先在调度程序的等待队列中排队的任务将首先运行(以FIFO排序),并一直运行到底。
使用基于抢占优先级的调度程序,每个任务都有一个优先级,内核确保将CPU分配给准备运行的最高优先级任务。这种调度方法是抢占式的,因为如果优先级高于当前任务的任务准备好运行,内核将保存当前任务的上下文并切换到优先级更高的任务的上下文。Xenomai内核的优先级介于最高优先级99和最低优先级1之间。
二、相关API
1、
rt_task_create ( RT_TASK * task,
const char * name,
int stksize,
int prio,
int mode
)
在创建任务的时候就可以赋予任务以优先级,在rt_task_create()可赋予任务以优先级。
2、 rt_task_set_priority(RT_TASK *task, int prio)
可通过此函数第二个参数进行修改相应的任务的优先级。
3、 void rt_timer_spin(RTIME ns) 将CPU挂起,相当于延时。
三、例子
1、三个具有不同优先级的任务。每个任务都有一个EXECTIME ns的执行,在每个SPINTIME ns之后都会打印一条消息。
程序4a:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <alchemy/task.h>
#include <alchemy/sem.h>
#include <alchemy/timer.h>
#define NTASKS 3
#define HIGH 52 /* high priority */
#define MID 51 /* medium priority */
#define LOW 50 /* low priority */
RT_TASK demo_task[NTASKS];
RT_SEM mysync;
#define EXECTIME 1e8 // execution time in ns
#define SPINTIME 1e7 // spin time in ns
void demo(void *arg)
{
RTIME starttime, runtime;
RT_TASK_INFO taskinfo;
int num=*(int *)arg;
printf("Task : %d\n",num);
rt_sem_p(&mysync,TM_INFINITE);
runtime = 0;
while(runtime < EXECTIME) {
rt_timer_spin(SPINTIME); // spin cpu doing nothing
runtime = runtime + SPINTIME;
printf("Running Task : %d at ms : %d\n",num, runtime/1000000);
}
printf("End Task : %d\n",num);
}
//startup code
void startup()
{
int i;
char str[20] ;
// semaphore to sync task startup on
rt_sem_create(&mysync,"MySemaphore",0,S_FIFO);
for(i=0; i < NTASKS; i++) {
printf("start task : %d\n",i);
sprintf(str,"task%d",i