一个简单的不可剥夺型内核

    最近看ucos-ii,看了前后台系统、不可剥夺型内核和可剥夺型内核,作为复习,写了个简单的不可剥夺型内核。

    基本假设:

     1。 任务自动让出CPU,即处于就绪态的任务运行一次后,该任务变为未就绪态

     2。 和任务相关的后台事件或者其他任务可使任务再次处于就绪态

     其实这个内核的目的仅仅是缩短任务响应时间,让系统不至于像前后台系统那样轮询完整个标志位才能再次执行到判断 

    源码:

    1. 头文件:os.h

typedef unsigned int INT16U; typedef unsigned char INT8U; typedef struct { void (*OSTask)(void); }OS_TCB; #define MAX_TASK 16 // 最大任务数,最低级被TaskIdle占用 void OS_Init(void); void Task_Create(void (*task)(void), INT8U prio,INT8U status); void OS_Sched(void);

    2. 源文件:os.c

#include "os.h" OS_TCB OSTCBTbl[MAX_TASK]; INT16U OSTaskRdy; // 任务就绪表,每一位表示一个任务,0表示未就绪,1表示就绪 INT16U TaskMask[16] = { 0x0001,0x0002,0x0004,0x0008, 0x0010,0x0020,0x0040,0x0080, 0x0100,0x0200,0x0400,0x0800, 0x1000,0x2000,0x4000,0x8000 }; // ======================================= // 空闲任务,无操作 // ======================================= static void TaskIdle(void) { } // ======================================= // 系统初始化函数 // ======================================= void OS_Init(void) { INT8U i; for(i = 0; i < MAX_TASK; i++) OSTCBTbl[i].OSTask = TaskIdle; // 所有指针都指向TaskIdle,以免出错 OSTaskRdy = 0x8000; // 最高位为空闲任务 } // ======================================= // 创建任务函数 // 注意,无参数检查,要求用户自己小心 // task:函数指针, // prio: 优先级,0-14 // status: 任务状态,0,1 // ======================================= void Task_Create(void (*task)(void), INT8U prio,INT8U status) { OSTCBTbl[prio].OSTask = task; if(status == 0) OSTaskRdy &= ~TaskMask[prio]; else if(status == 1) OSTaskRdy |= TaskMask[prio]; } // ======================================= // 调度函数 // 调度和运行任务 // ======================================= void OS_Sched(void) { INT8U i; // 查找处于就绪态的最高优先级任务 for(i = 0; i < MAX_TASK;i++) { if(OSTaskRdy & TaskMask[i]) break; } // 运行任务 OSTCBTbl[i].OSTask(); // 将任务切换到未就绪态,让出CPU if(i != 15) // 最低优先级为TaskIdle()任务占有,永远为就绪态 OSTaskRdy &= ~TaskMask[i]; }

3. 测试文件:main.c  (芯片:MC9S12XDP512)

#include <hidef.h> /* common defines and macros */ #include "derivative.h" /* derivative-specific definitions */ #include "os.h" extern INT16U OSTaskRdy; extern INT16U TaskMask[]; void Device_Init(void); void TaskA(void); void TaskB(void); void main(void) { /* put your own code here */ EnableInterrupts; Device_Init(); OS_Init(); Task_Create(TaskA,0,1); Task_Create(TaskB,1,1); for(;;) OS_Sched(); } void Device_Init(void) { PITMTLD0 = 199; PITMUX = 0x00; // 所有都接micro time base 0 // PIT1 PITLD1 = 4999; PITCE |= 0x02; // PIT1通道使能 PITINTE |= 0x02; // PIT1通道中断使能 PITCFLMT |= 0x80; // 使能PIT // PIT0 PITLD0 = 4999; PITCE |= 0x01; PITINTE |= 0x01; // PORT DDRB = 0xFF; // output } void TaskA(void) { PORTB_PB2 = ~PORTB_PB2; } void TaskB(void) { PORTB_PB3 = ~PORTB_PB3; } #pragma CODE_SEG NON_BANKED void interrupt 66 PIT0(void) { PITTF = 0x01; // 写1清零 OSTaskRdy |= TaskMask[0]; // 任务0处于就绪态 } void interrupt 67 PIT1(void) { PITTF = 0x02; OSTaskRdy |= TaskMask[1]; }

你可能感兴趣的:(一个简单的不可剥夺型内核)