📄 task.c
字号:
return (ERR_INVALID_PRIORITY);
}
if (stack_size<=SYS_MIN_STACK ) return (ERR_INVALID_SIZE);
/* TASK_TCB init*/
task_id=_NewTaskId();
if(task_id<0)
return (task_id);
#if ENABLE_MEM
err=AllocBuff(KERNAL.task_pool,&(void *)task_ptr,-1);
if(err!=OK)
return (ERR_NO_MEMORY);
err=AllocBuff(KERNAL.stack_pool,&(void *)pointer,-1);
if(err!=OK){
FreeBuff(task_ptr);
return (ERR_NO_MEMORY);
}
#if SYS_STK_GROWTH==1
stack_address=(UNSIGNED *)pointer+stack_size;
#else
stack_address=pointer;
#endif
#else
if(!task_ptr) return ERR_INVALID_TASK;
else if(TaskTable[task_ptr->id]==task_ptr) return (task_ptr->id);
#endif
#if DEBUG
DebugLog(CREATE_SIGTASK_ID,task_ptr->id);//在日志中记录操作,时间等信息
#endif
TaskTable[task_id]=task_ptr;
task_ptr->id=task_id;
task_ptr->type=SIG_TASK;
task_ptr->current_protect=NULL;
task_ptr->priority=priority;
task_ptr->time_slice=SYS_TIME_SLICE;
task_ptr->task_timeout=-1;
task_ptr->preemption=FALSE;
task_ptr->timer_active=FALSE;
task_ptr->stack_start=(UNSIGNED *)stack_address;
task_ptr->stack_pointer =stack_address; /* TaskInit the task's stack */
#if SYS_STK_GROWTH==1
task_ptr->stack_end=(UNSIGNED *)stack_address-stack_size;
#else
task_ptr->stack_end=(UNSIGNED *)stack_address+stack_size;
#endif
#if STACK_CHECK
stack_address=(INT8U *)(task_ptr->stack_end);
*stack_address=0xAA;
#if SYS_STK_GROWTH == 1
*(stack_address+1)=0X55;
#else
*(stack_address-1)=0X55;
#endif
#endif
task_ptr->scheduled=0;
#if ENABLE_SIGNAL_HANDLE==TRUE
task_ptr->enabled_signals =0;
#endif
task_ptr->status=EVENT_SUSPEND;
return (task_id);
}
/*
*********************************************************************************************************
* 创建任务函数原型
创建任务的扩展形式:创建带参数的任务,
任务创建后可以处于准备好状态.也可以处于挂起状态,
根据任务结构在创建前分配与否,提供两种函数形式
*******************************************************************************************************
*/
#if ENABLE_MEM
SIGNED CreateTaskExt(void(*entry)(INT8U, void*),INT8U argc, void *argv,UNSIGNED stack_size,INT8U priority,INT8U auto_start)
#else
SIGNED CreateTaskExt(TASK_TCB *task_ptr,void(*entry)(INT8U, void*),INT8U argc, void *argv, INT8U *stack_address, UNSIGNED stack_size,
INT8U priority,INT8U auto_start)
#endif
{
UCHAR prio_group,prio_groupbit;
SIGNED task_id;
STATUS err;
void *pointer;
#if ENABLE_MEM
TASK_TCB *task_ptr;
INT8U *stack_address;
#endif
if (entry==NULL) return(ERR_INVALID_ENTRY);
if (stack_address==NULL) return(ERR_INVALID_MEMORY);
if (stack_size<=SYS_MIN_STACK ) return (ERR_INVALID_SIZE);
if(auto_start>1) return(ERR_INVALID_START);
task_id=_NewTaskId();
if(task_id<0)
return (task_id);
#if ENABLE_MEM
err=AllocBuff(KERNAL.task_pool,&(void *)task_ptr,-1);
if(err!=OK)
return (ERR_NO_MEMORY);
err=AllocBuff(KERNAL.stack_pool,&(void *)pointer,-1);
if(err!=OK){
FreeBuff(task_ptr);
return (ERR_NO_MEMORY);
}
#if SYS_STK_GROWTH==1
stack_address=(UNSIGNED *)pointer+stack_size;
#else
stack_address=pointer;
#endif
#else
if(!task_ptr) return ERR_INVALID_TASK;
else if(TaskTable[task_ptr->id]==task_ptr) return (task_ptr->id);
#endif
if (priority > LOWEST_PRIORITY) /* Make sure priority is within allowable range */
return (ERR_INVALID_PRIORITY);
#if DEBUG
DebugLog(CREATE_TASK_ID,task_ptr->id);//在日志中记录操作,时间等信息
#endif
TaskTable[task_id]=task_ptr;
task_ptr->id=task_id;
task_ptr->type=TASK;
task_ptr->current_protect=NULL;
task_ptr->priority=priority;
task_ptr->time_slice=SYS_TIME_SLICE;
task_ptr->task_timeout=-1;
task_ptr->preemption=TRUE;
task_ptr->timer_active=TRUE;
task_ptr->stack_start=(UNSIGNED *)stack_address;
task_ptr->entry=(void *)entry;
task_ptr->argc=argc;
task_ptr->argv=argv;
#if ENABLE_SIGNAL_HANDLE==TRUE
task_ptr->enabled_signals =0; //包含允许信号掩码
#endif
task_ptr->stack_pointer =(UNSIGNED *) _InitTaskStack(task_ptr); /* TaskInit the task's stack */
#if SYS_STK_GROWTH==1
task_ptr->stack_end=(UNSIGNED *)stack_address-stack_size;
#else
task_ptr->stack_end=(UNSIGNED *)stack_address+stack_size;
#endif
#if STACK_CHECK
stack_address=(INT8U *)(task_ptr->stack_end);
*stack_address=0xAA;
#if SYS_STK_GROWTH == 1
*(stack_address+1)=0X55;
#else
*(stack_address-1)=0X55;
#endif
#endif
task_ptr->scheduled=0;
InitTaskTimer(&(task_ptr->timer_control),task_ptr);
if (auto_start){
prio_group=priority/8;
prio_groupbit=priority % 8;
EnLock();
Priority_Group |= 1<<prio_group;
Sub_Priority_Groups[prio_group] |= 1<<prio_groupbit;
AddTaskList(&(Priority_Head[priority]),task_ptr,0);
UnLock();
task_ptr->status=READY;
}
else
task_ptr->status=PURE_SUSPEND;
return (task_id);
}
/*
*********************************************************************************************************
* 强制终止一个任务函数原型,终止后的任务只能用任务复位调用来恢复
*********************************************************************************************************
*/
STATUS StopTask(SIGNED task_id)
{
TASK_TCB *task_ptr;
SIGNED state;
if (!KERNAL.current_thread){
return (ERR_INVALID_TASK);
}
if ( task_id >MAX_TASK_NUM) { /* Not allowed to Del idle task */
return (ERR_INVALID_TASK);
}
task_ptr=TaskTable[task_id];
#if DEBUG
DebugLog(STOP_TASK_ID,task_ptr->name);//在日志中记录操作,时间等信息
#endif
DoProtect(task_ptr);
if(task_ptr==NULL)
return (ERR_INVALID_TASK);
if (task_ptr->status==TERMINATED || (((TASK_TCB *)KERNAL.current_thread)->type==SIG && task_ptr==KERNAL.current_thread)){
UnProtect(task_ptr);
return(OK);
}
if (task_ptr->status & PURE_SUSPEND || task_ptr->status & EVENT_SUSPEND){//挂起状态//必须保护,
if(task_ptr->status & TIMER_SUSPEND)
StopTimer(&(task_ptr->timer_control));
task_ptr->status=TERMINATED;
if(task_ptr->cleanup)
task_ptr->cleanup(task_ptr->cleanup_info);
UnProtect(task_ptr);
return (OK);
}
else if (task_ptr->status==READY){
task_ptr->status=TERMINATED;
UnProtect(task_ptr);
state= _SuspendTask(task_ptr,TERMINATED,NULL,NULL,0); // 若不在挂起和停止状态,先挂起
if(state==TRUE)
_ControlToSystem();
}
return (OK);
}
/*
*********************************************************************************************************
* 删除一个任务函数原型
*********************************************************************************************************
*/
STATUS DelTask(SIGNED task_id)
{
TASK_TCB *task_ptr;
UNSIGNED *pointer;
if ( task_id >MAX_TASK_NUM) { /* Not allowed to Del idle task */
return (ERR_INVALID_TASK);
}
task_ptr=TaskTable[task_id];
#if DEBUG
DebugLog(DELETE_TASK_ID,task_ptr->id);//在日志中记录操作,时间等信息
#endif
DoProtect(task_ptr);
if(task_ptr==NULL)
return (ERR_INVALID_TASK);
if (task_ptr->status!=TERMINATED && task_ptr->status!=FINISHED){/* Not allowed to Del not terminated or not finished task */
UnProtect(task_ptr); //ensure not calling task
return(ERR_INVALID_DELETE);
}
#if ENABLE_MEM
#if SYS_STK_GROWTH==1
pointer=task_ptr->stack_end;
#else
pointer=task_ptr->stack_start;
#endif
FreeBuff(pointer);
#endif
UnProtect(task_ptr);
EnLock();
task_ptr->next=TaskFreeList;
TaskFreeList=task_ptr;
TaskTable[task_id]=NULL;
UnLock();
return (OK);
}
/*
*********************************************************************************************************
* 复位一个特定停止或已完成的任务函数原型,复位后任务处于挂起状态,等待恢复执行
*********************************************************************************************************
*/
STATUS ResetTask(SIGNED task_id)
{
UCHAR prio_group,prio_groupbit;
TASK_TCB *task_ptr;
if (!KERNAL.current_thread){
return (ERR_INVALID_TASK);
}
if (task_id >MAX_TASK_NUM) /* Not allowed to Del idle task */
return (ERR_INVALID_TASK);
task_ptr=TaskTable[task_id];
#if DEBUG
DebugLog(RESET_TASK_ID,task_ptr->name);//在日志中记录操作,时间等信息
#endif
DoProtect(task_ptr);
if (task_ptr == NULL)
return (ERR_INVALID_TASK);
if (task_ptr->status!=TERMINATED && task_ptr->status!=FINISHED){/* Not allowed to Del not terminated or not finished task */
UnProtect(task_ptr);
return(ERR_NOT_TERMINATED);
}
prio_group=(task_ptr->priority)/8;
prio_groupbit=(task_ptr->priority) % 8;
EnLock();
Priority_Group |= (1<<prio_group);
Sub_Priority_Groups[prio_group] |= 1<<prio_groupbit;
AddTaskList(&(Priority_Head[task_ptr->priority]),task_ptr,0);
UnLock();
task_ptr->stack_pointer =(UNSIGNED *) _InitTaskStack(task_ptr); /* TaskInit the task's stack */
task_ptr->status=READY;
UnProtect(task_ptr);
_ControlToSystem();
return (OK);
}
/*
*********************************************************************************************8
挂起任务的内部调用函数,任务无论是强行挂起,还是因等待某个资源发生而挂起,都最终调用该函数
在挂起一个任务时,任务状态的改变必须与相应表格的修改一次完成,否则将出现不一致。
并定义任务的清除函数和挂起时间量函数原型
********************************************************************************************
*/
STATUS _SuspendTask(TASK_TCB *task_ptr,INT8U suspend_type,void (*cleanup),void*information,UNSIGNED timeout)
{
UCHAR prio_group,prio_groupbit;
#if DEBUG
DebugLog(CHANGE_PRIORITY_ID,task_ptr->name);//在日志中记录操作,时间等信息
#endif
DoProtect(task_ptr);
if (task_ptr == NULL) /* Not allowed to Del idle task */
return (ERR_INVALID_TASK);
if (task_ptr->status & PURE_SUSPEND || task_ptr->status & EVENT_SUSPEND){// 如果任务已经挂起
UnProtect(task_ptr);
return FALSE;
}
else if (task_ptr->status==READY || task_ptr->status==FINISHED || task_ptr->status==TERMINATED)
{
task_ptr->cleanup=cleanup;
task_ptr->cleanup_info=information;
task_ptr->status=suspend_type;
if (timeout>0){
task_ptr->status |=TIMER_SUSPEND;
timeout=timeout * TIME_SCALE;
StartTimer(&(task_ptr->timer_control),timeout);
}
prio_group=(task_ptr->priority)/8;
prio_groupbit=(task_ptr->priority) % 8;
EnLock();
DelTaskList(&(Priority_Head[task_ptr->priority]),task_ptr);
if(Priority_Head[task_ptr->priority]==NULL){
(Sub_Priority_Groups[prio_group]) &= (~(1<<prio_groupbit));
}
if (Sub_Priority_Groups[prio_group]==0)
Priority_Group &= ~(1<<prio_group);
if (task_ptr==KERNAL.current_thread){
if (Priority_Head[task_ptr->priority]) {
DirectSched=TRUE;
HighRdyThread=Priority_Head[task_ptr->priority];
}
UnLock();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -