|
|
||||||||||
|
|||||||||||
|
Tics Realtime System CallsUser Level Kernel Interface
System Level Kernel Interface
Serial Communications Interface
cancelMsg, cancelTimer
Cancel a message, cancel a timer.
int cancelMsg(typeMsg * msg, long seqNum); int cancelTimer(typeMsg * msg, long seqNum);
These functions attempt to cancel a message pointed to by msg, with sequence number seqNum. If the message is in the message queue, it is removed. However, if the message has already been received or canceled, it is not removed. If a message is to be canceled, a pointer to the message and its sequence number must be saved prior
to sending it.
Examples
enterRegion, exitRegion
Gain or release exclusive access to a protected region.
void enterRegion(typeTcb * regionMgrTcb); void exitRegion(typeTcb * regionMgrTcb);
Following the enterRegion call, a task has exclusive access to a protected region, assuming that all other tasks that require access also use the enterRegion call. When finished using the region, the task must relinquish ownership by calling exitRegion.
exitTics
Exit the Tics Kernel and restore the hardware to its original state. For use on MS-DOS systems only.
void exitTics(void); exitTics restores the PC hardware timer chip, the timer isr, and the keyboard isr to their original state. exitTics should always be called prior to exiting when using the Tics Kernel under MS-DOS. freeMailClear the mail available flag for the mailbox. int freeMail(typeMail * mail); Each tcb contains 32 mail flag bits; if a bit is set, mail is available for the corresponding mailbox number. Mailbox numbers range from 0 to 31. freeMail clears the mail available bit for the mailbox pointed to by mail. Examples
freeMsgFree a message. void freeMsg(void * msg); freeMsg adds the message pointed to by msg, to the free message list. Examples
makeMail, sendMailMake mail, send mail to a task. typeMail * makeMail(typeTcb *tcb, mailBoxNum) typeMail * sendMail(typeMail * mail) makeMail creates a mailbox structure with mailbox number mailBoxNum and destination tcb. sendMail sends the mail pointed to by mail. sendMail over-writes unread mail unless the OVER_WRITE_DISABLE bit in the flags field of the mailbox is set. OVER_WRITE_DISABLE is defined in the Tics header file. Returns a pointer to the mail structure. Examples
makeMsg, sendMsgMake a message, send a message to a task. typeMsg * makeMsg(typeTcb * tcb, int msgNum); typeMsg * sendMsg(typeMsg * msgPtr);
makeMsg creates a message with number msgNum and destination tcb. sendMsg sends the message pointed to by msgPtr.
Examples
makeTask, startTaskMake a task control block, start task execution. typeTcb * makeTask(void (* task)(void), int taskNum); typeTcb * startTask(typeTcb * tcb);
makeTask creates a task control block (tcb) for the C function task, and assigns it the task number taskNum.
makeTask defaults the tcb entries as follows.
startTask allocates a 1K stack, and schedules the task to run according to its priority.
ExamplesSee any example. makeTics, startTicsInitialize the Tics Kernel and hardware. typeTics * makeTics(typeFreeMsg * msgSpace, int numMsgs); typeTics * startTics(typeTics * ticsInfo); These functions must be called before any other Tics function. makeTics creates a typeTics data structure and returns a pointer to it. MsgSpace points to a block of memory to be used for message space. numMsgs is the number of messages of type typeFreeMsg that is represented by the space. The elements of this structure are defined below with the default values shown in parentheses.
Returns a pointer to a structure of type typeTics. Examples
makeTimer, startTimerMake a timer message, start a timer. typeMsg * makeTimer(long msTimeout); typeMsg * startTimer(typeMsg * msgPtr); makeTimer makes a timer message. startTimer starts the timer countdown. On timeout, the message TIMEOUT (defined in the Tics header file) is issued to the destination task after msTimeout milliseconds. makeTimer defaults the message structure members as follows.
Returns a pointer to the message. Examples
pauseSuspend task execution for a given number of milliseconds. int pause(long msPause); pause suspends the current task for msPause milliseconds. Examples
rcvMailReturns the mail data in the mailbox. typeMail * rcvMail(int mailBoxNum);
If mail is available, rcvMail returns a pointer to the indicated mailbox number, otherwise NULL is returned. Mailbox numbers range from 0 to 31.
Examples
rcvMsgRetrieve a specific message from a task's message queue. typeMsg * rcvMsg(int msgNum);
rcvMsg retrieves the next available message from the active task's message queue with number msgNum. If msgNum equals ANY_MSG, and the queue is not empty, the first message in the queue is returned. If the desired message is not in the queue, NULL is returned. The message must be freed after use by calling freeMsg.
Examples
suspendSuspend the active task. Typically this is only used as the last statement of main. void suspend(void); suspend suspends the active task and runs the task at the front of the ready queue. The suspended task will run again only if a message is sent to it, or a wakeup is executed. waitMailWait for mail. typeMail * waitMail(int mailBoxNum); waitMail waits for mail to arrive in mailbox number mailBoxNum for the active task. If mail is available, control is returned immediately, otherwise, the active task is suspended until mail arrives. Mail must be freed after use by calling freeMail. Mailbox numbers range from 0 to 31. If mail is available, a pointer to the mailbox is returned, otherwise, the active task is suspended until mail for the indicated mailbox arrives.
Examples
waitMsgWait for a specific message. typeMsg * waitMsg(int msgNum);
waitMsg waits for a message with number msgNum to appear in the active task's queue and returns a pointer to it. If msgNum equals ANY_MSG, the first message in the queue is returned. If a message is available, control is returned immediately, otherwise, the active task is suspended until a message arrives. The message must be freed after use by calling freeMsg.
Examples
wakeupWake up a suspended task. Typically, this function is used only by the kernel. void wakeup(typeTcb * tcb); wakeup wakes up the suspended task connected to the task control block tcb. System Level Kernel InterfaceSystem Level Kernel interface calls provide a lower level interface to Tics services. Most System Level calls can be invoked from within an isr. System Level calls provide more flexibility and power, but more responsibility is placed upon the user._dosIsrRet, _isrRetReturn from an MS-DOS isr, return from an isr. void _isrRet(); void _dosIsrRet(); _isrRet and _dosIsrRet both check the priority of the active task against the task at the front of the ready queue. _isrRet always returns to the highest priority task. _dosIsrRet returns to the highest priority task only when the system is not in an MS-DOS system call. Use _dosIsrRet when running under MS-DOS. These calls must be the last statement of the isr. If neither of these calls is made from within the isr, then control returns to the interrupt task. Examples
extern typeTcb * IoTcb;
void interrupt far IoIsr(void)
{
typeMsg * msg;
char ioChar;
ioChar = inportb(0x50);
msg = _makeMsg(IoTcb, NEW_DATA, FALSE);
msg->iData = ioChar;
_sendMsg(msg, FALSE, FALSE);
_dosIsrRet();
}
_freeMsgFree a message. void _freeMsg(void * msg, int diOpt); _freeMsg adds the message pointed to by msg, to the free message list. diOpt is TRUE if interrupts are to be disabled when required, otherwise interrupts are assumed to be disabled on entry. Examples
typeMsg * msg;
msg = rcvMsg();
if (msg != NULL) {_freeMsg(msg, TRUE);}
_isrPreemptPreempt active task from within an isr. void _isrPreempt(int diOpt); _isrPreempt is typically used from within an isr to preempt the active task so that when a return from interrupt is performed, control is returned to a higher priority task that the isr put into the ready queue. If interrupts are explicitly enabled while in the isr, then diOpt should be TRUE, otherwise diOpt should always be FALSE when invoking _isrPreempt from within an isr. _isrPreempt preempts the active task and runs the task at the front of the ready queue even if the active task has a higher priority. _isrPreempt assumes that the user has made the appropriate checks and has determined that preemption is required. _isrRet and _dosIsrRet both check the priority of the active task against the task at the front of the ready queue. _isrRet always returns to the highest priority task. _dosIsrRet returns to the highest priority task only when the system is not in an MS-DOS system call. These two calls are preferred over _isrPreempt and should be used whenever possible. However, if other considerations beyond the priority of the ready to run task and the active task are at issue, then _isrPreempt should be used.
Examples
extern typeTcb * IoTcb;
void interrupt far IoIsr(void)
{
typeMsg * msg;
char ioChar;
ioChar = inportb(0x50);
msg = _makeMsg(IoTcb, NEW_DATA, FALSE);
msg->iData = ioChar;
_sendMsg(msg, FALSE, FALSE);
if (ActiveTcb->pri > IoTcb->pri &&
notInDos()) {
_isrPreempt(FALSE);
}
}
_makeMsg, _sendMsgMake a message, send message to a task. typeMsg * _makeMsg(typeTcb * tcb, msgNum, int diOpt); typeMsg *_sendMsg(typeMsg * msgPtr, int diOpt, int preeOpt);
_makeMsg creates a message with number msgNum and destination tcb. _sendMsg sends the message pointed to by msgPtr. diOpt is TRUE if interrupts are to be disabled when required, otherwise interrupts are assumed to be disabled on entry. If interrupts are explicitly enabled during isr execution, then diOpt should be TRUE, otherwise diOpt should always be FALSE when invoked from within an isr. preeOpt is TRUE if the active task is to be preempted if necessary. preeOpt should always be FALSE when invoked from within an isr.
Examplesextern typeTcb * IoTask; extern typeTcb * TaskA; typeMsg * msgPtr; msgPtr = _makeMsg(IoTask, START, TRUE); /* Raise msg priority */ msgPtr->pri = DEF_PRI - 1; /* Change sender */ msgPtr->senderTcb = TaskA; /* Send the message */ _sendMsg(msgPtr, TRUE, TRUE);
_makeTimerMake a timer message. typeMsg *_makeTimer(long ticCount, int diOpt); _makeTimer makes a timer message. ticCount is the number of system tics. A system tic occurs each time the timer isr is entered. If interrupts are explicitly enabled during isr execution, then diOpt should be TRUE, otherwise diOpt should always be FALSE when invoked from within an isr. _makeTimer defaults message structure members as follows.
ExamplesSee makeTimer example. _rcvMsgRetrieve a message from a task's message queue. typeMsg * _rcvMsg(typeTcb * tcb, int msgQNum, int msgNum, int diOpt, int remOpt);
_rcvMsg gets the message with number msgNum and message queue number msgQNum from tcb. If msgNum equals ANY_MSG, the first message in the queue is returned, otherwise the requested message is returned. If remOpt is TRUE, the message is removed from the queue, otherwise, the message is left in the queue. This option is useful for checking the queue without removing messages. In all cases NULL is returned if the desired message is not in the queue. diOpt is TRUE if interrupts are to be disabled when required, otherwise interrupts are assumed to be disabled on entry. If interrupts are explicitly enabled during isr execution, then diOpt should be TRUE, otherwise diOpt should always be FALSE when invoking _rcvMsg from within an isr. The message must be freed after use by calling freeMsg or _freeMsg.
Examples/* Get the GO msg from msg queue 0 for the active task. */ typeMsg * msgPtr; msgPtr = _rcvMsg(ActiveTcb, 0, GO, TRUE, TRUE);
_sendMailSend mail to a task. void _sendMail(typeMail * mail, int diOpt, int preeOpt) _sendMail sends the mail pointed to by mail. _sendMail over-writes unread mail unless the OVER_WRITE_DISABLE bit in the flags field of the mailbox is set. OVER_WRITE_DISABLE is defined in the Tics header file. diOpt is TRUE if interrupts are to be disabled when required, otherwise interrupts are assumed to be disabled on entry. preeOpt is TRUE if the active task is to be preempted if necessary. ExamplesSee sendMail example. _waitMailWait for mail. typeMail * _waitMail(int mailBoxNum, int diOpt)
_waitMail waits for mail to arrive in mailbox number mailBoxNum for the active task. If mail is available, control is returned immediately, otherwise, the active task is suspended until mail arrives. diOpt is TRUE if interrupts are to be disabled when required, otherwise interrupts are assumed to be disabled on entry. Mail must be freed after use by calling freeMail. Mailbox numbers range from 0 to 31.
Examples_waitMsgWait for a specific message in a specific message queue. typeMsg * _waitMsg(int msgQNum, int msgNum, int diOpt, int remOpt);
_waitMsg waits for a message with number msgNum to appear in the message queue msgQNum and returns a pointer to it. If a message is available, control is returned immediately, otherwise, the active task is suspended until a message arrives. If msgNum equals ANY_MSG, the first message that arrives in the queue is returned, otherwise the requested message is returned as soon as it arrives. diOpt must be FALSE if interrupts are disabled when the call is made, otherwise, it must always be TRUE. If remOpt is TRUE, the message is removed from the queue, otherwise, the message is left in the queue. This option is useful for checking the queue without removing messages. The message must be freed after use by calling freeMsg or _freeMsg.
Examples
#define MSG1 1000
#define MSG2 1001
typeMsg * msgPtr;
/* Wait for the arrival of any msg, but
do not remove it from the queue */
_waitMsg(MSGQ, ANY_MSG, TRUE, FALSE);
/* Now use _rcvMsg to see if MSG1 or MSG2 has arrived */
if (msgPtr = _rcvMsg(ActiveTcb, MSGQ, MSG1, TRUE, TRUE) != NULL) {
processMsg1(msgPtr);
freeMsg(msgPtr);
}
if (msgPtr = _rcvMsg(ActiveTcb, MSGQ, MSG2, TRUE, TRUE) != NULL) {
processMsg2(msgPtr);
freeMsg(msgPtr);
}
_wakeupWake up a suspended task. void _wakeup(typeTcb * tcb, int diOpt); _wakeup wakes up the suspended task connected to the task control block tcb. diOpt is TRUE if interrupts are to be disabled when required, otherwise interrupts are assumed to be disabled on entry. Typically this call is only used by the Tics kernel. Extended Kernel InterfaceThe following section details the Tics Extended Kernel functions. getMem, _getMemAllocate a block of memory. void * getMem(typeMem * * memPtr); void * _getMem(typeMem * * memPtr, int diOpt);
These functions return a block of memory from the memory pool specified by memPtr. The memory pool must first be created by makeMem. _getMem is useful when memory must be allocated from within an isr when interrupts are disabled. A TRUE diOpt argument indicates that interrupts are already disabled.
makeMem, putMem. Example #define DATA 1000 extern typeMem * MemPoolA; extern typeTcb * TcbA; typeMsg * msg; msg = makeMsg(TcbA, DATA); msg->pData = getMem(&MemPoolA); sendMsg(msg);
makeMem, _makeMemCreate a pool of fixed size memory blocks. typeMem * makeMem(void * memPtr, unsigned long poolSize, int blkSize); typeMem * _makeMem(void * memPtr, unsigned long poolSize, int blkSize, int diOpt);
These functions create a pool of fixed size memory blocks. Any number of pools may be created with successive calls to either of these functions. Each memory block will be blkSize bytes in length. The memory blocks are created from a caller supplied buffer pointed to by memPtr which is poolSize bytes in length. A TRUE diOpt argument indicates that interrupts are already disabled.
Examples
#define NUM_MSGS 100
#define LEN_MEM_POOL 4096
typeFreeMsg MsgSpace[NUM_MSGS];
typeMem * MemPool;
char MemPoolSpace[LEN_MEM_POOL];
void main()
{
typeTics * tics;
tics = makeTics(MsgSpace, NUM_MSGS);
startTics(tics);
startTask(makeTask(taskA, 0));
MemPool =
makeMem(MemPoolSpace, LEN_MEM_POOL, 128);
suspend();
}
putMem, _putMemFree a block of memory. void putMem(typeMem * * memPtr, void * blkPtr); void _putMem(typeMem * * memPtr, void * blkPtr, int diOpt); These functions release the memory block pointed to by blkPtr back to the memory pool specified by memPtr. The memory pool must first be created by makeMem. _putMem is useful when memory must be freed from within an isr when interrupts are disabled. A TRUE diOpt argument indicates that interrupts are already disabled. Examples#define DATA 1000 extern typeMem * MemPoolA; msg = waitMsg(DATA); processData(msg->pData); putMem(&MemPoolA, msg->pData); freeMsg(msg);
waitTimedMsgWait for a message. If the message does not arrive within the indicated number of milliseconds, wake the waiting task with a TIMEOUT message. typeMsg * waitTimedMsg(int msgNum, long timeout);
This function performs a waitMsg function call for message number msgNum. If the message does not arrive within timeout milliseconds, the waiting task is sent a TIMEOUT message. The function cancels the timer if the message arrives in time.
Examples
#define DATA 1000
typeMsg * msg;
msg = waitTimedMsg(DATA, 1000L);
switch (msg->msgNum) {
case DATA:
processData(msg);
break;
case TIMEOUT:
handleTimeout();
break;
}
freeMsg(msg);
yieldVoluntarily relinquish control so that other tasks can run. void yield(void); yield suspends the current task so that other tasks can run. yield is typically used to share time between two or more tasks of the same priority. Examples
void ioTask(void)
{
while (TRUE) {
readIOData();
yield();
}
}
void keyboardTask(void)
{
while (TRUE) {
if (kbhit()) {processKey();}
yield();
}
}
The two tasks above share time by first doing their work, and then yielding so that the other task can run. Serial Communication InterfaceThe following section details the Tics serial communications functions. makeCom, startCom, restoreComMake a com port structure, initialize a com port, restore a com port. typeCom * makeCom(int comNum); void startCom(typeCom * com); void restoreCom(typeCom * com);
makeCom creates a com port structure of type typeCom (defined in ticscom.h) with default values and returns a pointer to it. comNum is 0 for COM1 and 1 for COM2. startCom uses the information in the com port structure to initialize the UART and the interrupt vector table. restoreCom restores the com port to its original state.
Examples
readCom, writeComRead,/write data directly to/from the UART. unsigned char readCom(typeCom * com, int offset); void writeCom(typeCom * com, int offset, unsigned char data);
These functions read and write to the UART directly. The UART register base address is contain in the "com" argument. The "offset" argument designates a UART register which is "offset" bytes from the base address. "data" contains the character to be written to the indicated register. See ticscom.h for UART register offsets and related details.
rcvCom, waitCom, xmitComint rcvCom(typeCom * com, unsiged char * data); unsigned char waitCom(typeCom * com); void xmitCom(typeCom * com, unsigned char data);
rcvCom returns the character at the front of the receive fifo on the "data" argument and returns YES if a character was available, otherwise, NO is returned. In either case, rcvCom always returns immediately. waitCom calls rcvCom to retrieve the character at the front of the com port's receive fifo. if the fifo is empty, the fifo is sampled every com->rcvPause milliseconds until data arrives. waitCom returns the received data.
writeComFieldWrite a bit in a UART register. void writeComField(typeCom * com, int offset, unsigned char mask, unsigned char data); writeComField writes "data" to the UART register located at com->portNum + offset. The data is written to the bit field defined by "mask".
Copyright © 2000, Tics Realtime
| |||||||||||