📄 task.c
字号:
if(!hisr_ptr) return ERR_INVALID_TASK;
else if(HisrTable[hisr_ptr->id]==hisr_ptr) return (hisr_ptr->id);
if (priority > HISR_LOWEST_PRIO) { /* Make sure priority is within allowable range */
return (ERR_INVALID_PRIORITY);
}
if (hisr_entry==NULL) return(ERR_INVALID_ENTRY);
if (stack_address==NULL) return(ERR_INVALID_MEMORY);
if (stack_size==SYS_MIN_STACK ) return (ERR_INVALID_SIZE);
/* TASK_TCB init*/
hisr_id=_NewHisrId();
if(hisr_id<0)
return (hisr_id);
HisrTable[hisr_id]=hisr_ptr;
hisr_ptr->id=hisr_id;
#if DEBUG
DebugLog(CREATE_HISR_ID,hisr_ptr->id);//在日志中记录操作,时间等信息
#endif
hisr_ptr->type=HISR;
hisr_ptr->current_protect=NULL;
hisr_ptr->priority=priority;
hisr_ptr->stack_start=stack_address;
hisr_ptr->stack_pointer =(UNSIGNED *) _InitHISRStack(hisr_ptr); /* TaskInit the task's stack */
#if (SYS_STK_GROWTH==1)
hisr_ptr->stack_end=(UNSIGNED *)stack_address-stack_size;
#else
hisr_ptr->stack_end=(UNSIGNED *)stack_address+stack_size;
#endif
#if STACK_CHECK
stack_address=(INT8U *)(hisr_ptr->stack_end);
*stack_address=0xAA;
#if SYS_STK_GROWTH == 1
*(stack_address+1)=0X55;
#else
*(stack_address-1)=0X55;
#endif
#endif
hisr_ptr->activation_count=0;
hisr_ptr->entry=hisr_entry;
return (hisr_id);
}
/*
*********************************************************************************************************
* 删除一个HIST线程函数
*********************************************************************************************************
*/
STATUS DelHISR(INT8 hisr_id)
{
TASK_HCB *hisr_ptr;
if (((TASK_HCB *)KERNAL.current_thread)->type==HISR)
return(ERR_INVALID_DELETE);
if ( hisr_id >MAX_HISR_NUM) { /* Not allowed to Del idle task */
return (ERR_INVALID_HISR);
}
hisr_ptr=HisrTable[hisr_id];
#if DEBUG
DebugLog(DELETE_HISR,hisr_ptr->id);//在日志中记录操作,时间等信息
#endif
DoProtect(hisr_ptr);
if (hisr_ptr == NULL) /* Not allowed to Del idle task */
return (ERR_INVALID_HISR);
if (hisr_ptr->activation_count){
UnProtect((TASK_TCB *)hisr_ptr);
return(ERR_INVALID_DELETE);
}
UnProtect(hisr_ptr);
EnLock();
hisr_ptr->next=HisrFreeList;
HisrFreeList=hisr_ptr;
HisrTable[hisr_id]=NULL;
UnLock();
return (OK);
}
/*
*********************************************************************************************************
该函数用来激活特定的HISR,如果该HISR已经激活,则该HISR的激活次数加上1,
否则,该HISR放入适当的HISR优先级表,准备调度执行.
*********************************************************************************************************
*/
void ActivateHISR(INT8 hisr_id)
{
/* if (((TASK_LISR *)KERNAL.current_thread)->type != LISR){
exit(-1) ;
}*/
TASK_HCB *hisr;
hisr=HisrTable[hisr_id];
if (hisr->activation_count>0)
(hisr->activation_count)++;
else {
AddTaskList(&(TASK_TCB *)(KERNAL.Active_HISR_Heads[hisr->priority]),(TASK_TCB *)hisr,0);
hisr->activation_count=1;
}
Schedule();
}
/*
*********************************************************************************************************
* 得到当前HISR指针函数原型
*********************************************************************************************************
*/
void *GetCurrentHISR(void)
{
TASK_HCB *hisr_ptr;
hisr_ptr=(TASK_HCB *)KERNAL.current_thread;
if (((TASK_HCB *)KERNAL.current_thread)->type ==HISR){
return (hisr_ptr);
}
else{
return (NULL);
}
}
STATUS ListHisr(INT8 hisr_id,HISR_DATA **hisr_lst)
{
TASK_HCB *hisr_ptr;
UNSIGNED i;
if (((TASK_TCB *)KERNAL.current_thread)->type==HISR)
return (ERR_INVALID_OPERATION);
if (hisr_id+1>MAX_HISR_NUM) { /* Not allowed to Del idle task */
return (ERR_INVALID_HISR);
}
if(hisr_id>=0){
hisr_ptr=HisrTable[hisr_id];
DoProtect(hisr_ptr);
if (hisr_ptr == NULL) { /* Not allowed to Del idle task */
return (ERR_INVALID_HISR);
}
(*hisr_lst)->priority=hisr_ptr->priority;
(*hisr_lst)->activation_count=hisr_ptr->activation_count ;
UnProtect(hisr_ptr);
return (OK);
}else{
for(i=0;i<MAX_HISR_NUM;i++){
hisr_ptr=HisrTable[i];
DoProtect(hisr_ptr);
if (hisr_ptr) { /* Not allowed to Del idle task */
(*hisr_lst)->priority=hisr_ptr->priority;
(*hisr_lst)->activation_count=hisr_ptr->activation_count;
hisr_lst++;
}
UnProtect(hisr_ptr);
}
return (OK);
}
}
/*
*********************************************************************************************************
该函数用来建立特定HISR运行所需的堆栈环境
*********************************************************************************************************
*/
static void * _InitHISRStack(TASK_HCB *hisr)
{
INT16U *stk;
stk =(INT16U *)hisr->stack_start; /* Load stack pointer*/
*stk-- = (INT16U)0x0202;
*stk-- = (INT16U)FP_SEG(hisr->entry); //CS /* Put pointer to task on top of stack */
*stk-- = (INT16U)FP_OFF(hisr->entry); //IP
*stk-- = _AX; /* AX = 0xAAAA */
*stk-- = _BX; /* BX = 0xCCCC */
*stk-- = _CX; /* CX = 0xDDDD */
*stk-- = _DX; /* DX = 0xBBBB */
*stk-- = _ES; /* ES= 0x0000 */
*stk-- = _DS; /* DS = 0x1111 */
*stk-- = _SI; /* SI = 0x2222 */
*stk-- = _DI; /* DI = 0x3333*/
*stk-- = (INT16U)0x4444; //BP
*stk = (INT16U)0x0202; //FLAGS
return ((void *)stk);
}
#if ENABLE_SIGNAL_HANDLE
static void *_InitSignalFrame(TASK_TCB *task_ptr,INT8U signal);
/*
*********************************************************************************************************
在信号处理句柄完成时,返回到此,在此返回任务线程,并恢复任务堆栈.
*********************************************************************************************************
*/
static void _SignalHandleExit(void)
{
DoProtect(KERNAL.current_thread);
((TASK_TCB *)KERNAL.current_thread)->sig=NULL;
((TASK_TCB *)KERNAL.current_thread)->type=((TASK_TCB *)KERNAL.current_thread)->save_type;
if(((TASK_TCB *)KERNAL.current_thread)->type==SIG_TASK){
UnProtect(KERNAL.current_thread);
_SuspendTask(KERNAL.current_thread,EVENT_SUSPEND,NULL,NULL,0);
}
else{
UnProtect(KERNAL.current_thread);
EnLock();
DirectSched=TRUE;
UnLock();
}
Schedule();
}
/*
*********************************************************************************************************
* 清除当前任务已接收到的信号
*********************************************************************************************************
*/
UNSIGNED ClearSignal(void)
{
UNSIGNED signals;
if (((TASK_TCB *)KERNAL.current_thread)->type!=TASK && ((TASK_TCB *)KERNAL.current_thread)->type!=SIG_TASK) {
return (ERR_INVALID_OPERATION);
}
#if DEBUG
DebugLog(CHECK_SIGNAL_ID,0);//在日志中记录操作,时间等信息
#endif
DoProtect(KERNAL.current_thread);
signals=((TASK_TCB *)KERNAL.current_thread)->signals;
((TASK_TCB *)KERNAL.current_thread)->sig=NULL;
UnProtect(KERNAL.current_thread);
return (signals);
}
/*
*********************************************************************************************************
* 主动接收信号并处理,然后清除信号位
*********************************************************************************************************
*/
STATUS ReceiveSignal(SIGNED task_id, UNSIGNED signal,INT8 mode)
{
UNSIGNED signals;
TASK_TCB *task_ptr;
task_ptr=(TASK_TCB *)KERNAL.current_thread;
if (task_ptr->type!=TASK && task_ptr->type!=SIG_TASK) {
return (ERR_INVALID_OPERATION);
}
#if DEBUG
DebugLog(CHECK_SIGNAL_ID,0);//在日志中记录操作,时间等信息
#endif
DoProtect(task_ptr);
if(task_ptr->sig->signal_handler[signal]==NULL || task_ptr->enabled_signals==0)
return ERR_NOT_REGISTERED;
signals=task_ptr->signals;
if (task_ptr->enabled_signals & (signals & 1<< signal))
if((task_id>=0 && task_ptr->sig->src==task_ptr->id) || (task_id==-1)){
task_ptr->sig->signal_handler[signal]();
task_ptr->signals &= ~signal;
UnProtect(task_ptr);
return (OK);
}
if(mode!=NO_SUSPEND){
UnProtect(task_ptr);
_SuspendTask(task_ptr,SIGNAL_SUSPEND,NULL,NULL,mode);
_ControlToSystem();
DoProtect(task_ptr);
if (task_ptr->enabled_signals & (signals & 1<< signal)){
if((task_id>=0 && task_ptr->sig->src==task_ptr->id) || (task_id==-1)){
task_ptr->sig->signal_handler[signal]();
task_ptr->signals &= ~signal;
UnProtect(task_ptr);
return (OK);
}
else{
task_ptr->signals &= ~signal;
UnProtect(task_ptr);
return (ERR_DST_MATCH);
}
}
UnProtect(task_ptr);
return(ERR_TIMEOUT);
}// if(suspend=SUSPEND){//任务挂起
UnProtect(task_ptr);
return (ERR_NOT_PRESENT);
}
/*
*********************************************************************************************************
* 为当前任务设置信号掩码,并返回旧的信号掩码
*********************************************************************************************************
*/
UNSIGNED SetSignalMask(UNSIGNED enable_signal_mask)
{
UNSIGNED old_enable_sig_mask;
TASK_TCB *task_ptr;
if (((TASK_TCB *)KERNAL.current_thread)->type!=TASK &&((TASK_TCB *)KERNAL.current_thread)->type!=SIG_TASK) {
return (ERR_INVALID_OPERATION);
}
#if DEBUG
DebugLog(SET_SIG_MASK,0);//在日志中记录操作,时间等信息
#endif
task_ptr=(TASK_TCB *)KERNAL.current_thread;
DoProtect(task_ptr);
old_enable_sig_mask=task_ptr->enabled_signals;
task_ptr->enabled_signals= enable_signal_mask;
UnProtect(task_ptr);
return (old_enable_sig_mask);
}
/*
*********************************************************************************************************
为当前任务登记一个信号处理句柄,在对一个任务发送信号前,该信号处理句柄必须登记
在登记后,若该任务上有信号要处理,则执行
*********************************************************************************************************
*/
STATUS RegisterSignalHandler(INT8U signal,void (*signal_handler)(void))
{
struct signal_struct sig;
TASK_TCB *task_ptr;
if (((TASK_TCB *)KERNAL.current_thread)->type!=TASK && ((TASK_TCB *)KERNAL.current_thread)->type!=SIG_TASK) {
return (ERR_INVALID_OPERATION);
}
if (signal_handler==NULL){
return (ERR_INVALID_POINTER);
}
#if DEBUG
DebugLog(REGISTER_SIGNAL_ID,0);//在日志中记录操作,时间等信息
#endif
sig.signal_handler[signal]=signal_handler;
task_ptr=(TASK_TCB *)KERNAL.current_thread;
DoProtect(task_ptr);
task_ptr->sig=&sig;
if (task_ptr->enabled_signals & (task_ptr->signals & 1<< signal)) {
task_ptr->save_type=task_ptr->type;
task_ptr->type=SIG;
task_ptr->saved_stack_ptr=(UNSIGNED *)_InitSignalFrame(task_ptr,signal);
UnProtect(task_ptr);
_DirectSchedule(task_ptr);
return (OK);
}
UnProtect(KERNAL.current_thread);
return (OK);
}
/*
*********************************************************************************************************
* 发送特定的信号组到特定任务,如果该任务的该信号允许,则该任务恢复并启动信号处理函数来处理该信号
***************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -