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

📄 cxver5.c

📁 上传一个带源代码的嵌入式实时多任务操作系统CMX
💻 C
📖 第 1 页 / 共 5 页
字号:
			{
#if (defined(CMXTRACKER) || defined(WINTRACKER))
		if (CMXTRACKER_ON)
			{
			cmxtracker_in2(CXMSWATM_NOMESG_K_ERROR,mailbox);
			}
#endif
			return(NULL);	/* yes, pass back null, indicating no message. */
			}
		else
			{
			K_I_Disable_Sched();	/* set task lock */
			}
		}

	link = mail_ptr->first_lnk;	/* get first link. */
	link->env_link = message_ptr->env_link; /* re-arrange linked list. */
	message_ptr->env_link = link;
	message_free++;	/* increment message free counter. */

	copy_ptr = link->message;		/* address of message */
	activetcb->mesg_sender = link->sender;	/* what task sent this message. */

	/* update link to point to next message link, also test if more messages
		present. */
	if ((mail_ptr->first_lnk = link->link)) 
		{
		if (mail_ptr->task_num)	/* see if mailbox is suppose to signal event,
											that it has messages. */
			/* yes, then go set proper event bit. */
			K_Event_Signal(0,mail_ptr->task_num,mail_ptr->event_num);
		}
	link->link = NULL;	/* set message link to NULL. */
#if (defined(CMXTRACKER) || defined(WINTRACKER))
		if (CMXTRACKER_ON)
			{
			if (is_get)
#if (defined(WINTRACKER))
				cmxtracker_in2(CXMSGET_K_OK,mailbox);
#else
				cmxtracker_in5(CXMSGET_K_OK,mailbox,copy_ptr);
#endif
			else
#if (defined(WINTRACKER))
				cmxtracker_in2(CXMSWATM_K_OK,mailbox);
#else
				cmxtracker_in5(CXMSWATM_K_OK,mailbox,copy_ptr);
#endif
			}
#endif
	K_I_Func_Return();	/* release task block */
	return((void *)copy_ptr);	/* return good status to caller */
}

/*******************************************************************
 General function for sending a message to a mailbox.
 
 wait = 0, do not wait after sending message

 wait = 1, wait after sending message, for receiver to wake us

*******************************************************************/
byte K_I_Mesg_Send_Common(byte mailbox,word16 timecnt,void *mesg,byte wait)
{
	MAILBOX *mail_ptr;
	MSG *link;	/* scratch pointer */

	K_I_Disable_Sched();
	/* see if mailbox within range and that there are
		message links available. */
	if ((mailbox >= MAX_MAILBOXES) || (!message_free))	
		{
		/* error */
#if (defined(CMXTRACKER) || defined(WINTRACKER))
		if (CMXTRACKER_ON)
			{
			cmxtracker_in3(CXMSSEND_K_ERROR,mailbox,wait);
			}
#endif
		K_I_Func_Return();	/* release task block */
		return(K_ERROR);	/* return good status to caller */
		}
	mail_ptr = &mail_box[mailbox];	/* CMX mailbox handler. */
	if (mail_ptr->waiter)	/* task waiting on this mailbox */
		{
		mail_ptr->waiter->tcbstate = RESUME;	/* allow task to run again */
		if (mail_ptr->waiter->priority < active_priority)
			PREEMPTED;	/* yes, so set the preempted scheduling flag */
		}

	link = message_ptr;	/* link now points to message header */
	message_ptr = link->env_link; /* update linked list */

	if (mail_ptr->first_lnk)	/* see if first link set */
		{
		mail_ptr->next_lnk->link = link;	/* yes, set next link. */
		}
	else
		{
		mail_ptr->first_lnk = link;	/* set first link. */
		/* because this is the first message into the mailbox
			see if mailbox is suppose to notify task that there
			are messages now residing in mailbox. */
		if (mail_ptr->task_num)	/* does task want to be notified? */
			/* yes, go set event. */
			{
#if (defined(CMXTRACKER) || defined(WINTRACKER))
			if (CMXTRACKER_ON)
				{
				if (locked_out == 2)
					{
					cmxtracker_in1(INT_ACTION);
					}
				}
#endif
			K_Event_Signal(0,mail_ptr->task_num,mail_ptr->event_num);
			}
		}
	mail_ptr->next_lnk = link;	/* set mailbox next link. */
	link->message = (byte *)mesg;	/* load address of message. */
	link->sender = NULL; /* set sender to NULL. This way interrupt will be covered */
	--message_free;	/* decrement message free */

	if (wait)	/* is this the send and wait call function */
		{
		link->sender = activetcb; /* load what task sent message. */
		/* this task will now be suspended. */
#if (defined(CMXTRACKER) || defined(WINTRACKER))
			if (CMXTRACKER_ON)
				{
#if (defined(WINTRACKER))
				cmxtracker_in2(CXMSSENW_K_OK,mailbox);
#else
				cmxtracker_in5(CXMSSENW_K_OK,mailbox,mesg);
#endif
				cmxtracker_in4(CXMSSEND_CALL,mailbox,timecnt);
				}
#endif
		if (K_I_Time_Common(timecnt,SEND_MESG))
			{
#if (defined(CMXTRACKER) || defined(WINTRACKER))
			if (CMXTRACKER_ON)
				{
				cmxtracker_in2(CXMSSEND_K_TIMEOUT,mailbox);
				}
#endif
			return(K_TIMEOUT);
			}
		else
			{
#if (defined(CMXTRACKER) || defined(WINTRACKER))
			if (CMXTRACKER_ON)
				{
				cmxtracker_in2(CXMSSEND_K_OK,mailbox);
				}
#endif
			return(K_OK);
			}
		}
	else
		{
		link->sender = NULL; /* set sender to NULL. */
#if (defined(CMXTRACKER) || defined(WINTRACKER))
			if (CMXTRACKER_ON)
				{
#if (defined(WINTRACKER))
				cmxtracker_in2(CXMSSEND_K_OK1,mailbox);
#else
				cmxtracker_in5(CXMSSEND_K_OK1,mailbox,mesg);
#endif
				}
#endif
		K_I_Func_Return();	/* release task block */
		return(K_OK);	/* return good status to caller */
		}
}

/************************************************************
 the following function sets up a mailbox to automatically
 set an event of a particular task, when and if this mailbox
 has messages in it.
*************************************************************/
byte K_Mbox_Event_Set(byte mailbox,byte taskid,word16 event_num)
{
	MAILBOX *mail_ptr;

	if (mailbox >= MAX_MAILBOXES) /* see if mailbox number OK. */
		{
#if (defined(CMXTRACKER) || defined(WINTRACKER))
		if (CMXTRACKER_ON)
			{
			cmxtracker_in2(CXMSBXEV_K_ERROR,mailbox);
			}
#endif
		return(K_ERROR);	/* NO, send error status. */
		}
	K_I_Disable_Sched();	/* set task block. */

	mail_ptr = &mail_box[mailbox];	/* get CMX mailbox handler */
	mail_ptr->task_num = taskid;	/* load task_num with task slot number. */
	mail_ptr->event_num = event_num;	/* what event bit will be set. */
#if (defined(CMXTRACKER) || defined(WINTRACKER))
		if (CMXTRACKER_ON)
			{
			cmxtracker_in2(CXMSBXEV_K_OK,mailbox);
			}
#endif
	K_I_Func_Return();	/* release task block. */
	return(K_OK);	/* return good status. */
}

/*****************************************************************
 This function allows a task that received a message to go wake
 the task that sent this message, if the task is waiting for an
 acknowledgement.
*****************************************************************/
byte K_Mesg_Ack_Sender(void)
{
	K_I_Disable_Sched();	/* set task block. */
	if (activetcb->mesg_sender)	/* see if message was sent by a task. */
		{
		/* see if the task that sent message waiting for acknowledgement. */
		if (activetcb->mesg_sender->tcbstate & SEND_MESG)	
			{
			activetcb->mesg_sender->tcbstate = RESUME; /* yes, wake task. */
			/* see if this task has a higher priority, then current running task. */
			if (activetcb->mesg_sender->priority < active_priority)
				PREEMPTED;	/* yes, so set the preempted scheduling flag */
#if (defined(CMXTRACKER) || defined(WINTRACKER))
		if (CMXTRACKER_ON)
			{
			cmxtracker_in2(CXMSACK_K_OK,(byte)(activetcb->mesg_sender - cmx_tcb));
			}
#endif
			}
		}
	K_I_Func_Return();	/* release task block. */
	return(K_OK);	/* always return good status */
}

/********************************************************************
		CYCLIC TIMER FUNCTIONS
*********************************************************************/
/* tproc_start states:
	0 = stopped
	1 = started
*/

/********************************************************************
 This function sets up the cyclic timer's event parameters.
********************************************************************/
byte K_Timer_Create(byte timed_num,byte mode,byte tskid_pri,word16 event_num)
{
	struct _tcproc *tpptr;

	if (timed_num >= MAX_CYCLIC_TIMERS)	/* have we exceeded the maximum number */
		{
#if (defined(CMXTRACKER) || defined(WINTRACKER))
		if (CMXTRACKER_ON)
			{
			cmxtracker_in2(CXCTCRE_K_ERROR,timed_num);
			}
#endif
		return(K_ERROR);	/* yes, return error status */
		}
	K_I_Disable_Sched();	/* set task block */
	tpptr = &tcproc[timed_num];	/* get address of cyclic timer handler */
	tpptr->mode = mode;	/* load K_Event_Signal MODE */ 
	tpptr->tskid_pri = tskid_pri;	/* load in the tasks slot number
												or priority. May not be used. */
	tpptr->event_num = event_num;	/* load in the event to be set. */
#if (defined(CMXTRACKER) || defined(WINTRACKER))
		if (CMXTRACKER_ON)
			{
			cmxtracker_in2(CXCTCRE_K_OK,timed_num);
			}
#endif
	K_I_Func_Return();	/* release task block */
	return(K_OK);	/* return good status */
}

/******************************************************************
 This is the common routine that the most of the cyclic timer functions
 will call. This function starts, or restarts a cyclic timer and possibly
 also changes the cyclic timer's time parameters.

mode:
= 0: = just restart timer if not started 
= 1: = change only initial time and start 
= 2: = change only cyclic time and start 
= 3: = change both initial time and cyclic time and start
**************************************************************************/
byte K_I_Cyclic_Common(byte timed_num,word16 timecnt, word16 cyclic,byte mode)
{
	struct _tcproc *tpptr;

	if (timed_num >= MAX_CYCLIC_TIMERS)	/* have we exceeded the maximum number */
		{
#if (defined(CMXTRACKER) || defined(WINTRACKER))
		if (CMXTRACKER_ON)
			{
			cmxtracker_in2(CXCTCOM_K_ERROR,timed_num);
			}
#endif
		return(K_ERROR);
		}
	K_I_Disable_Sched();	/* set task block */
	tpptr = &tcproc[timed_num];	/* get the CMX handler for this cyclic timer. */
	if (mode & 0x01)	/* see if mode bit 0 set. */
		{
		tpptr->tproc_timer = timecnt;	/* load time period into counter */
		}
	if (mode & 0x02)	/* see if mode bit 1 set. */
		{
		tpptr->reload_time = cyclic;	/* load cyclic time into counter */
		}
	if (!(tpptr->tproc_start))	/* see if 0 */
		{
		tpptr->tproc_start = 1;	/* start the timed procedure */
		/* add to the cyclic timers doubly linked list. */
		if (cyclic_lnk->ftlink != (struct _tcproc *)cyclic_lnk)	
			{
			tpptr->ftlink = cyclic_lnk->btlink->ftlink;
			cyclic_lnk->btlink->ftlink = tpptr;
			tpptr->btlink = cyclic_lnk->btlink;
			}
		else
			{
			tpptr->ftlink = tpptr->btlink = (struct _tcproc *)cyclic_lnk;
			cyclic_lnk->ftlink = tpptr;
			}
		cyclic_lnk->btlink = tpptr;
		}
#if (defined(CMXTRACKER) || defined(WINTRACKER))
		if (CMXTRACKER_ON)
			{
			if (mode == 3)
				{
				cmxtracker_in2(CXCTSTT_K_OK,timed_num);
				}
			else if (mode == 2)
				{
				cmxtracker_in2(CXCTRSTC_K_OK,timed_num);
				}
			else if (mode == 1)
				{
				cmxtracker_in2(CXCTRSTI_K_OK,timed_num);
				}
			else
				{
				cmxtracker_in2(CXCTRSTT_K_OK,timed_num);
				}
			}
#endif
	K_I_Func_Return();	/* release task block */
	return(K_OK);	/* return good status */
}

/******************************************************************
 stop a cyclic timer function
******************************************************************/
byte K_Timer_Stop(byte timed_num)
{
	struct _tcproc *tpptr;

	if (timed_num >= MAX_CYCLIC_TIMERS)	/* have we exceeded the maximum number */
		{
#if (defined(CMXTRACKER) || defined(WINTRACKER))
		if (CMXTRACKER_ON)
			{
			cmxtracker_in2(CXCTSTP_K_ERROR,timed_num);
			}
#endif
		return(K_ERROR);
		}
	K_I_Disable_Sched();	/* set task block */
	tpptr = &tcproc[timed_num];	/* address of cyclic timer structure. */
	if (tpptr->tproc_start)	/* see if non 0 */
		{
		tpptr->tproc_start = 0;	/* stop cyclic timer. */
		/* the following removes the cyclic timer from
			the doubly linked list of started cyclic timers. */
		tpptr->ftlink->btlink = tpptr->btlink;
		tpptr->btlink->ftlink = tpptr->ftlink;
		}
#if (defined(CMXTRACKER) || defined(WINTRACKER))
		if (CMXTRACKER_ON)
			{
			cmxtracker_in2(CXCTSTP_K_OK,timed_num);
			}
#endif
	K_I_Func_Return();	/* release task block */
	return(K_OK);	/* return good status */
}


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

		memory manager

**********************************************************************/
/* here's what a memory partition will look like
	ptr head;	 ptr to head of free list_ptr
	byte body;	 body of memory partition starts here
	does not test to ensure size of array is large enough for
	block size times the number of blocks */

/****************************************************************
 This function creates a fixed memory block according to the
 parameters passed. Make note, that the memory address supplied
 as the beginning of this fixed memory block is not tested as
 to legal CPU boundries and that the size of this memory block
 is free to be used.
****************************************************************/
void K_Mem_FB_Create(void *part,word16 bsize,word16 nblocks)
{
	byte *link;		/* scratch pointer */

#if (defined(CMXTRACKER) || defined(WINTRACKER))
		if (CMXTRACKER_ON)
			{
#if (defined(WINTRACKER))
			cmxtracker_in1(CXBFCRE_K_OK);
#else
			cmxtracker_in5(CXBFCRE_K_OK,0,part);
#endif

⌨️ 快捷键说明

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