以前玩AVR时写的一套最基本的调度核,应用在一些系统中,静态分配,使用起来很方便,要占用一个定时器。实现了任务延时、任务挂起、任务恢复、资源分配。具体的参见附件,下面做一些简单的说明。
定义时钟滴答值,单位ms
#define SYS_TICK_FREQ 1000
位操作定义
#define sbi(Port, Bit) (Port |= (1<<Bit))
#define cbi(Port, Bit) (Port &= ~(1<<Bit))
#define eoi(Port, Bit) (Port ^= (1<<Bit))
定义的任务数量
#define N 5
定义的单个任务占用的RAM
#define S 250
定义任务属性结构
typedef struct TASK_CONTROL_BLOCK
{
volatile unsigned int ui_task_entry;
volatile unsigned int ui_task_tick;
volatile unsigned char uc_task_property;
volatile unsigned char uc_task_stack[S];
}
STRUCT_TCB;
STRUCT_TCB TCB[N];
定义的任务数量和当前的任务检索值
volatile unsigned char uc_task_quantity;
volatile unsigned char uc_task_current;
调度核中的所有函数
void OS_Init(void);
void OS_TaskStart(void);
void OS_TaskSchedule(void);
void OS_TaskDelay(unsigned int ui_ms);
void OS_TaskCreate(void(*pTaskEntry)(void));
#define OS_TaskPause(task_id, b_pause) \
b_pause==false? \
cbi(TCB[task_id].uc_task_property, 7): \
sbi(TCB[task_id].uc_task_property, 7) \
#define OS_IsTaskPause(task_id) \
TCB[task_id].uc_task_property & 0x80? \
true: \
false \
另外处理临界时的定义,具体见附件
#define PUSH_ALL()
#define POP_ALL()
在调用时比较简单,比如:
int main(void)
{
OS_Init();
OS_TaskCreate(Task_1);
OS_TaskCreate(Task_2);
OS_TaskCreate(Task_3);
OS_TaskStart();
return(0);
}
void Task_1(void)
{
TaskStart:
// 你的代码
OS_TaskDelay(0);
goto TaskStart;
}
void Task_2(void)
{
TaskStart:
// 你的代码
eoi(DO8, LAMP_R);
OS_TaskDelay(500);
goto TaskStart;
}
void Task_3(void)
{
TaskStart:
// 你的代码
eoi(DO8, LAMP_G);
OS_TaskDelay(500);
goto TaskStart;
}
上面这个例子就实现了两个指示灯的定时闪烁,调用OS_TaskDelay函数将立刻执行调度函数,并判断当前任务的滴答值进行处理,需要说明的是Task_1中的OS_TaskDelay参数只能为0,这个任务相当于整个调度系统的IDLE任务。
附件:https://static.assets-stash.eet-china.com/album/old-resources/2008/12/13/e3eb1a4a-2c87-4ea9-b024-4c8cb39f5983.rar
用户1065177 2009-4-1 18:04