目标实现一个多任务环境。
1. 系统可以多任务执行;
2. 任务可以模块化编程;
3. 没有调度算法, 调度点由用户决定。
操作系统描述的是多任务处理。多任务的意思是在宏观上多个任务是同时在运行的,但是微观上,任何一个时刻只有一个任务在运行。
操作系统有一个任务控制块的结构体,里面有一个最重要的成员:栈指针,记录任务在切换时候上下文的位置。先定义TCB结构体
typedef struct TCB{
STACK *stack_ptr;
}TCB;
声明创建函数
void task_creat(TCB*tcb, TASK_ENTRY fun, STACK *stack);
创建任务的时候,任务的栈指针应该指向栈底,因为任务被调度运行,总是出栈,栈指针是增长的。
void task_creat(TCB*tcb, TASK_ENTRY fun, STACK *stack)
{
tcb->stack_ptr =stack_init(stack, size, fun);
}
所以有栈初始化函数
U32 *stack_init(STACK *p_stk_base, U32 stk_size, TASK_ENTRY p_task);
初始化栈指针,把任务地址(本质是一个函数)压入栈,然后返回栈底指针。
现在main里创建两个任务,然后让CPU调度。
void main()
{
uart_init();
char *ptr ="WELLCOME TO YSJ_OS\n";
task_creat(&tcb1,fun1, stack1);
task_creat(&tcb2,fun2, stack2);
new_task = &tcb1;
old_task = &tcb2;
/*start_schedule function is in asm*/
extern void start_schedule();
start_schedule();
while (1)
{
;
//uart_print_str(ptr);
};
}
大体框架写出来后,应该补充什么的就补充什么,比如两个任务的任务控制块tcb1、tcb2、任务函数fun1、fun2、开始调度函数start_schedule。new_task函数是指要被调度运行的任务,old_task函数是指要被调换出去停止运行的任务。
void fun1(void *temp)
{
while (1)
{
uart_print_str("fun1 print\n");
old_task =&tcb1;
new_task =&tcb2;
schedule();
}
}
void fun2(void *temp)
{
while (1)
{
uart_print_str("fun2 print\n");
};
}