89 lines
2.5 KiB
C
89 lines
2.5 KiB
C
#include <os_sched.h>
|
|||
|
|
#include "os_port.h"
|
||
|
|
#include "os_critical.h"
|
||
|
|
#include "os_rdy_list.h"
|
||
|
|
#include "os_yield_list.h"
|
||
|
|
#include "os_idle.h"
|
||
|
|
#include "os_isr.h"
|
||
|
|
|
||
|
|
volatile os_task_t* g_os_sched_current_task_p;
|
||
|
|
volatile os_size_t g_os_sched_pending_cnt;
|
||
|
|
static volatile os_task_t* p_curr_task;
|
||
|
|
static volatile os_task_t* p_next_task;
|
||
|
|
static os_bool_t s_os_sched_wip_flag;
|
||
|
|
|
||
|
|
/* ------------------------------------------------------------------------------------------------------------------ */
|
||
|
|
/* */
|
||
|
|
|
||
|
|
|
||
|
|
void os_sched_init(void){
|
||
|
|
g_os_sched_current_task_p = 0;
|
||
|
|
g_os_sched_pending_cnt = 0;
|
||
|
|
s_os_sched_wip_flag = OS_FALSE;
|
||
|
|
}
|
||
|
|
|
||
|
|
void os_sched_in_isr(void){
|
||
|
|
os_critical_enter_in_isr();
|
||
|
|
|
||
|
|
if(s_os_sched_wip_flag == OS_TRUE){
|
||
|
|
// 调度正在进行中,返回
|
||
|
|
os_critical_leave_in_isr();
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
s_os_sched_wip_flag = OS_TRUE;
|
||
|
|
|
||
|
|
if(g_os_isr_nesting_cnt>0){
|
||
|
|
// 中断嵌套
|
||
|
|
g_os_sched_pending_cnt++;
|
||
|
|
s_os_sched_wip_flag = OS_FALSE;
|
||
|
|
os_critical_leave_in_isr();
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(g_os_sched_current_task_p && g_os_sched_current_task_p->state == kOsTaskState_Running){
|
||
|
|
// 当前任务还在运行,返回
|
||
|
|
s_os_sched_wip_flag = OS_FALSE;
|
||
|
|
os_critical_leave_in_isr();
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
p_curr_task = g_os_sched_current_task_p;
|
||
|
|
|
||
|
|
// 获取下一个任务
|
||
|
|
os_priority_t priority = os_priority_get_highest();
|
||
|
|
os_rdy_list_t* p_rdy_list = os_rdy_list_get(priority);
|
||
|
|
os_list_node_t* p_node = p_rdy_list->head.next;
|
||
|
|
p_next_task = os_list_member_of(p_node, os_task_t, node);
|
||
|
|
if(!os_idle_is_idle_task((os_task_t*)p_next_task)){
|
||
|
|
os_rdy_list_remove((os_task_t*)p_next_task);
|
||
|
|
}
|
||
|
|
|
||
|
|
// yield 的任务加入就绪表
|
||
|
|
for(p_node = g_os_yield_list.next; p_node!=&g_os_yield_list; ){
|
||
|
|
os_task_t* p_task = os_list_member_of(p_node, os_task_t, node);
|
||
|
|
p_node = p_node->next;
|
||
|
|
os_yield_list_remove(p_task);
|
||
|
|
if(!os_idle_is_idle_task(p_task)) {
|
||
|
|
os_rdy_list_insert(p_task);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// 下个任务就是当前任务, 获得一次运行的机会
|
||
|
|
if(p_next_task==p_curr_task){
|
||
|
|
p_next_task->state = kOsTaskState_Running;
|
||
|
|
p_next_task->remain_ticks = p_next_task->init_ticks;
|
||
|
|
s_os_sched_wip_flag = OS_FALSE;
|
||
|
|
os_critical_leave_in_isr();
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
s_os_sched_wip_flag = OS_FALSE;
|
||
|
|
os_critical_leave_in_isr();
|
||
|
|
|
||
|
|
// 执行上下文切换
|
||
|
|
os_port_context_switch((void*)(p_curr_task?&p_curr_task->stack.sp:0), (void*)&p_next_task->stack.sp);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|