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

📄 cxver5.c

📁 上传一个带源代码的嵌入式实时多任务操作系统CMX
💻 C
📖 第 1 页 / 共 5 页
字号:
/************************************************************
 The following function will be called by both the K_Task_Wake and
 K_Task_Wake_Force functions. This will determine whether a task will
 be forced to wake up, or to normally be woken up.

 if force = 0, then wake task only if task had called K_Task_Wait

 if force = 1, then wake task regardless of what function
               was called, that suspended task

************************************************************/
byte K_I_Wake_Common(byte tskid,byte force)
{
	tcbpointer tcbptr;

	if(K_I_Get_Ptr(tskid,&tcbptr))	/* send address of pointer */
		{
#if (defined(CMXTRACKER) || defined(WINTRACKER))
		if (CMXTRACKER_ON)
			{
			cmxtracker_in2(CXTWAK_K_ERROR,tskid);
			}
#endif
		return(K_ERROR);
		}
	K_I_Disable_Sched();	/* set task block */

	/* if force non 0, then wake task, regardless of what it
		was waiting for. If force = 0, then only wake task
		if it was waiting on time or indefinitely. */
	if (tcbptr->tcbstate & (force ? ANY_WAIT : WAIT))
		{
		/* see if task was waiting for a resource */
		if (tcbptr->tcbstate & (RESOURCE | SEMAPHORE))
			{
			/* yes, remove task from resource wait linked list. */
			tcbptr->fwlink->bwlink = tcbptr->bwlink;
			tcbptr->bwlink->fwlink = tcbptr->fwlink;
			}
		/* put task into the RESUME state, also possibly indicate time
			expired, though it may not in the true sense */
		if (force)
			tcbptr->tcbstate = RESUME | TIME_EXPIRED;
		else
			tcbptr->tcbstate = RESUME;

		/* see if this task has a higher priority then the current RUNNING task */
		if (tcbptr->priority < active_priority)
			{
			PREEMPTED;	/* yes, set the preempted scheduling flag */
			}
#if (defined(CMXTRACKER) || defined(WINTRACKER))
		if (CMXTRACKER_ON)
			{
			cmxtracker_in2(CXTWAK_K_OK,tskid);
			}
#endif
		K_I_Func_Return();	/* release task block */
		return(K_OK);	/* return good status */
		}
	else
		{
#if (defined(CMXTRACKER) || defined(WINTRACKER))
		if (CMXTRACKER_ON)
			{
			cmxtracker_in1(CXTWAK_K_NOT_WAITING);
			}
#endif
		K_I_Func_Return();	/* release task block */
		return(K_NOT_WAITING);	/* return error that task was not waiting */
		}
}

/*****************************************************************
		!!! WARNING: the CMX timer task will not run !!!!
 The CMX timer task will not be executed, nor the interrupt pipe
 if this function is called. The task that called this function should
 release it, by using the K_Task_Unlock function as soon as possible.
 In most cases this function should NOT be used. Improper use is
 abuse. Also the task that calls this function, MUST NOT call any
 function that may suspend this task
*****************************************************************/
void K_Task_Lock(void)
{
	/* set the task lock flag. This will stop the K_I_Scheduler
		from re-scheduling, until the K_Task_Unlock function is called */

	K_I_Disable_Sched();
#if (defined(CMXTRACKER) || defined(WINTRACKER))
		if (CMXTRACKER_ON)
			{
			cmxtracker_in1(CXPRVR_CALL);
			}
#endif
}
/****************************************************************
 Should be used ONLY if the task used the K_Task_Lock function.
*****************************************************************/
void K_Task_Unlock(void)
{
	/* lower the task privilege flag. See if the K_I_Scheduler
		should be invoked */

#if (defined(CMXTRACKER) || defined(WINTRACKER))
		if (CMXTRACKER_ON)
			{
			cmxtracker_in1(CXPRVL_CALL);
			}
#endif
	K_I_Func_Return();
}
/***************************************************************
 The following function performs a cooperative scheduling.
***************************************************************/
void K_Task_Coop_Sched(void)
{
	K_I_Disable_Sched();	/* set task block */
#if (defined(CMXTRACKER) || defined(WINTRACKER))
		if (CMXTRACKER_ON)
			{
			cmxtracker_in1(CXSCHED_CALL);
			}
#endif
	DO_COOP_SCHED;	/* set the cooperative scheduling flag */
	K_I_Func_Return();	/* release task block */
}

/***********************************************************
 Remove a task. Once removed this task can not be used in anyway
 Also the task MUST NOT be waiting on anything, for it will not
 be removed if so.
***********************************************************/
byte K_Task_Delete(byte tskid)
{
	tcbpointer tcbptr;

	if(K_I_Get_Ptr(tskid,&tcbptr))	/* send address of pointer */
		{
#if (defined(CMXTRACKER) || defined(WINTRACKER))
		if (CMXTRACKER_ON)
			{
			cmxtracker_in2(CXTRMV_K_ERROR,tskid);
			}
#endif
		return(K_ERROR);
		}
	K_I_Disable_Sched();	/* set task block */
	if (tcbptr->tcbstate & ANY_WAIT)	/* see if task waiting */
		{
#if (defined(CMXTRACKER) || defined(WINTRACKER))
		if (CMXTRACKER_ON)
			{
			cmxtracker_in2(CXTRMV_WAIT_K_ERROR,tskid);
			}
#endif
		K_I_Func_Return();	/* task was waiting, cannot terminate this task */
		return(K_ERROR);	/* return error status, task was not terminated */
		}
	else
		{
		K_I_Unlink(tcbptr);	/* no, task not waiting. Remove task from TCB */
		if (tcbptr == activetcb)	/* is task trying to commit suicide */
			{
			activetcb->tcbstate = 0;	/* load in highest priority task */
			PREEMPTED;	/* set the preempted scheduling flag */
			}
		}
#if (defined(CMXTRACKER) || defined(WINTRACKER))
		if (CMXTRACKER_ON)
			{
			cmxtracker_in2(CXTRMV_K_OK,tskid);
			}
#endif
	K_I_Func_Return();	/* release task block */
	return(K_OK);	/* return good status, if task not committing suicide */
}

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

		TASK GENERAL PURPOSE FLAGS SYNCHRONIZATION

************************************************************************/
/***************************************************************
 This allows a task to reset a task's event flags that they
 would like to be cleared.
***************************************************************/
byte K_Event_Reset(byte tskid,word16 event)
{
	tcbpointer tcbptr;

	if(K_I_Get_Ptr(tskid,&tcbptr))	/* send address of pointer */
		{
#if (defined(CMXTRACKER) || defined(WINTRACKER))
		if (CMXTRACKER_ON)
			{
			cmxtracker_in2(CXERST_K_ERROR,tskid);
			}
#endif
		return(K_ERROR);
		}
	K_I_Disable_Sched();	/* set task block */
	tcbptr->e_flags &= (~event);		/* place the event bit(s) into clear state, indicated by mask. */
#if (defined(CMXTRACKER) || defined(WINTRACKER))
		if (CMXTRACKER_ON)
			{
			cmxtracker_in4(CXERST_K_OK,tskid,event);
			}
#endif
	K_I_Func_Return();	/* release task block */
	return(K_OK);	/* return good status, if task not committing suicide */
}
/***************************************************************
 The following allows a task to wait for 1 or more events to be
 set, if they are not. Also a time period may be specified on how
 long the task will wait for at least 1 event to be set, in which
 the task wants.
MODE:
= 0 nothing
= 1 clear at beginning
= 2 auto clear on match
= 3 both 1 and 2
***************************************************************/
word16 K_Event_Wait(word16 match,word16 timecnt,byte mode)
{
	word16 good_bits;

	K_I_Disable_Sched();	/* set task block */
	if (mode & 0x01) 	/* see if we should clear specified events at beginning. */
		{
		activetcb->e_flags &= (~match);	/* yes, clear them. */
		}
		/* see if ANY task flags match */
	if (!(activetcb->e_flags & (activetcb->e_match = match)))
		{
		/* NO, so call CMX function that will suspend task. */
#if (defined(CMXTRACKER) || defined(WINTRACKER))
		if (CMXTRACKER_ON)
			{
			cmxtracker_in4(CXEWATM_CALL,0,timecnt);
			}
#endif
		if (K_I_Time_Common(timecnt,FLAGS))	
			{
#if (defined(CMXTRACKER) || defined(WINTRACKER))
		if (CMXTRACKER_ON)
			{
			cmxtracker_in1(CXEWATM_DELAY_K_TIMEOUT);
			}
#endif
			return(0);	/* return the warning: that the time period expired */
			}
		K_I_Disable_Sched();	/* set task block. */
		}
	good_bits = activetcb->e_flags & match;	/* what event bits matched. */
	if (mode & 0x02)	/* should we clear the events now? */
		{
		activetcb->e_flags &= ~match;	/* yes, clear them. */
		}
#if (defined(CMXTRACKER) || defined(WINTRACKER))
		if (CMXTRACKER_ON)
			{
			cmxtracker_in4(CXEWATM_K_OK,0,good_bits);
			}
#endif
	K_I_Func_Return();	/* release task lock. */
	return(good_bits);	/* return events that were set according to mask. */
}

/**********************************************************************
 The following function will set possibly set an event.

byte mode: 	0 = specific task
				1 = highest priority (single task even if more then one of same)
				2 = highest priority waiting task on THIS EVENT
				3 = all tasks
				4 = all waiting tasks THIS EVENT
				5 = all with same priority (specify priority)
				6 = all waiting with same priority (specify priority) THIS EVENT
************************************************************************/
byte K_Event_Signal(byte mode, byte tskid_pri,word16 flag)
{
	tcbpointer tcbptr;
#if (defined(CMXTRACKER) || defined(WINTRACKER))
	byte cmxtracker_sent;
#endif

	if (mode > 0x06)	/* see if mode greater then maximum allowed. */
		{
#if (defined(CMXTRACKER) || defined(WINTRACKER))
		if (CMXTRACKER_ON)
			{
			cmxtracker_in2(CXESIG_MODE,mode);
			}
#endif
		return(K_ERROR);
		}
	K_I_Disable_Sched();	/* set task block */
#if (defined(CMXTRACKER) || defined(WINTRACKER))
	cmxtracker_sent = 0;
#endif
	if (!mode)	/* is mode 0. */
		{
		if(K_I_Get_Ptr(tskid_pri,&tcbptr))	/* send address of pointer */
			{
#if (defined(CMXTRACKER) || defined(WINTRACKER))
		if (CMXTRACKER_ON)
			{
			cmxtracker_in2(CXESIG_K_ERROR,tskid_pri);
			}
#endif
			K_I_Func_Return();
			return(K_ERROR);
			}
		goto test_event;
		}
	else
		{
		tcbptr = timertask->nxttcb;	/* start at head of linked list. */
		}
	for (; tcbptr != cmx_tcb; tcbptr = tcbptr->nxttcb) /* see if we tested all. */
		{
		if (mode > 0x04)	/* is mode greater then 4? */
			{
			if (tcbptr->priority != tskid_pri)	/* see if priority match. */
				continue;
			}
		if (!(mode & 0x01))	/* see if task must be waiting on this EVENT */
			{
			if (!((tcbptr->e_match & flag) &&
				(tcbptr->tcbstate & FLAGS)))
				{
				continue;	/* continue if task was not. */
				}
			}
test_event:
#if (defined(CMXTRACKER) || defined(WINTRACKER))
		if (CMXTRACKER_ON)
			{
			if (!cmxtracker_sent)
				{
				cmxtracker_sent = tcbptr - cmx_tcb;
				}
			}
#endif
		/* see if task event(s) match. */
		if (tcbptr->e_match & (tcbptr->e_flags |= flag))
			{
			if (tcbptr->tcbstate & FLAGS)	/* see if task was waiting on EVENT. */
				{
				tcbptr->tcbstate = RESUME; /* yes, the task may now resume. */
				
				if (TEST_NOT_PREEMPTED)	/* see if preempted flag not set yet. */
					{
					if (tcbptr->priority < active_priority)
						PREEMPTED;	/* yes, set the preempted scheduling flag */
					}
				if (mode < 0x03)	/* see if we should exit function. */
					break;
				}
			}
		if (mode < 0x02)	/* see if we should exit function. */
			break;
		}
#if (defined(CMXTRACKER) || defined(WINTRACKER))
 	if (CMXTRACKER_ON)
		{
		cmxtracker_in3(CXESIG_K_OK,mode,cmxtracker_sent);
		}
#endif
	K_I_Func_Return();	/* call CMX function, that will release task block */	
	return(K_OK);	/* return good status */
}

/*******************************************************************
		RESOURCE MANAGER
********************************************************************/

/*******************************************************************
 This function allows a task to reserve or get this resource.

 if func_mode = 1, then means get resource if free, otherwise return

 if func_mode = 0, then if the resource is "owned" by another task,
 then this task will be suspended until this resource is free or time
 period expires.
*******************************************************************/
byte K_I_Resource_Common(byte res_grp,word16 timecnt,byte func_mode)
{
	RESHDR *res_ptr;
	tcbpointer tp;

	if (res_grp >= MAX_RESOURCES)	/* see if resource number allowed */
		{
#if (defined(CMXTRACKER) || defined(WINTRACKER))
		if (CMXTRACKER_ON)
			{
			cmxtracker_in3(CXRSRSV_K_ERROR,res_grp,func_mode);
			}
#endif
		return(K_ERROR);	/* no, return error status */
		}

	K_I_Disable_Sched();	/* set task block */

	res_ptr = &res_que[res_grp];	/* get address of resource */

	if (res_ptr->owner)	/* does a task own this resource? */
		{
		/* yes, what function was used. */
		if (func_mode)		/* did the K_Resource_Get function call this function */
			{
#if (defined(CMXTRACKER) || defined(WINTRACKER))
		if (CMXTRACKER_ON)
			{
			cmxtracker_in2(CXRSRSV_K_RESOURCE_OWNED,res_grp);
			}
#endif
			 K_I_Func_Return();	/* release task block */
			 return(K_RESOURCE_OWNED);	/* return error that resource is already owned */
			}
#if (defined(CMXTRACKER) || defined(WINTRACKER))
		if (CMXTRACKER_ON)
			{
			cmxtracker_in4(CXRSRSV_CALL,res_grp,timecnt);
			}
#endif

⌨️ 快捷键说明

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