⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 task.c

📁 一种操作系统源码核
💻 C
📖 第 1 页 / 共 5 页
字号:
#define  OS_GLOBALS
#if !defined(__EBOS_H)
#include "ebos.h"
#endif
extern jmp_buf  jmpb;
/*
*********************************************************************************************************
*                                          TASK COMPOENT Implementation
*********************************************************************************************************
*/
/*
*********************************************************************************************************
                                 该函数是由线程调度函数调用的函数,用来把控制交给特定线程,线程的
                                 调度次数加1,并使KERNAL.current_thread指针指向该线程.

*********************************************************************************************************
*/
static TASK_TCB  *HighRdyThread;
static void   *reserved;
static TASK_TCB *Priority_Head[LOWEST_PRIORITY];          // 优先级表头指针
static void (* LISR_Pointers[MAX_INT_VECT])(void);       // 中断函数指针的列表,该列表由中断向量作为索引,在该表中找到要执行的中断函数
static UCHAR Sub_Priority_Groups[LOWEST_PRIORITY/8];    // 子组优先级指针
static UNSIGNED Priority_Group ;                       //  优先级组位掩码
static UCHAR DirectSched;                               //是否直接调度
static UNSIGNED     Int_Count;   		        //Interrupt nesting level
// UNSIGNED           OSCtxSwCtr;               /* Counter of number of context switches

static TASK_TCB *TaskTable[MAX_TASK_NUM];         //任务向量表
static TASK_HCB *HisrTable[MAX_HISR_NUM];         //高级中断处理线程向量表
static void * _InitHISRStack(TASK_HCB *hisr);     //高级中断处理线程堆栈初始化
static TASK_TCB *TaskFreeList;                    //可用任务列表头指针 
static TASK_HCB *HisrFreeList;                    //可用HISR表头指针
/********************************************************************************************
                      取得一个可用的任务ID号
***************************************************************************************/  
static SIGNED _NewTaskId()
{
	static UNSIGNED next_task_id;
	UNSIGNED  id;			/* process id to return		*/
	EnLock();
	if ((id=next_task_id++) < MAX_TASK_NUM){
	    	if (TaskTable[id] == NULL){
		 	UnLock();
		 	return(id);
	    	}
	}
	else if(TaskFreeList){
	  	id=TaskFreeList->id;
	  	#if ENABLE_MEM
	    		FreeBuff(TaskFreeList);
	  	#endif
	  	TaskFreeList=TaskFreeList->next;
	   	UnLock();
	  	return(id);
	}
	UnLock();
	return(NO_TASK_SPACE);

}
/********************************************************************************************
                      取得一个可用的HISR ID号
***************************************************************************************/  
static SIGNED _NewHisrId()
{
	static UNSIGNED next_hisr_id;
	UNSIGNED  id;			/* process id to return		*/
	UNSIGNED  i;
        EnLock();
	if ( (id=next_hisr_id++)< MAX_HISR_NUM){
	    	if (HisrTable[id] == NULL){
		 	UnLock();
	  	 	return(id);
	    	}
	}
	else if(HisrFreeList){
	   	id=HisrFreeList->id;
	   	HisrFreeList=HisrFreeList->next;
	   	UnLock();
	  	return(id);
	}
	UnLock();
	return(NO_HISR_SPACE);

}
/********************************************************************************************
                      任务切换时保存当前上下文
***************************************************************************************/ 
void  interrupt StackSave()
{

   	EnLock();
   
    	FP_SEG(((TASK_TCB *)KERNAL.current_thread)->stack_pointer)=_SS;
    	FP_OFF(((TASK_TCB *)KERNAL.current_thread)->stack_pointer)=_SP;

    	Schedule();
}
/********************************************************************************************
                      恢复当前具有最高优先级的处于准备好状态的线程的上下文,切换到该线程执行
***************************************************************************************/ 


 void   _ControlToThread(void)
 {
    
     	EnLock();
     
     	if (((TASK_HCB *)KERNAL.current_thread)->type==HISR){    //HISR每次调度都是从初始开始执行
		((TASK_HCB *)KERNAL.current_thread)->stack_pointer=_InitHISRStack(((TASK_HCB *)KERNAL.current_thread));
      	}
     	if(((TASK_TCB *)KERNAL.current_thread)->type==SIG){
   		_SS=FP_SEG(((TASK_TCB *)KERNAL.current_thread)->saved_stack_ptr);
   		_SP=FP_OFF(((TASK_TCB *)KERNAL.current_thread)->saved_stack_ptr); //若为信号处理线程
   	
   	}
   	else{ 
    		_SS=FP_SEG(((TASK_TCB *)KERNAL.current_thread)->stack_pointer);
    		_SP=FP_OFF(((TASK_TCB *)KERNAL.current_thread)->stack_pointer);
    	}
   	asm  POPF
   	asm  POP BP                       //     ; Load new task's context
   	asm  POP DI
   	asm  POP SI
   	asm  POP DS
   	asm  POP ES
   	asm  POP DX
   	asm  POP CX
   	asm  POP BX
   	asm  POP AX
   	asm  IRET                              //     ; Return to new task
}
/********************************************************************************************
                      触发任务切换
***************************************************************************************/ 
void _ControlToSystem(void)
{
	// EnLock();
	
	Ctrl_Task_Save();	//保存当前任务的上下文

	//UnProtect();  //open interrupt
}
/*
*********************************************************************************************************
				 该函数是直接调度函数,直接调度到当前已经知道的处于准备好状态中的最高优先级的任务执行,
				 并关掉任务时间片和强占标志,使该任务不被强占的执行

                             

*********************************************************************************************************
*/
 void ScheduleToLockTask(TASK_TCB *task)
{

 	task->timer_active=FALSE;//不允许中断
       	task->preemption=FALSE;
	HighRdyThread=task;
       	DirectSched=TRUE;
        _ControlToSystem();


}
/*
*********************************************************************************************************
				  该函数在下一个运行任务已经确定的情况下使用,或在并不需要回到原来线程情况下使用,如信号线程处理
				  完成重新执行其对应任务等

*********************************************************************************************************
*/

 void _DirectSchedule(TASK_TCB *task)
{

    	EnLock();
        DirectSched=TRUE;
        HighRdyThread=task;
        _ControlToSystem();

}
/*
*********************************************************************************************************
				TaskShell是任务完成时的返回函数入口,


*********************************************************************************************************
*/
static void TaskShell(void)
{
  	STATUS state;
  	DoProtect(KERNAL.current_thread);
  	((TASK_TCB *)KERNAL.current_thread)->status=FINISHED;
  	UnProtect(KERNAL.current_thread);
  	state=_SuspendTask(KERNAL.current_thread,FINISHED,NULL,NULL,0);
  	if(state==TRUE)
	 	_ControlToSystem();

}
/*
*********************************************************************************************************
                                以下函数用于建立任务的上下文环境
                                该函数用来建立特定任务运行所需的堆栈环境,包括向入口函数传递的参数等
                            
*********************************************************************************************************
*/
static void * _InitTaskStack(TASK_TCB *task)

{
    	INT16U *stk;
    	stk    =(INT16U *)task->stack_start;                /* Load stack pointer*/
  	//  p=stk;
    	*stk-- = (INT16U)FP_SEG(TaskShell);     //CS     /* Put pointer to task   on top of stack                   */
    	*stk-- = (INT16U)FP_OFF(TaskShell);
   	if(task->argc){
      		*stk-- = (INT16U)FP_SEG(task->argv);         /* Simulate call to function with argument                 */
      		*stk-- = (INT16U)FP_OFF(task->argv);
      		*stk-- = (INT16U)(task->argc);         /* Simulate call to function with argument                 */
      		*stk-- = (INT16U)FP_SEG(task->entry);         /* Simulate call to function with argument                 */
      		*stk-- = (INT16U)FP_OFF(task->entry);
     	}

    	*stk-- = (INT16U)0x0202;
    	*stk-- = (INT16U)FP_SEG(task->entry);     //CS     /* Put pointer to task   on top of stack                   */
    	*stk-- = (INT16U)FP_OFF(task->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-- = _BP;                /* BP = 0x4444 */
    	*stk   = (INT16U)0x0202;           //FLAGS
   
    	return ((void *)stk);
 }
/*
*********************************************************************************************************
*                                  创建任务函数原型
创建任务分两种方式:1 使用CreateTaskExt函数规定好参数,一次完成任务创建.
                 2 使用CreateTask函数,规定好部分参数,其它为空或默认,如argc,*argv参数,
                   任务创建后自动处于准备好状态.根据任务结构在创建前分配与否,提供两种函数形式
 
*******************************************************************************************************
*/
 #if ENABLE_MEM
 SIGNED CreateTask(void (*entry)(void),UNSIGNED stack_size,INT8U priority)
 #else
 SIGNED CreateTask(TASK_TCB  *task_ptr,void (*entry)(void),INT8U *stack_address,UNSIGNED stack_size,INT8U priority)
 #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 (priority >LOWEST_PRIORITY) {             /* Make sure priority is within allowable range           */
	    	return (ERR_INVALID_PRIORITY);
	}
	if (entry==NULL) return(ERR_INVALID_ENTRY);
	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=(INT8U *)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_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->preemption=TRUE;
	task_ptr->task_timeout=-1;
	task_ptr->timer_active=TRUE;
	task_ptr->stack_start=(UNSIGNED *)stack_address;
	task_ptr->entry=entry;
	task_ptr->argc=0;
	task_ptr->argv=NULL;
	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;
       	#if ENABLE_SIGNAL_HANDLE==TRUE
                task_ptr->enabled_signals =0;
        #endif
        InitTaskTimer(&(task_ptr->timer_control),task_ptr);
        task_ptr->status=READY;
        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();
	return (task_id);

}
/*
*********************************************************************************************************
*                                  创建任务函数原型
                 创建专门处理信号任务的两种方式:
                 任务创建后自动处于等待状态.等待接收信号,被发送到该任务的信号激活,执行完后重新回到等待状态
 
*******************************************************************************************************
*/
  #if ENABLE_MEM
  SIGNED CreateSigTask(UNSIGNED stack_size,INT8U priority)
  #else
  SIGNED CreateSigTask(TASK_TCB  *task_ptr,INT8U *stack_address,UNSIGNED stack_size,INT8U priority)
  #endif
  {
	UCHAR  prio_group,prio_groupbit;
	SIGNED task_id;
	SIGNED err;
	void *pointer;
        #if ENABLE_MEM
		TASK_TCB  *task_ptr;
	   	INT8U *stack_address;
	#endif  
	if (priority >LOWEST_PRIORITY) {             /* Make sure priority is within allowable range           */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -