📄 task.c
字号:
}
if (task_ptr->status !=READY && (task_ptr->status & PURE_SUSPEND==0) && (task_ptr->status & EVENT_SUSPEND==0)){
UnProtect(task_ptr);
return (task_ptr->priority);
}
old_priority= task_ptr->priority;
cur_priority=(((TASK_TCB *)KERNAL.current_thread)->priority);
if(task_ptr->status ==READY){
prio_group=old_priority/8;
prio_groupbit=(old_priority) % 8;
EnLock();
DelTaskList(&(Priority_Head[old_priority]),task_ptr);
if(Priority_Head[old_priority]==NULL){
Sub_Priority_Groups[prio_group] &=~ 1<<prio_groupbit;
}
if (Sub_Priority_Groups[prio_group]==0)
Priority_Group &= ~(1<<prio_group);
prio_group= new_priority/8;
prio_groupbit=(new_priority) % 8;
Priority_Group |= 1<<prio_group;
Sub_Priority_Groups[prio_group] |= 1<<prio_groupbit;
AddTaskList(&(Priority_Head[new_priority]),task_ptr,0);
UnLock();
}
task_ptr->priority= new_priority;
UnProtect(task_ptr);
if(new_priority<cur_priority)
_DirectSchedule(task_ptr);
return (old_priority);
}
/*
*********************************************************************************************************
* 得到一个任务的优先级函数原型
*********************************************************************************************************
*/
SIGNED GetPriority(SIGNED task_id)
{
UCHAR prio;
TASK_TCB *task_ptr;
if ( task_id >MAX_TASK_NUM) { /* Not allowed to Del idle task */
return (ERR_INVALID_TASK);
}
task_ptr=TaskTable[task_id];
DoProtect(task_ptr);
if (task_ptr == NULL) {
return (ERR_INVALID_TASK); /* Not allowed is idle task */
}
prio=task_ptr->priority;
UnProtect(task_ptr);
return (prio);
}
/*
*********************************************************************************************************
该函数是用来检查当前调用线程的堆栈的溢出情况(少于保存调用任务的上下文需要的)
,并跟踪该任务的可用堆栈空间
*********************************************************************************************************
*/
void ERR_System_Error(INT8 code)
{
printf("%d",code);
exit(code);
}
void CheckStack(void)
{
INT8U *pointer;
pointer =(INT8U *)(((TASK_TCB *)KERNAL.current_thread)->stack_end);
#if SYS_STK_GROWTH == 1
if(*pointer!==0xAA && *(pointer+1)!=0x55)
#else
if(*pointer!=0xAA && *(pointer-1)!=0x55)
#endif
ERR_System_Error(ERR_STACK_OVERFLOW);
}
/*
*********************************************************************************************************
在任务挂起规定一个超时时间时,当该时间到时,调用该函数,在进行必要的清除后,恢复挂起任务
*********************************************************************************************************
*/
void TaskSuspendTimeout(TASK_TCB *task_ptr)
{
if(task_ptr->cleanup)
task_ptr->cleanup(task_ptr->cleanup_info);
_ResumeTask(task_ptr,task_ptr->status);
}
/*
*********************************************************************************************************
任务处理函数,用于任务处理超时的处理,当任务规定的运行时间到时,调用该
函数,用来终止该任务
*********************************************************************************************************
*/
void TaskTimerOut(TASK_TCB *task_ptr)
{
if (task_ptr->status!=READY){
return ;
}
StopTask(task_ptr->id);
}
/*
*********************************************************************************************************
* 该函数用来在一个正执行的任务的时间片到期时,把该任务移到具有相同优先级级任务
链表的最后,使同级任务有同等机会执行
*********************************************************************************************************
*/
void TaskTimeSlice(TASK_TCB *task_ptr)
{
DoProtect(task_ptr);
if (task_ptr->status==READY && task_ptr->time_slice==0) {
if(task_ptr->task_timeout>0) {
task_ptr->task_timeout--;
}
if(Priority_Head[task_ptr->priority]){
DelTaskList(&(Priority_Head[task_ptr->priority]),task_ptr);
AddTaskList(&(Priority_Head[task_ptr->priority]),task_ptr,0);
}
task_ptr->time_slice=SYS_TIME_SLICE;
UnProtect(task_ptr);
_DirectSchedule(((TASK_TCB *)Priority_Head[task_ptr->priority]));
}
UnProtect(task_ptr);
}
/*
*********************************************************************************************************
系统初始化函数
*********************************************************************************************************
*/
void SysInit(void)
{
#if WAIT_QUEUE_ALLOC_MODE == FALSE
UNSIGNED i;
for (i = 0; i < (MAX_WAIT_QUEUE_SIZE - 1); i++) { /* Init. list of free EVENT control blocks */
WaitQueueTable[i].queue_ptr = (WAIT_QUEUE *)&WaitQueueTable[i + 1];
}
WaitQueueTable[MAX_WAIT_QUEUE_SIZE - 1].queue_ptr = (WAIT_QUEUE *)0;
WaitQueueFreeList = &WaitQueueTable[0];
#endif
}
/*
*********************************************************************************************************
* 任务模块初始化函数
*********************************************************************************************************
*/
void TaskInit(void)
{
UNSIGNED i;
Priority_Group=0L; // 优先级组位掩码清0
for (i = 0; i <=LOWEST_PRIORITY; i++) {
Priority_Head[i] = (TASK_TCB *)0;
}
for (i = 0; i < LOWEST_PRIORITY/8; i++) {
Sub_Priority_Groups[i] = 0;
}
for(i=0;i<=HISR_LOWEST_PRIO;i++){
KERNAL.Active_HISR_Heads[i]=(TASK_HCB *)0;
}
KERNAL.current_thread = (TASK_TCB *)0;
for(i=0;i<MAX_TASK_NUM;i++)
TaskTable[i]=(TASK_TCB *)0;
for(i=0;i<MAX_HISR_NUM;i++)
HisrTable[i]=(TASK_HCB *)0;
TaskFreeList=NULL;
HisrFreeList=NULL;
DirectSched=0;
setvect(INTSWITCH,StackSave);
}
/*
*********************************************************************************************************
该函数是线程调度函数,从这任务和HISR被调度运行
*********************************************************************************************************
*/
BOOLEAN PC_GetKey (INT16U *c)
{
if (kbhit()) { /* See if a key has been pressed */
*c = getch(); /* Get key pressed */
return (TRUE);
} else {
*c = 0x00; /* No key pressed */
return (FALSE);
}
}
static INT8 generic_ffs(UNSIGNED x)
{
int r = 0;
if (!x)
return -1;
#if DEVICE_TYPE==CPU32
if (!(x & 0xffff)){
if (!(x&0xffffff))
r=24;
else r=16;
}
else if(!(x & 0xff))
r=8;
#endif
#if DEVICE_TYPE==CPU16
if(!(x & 0xff))
r=8;
#endif
#if (DEVICE_TYPE==CPU8 || DEVICE_TYPE==CPU16 || DEVICE_TYPE== CPU32)
if (!(x & 0xf)) {x >>= 4;r += 4;}
if (!(x & 3)) { x >>= 2;r += 2; }
if (!(x & 1)) { x >>= 1;r += 1; }
#endif
return r;
}
static INT8 generic_ffs8(INT8U x)
{
UCHAR r = 0;
if (!x)
return -1;
if (!(x & 0xf)) {x >>= 4;r += 4;}
if (!(x & 3)) { x >>= 2;r += 2; }
if (!(x & 1)) {x >>= 1; r += 1;}
return r;
}
void Schedule()
{
UNSIGNED highprio_gp,HighRdyPrio;
TASK_HCB *HighRdyHISR;
USHORT key;
UCHAR i;
#if STACK_CHECK
CheckStack();
#endif
while(1){
EnLock();
if(!DirectSched){
for(i=0;i<=HISR_LOWEST_PRIO;i++){
if (KERNAL.Active_HISR_Heads[i]!=NULL){
HighRdyHISR=KERNAL.Active_HISR_Heads[i];
KERNAL.current_thread=HighRdyHISR;
((TASK_HCB *)KERNAL.current_thread)->type=HISR;
UnLock();
_ControlToThread();
}
}
if(Priority_Group && HighRdyThread->preemption){
highprio_gp=generic_ffs(Priority_Group);
HighRdyPrio=generic_ffs8(Sub_Priority_Groups[highprio_gp])+8*highprio_gp;
HighRdyThread =(TASK_TCB *)(Priority_Head[HighRdyPrio]);
HighRdyThread->scheduled++;
KERNAL.current_thread=HighRdyThread;
((TASK_TCB *)KERNAL.current_thread)->type=TASK;
// CtxSwCtr++; /* Increment context switch counter */
UnLock();
_ControlToThread(); /* Perform a context switch */
}
else if (Priority_Group==0){
KERNAL.current_thread=NULL;
UnLock();
if (PC_GetKey(&key) == TRUE) { /* See if key has been pressed */
if (key == 0x1B) /* Yes, see if it's the ESCAPE key */
break;
}
}
}
else if(((TASK_TCB *)KERNAL.current_thread)->preemption){//直接调度
DirectSched=FALSE;
HighRdyThread->scheduled++;
KERNAL.current_thread=HighRdyThread;
// CtxSwCtr++; /* Increment context switch counter */
UnLock();
_ControlToThread(); /* Perform a context switch */
}
} //end while
TimerUninstall();
longjmp(jmpb,1); // Return to DOS
exit(0);
}
/*
*********************************************************************************************************
* 把一个中断向量与一个中断处理函数联系起来函数,该函数是硬件相关的
*********************************************************************************************************
*/
void SetupVector(INT8U vect, void (*isr)(void))
{
setvect(vect, (void interrupt (*)(void))isr);
}
/*
*********************************************************************************************************
* 允许/不允许一个中断,该函数是硬件相关的
*********************************************************************************************************
*/
void ControlIrq(INT8U irq,INT8U enable)
{
static unsigned int cached_irq_mask = 0xffff;
unsigned int mask ;
INT8U irq_mask;
if(enable==ENABLE){
mask = 1 << irq;
cached_irq_mask |= mask;
}
else{
mask = ~(1 << irq);
cached_irq_mask &= mask;
}
if (irq & 8){
irq_mask=cached_irq_mask & 0xff00 >>8;
outb(irq_mask ,0xA1);
}
else{
irq_mask=cached_irq_mask & 0x00ff;
outb(irq_mask,0x21);
}
}
/*
*********************************************************************************************************
* 创建HIST线程函数原型
*********************************************************************************************************
*/
INT8 CreateHISR(TASK_HCB *hisr_ptr,void (*hisr_entry)(void),void *stack_address,UNSIGNED stack_size,INT8U priority)
{
CHAR hisr_id;
UNSIGNED remaining;
STATUS err;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -