📄 cxver5.c
字号:
queue_ptr->base_ptr = queuearray; /* tell CMX where queue begins. */
queue_ptr->num_slots = num_slots; /* load number of slots */
queue_ptr->size_slot = slot_size; /* load in the size of slots */
K_Que_Reset(queuenum); /* reset the queue, all slots empty. */
K_I_Func_Return(); /* release task block */
return(K_OK);
}
byte K_Que_Reset(byte queuenum)
{
QUEHDR *queue_ptr;
if (queuenum >= MAX_QUEUES) /* see if queue number within range. */
{
#ifdef CMXTRACKER
if (CMXTRACKER_ON)
{
cmxtracker_in2(CXQRST_K_ERROR,queuenum);
}
#endif
return(K_ERROR);
}
K_I_Disable_Sched(); /* set task block. */
queue_ptr = &queue[queuenum]; /* get address of proper queue handler. */
/* reset the queue_ptr's variables, that maintain the queue_ptr */
queue_ptr->queue_cnt = queue_ptr->head = queue_ptr->tail = 0;
#ifdef CMXTRACKER
if (CMXTRACKER_ON)
{
cmxtracker_in2(CXQRST_K_OK,queuenum);
}
#endif
K_I_Func_Return(); /* release task block */
return(K_OK); /* return good status. */
}
/************************************************************
CMX general add to queue function.
called by K_Que_Add_Top and K_Que_Add_Bottom functions.
test: if testing for less then 0, then pointer = num_slots - 1
if testing for equal to num_slots then pointer = 0
when adding to top
add to where head points
increment head and test.
when adding to bottom.
decrement tail and test
add to where tail points
when removing from top
decrement head and test
remove from where head points
when removing from bottom
remove from where tail points
increment tail and test
top = 0: add to bottom
top = 1: add to top
*************************************************************/
byte K_I_Que_Add_Common(byte queuenum,void *byteptr,sign_word16 top)
{
QUEHDR *queue_ptr;
queue_ptr = &queue[queuenum]; /* get address of proper queue handler. */
if (queuenum >= MAX_QUEUES || (!queue_ptr->size_slot))
{
#ifdef CMXTRACKER
if (CMXTRACKER_ON)
{
cmxtracker_in2(CXQADD_K_ERROR,queuenum);
}
#endif
return(K_ERROR);
}
K_I_Disable_Sched(); /* set task block */
/* see if queue is full already */
if (queue_ptr->queue_cnt == queue_ptr->num_slots)
{
#ifdef CMXTRACKER
if (CMXTRACKER_ON)
{
cmxtracker_in2(CXQADD_FULL,queuenum);
}
#endif
K_I_Func_Return(); /* release task block. */
return(K_ERROR); /* return proper status. */
}
if (top) /* see if adding to top of queue */
{
top = queue_ptr->head; /* top will now be our index into array. */
/* see if head equals the max number slots, and
if so, set pointer to bottom of queue */
if (++queue_ptr->head == queue_ptr->num_slots)
queue_ptr->head = 0;
}
else
{
/* were adding to bottom of queue, use tail pointer */
if (--queue_ptr->tail < 0) /* decrement tail pointer and test */
queue_ptr->tail = (queue_ptr->num_slots - 1);
top = queue_ptr->tail; /* top will now be our index into array. */
}
/* K_I_Copy = dest,source,count */
K_I_Copy((&(queue_ptr->base_ptr[top *
queue_ptr->size_slot])),byteptr,queue_ptr->size_slot);
#ifdef CMXTRACKER
if (CMXTRACKER_ON)
{
cmxtracker_in2(CXQADD_K_OK,queuenum);
}
#endif
/* see if queue now full */
if (++queue_ptr->queue_cnt == queue_ptr->num_slots)
{
K_I_Func_Return();
return(K_QUE_FULL); /* return status indicating queue now full. */
}
K_I_Func_Return(); /* release task block */
return(K_OK); /* return good status */
}
/********************************************************
test: if testing for less then 0 then pointer = num_slots - 1
if testing for equal to num_slots then pointer = 0
when removing from top
decrement head and test
remove from where head points
when removing from bottom
remove from where tail points
increment tail and test
top = 0: remove from bottom
top = 1: remove from top
*********************************************************/
byte K_I_Que_Get_Common(byte queuenum,void *byteptr,sign_word16 top)
{
QUEHDR *queue_ptr;
queue_ptr = &queue[queuenum]; /* get address of proper queue handler. */
if (queuenum >= MAX_QUEUES || (!queue_ptr->size_slot))
{
#ifdef CMXTRACKER
if (CMXTRACKER_ON)
{
cmxtracker_in2(CXQRMV_K_ERROR,queuenum);
}
#endif
return(K_ERROR);
}
K_I_Disable_Sched(); /* set task block */
/* see if queue_ptr has any slots filled */
if (!(queue_ptr->queue_cnt))
{
#ifdef CMXTRACKER
if (CMXTRACKER_ON)
{
cmxtracker_in2(CXQRMV_EMPTY,queuenum);
}
#endif
K_I_Func_Return();
return(K_ERROR); /* no, return error */
}
if (top) /* see if request was to remove top slot contents */
{
/* decrement head and test to see if head less then 0 */
if (--queue_ptr->head < 0)
queue_ptr->head = (queue_ptr->num_slots - 1);
top = queue_ptr->head; /* top will now be our index into array. */
}
else
{
/* request was to remove from bottom slot */
top = queue_ptr->tail; /* top will now be our index into array. */
/* see if tail pointer has reached it's maximum count and set
to 0, if so */
if (++queue_ptr->tail == queue_ptr->num_slots)
queue_ptr->tail = 0;
}
/* K_I_Copy = dest,source,count */
K_I_Copy(byteptr,(&(queue_ptr->base_ptr[top *
queue_ptr->size_slot])),queue_ptr->size_slot);
#ifdef CMXTRACKER
if (CMXTRACKER_ON)
{
cmxtracker_in2(CXQRMV_K_OK,queuenum);
}
#endif
/* see if queue_ptr now empty */
if (--queue_ptr->queue_cnt)
{
K_I_Func_Return(); /* no, release task block */
return(K_OK); /* return good operation */
}
K_I_Func_Return(); /* yes, queue empty, release task block */
return(K_QUE_EMPTY); /* return warning that queue now empty */
}
/***********************************************************
MESSAGE FUNCTIONS
**********************************************************/
/**********************************************************
The following is the generalize message wait function
is_get = 0, means to wait for message, with possible timeout
is_get = 1, means don't wait for message, if none.
**********************************************************/
void * K_I_Mesg_Wait_Common(byte mailbox,word16 timecnt,byte is_get)
{
MAILBOX *mail_ptr;
byte *copy_ptr;
MSG *link;
if (mailbox >= MAX_MAILBOXES) /* see if mailbox number OK. */
{
#ifdef CMXTRACKER
if (CMXTRACKER_ON)
{
cmxtracker_in3(CXMSWATM_K_ERROR,mailbox,is_get);
}
#endif
return(NULL); /* no, return null idicating error. */
}
K_I_Disable_Sched(); /* set task block. */
mail_ptr = &mail_box[mailbox]; /* address of the CMX mailbox handler. */
if (mail_ptr->waiter) /* see if another task already "owns" this mailbox. */
{
#ifdef CMXTRACKER
if (CMXTRACKER_ON)
{
cmxtracker_in3(CXMSWATM_MAILBOX_K_ERROR,mailbox,is_get);
}
#endif
K_I_Func_Return(); /* release task block. */
return(NULL); /* return error, for only one task may wait on mailbox. */
}
if (!mail_ptr->first_lnk) /* any messages present in mailbox, null = no */
{
if (is_get) /* K_Mesg_Get function used, do not wait */
{
#ifdef CMXTRACKER
if (CMXTRACKER_ON)
{
cmxtracker_in2(CXMSGET_NOMESG_K_ERROR,mailbox);
}
#endif
K_I_Func_Return(); /* release task block. */
return(NULL); /* return error. */
}
mail_ptr->waiter = activetcb; /* identify who "owns" mailbox. */
#ifdef CMXTRACKER
if (CMXTRACKER_ON)
{
cmxtracker_in4(CXMSWATM_CALL,mailbox,timecnt);
}
#endif
K_I_Time_Common(timecnt,WAIT_MESG); /* go suspend task. */
/* task will be return to here by the K_I_Time_Common function. */
mail_ptr->waiter = NULL; /* now task will NOT own mailbox. */
/* test to see if time expired or task forcefully woken, prior
to a message being set to this mailbox. */
if (activetcb->tcbstate & TIME_EXPIRED)
{
#ifdef CMXTRACKER
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. */
#ifdef CMXTRACKER
if (CMXTRACKER_ON)
{
if (is_get)
cmxtracker_in5(CXMSGET_K_OK,mailbox,copy_ptr);
else
cmxtracker_in5(CXMSWATM_K_OK,mailbox,copy_ptr);
}
#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 */
#ifdef CMXTRACKER
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. */
{
#ifdef CMXTRACKER
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. */
#ifdef CMXTRACKER
if (CMXTRACKER_ON)
{
cmxtracker_in5(CXMSSENW_K_OK,mailbox,mesg);
cmxtracker_in4(CXMSSEND_CALL,mailbox,timecnt);
}
#endif
if (K_I_Time_Common(timecnt,SEND_MESG))
{
#ifdef CMXTRACKER
if (CMXTRACKER_ON)
{
cmxtracker_in2(CXMSSEND_K_TIMEOUT,mailbox);
}
#endif
return(K_TIMEOUT);
}
else
{
#ifdef CMXTRACKER
if (CMXTRACKER_ON)
{
cmxtracker_in2(CXMSSEND_K_OK,mailbox);
}
#endif
return(K_OK);
}
}
else
{
link->sender = NULL; /* set sender to NULL. */
#ifdef CMXTRACKER
if (CMXTRACKER_ON)
{
cmxtracker_in5(CXMSSEND_K_OK1,mailbox,mesg);
}
#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. */
{
#ifdef CMXTRACKER
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. */
#ifdef CMXTRACKER
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 recieved 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 */
#ifdef CMXTRACKER
if (CMXTRACKER_ON)
{
cmxtracker_in2(CXMSACK_K_OK,(byte)(activetcb->mesg_sender - cmx_tcb));
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -