µC/OS-II API Reference

This section provides a user’s guide to µC/OS-II services. Each of the user-accessible kernel services is presented in alphabetical order and the following information is provided for each of the services.

  • A brief description
  • The function prototype
  • The filename of the source code
  • The #define constant needed to enable the code for the service
  • A description of the arguments passed to the function
  • A description of the return value(s)
  • Specific notes and warnings on using the service
  • One or two examples of how to use the function


OS_ENTER_CRITICAL()

FileCalled FromCode Enabled By
OS_CPU.HTask or ISRN/A

OS_ENTER_CRITICAL() and OS_EXIT_CRITICAL() are macros used to disable and enable, respectively, the processor’s interrupts.

Arguments

None

Returned Value

None

Notes/Warnings

These macros must be used in pairs.

If OS_CRITICAL_METHOD is set to 3, your code is assumed to have allocated local storage for a variable of type OS_CPU_SR called cpu_sr as follows:


#if OS_CRITICAL_METHOD == 3      /* Allocate storage for CPU status register */
    OS_CPU_SR  cpu_sr;
#endif  


Example

void TaskX(void *pdata)
{
#if OS_CRITICAL_METHOD == 3
      OS_CPU_SR   cpu_sr;
 #endif
      for (;;) {
         .
         .
         OS_ENTER_CRITICAL();    /* Disable interrupts     */
         .
         .                       /* Access critical code   */
         .
         OS_EXIT_CRITICAL();     /* Enable  interrupts     */
         .
         .
      }
}


OS_EXIT_CRITICAL()

FileCalled FromCode Enabled By
OS_CPU.HTask or ISRN/A

OS_ENTER_CRITICAL() and OS_EXIT_CRITICAL() are macros used to disable and enable, respectively, the processor’s interrupts.

Arguments

None

Returned Value

None

Notes/Warnings

These macros must be used in pairs.

If OS_CRITICAL_METHOD is set to 3, your code is assumed to have allocated local storage for a variable of type OS_CPU_SR called cpu_sr as follows:


#if OS_CRITICAL_METHOD == 3      /* Allocate storage for CPU status register */
    OS_CPU_SR  cpu_sr;
#endif  


Example

void TaskX(void *pdata)
{
#if OS_CRITICAL_METHOD == 3
      OS_CPU_SR   cpu_sr;
 #endif
      for (;;) {
         .
         .
         OS_ENTER_CRITICAL();    /* Disable interrupts     */
         .
         .                       /* Access critical code   */
         .
         OS_EXIT_CRITICAL();     /* Enable  interrupts     */
         .
         .
      }
}


OSFlagAccept()

OS_FLAGS OSFlagAccept(OS_FLAG_GRP *pgrp, 
                      OS_FLAGS     flags,
                      INT8U        wait_type, 
                      INT8U       *err);
FileCalled FromCode Enabled By
OS_FLAG.CTaskOS_FLAG_EN and OS_FLAG_ACCEPT_EN

OSFlagAccept() allows you to check the status of a combination of bits to be either set or cleared in an event flag group. Your application can check for ANY bit to be set/cleared or ALL bits to be set/cleared. This function behaves exactly as OSFlagPend() except that the caller will NOT block if the desired event flags are not present.

Arguments

pgrp

is a pointer to the event flag group. This pointer is returned to your application when the event flag group is created (see OSFlagCreate()).

flags

is a bit pattern indicating which bit(s) (i.e., flags) you wish to check. The bits you want are specified by setting the corresponding bits in flags . word

wait_type

specifies whether you want ALL bits to be set/cleared or ANY of the bits to be set/cleared. You can specify the following argument:

OS_FLAG_WAIT_CLR_ALL

You will check ALL bits in 'flags ' to be clear (0)

OS_FLAG_WAIT_CLR_ANY

You will check ANY bit in 'flags ' to be clear (0)

OS_FLAG_WAIT_SET_ALL

You will check ALL bits in 'flags ' to be set (1)

OS_FLAG_WAIT_SET_ANY

You will check ANY bit in 'flags ' to be set (1)

You can add OS_FLAG_CONSUME if you want the event flag(s) to be ‘consumed’ by the call. For example, to wait for ANY flag in a group and then clear the flags that are present, set wait_type to:

OS_FLAG_WAIT_SET_ANY + OS_FLAG_CONSUME

err

is a pointer to an error code and can be:

OS_NO_ERR

No error

OS_ERR_EVENT_TYPE

You are not pointing to an event flag group

OS_FLAG_ERR_WAIT_TYPE

You didn't specify a proper 'wait_type ' argument.

OS_FLAG_INVALID_pgrp

You passed a NULL pointer instead of the event flag handle.

OS_FLAG_ERR_NOT_RDY

The desired flags you are waiting for are not available.

Returned Value

The state of the flags in the event flag group.

Notes/Warnings

  • The event flag group must be created before it is used.
  • This function does NOT block if the desired flags are not present.

Example

#define  ENGINE_OIL_PRES_OK   0x01
#define  ENGINE_OIL_TEMP_OK   0x02
#define  ENGINE_START         0x04
 
OS_FLAG_GRP *EngineStatus;
 
void Task (void *pdata)
{
    INT8U     err;
    OS_FLAGS  value;
    pdata = pdata;
    for (;;) {
        value = OSFlagAccept(EngineStatus,
                             ENGINE_OIL_PRES_OK + ENGINE_OIL_TEMP_OK,
                             OS_FLAG_WAIT_SET_ALL,
                             &err);
        switch (err) {
            case OS_NO_ERR:
                 /* Desired flags are available         */
                 break;
            case OS_FLAG_ERR_NOT_RDY:
                 /* The desired flags are NOT available */
                 break;
        }
        .
        .
    }
}

OSFlagCreate()

OS_FLAG_GRP *OSFlagCreate (OS_FLAGS flags, INT8U *err);
FileCalled FromCode Enabled By
OS_FLAG.CTask or startup codeOS_FLAG_EN

OSFlagCreate() is used to create and initialize an event flag group.

Arguments

flags

contains the initial value to store in the event flag group.

err

is a pointer to a variable which will be used to hold an error code. The error code can be one of the following:

OS_NO_ERR

if the call was successful and the event flag group was created.

OS_ERR_CREATE_ISR

if you attempted to create an event flag group from an ISR.

OS_FLAG_GRP_DEPLETED

if there are no more event flag groups available. You will need to increase the value of OS_MAX_FLAGS in OS_CFG.H .

Returned Value

A pointer to the event flag group if a free one is available. If no event flag group is available, OSFlagCreate() will return a NULL pointer.

Notes/Warnings

Event flag groups must be created by this function before they can be used by the other services.

Example

OS_FLAG_GRP *EngineStatus;
 
void main (void)
{
    INT8U  err;
    .
    .
    OSInit();                /* Initialize µC/OS-II                                         */
    .
    .
                             /* Create a flag group containing the engine's status          */
    EngineStatus = OSFlagCreate(0x00, &err);    .
    .
    OSStart();               /* Start Multitasking                                          */
}

OSFlagDel()

OS_FLAG_GRP *OSFlagDel(OS_FLAG_GRP *pgrp, 
                             INT8U  opt,
                             INT8U *err);
FileCalled FromCode Enabled By
OS_FLAG.CTaskOS_FLAG_EN and OS_FLAG_DEL_EN

OSFlagDel() is used to delete an event flag group. This is a dangerous function to use because multiple tasks could be relying on the presence of the event flag group. You should always use this function with great care. Generally speaking, before you would delete an event flag group, you would first delete all the tasks that access the event flag group.

Arguments

pgrp

is a pointer to the event flag group. This pointer is returned to your application when the event flag group is created (see OSFlagCreate()).

opt

specifies whether you want to delete the event flag group only if there are no pending tasks (OS_DEL_NO_PEND) or whether you always want to delete the event flag group regardless of whether tasks are pending or not (OS_DEL_ALWAYS). In this case, all pending task will be readied.

err

is a pointer to a variable which will be used to hold an error code. The error code can be one of the following:

OS_NO_ERR

if the call was successful and the event flag group was deleted.

OS_ERR_DEL_ISR

if you attempted to delete an event flag group from an ISR.

OS_FLAG_INVALID_pgrp

if you passed a NULL pointer in pgrp .

OS_ERR_EVENT_TYPE

if pgrp is not pointing to an event flag group.

OS_ERR_INVALID_OPT

if you didn’t specify one of the two options mentioned above.

OS_ERR_TASK_WAITING

if one or more task were waiting on the event flag group and you specified OS_DEL_NO_PEND .

Returned Value

A NULL pointer if the event flag group is deleted, or pgrp if the event flag group was not deleted. In the latter case, you would need to examine the error code to determine the reason.

Notes/Warnings

  • You should use this call with care because other tasks may expect the presence of the event flag group.
  • This call can potentially disable interrupts for a long time. The interrupt disable time is directly proportional to the number of tasks waiting on the event flag group.

Example

OS_FLAG_GRP *EngineStatusFlags;
 
void Task (void *pdata)
{
    INT8U        err;
    OS_FLAG_GRP *pgrp
;
    pdata = pdata;
    while (1) {
        .
        .
        pgrp = OSFlagDel(EngineStatusFlags, OS_DEL_ALWAYS, &err);
        if (pgrp == (OS_FLAG_GRP *)0) {
            /* The event flag group was deleted */
        }
        .
        .
    }
}

OSFlagPend()

OS_FLAGS OSFlagPend(OS_FLAG_GRP *pgrp,
                    OS_FLAGS     flags,
                    INT8U        wait_type,
                    INT16U       timeout,
                    INT8U       *err);
FileCalled FromCode Enabled By
OS_FLAG.CTask onlyOS_FLAG_EN

OSFlagPend() is used to have a task wait for a combination of conditions (i.e., events or bits) to be set (or cleared) in an event flag group. You application can wait for ANY condition to be set (or cleared) or, ALL conditions to be either set or cleared. If the events that the calling task desires are not available then, the calling task will be blocked until the desired conditions are satisfied or, the specified timeout expires.

Arguments

pgrp

is a pointer to the event flag group. This pointer is returned to your application when the event flag group is created (see OSFlagCreate()).

flags

is a bit pattern indicating which bit(s) (i.e., flags) you wish to check. The bits you want are specified by setting the corresponding bits in flags .

wait_type

specifies whether you want ALL bits to be set/cleared or ANY of the bits to be set/cleared. You can specify the following argument:

OS_FLAG_WAIT_CLR_ALL

You will check ALL bits in 'flags ' to be clear (0)

OS_FLAG_WAIT_CLR_ANY

You will check ANY bit in 'flags ' to be clear (0)

OS_FLAG_WAIT_SET_ALL

You will check ALL bits in 'flags ' to be set (1)

OS_FLAG_WAIT_SET_ANY

You will check ANY bit in 'flags ' to be set (1)

You can also specify whether the flags will be ‘consumed’ by adding OS_FLAG_CONSUME to the wait_type . For example, to wait for ANY flag in a group and then CLEAR the flags that satisfy the condition, set wait_type to:

OS_FLAG_WAIT_SET_ANY + OS_FLAG_CONSUME

err

is a pointer to an error code and can be:

OS_NO_ERR

No error

OS_ERR_PEND_ISR

You tried to call OSFlagPend from an ISR which is not allowed.

OS_FLAG_INVALID_pgrp

You passed a NULL pointer instead of the event flag handle.

OS_ERR_EVENT_TYPE

You are not pointing to an event flag group

OS_TIMEOUT

The flags were not available within the specified amount of time.

OS_FLAG_ERR_WAIT_TYPE

You didn't specify a proper 'wait_type ' argument.

Returned Value

The value of the flags in the event flag group after they are consumed (if OS_FLAG_CONSUME is specified) or, the state of the flags just before OSFlagPend() returns. OSFlagPend() returns 0 if a timeout occurs.

Notes/Warnings

The event flag group must be created before it’s used.

Example

#define  ENGINE_OIL_PRES_OK   0x01
#define  ENGINE_OIL_TEMP_OK   0x02
#define  ENGINE_START         0x04
 
OS_FLAG_GRP *EngineStatus;
 
void Task (void *pdata)
{
    INT8U     err;
    OS_FLAGS  value;
    pdata = pdata;
    for (;;) {
        value = OSFlagPend(EngineStatus,
                           ENGINE_OIL_PRES_OK   + ENGINE_OIL_TEMP_OK,
                           OS_FLAG_WAIT_SET_ALL + OS_FLAG_CONSUME,
                           10,
                           &err);
        switch (err) {
            case OS_NO_ERR:
                 /* Desired flags are available */
                 break;
            case OS_TIMEOUT:
                 /* The desired flags were NOT available before 10 ticks occurred */
                 break;
        }
        .
        .
    }
}

OSFlagPost() 

OS_FLAGS OSFlagPost(OS_FLAG_GRP *pgrp,
                    OS_FLAGS     flags,
                    INT8U        opt,
                    INT8U       *err);
FileCalled FromCode Enabled By
OS_FLAG.CTask or ISROS_FLAG_EN

You set or clear event flag bits by calling OSFlagPost() . The bits set or cleared are specified in a ‘bit mask’. OSFlagPost() will ready each task that has it’s desired bits satisfied by this call. You can set or clear bits that are already set or cleared.

Arguments

pgrp

is a pointer to the event flag group. This pointer is returned to your application when the event flag group is created (see OSFlagCreate()).

flags

specifies which bits you want set or cleared. If opt (see below) is OS_FLAG_SET , each bit that is set in 'flags ' will set the corresponding bit in the event flag group. For example, to set bits 0, 4 and 5 you would set flags to 0x31 (note, bit 0 is least significant bit). If opt (see below) is OS_FLAG_CLR , each bit that is set in flags will CLEAR the corresponding bit in the event flag group. For example, to clear bits 0, 4 and 5 you would specify 'flags ' as 0x31 (note, bit 0 is least significant bit).

opt

indicates whether the flags will be set (OS_FLAG_SET) or cleared (OS_FLAG_CLR).

err

is a pointer to an error code and can be:

OS_NO_ERR

The call was successful

OS_FLAG_INVALID_pgrp

You passed a NULL pointer

OS_ERR_EVENT_TYPE

You are not pointing to an event flag group

OS_FLAG_INVALID_OPT

You specified an invalid option

Returned Value

The new value of the event flags.

Notes/Warnings

  • Event flag groups must be created before they are used.
  • The execution time of this function depends on the number of tasks waiting on the event flag group. However, the execution time is deterministic.
  • The amount of time interrupts are DISABLED also depends on the number of tasks waiting on the event flag group.

Example

#define  ENGINE_OIL_PRES_OK   0x01
#define  ENGINE_OIL_TEMP_OK   0x02
#define  ENGINE_START         0x04
 
OS_FLAG_GRP  *EngineStatusFlags;
 
void  TaskX (void *pdata)
{
    INT8U  err;
    pdata = pdata;
    for (;;) {
        .
        .
        err = OSFlagPost(EngineStatusFlags, ENGINE_START, OS_FLAG_SET, &err);
        .
        .
    }
}

OSFlagQuery()

OS_FLAGS OSFlagQuery (OS_FLAG_GRP *pgrp, 
                      INT8U       *err);
FileCalled FromCode Enabled By
OS_FLAG.CTask or ISROS_FLAG_EN and OS_FLAG_QUERY_EN

OSFlagQuery() is used to obtain the current value of the event flags in a group. At this time, this function does NOT return the list of tasks waiting for the event flag group.

Arguments

pgrp

is a pointer to the event flag group. This pointer is returned to your application when the event flag group is created (see OSFlagCreate()).

err

is a pointer to an error code and can be:

OS_NO_ERR

The call was successful

OS_FLAG_INVALID_pgrp

You passed a NULL pointer

OS_ERR_EVENT_TYPE

You are not pointing to an event flag group

Returned Value

The state of the flags in the event flag group.

Notes/Warnings

  • The event flag group to query must be created.
  • You can call this function from an ISR.

Example

OS_FLAG_GRP *EngineStatusFlags;
 
void Task (void *pdata)
{
    OS_FLAGS flags;
    INT8U    err;
    pdata = pdata;
    for (;;) {
        .
        .
        flags = OSFlagQuery(EngineStatusFlags, &err);
        .
        .
    }
}

OSInit()

void OSInit (void);
FileCalled FromCode Enabled By
OS_CORE.CStartup code onlyN/A

OSInit() initializes µC/OS-II and must be called prior to calling OSStart() , which actually starts multitasking.

Arguments

None

Returned Value

None

Notes/Warnings

OSInit() must be called before OSStart() .

Example

void main (void)
{
      .
      .
      OSInit();      /* Initialize uC/OS-II */
      .
      .
      OSStart();     /* Start Multitasking  */
}

OSIntEnter()

void OSIntEnter (void);
FileCalled FromCode Enabled By
OS_CORE.CISR onlyN/A

OSIntEnter() notifies µC/OS-II that an ISR is being processed. This allows µC/OS-II to keep track of interrupt nesting. OSIntEnter() is used in conjunction with OSIntExit() .

Arguments

None

Returned Value

None

Notes/Warnings

This function must not be called by task-level code.

You can increment the interrupt nesting counter (OSIntNesting) directly in your ISR to avoid the overhead of the function call/return. It’s save to increment OSIntNesting in your ISR because interrupts are assumed to be disabled when OSIntNesting needs to be incremented.

You are allowed to nest interrupts up to 255 levels deep.

Example 1

(Intel 80x86, real mode, large model)

Use OSIntEnter() for backward compatibility with µC/OS.

    ISRx PROC   FAR
         PUSHA                          ; Save interrupted task's context
         PUSH   ES
         PUSH   DS
;
         MOV    AX, SEG(_OSIntNesting)  ; Reload DS
         MOV    DS, AX
;
         CALL   FAR PTR _OSIntEnter     ; Notify µC/OS-II of start of ISR
         .
         .
         POP    DS                      ; Restore processor registers
         POP    ES
         POPA
         IRET                           ; Return from interrupt
    ISRx ENDP

Example 2

(Intel 80x86, real mode, large model)

    ISRx    PROC   FAR
            PUSHA                          ; Save interrupted task's context
            PUSH   ES
            PUSH   DS
;
            MOV    AX, SEG(_OSIntNesting)  ; Reload DS
            MOV    DS, AX
;
            INC    BYTE PTR _OSIntNesting  ; Notify ?C/OS-II of start of ISR
            .
            .
            .
            POP    DS                      ; Restore processor registers
            POP    ES
            POPA
            IRET                           ; Return from interrupt
    ISRx    ENDP

OSIntExit()

void OSIntExit (void);
FileCalled FromCode Enabled By
OS_CORE.CISR onlyN/A

OSIntExit() notifies µC/OS-II that an ISR has completed. This allows µC/OS-II to keep track of interrupt nesting. OSIntExit() is used in conjunction with OSIntEnter() . When the last nested interrupt completes, OSIntExit() determines if a higher priority task has been made ready to run, in which case, the interrupt returns to the higher priority task instead of the interrupted task.

Arguments

None

Returned Value

None

Notes/Warnings

This function must not be called by task-level code. Also, if you decided to increment OSIntNesting, you still need to call OSIntExit() .

Example

(Intel 80x86, real mode, large model)
    ISRx    PROC    FAR
            PUSHA                      ; Save processor registers
            PUSH    ES
            PUSH    DS
            .
            .
            CALL    FAR PTR _OSIntExit ; Notify µC/OS-II of end of ISR
            POP     DS                 ; Restore processor registers
            POP     ES
            POPA
            IRET                       ; Return to interrupted task
    ISRx    ENDP

OSMboxAccept()

void *OSMboxAccept (OS_EVENT *pevent);
FileCalled FromCode Enabled By
OS_MBOX.CTask or ISROS_MBOX_EN and OS_MBOX_ACCEPT_EN

OSMboxAccept() allows you to see if a message is available from the desired mailbox. Unlike OSMboxPend() , OSMboxAccept() does not suspend the calling task if a message is not available. In other words, OSMboxAccept() is non-blocking. If a message is available, the message is returned to your application and the content of the mailbox is cleared. This call is typically used by ISRs because an ISR is not allowed to wait for a message at a mailbox.

Arguments

pevent

is a pointer to the mailbox from which the message is received. This pointer is returned to your application when the mailbox is created [see OSMboxCreate()].

Returned Value

A pointer to the message if one is available; NULL if the mailbox does not contain a message.

Notes/Warnings

Mailboxes must be created before they are used.

Example

OS_EVENT *CommMbox;
 
void Task (void *pdata)
{
    void *msg;
    pdata = pdata;
    for (;;) {
        msg = OSMboxAccept(CommMbox); /* Check mailbox for a message
*/
        if (msg != (void *)0) {
          .                           /* Message received, process
*/
          .
        } else {
          .                           /* Message not received, do ..
*/
          .                           /* .. something else
*/
        }
       .
       .
    }
}

OSMboxCreate()

OS_EVENT *OSMboxCreate (void *msg);
FileCalled FromCode Enabled By
OS_MBOX.CTask or startup codeOS_MBOX_EN

OSMboxCreate() creates and initializes a mailbox. A mailbox allows tasks or ISRs to send a pointer-sized variable (message) to one or more tasks.

Arguments

msg

is used to initialize the contents of the mailbox. The mailbox is empty when msg is a NULL pointer. The mailbox initially contains a message when msg is non-NULL.

Returned Value

A pointer to the event control block allocated to the mailbox. If no event control block is available, OSMboxCreate() returns a NULL pointer.

Notes/Warnings

Mailboxes must be created before they are used.

Example

OS_EVENT *CommMbox;
 
    void main(void)
    {
        .
        .
        OSInit();                             /* Initialize ?C/OS-II  */
        .
        .
        CommMbox = OSMboxCreate((void *)0);   /* Create COMM mailbox  */
        OSStart();                            /* Start Multitasking   */
}

OSMboxDel()

OS_EVENT *OSMboxDel (OS_EVENT *pevent, 
                     INT8U     opt,
                     INT8U    *err);
FileCalled FromCode Enabled By
OS_MBOX.CTaskOS_MBOX_EN and OS_MBOX_DEL_EN

OSMboxDel() is used to delete a message mailbox. This is a dangerous function to use because multiple tasks could attempt to access a deleted mailbox. You should always use this function with great care. Generally speaking, before you would delete a mailbox, you would first delete all the tasks that can access the mailbox.

Arguments

pevent

is a pointer to the mailbox. This pointer is returned to your application when the mailbox is created (see OSMboxCreate()).

opt

specifies whether you want to delete the mailbox only if there are no pending tasks (OS_DEL_NO_PEND) or whether you always want to delete the mailbox regardless of whether tasks are pending or not (OS_DEL_ALWAYS). In this case, all pending task will be readied.

err

is a pointer to a variable which will be used to hold an error code. The error code can be one of the following:

OS_NO_ERR

if the call was successful and the mailbox was deleted.

OS_ERR_DEL_ISR

if you attempted to delete the mailbox from an ISR

OS_ERR_INVALID_OPT

if you didn’t specify one of the two options mentioned above.

OS_ERR_TASK_WAITING

One or more tasks were waiting on the mailbox

OS_ERR_EVENT_TYPE

if pevent is not pointing to a mailbox.

OS_ERR_PEVENT_NULL

if there are no more OS_EVENT structures available.

Returned Value

A NULL pointer if the mailbox is deleted or, pevent if the mailbox was not deleted. In the latter case, you would need to examine the error code to determine the reason.

Notes/Warnings

You should use this call with care because other tasks may expect the presence of the mailbox.

Interrupts are disabled when pended tasks are readied. This means that interrupt latency depends on the number of tasks that were waiting on the mailbox.

OSMboxAccept() callers will not know that the mailbox has been deleted.

Example

OS_EVENT *DispMbox;
 
void Task (void *pdata)
{
    INT8U  err;
    pdata = pdata;
    while (1) {
        .
        .
        DispMbox = OSMboxDel(DispMbox, OS_DEL_ALWAYS, &err);
        if (DispMbox == (OS_EVENT *)0) {
            /* Mailbox has been deleted */
        }
        .
        .
    }
}

OSMboxPend()

void *OSMboxPend (OS_EVENT *pevent, 
                  INT16U    timeout, 
                  INT8U    *err);
FileCalled FromCode Enabled By
OS_MBOX.CTask onlyOS_MBOX_EN

OSMboxPend() is used when a task expects to receive a message. The message is sent to the task either by an ISR or by another task. The message received is a pointer-sized variable and its use is application specific. If a message is present in the mailbox when OSMboxPend() is called, the message is retrieved, the mailbox is emptied, and the retrieved message is returned to the caller. If no message is present in the mailbox, OSMboxPend() suspends the current task until either a message is received or a user-specified timeout expires. If a message is sent to the mailbox and multiple tasks are waiting for the message, µC/OS-II resumes the highest priority task waiting to run. A pended task that has been suspended with OSTaskSuspend() can receive a message. However, the task remains suspended until it is resumed by calling OSTaskResume() .

Arguments

pevent

is a pointer to the mailbox from which the message is received. This pointer is returned to your application when the mailbox is created [see OSMboxCreate()].

timeout

allows the task to resume execution if a message is not received from the mailbox within the specified number of clock ticks. A timeout value of 0 indicates that the task wants to wait forever for the message. The maximum timeout is 65,535 clock ticks. The timeout value is not synchronized with the clock tick. The timeout count begins decrementing on the next clock tick, which could potentially occur immediately.

err

is a pointer to a variable that holds an error code. OSMboxPend() sets *err to one of the following:

OS_NO_ERR

if a message was received.

OS_TIMEOUT

if a message was not received within the specified timeout period.

OS_ERR_EVENT_TYPE

pevent is not pointing to a mailbox.

OS_ERR_PEND_ISR

if you called this function from an ISR and µC/OS-II has to suspend it. In general, you should not call OSMboxPend() from an ISR, but µC/OS-II checks for this situation anyway.

OS_ERR_PEVENT_NULL

if pevent is a NULL pointer.

Returned Value

OSMboxPend() returns the message sent by either a task or an ISR and *err is set to OS_NO_ERR . If a message is not received within the specified timeout period, the returned message is a NULL pointer and *err is set to OS_TIMEOUT .

Notes/Warnings

  • Mailboxes must be created before they are used.
  • You should not call OSMboxPend() from an ISR.

Example

OS_EVENT *CommMbox;
 
void CommTask(void *pdata)
{
      INT8U  err;
      void  *msg;
      pdata = pdata;
      for (;;) {
         .
         .
         msg = OSMboxPend(CommMbox, 10, &err);
         if (err == OS_NO_ERR) {
             .
             . /* Code for received message                    */
             .
         } else {
             .
             . /* Code for message not received within timeout */
             .
         }
         .
         .
      }
}

OSMboxPost()

INT8U OSMboxPost (OS_EVENT *pevent, 
                  void     *msg);
FileCalled FromCode Enabled By
OS_MBOX.CTask or ISROS_MBOX_EN and OS_MBOX_POST_EN

OSMboxPost() sends a message to a task through a mailbox. A message is a pointer-sized variable and its use is application specific. If a message is already in the mailbox, an error code is returned indicating that the mailbox is full. OSMboxPost() then immediately returns to its caller and the message is not placed in the mailbox. If any task is waiting for a message at the mailbox, the highest priority task waiting receives the message. If the task waiting for the message has a higher priority than the task sending the message, the higher priority task is resumed and the task sending the message is suspended. In other words, a context switch occurs.

Arguments

pevent

is a pointer to the mailbox into which the message is deposited. This pointer is returned to your application when the mailbox is created [see OSMboxCreate()].

msg

is the actual message sent to the task. msg is a pointer-sized variable and is application specific. You must never post a NULL pointer because this indicates that the mailbox is empty.

Returned Value

OSMboxPost() returns one of two error codes:

OS_NO_ERR

if the message was deposited in the mailbox.

OS_MBOX_FULL

if the mailbox already contained a message.

OS_ERR_EVENT_TYPE

if pevent is not pointing to a mailbox.

OS_ERR_PEVENT_NULL

if pevent is a pointer to NULL.

OS_ERR_POST_NULL_PTR

if you are attempting to post a NULL pointer. By convention a NULL pointer is not supposed to point to anything.

Notes/Warnings

Mailboxes must be created before they are used.

You must never post a NULL pointer because this indicates that the mailbox is empty.

Example

OS_EVENT *CommMbox;
INT8U     CommRxBuf[100];
void CommTaskRx(void *pdata)
{
      INT8U  err;
      pdata = pdata;
      for (;;) {
         .
         .
          err = OSMboxPost(CommMbox, (void *)&CommRxBuf[0]);
         .
         .
      }
}

OSMboxPostOpt()

INT8U OSMboxPostOpt (OS_EVENT *pevent, 
                     void     *msg,
                     INT8U     opt);
FileCalled FromCode Enabled By
OS_MBOX.CTask or ISROS_MBOX_EN and OS_MBOX_POST_OPT_EN

OSMboxPostOpt() works just like OSMboxPost() except that it allows you to post a message to multiple tasks. In other words, OSMboxPostOpt() allows the message posted to be broadcast to ALL tasks waiting on the mailbox. OSMboxPostOpt() can actually replace OSMboxPost() because it can emulate OSMboxPost() .

OSMboxPostOpt() is used to send a message to a task through a mailbox. A message is a pointer-sized variable and its use is application specific. If a message is already in the mailbox, an error code is returned indicating that the mailbox is full. OSMboxPostOpt() then immediately returns to its caller and the message is not placed in the mailbox. If any task is waiting for a message at the mailbox, OSMboxPostOpt() allows you to either post the message to the highest priority task waiting at the mailbox (opt set to OS_POST_OPT_NONE) or, to all tasks waiting at the mailbox (opt is set to OS_POST_OPT_BROADCAST). In either case, scheduling will occur and if any of the task that receives the message has a higher priority than the task that is posting the message then, the higher priority task will be resumed and the sending task will be suspended. In other words, a context switch will occur.

Arguments

pevent

is a pointer to the mailbox. This pointer is returned to your application when the mailbox is created (see OSMboxCreate()).

msg

is the actual message sent to the task(s) msg is a pointer-sized variable and what msg points to is application specific. You must never post a NULL pointer because this indicates that the mailbox is empty.

opt

specifies whether you want to send the message to the highest priority task waiting at the mailbox (when opt is set to OS_POST_OPT_NONE) or, to ALL tasks waiting at the mailbox (when opt is set to OS_POST_OPT_BROADCAST).

Returned Value

err

is a pointer to a variable which will be used to hold an error code. The error code can be one of the following:

OS_NO_ERR

if the call was successful and the message was sent.

OS_MBOX_FULL

if the mailbox already contains a message. You can only send ONE message at a time to a mailbox and thus, the message MUST be consumed before you are allowed to send another one.

OS_ERR_EVENT_TYPE

if pevent is not pointing to a mailbox.

OS_ERR_PEVENT_NULL

if pevent is a NULL pointer.

OS_ERR_POST_NULL_PTR

if you are attempting to post a NULL pointer. By convention, a NULL pointer is not supposed to point to anything.

Notes/Warnings

Mailboxes must be created before they are used.

You must NEVER post a NULL pointer to a mailbox because this indicates that the mailbox is empty.

If you need to use this function and want to reduce code space, you may disable code generation of OSMboxPost() since OSMboxPostOpt() can emulate OSMboxPost() .

The execution time of OSMboxPostOpt() depends on the number of tasks waiting on the mailbox if you set opt to OS_POST_OPT_BROADCAST .

Example

OS_EVENT *CommMbox;
 
INT8U     CommRxBuf[100];
 
void CommRxTask (void *pdata)
{
    INT8U  err;
    pdata = pdata;
    for (;;) {
        .
        .
        err = OSMboxPostOpt(CommMbox, (void *)&CommRxBuf[0], OS_POST_OPT_BROADCAST);
        .
        .
    }
}

OSMboxQuery()

INT8U OSMboxQuery (OS_EVENT     *pevent, 
                   OS_MBOX_DATA *pdata);
FileCalled FromCode Enabled By
OS_MBOX.CTask or ISROS_MBOX_EN and OS_MBOX_QUERY_EN

OSMboxQuery() obtains information about a message mailbox. Your application must allocate an OS_MBOX_DATA data structure, which is used to receive data from the event control block of the message mailbox. OSMboxQuery() allows you to determine whether any tasks are waiting for a message at the mailbox and how many tasks are waiting (by counting the number of 1s in the .OSEventTbl[] field). You can also examine the content of the mailbox. Note that the size of .OSEventTbl[] is established by the #define constant OS_EVENT_TBL_SIZE (see uCOS_II.H).

Arguments

pevent

is a pointer to the mailbox. This pointer is returned to your application when the mailbox is created [see OSMboxCreate()].

pdata

is a pointer to a data structure of type OS_MBOX_DATA , which contains the following fields:


void  *OSMsg;                             /* Copy of the message stored in the mailbox */
INT8U  OSEventTbl[OS_EVENT_TBL_SIZE];     /* Copy of the mailbox wait list  */
INT8U  OSEventGrp;

Returned Value

OSMboxQuery() returns one of two error codes:

OS_NO_ERR

if the call was successful.

OS_ERR_PEVENT_NULL

if pevent is a NULL pointer.

OS_ERR_EVENT_TYPE

if you didn’t pass a pointer to a message mailbox.

Notes/Warnings

Message mailboxes must be created before they are used.

Example

OS_EVENT *CommMbox;
void Task (void *pdata)
{
      OS_MBOXDATA mbox_data;
      INT8U       err;
      pdata = pdata;
      for (;;) {
         .
         .
         err = OSMboxQuery(CommMbox, &mbox_data);
         if (err == OS_NO_ERR) {
           .  /* Mailbox contains a message if mbox_data.OSMsg is not NULL  */
         }
         .
         .
      }
}

OSMemCreate()

OS_MEM *OSMemCreate (void   *addr, 
                     INT32U  nblks, 
                     INT32U  blksize, 
                     INT8U  *err);
FileCalled FromCode Enabled By
OS_MEM.CTask or startup codeOS_MEM_EN

OSMemCreate() creates and initializes a memory partition. A memory partition contains a user-specified number of fixed-size memory blocks. Your application can obtain one of these memory blocks and, when done, release the block back to the partition.

Arguments

addr

is the address of the start of a memory area that is used to create fixed-size memory blocks. Memory partitions can be created either using static arrays or malloc() during startup.

nblks

contains the number of memory blocks available from the specified partition. You must specify at least two memory blocks per partition.

blksize

specifies the size (in bytes) of each memory block within a partition. A memory block must be large enough to hold at least a pointer.

err

is a pointer to a variable that holds an error code. OSMemCreate() sets *err to

OS_NO_ERR

if the memory partition was created successfully,

OS_MEM_INVALID_ADDR

if your are specifying an invalid address (i.e., addr is a NULL pointer),

OS_MEM_INVALID_PART

if a free memory partition was not available,

OS_MEM_INVALID_BLKS

if you didn’t specify at least two memory blocks per partition, or

OS_MEM_INVALID_SIZE

if you didn’t specify a block size that can contain at least a pointer variable.

Returned Value

OSMemCreate() returns a pointer to the created memory partition control block if one is available. If no memory partition control block is available, OSMemCreate() returns a NULL pointer.

Notes/Warnings

Memory partitions must be created before they are used.

Example

OS_MEM *CommMem;
 
INT8U   CommBuf[16][128];
 
void main(void)
{
      INT8U err;
      OSInit();                        /* Initialize µC/OS-II           */
      .
      .
      CommMem = OSMemCreate(&CommBuf[0][0], 16, 128, &err);
      .
      .
      OSStart();                       /* Start Multitasking            */
}

OSMemGet()

void *OSMemGet (OS_MEM *pmem, 
                INT8U  *err);
FileCalled FromCode Enabled By
OS_MEM.CTask or ISROS_MEM_EN

OSMemGet obtains a memory block from a memory partition. It is assumed that your application knows the size of each memory block obtained. Also, your application must return the memory block [using OSMemPut()] when it no longer needs it. You can call OSMemGet() more than once until all memory blocks are allocated.

Arguments

pmem

is a pointer to the memory partition control block that is returned to your application from the OSMemCreate() call.

err

is a pointer to a variable that holds an error code. OSMemGet() sets *err to one of the following:

OS_NO_ERR

if a memory block was available and returned to your application.

OS_MEM_NO_FREE_BLKS

if the memory partition didn’t contain any more memory blocks to allocate.

OS_MEM_INVALID_PMEM

if pmem is a NULL pointer.

Returned Value

OSMemGet() returns a pointer to the allocated memory block if one is available. If no memory block is available from the memory partition, OSMemGet() returns a NULL pointer.

Notes/Warnings

Memory partitions must be created before they are used.

Example

OS_MEM *CommMem;
 
void Task (void *pdata)
{
      INT8U *msg;
      pdata = pdata;
      for (;;) {
         msg = OSMemGet(CommMem, &err);
         if (msg != (INT8U *)0) {
            .                     /* Memory block allocated, use it. */
            .
         }
         .
         .
      }
}

OSMemPut()

INT8U OSMemPut (OS_MEM *pmem, 
                void   *pblk);
FileCalled FromCode Enabled By
OS_MEM.CTask or ISROS_MEM_EN

OSMemPut() returns a memory block to a memory partition. It is assumed that you will return the memory block to the appropriate memory partition.

Arguments

pmem

is a pointer to the memory partition control block that is returned to your application from the OSMemCreate() call.

pblk

is a pointer to the memory block to be returned to the memory partition.

Returned Value

OSMemPut() returns one of the following error codes:

OS_NO_ERR

if a memory block was available and returned to your application.

OS_MEM_FULL

if the memory partition could not accept more memory blocks. This is surely an indication that something is wrong because you are returning more memory blocks than you obtained using OSMemGet() .

OS_MEM_INVALID_PMEM

if pmem is a NULL pointer.

OS_MEM_INVALID_PBLK

if pblk is a NULL pointer.

Notes/Warnings

Memory partitions must be created before they are used.

You must return a memory block to the proper memory partition.

Example

OS_MEM *CommMem;
 
INT8U  *CommMsg;
 
void Task (void *pdata)
{
      INT8U err;
      pdata = pdata;
      for (;;) {
         err = OSMemPut(CommMem, (void *)CommMsg);
         if (err == OS_NO_ERR) {
            .                       /* Memory block released        */
            .
         }
         .
         .
      }
}

OSMemQuery()

INT8U OSMemQuery (OS_MEM      *pmem,
                  OS_MEM_DATA *pdata);
FileCalled FromCode Enabled By
OS_MEM.CTask or ISROS_MEM_EN and OS_MEM_QUERY_EN

OSMemQuery() obtains information about a memory partition. Basically, this function returns the same information found in the OS_MEM data structure, but in a new data structure called OS_MEM_DATA . OS_MEM_DATA also contains an additional field that indicates the number of memory blocks in use.

Arguments

pmem

is a pointer to the memory partition control block that is returned to your application from the OSMemCreate() call.

pdata

is a pointer to a data structure of type OS_MEM_DATA , which contains the following fields:


void   *OSAddr;     /* Points to beginning address of the memory partition             */
void   *OSFreeList; /* Points to beginning of the free list of memory blocks           */
INT32U  OSBlkSize;  /* Size (in bytes) of each memory block                            */
INT32U  OSNBlks;    /* Total number of blocks in the partition                         */
INT32U  OSNFree;    /* Number of memory blocks free                                    */
INT32U  OSNUsed;    /* Number of memory blocks used                                    */

Returned Value

OSMemQuery() returns one of the following error codes:

OS_NO_ERR

if a memory block was available and returned to your application.

OS_MEM_INVALID_PMEM

if pmem is a NULL pointer.

OS_MEM_INVALID_PDATA

if pdata is a NULL pointer.

Notes/Warnings

Memory partitions must be created before they are used.

Example

OS_MEM      *CommMem;
 
void Task (void *pdata)
{
      INT8U        err;
      OS_MEM_DATA  mem_data;
      pdata = pdata;
      for (;;) {
         .
         .
         err = OSMemQuery(CommMem, &mem_data);
         .
         .
      }
}

OSMutexAccept()

INT8U OSMutexAccept (OS_EVENT *pevent, 
                     INT8U    *err);
FileCalled FromCode Enabled By
OS_MUTEX.CTaskOS_MUTEX_EN

OSMutexAccept() allows you to check to see if a resource is available. Unlike OSMutexPend() , OSMutexAccept() does not suspend the calling task if the resource is not available. In other words, OSMutexAccept() is non-blocking.

Arguments

pevent

is a pointer to the mutex that guards the resource. This pointer is returned to your application when the mutex is created (see OSMutexCreate()).

err

is a pointer to a variable used to hold an error code. OSMutexAccept() sets *err to one of the following:

OS_NO_ERR

if the call was successful.

OS_ERR_EVENT_TYPE

if pevent is not pointing to a mutex.

OS_ERR_PEVENT_NULL

if pevent is a NULL pointer.

OS_ERR_PEND_ISR

if you called OSMutexAccept() from an ISR.

Returned Value

If the mutex was available, OSMutexAccept() returns 1. If the mutex was owned by another task, OSMutexAccept() returns 0.

Notes/Warnings

  • Mutexes must be created before they are used.
  • This function MUST NOT be called by an ISR.
  • If you acquire the mutex through OSMutexAccept() , you MUST call OSMutexPost() to release the mutex when you are done with the resource.

Example

OS_EVENT *DispMutex;
 
void Task (void *pdata)
{
    INT8U  err;
    INT8U  value;
    pdata = pdata;
    for (;;) {
        value = OSMutexAccept(DispMutex, &err);
        if (value == 1) {
            .                         /* Resource available, process */
            .
        } else {
            .                         /* Resource NOT available      */
            .
        }
        .
        .
    }
}

OSMutexCreate()

OS_EVENT *OSMutexCreate (INT8U  prio, 
                         INT8U *err);
FileCalled FromCode Enabled By
OS_MUTEX.CTask or startup codeOS_MUTEX_EN

OSMutexCreate() is used to create and initialize a mutex. A mutex is used to gain exclusive access to a resource.

Arguments

prio

is the Priority Inheritance Priority (PIP) that will be used when a high priority task attempts to acquire the mutex that is owned by a low priority task. In this case, the priority of the low priority task will be raised to the PIP until the resource is released.

err

is a pointer to a variable which will be used to hold an error code. The error code can be one of the following:

OS_NO_ERR

if the call was successful and the mutex was created.

OS_ERR_CREATE_ISR

if you attempted to create a mutex from an ISR.

OS_PRIO_EXIST

if a task at the specified priority inheritance priority already exist.

OS_ERR_PEVENT_NULL

if there are no more OS_EVENT structures available.

OS_PRIO_INVALID

if you specified a priority with a higher number than OS_LOWEST_PRIO .

Returned Value

A pointer to the event control block allocated to the mutex. If no event control block is available, OSMutexCreate() will return a NULL pointer.

Notes/Warnings

  • Mutexes must be created before they are used.
  • You MUST make sure that prio has a higher priority than ANY of the tasks that WILL be using the mutex to access the resource. For example, if 3 tasks of priority 20, 25 and 30 are going to use the mutex then, prio must be a number LOWER than 20. In addition, there MUST NOT already be a task created at the specified priority.

Example

OS_EVENT *DispMutex;
 
void main (void)
{
    INT8U  err;
    .
    .
    OSInit();                                 /* Initialize µC/OS-II           */
    .
    .
    DispMutex = OSMutexCreate(20, &err);  /* Create Display Mutex
      */
    .
    .
    OSStart();                                /* Start Multitasking            */
}

OSMutexDel()

OS_EVENT *OSMutexDel (OS_EVENT *pevent, 
                      INT8U     opt, 
                      INT8U    *err);
FileCalled FromCode Enabled By
OS_MUTEX.CTaskOS_MUTEX_EN and OS_MUTEX_DEL_EN

OSMutexDel() is used to delete a mutex. This is a dangerous function to use because multiple tasks could attempt to access a deleted mutex. You should always use this function with great care. Generally speaking, before you would delete a mutex, you would first delete all the tasks that can access the mutex.

Arguments

pevent

is a pointer to the mutex. This pointer is returned to your application when the mutex is created (see OSMutexCreate()).

opt

specifies whether you want to delete the mutex only if there are no pending tasks (OS_DEL_NO_PEND) or whether you always want to delete the mutex regardless of whether tasks are pending or not (OS_DEL_ALWAYS). In this case, all pending task will be readied.

err

is a pointer to a variable which will be used to hold an error code. The error code can be one of the following:

OS_NO_ERR

if the call was successful and the mutex was deleted.

OS_ERR_DEL_ISR

if you attempted to delete a mutex from an ISR.

OS_ERR_INVALID_OPT

if you didn’t specify one of the two options mentioned above.

OS_ERR_TASK_WAITING

if one or more task were waiting on the mutex and you specified OS_DEL_NO_PEND .

OS_ERR_EVENT_TYPE

if pevent is not pointing to a mutex.

OS_ERR_PEVENT_NULL

if there are no more OS_EVENT structures available.

Returned Value

A NULL pointer if the mutex is deleted or pevent if the mutex was not deleted. In the latter case, you would need to examine the error code to determine the reason.

Notes/Warnings

You should use this call with care because other tasks may expect the presence of the mutex.

Example

OS_EVENT *DispMutex;
 
void Task (void *pdata)
{
    INT8U  err;
    pdata = pdata;
    while (1) {
        .
        .
        DispMutex = OSMutexDel(DispMutex, OS_DEL_ALWAYS, &err);
        if (DispMutex == (OS_EVENT *)0) {
            /* Mutex has been deleted */
        }
        .
        .
    }
}

OSMutexPend()

void OSMutexPend (OS_EVENT *pevent, 
                  INT16U    timeout, 
                  INT8U    *err);
FileCalled FromCode Enabled By
OS_MUTEX.CTask onlyOS_MUTEX_EN

OSMutexPend() is used when a task desires to get exclusive access to a resource. If a task calls OSMutexPend() and the mutex is available, then OSMutexPend() will give the mutex to the caller and return to its caller. Note that nothing is actually given to the caller except for the fact that if err is set to OS_NO_ERR , the caller can assume that it owns the mutex. However, if the mutex is already owned by another task, OSMutexPend() will place the calling task in the wait list for the mutex. The task will thus wait until the task that owns the mutex releases the mutex and thus the resource or, the specified timeout expires. If the mutex is signaled before the timeout expires, µC/OS-II will resume the highest priority task that is waiting for the mutex. Note that if the mutex is owned by a lower priority task then OSMutexPend() will raise the priority of the task that owns the mutext to the Priority Inheritance Priority (PIP) as specified when you created the mutex (see OSMutexCreate()).

Arguments

pevent

is a pointer to the mutex. This pointer is returned to your application when the mutex is created (see OSMutexCreate()).

timeout

is used to allow the task to resume execution if the mutex is not signaled (i.e., posted to) within the specified number of clock ticks. A timeout value of 0 indicates that the task desires to wait forever for the mutex. The maximum timeout is 65535 clock ticks. The timeout value is not synchronized with the clock tick. The timeout count starts being decremented on the next clock tick which could potentially occur immediately.

err

is a pointer to a variable which will be used to hold an error code. OSMutexPend() sets *err to either:

OS_NO_ERR

if the call was successful and the mutex was available.

OS_TIMEOUT

if the mutex was not available within the specified timeout.

OS_ERR_EVENT_TYPE

if you didn’t pass a pointer to a mutex to OSMutexPend() .

OS_ERR_PEVENT_NULL

if pevent is a NULL pointer.

OS_ERR_PEND_ISR

if you attempted to acquire the mutex from an ISR.

Returned Value

NONE

Notes/Warnings

  • Mutexes must be created before they are used.
  • You shoud NOT suspend the task that owns the mutex, have the mutex owner wait on any other µC/OS-II objects (i.e., semaphore, mailbox or queue) and, you should NOT delay the task that owns the mutex. In other words, your code should hurry up and release the resource as quickly as possible.

Example

OS_EVENT *DispMutex;
void  DispTask (void *pdata)
{
    INT8U  err;
    pdata = pdata;
    for (;;) {
        .
        .
        OSMutexPend(DispMutex, 0, &err);
        .                            /* The only way this task continues is if ... */
        .                            /* ... the mutex is available or signaled!    */
    }
}

OSMutexPost()

INT8U OSMutexPost (OS_EVENT *pevent);
FileCalled FromCode Enabled By
OS_MUTEX.CTaskOS_MUTEX_EN

A mutex is signaled (i.e., released) by calling OSMutexPost() . You would call this function only if you acquired the mutex either by first calling OSMutexAccept() or OSMutexPend() . If the priority of the task that owns the mutex has been raised when a higher priority task attempted to acquire the mutex then, the original task priority of the task will be restored. If one or more tasks are waiting for the mutex, the mutex is given to the highest priority task waiting on the mutex. The scheduler is then called to determine if the awakened task is now the highest priority task ready to run and if so, a context switch will be done to run the readied task. If no task is waiting for the mutex, the mutex value is simply set to available (0xFF).

Arguments

pevent

is a pointer to the mutex. This pointer is returned to your application when the mutex is created (see OSMutexCreate()).

Returned Value

OSMutexPost() returns one of these error codes:

OS_NO_ERR

if the call was successful and the mutex released.

OS_ERR_EVENT_TYPE

if you didn’t pass a pointer to a mutex to OSMutexPost() .

OS_ERR_PEVENT_NULL

if pevent is a NULL pointer.

OS_ERR_POST_ISR

if you attempted to call OSMutexPost() from an ISR.

OS_ERR_NOT_MUTEX_OWNER

if the task posting (i.e., signaling the mutex) doesn’t actually owns the mutex.

Notes/Warnings

  • Mutexes must be created before they are used.
  • You cannot call this function from an ISR.

Example

OS_EVENT  *DispMutex;
void  TaskX (void *pdata)
{
    INT8U  err;
    pdata = pdata;
    for (;;) {
        .
        .
        err = OSMutexPost(DispMutex);
        switch (err) {
           case OS_NO_ERR: /* Mutex signaled       */
                .
                .
                break;
           case OS_ERR_EVENT_TYPE:
                .
                .
                break;
           case OS_ERR_PEVENT_NULL:
                .
                .
                break;
           case OS_ERR_POST_ISR:
                .
                .
                break;
        }
        .
        .
    }
}

OSMutexQuery()

INT8U OSMutexQuery (OS_EVENT      *pevent, 
                    OS_MUTEX_DATA *pdata);
FileCalled FromCode Enabled By
OS_MUTEX.CTaskOS_MUTEX_EN and OS_MUTEX_QUERY_EN

OSMutexQuery() is used to obtain run-time information about a mutex. Your application must allocate an OS_MUTEX_DATA data structure that will be used to receive data from the event control block of the mutex. OSMutexQuery() allows you to determine whether any task is waiting on the mutex, how many tasks are waiting (by counting the number of 1s) in the .OSEventTbl[] field, obtain the Priority Inheritance Priority (PIP) and determine whether the mutex is available (1) or not (0). Note that the size of .OSEventTbl[] is established by the #define constant OS_EVENT_TBL_SIZE (see uCOS_II.H).

Arguments

pevent

is a pointer to the mutex. This pointer is returned to your application when the mutex is created (see OSMutexCreate()).

pdata

is a pointer to a data structure of type OS_MUTEX_DATA , which contains the following fields:


INT8U  OSMutexPIP;        /* The PIP of the mutex                                            */
INT8U  OSOwnerPrio;       /* The priority of the mutex owner                                 */
INT8U  OSValue;           /* The current mutex value, 1 means available, 0 means unavailable */
INT8U  OSEventGrp;        /* Copy of the mutex wait list                                     */
INT8U  OSEventTbl[OS_EVENT_TBL_SIZE];

Returned Value

OSMutexQuery() returns one of these error codes:

OS_NO_ERR

if the call was successful.

OS_ERR_EVENT_TYPE

if you didn’t pass a pointer to a mutex to OSMutexQuery() .

OS_ERR_PEVENT_NULL

if pevent is a NULL pointer.

OS_ERR_QUERY_ISR

if you attempted to call OSMutexQuery() from an ISR.

Notes/Warnings

  • Mutexes must be created before they are used.
  • You cannot call this function from an ISR.

Example

In this example, we check the contents of the mutex to determine the highest priority task that is waiting for it.


OS_EVENT *DispMutex;
void Task (void *pdata)
{
    OS_MUTEX_DATA mutex_data;
    INT8U         err;
    INT8U         highest;       /* Highest priority task waiting on mutex */
    INT8U         x;
    INT8U         y;
    pdata = pdata;
    for (;;) {
        .
        .
        err = OSMutexQuery(DispMutex, &mutex_data);
        if (err == OS_NO_ERR) {
            if (mutex_data.OSEventGrp != 0x00) {
                y       = OSUnMapTbl[mutex_data.OSEventGrp];
                x       = OSUnMapTbl[mutex_data.OSEventTbl[y]];
                highest = (y << 3) + x;
                .
                .
            }
        }
        .
        .
    }
}

OSQAccept()

void *OSQAccept (OS_EVENT *pevent);
FileCalled FromCode Enabled By
OS_Q.CTask or ISROS_Q_EN

OSQAccept() checks to see if a message is available in the desired message queue. Unlike OSQPend(), OSQAccept() does not suspend the calling task if a message is not available. In other words, OSQAccept() is non-blocking. If a message is available, it is extracted from the queue and returned to your application. This call is typically used by ISRs because an ISR is not allowed to wait for messages at a queue.

Arguments

pevent

is a pointer to the message queue from which the message is received. This pointer is returned to your application when the message queue is created [see OSQCreate()].

Returned Value

A pointer to the message if one is available; NULL if the message queue does not contain a message.

Notes/Warnings

Message queues must be created before they are used.

Example

OS_EVENT *CommQ;
 
void Task (void *pdata)
{
      void *msg;
      pdata = pdata;
      for (;;) {
         msg = OSQAccept(CommQ);      /* Check queue for a message   */
         if (msg != (void *)0) {
            .                         /* Message received, process   */
            .
         } else {
            .                         /* Message not received, do .. */
            .                         /* .. something else           */
         }
         .
         .
      }
}

OSQCreate()

OS_EVENT *OSQCreate (void  **start, 
                     INT8U   size);
FileCalled FromCode Enabled By
OS_Q.CTask or startup codeOS_Q_EN

OSQCreate() creates a message queue. A message queue allows tasks or ISRs to send pointer-sized variables (messages) to one or more tasks. The meaning of the messages sent are application specific.

Arguments

start

is the base address of the message storage area. A message storage area is declared as an array of pointers to voids.

size

is the size (in number of entries) of the message storage area.

Returned Value

OSQCreate() returns a pointer to the event control block allocated to the queue. If no event control block is available, OSQCreate() returns a NULL pointer.

Notes/Warnings

Queues must be created before they are used.

Example

OS_EVENT *CommQ;
 
void     *CommMsg[10];
 
void main(void)
{
       OSInit();                                  /* Initialize ?C/OS-II   */
       .
       .
       CommQ = OSQCreate(&CommMsg[0], 10);    /* Create COMM Q         */
       .
       .
       OSStart();                                 /* Start Multitasking    */
}

OSQDel()

OS_EVENT *OSQDel (OS_EVENT *pevent, 
                  INT8U     opt, 
                  INT8U    *err);
FileCalled FromCode Enabled By
OS_Q.CTaskOS_Q_EN and OS_Q_DEL_EN

OSQDel() is used to delete a message queue. This is a dangerous function to use because multiple tasks could attempt to access a deleted queue. You should always use this function with great care. Generally speaking, before you would delete a queue, you would first delete all the tasks that can access the queue.

Arguments

pevent

is a pointer to the queue. This pointer is returned to your application when the queue is created (see OSQCreate()).

opt

specifies whether you want to delete the queue only if there are no pending tasks (OS_DEL_NO_PEND) or whether you always want to delete the queue regardless of whether tasks are pending or not (OS_DEL_ALWAYS). In this case, all pending task will be readied.

err

is a pointer to a variable which will be used to hold an error code. The error code can be one of the following:

OS_NO_ERR

if the call was successful and the queue was deleted.

OS_ERR_DEL_ISR

if you attempted to delete the queue from an ISR

OS_ERR_INVALID_OPT

if you didn’t specify one of the two options mentioned above.

OS_ERR_TASK_WAITING

if one or more tasks were waiting for messages at the message queue.

OS_ERR_EVENT_TYPE

if pevent is not pointing to a queue.

OS_ERR_PEVENT_NULL

if there are no more OS_EVENT structures available.

Returned Value

A NULL pointer if the queue is deleted or pevent if the queue was not deleted. In the latter case, you would need to examine the error code to determine the reason.

Notes/Warnings

You should use this call with care because other tasks may expect the presence of the queue.

Interrupts are disabled when pended tasks are readied. This means that interrupt latency depends on the number of tasks that were waiting on the queue.

Example

OS_EVENT *DispQ;
 
void Task (void *pdata)
{
    INT8U  err;
    pdata = pdata;
    while (1) {
        .
        .
        DispQ = OSQDel(DispQ, OS_DEL_ALWAYS, &err);
        if (DispQ == (OS_EVENT *)0) {
            /* Queue has been deleted */
        }
        .
        .
    }
}

OSQFlush()

INT8U *OSQFlush (OS_EVENT *pevent);
FileCalled FromCode Enabled By
OS_Q.CTask or ISROS_Q_EN and OS_Q_FLUSH_EN

OSQFlush() empties the contents of the message queue and eliminates all the messages sent to the queue. This function takes the same amount of time to execute whether tasks are waiting on the queue (and thus no messages are present) or the queue contains one or more messages.

Arguments

pevent

is a pointer to the message queue. This pointer is returned to your application when the message queue is created [see OSQCreate()].

Returned Value

OSQFlush()

returns one of the following codes:

OS_NO_ERR

if the message queue was flushed.

OS_ERR_EVENT_TYPE

if you attempted to flush an object other than a message queue.

OS_ERR_PEVENT_NULL

if pevent is a NULL pointer.

Notes/Warnings

Queues must be created before they are used.

Example

OS_EVENT *CommQ;
 
void main(void)
{
       INT8U err;
       OSInit();                           /* Initialize µC/OS-II   */
       .
       .
       err = OSQFlush(CommQ);
       .
       .
       OSStart();                          /* Start Multitasking    */
}

OSQPend()

void *OSQPend (OS_EVENT *pevent, 
               INT16U    timeout, 
               INT8U    *err);
FileCalled FromCode Enabled By
OS_Q.CTask onlyOS_Q_EN

OSQPend() is used when a task wants to receive messages from a queue. The messages are sent to the task either by an ISR or by another task. The messages received are pointer-sized variables, and their use is application specific. If a at least one message is present at the queue when OSQPend() is called, the message is retrieved and returned to the caller. If no message is present at the queue, OSQPend() suspends the current task until either a message is received or a user-specified timeout expires. If a message is sent to the queue and multiple tasks are waiting for such a message, then µC/OS-II resumes the highest priority task that is waiting. A pended task that has been suspended with OSTaskSuspend() can receive a message. However, the task remains suspended until it is resumed by calling OSTaskResume() .

Arguments

pevent

is a pointer to the queue from which the messages are received. This pointer is returned to your application when the queue is created [see OSQCreate()].

timeout

allows the task to resume execution if a message is not received from the mailbox within the specified number of clock ticks. A timeout value of 0 indicates that the task wants to wait forever for the message. The maximum timeout is 65,535 clock ticks. The timeout value is not synchronized with the clock tick. The timeout count starts decrementing on the next clock tick, which could potentially occur immediately.

err

is a pointer to a variable used to hold an error code. OSQPend() sets *err to one of the following:

OS_NO_ERR

if a message was received.

OS_TIMEOUT

if a message was not received within the specified timeout.

OS_ERR_EVENT_TYPE

pevent is not pointing to a message queue.

OS_ERR_PEVENT_NULL

if pevent is a NULL pointer..

OS_ERR_PEND_ISR

if you called this function from an ISR and µC/OS-II would have to suspend it. In general, you should not call OSQPend() from an ISR. µC/OS-II checks for this situation anyway.

Returned Value

OSQPend() returns a message sent by either a task or an ISR, and *err is set to OS_NO_ERR . If a timeout occurs, OSQPend() returns a NULL pointer and sets *err to OS_TIMEOUT .

Notes/Warnings

  • Queues must be created before they are used.
  • You should not call OSQPend() from an ISR.

Example

OS_EVENT *CommQ;
void CommTask(void *data)
{
      INT8U  err;
      void  *msg;
      pdata = pdata;
      for (;;) {
         .
         .
         msg = OSQPend(CommQ, 100, &err);
         if (err == OS_NO_ERR) {
            .
            .        /* Message received within 100 ticks!         */
            .
         } else {
            .
            .        /* Message not received, must have timed out  */
            .
         }
         .
         .
      }
}

OSQPost()

INT8U OSQPost (OS_EVENT *pevent,
               void     *msg);
FileCalled FromCode Enabled By
OS_Q.CTask or ISROS_Q_EN and OS_Q_POST_EN

OSQPost() sends a message to a task through a queue. A message is a pointer-sized variable, and its use is application specific. If the message queue is full, an error code is returned to the caller. In this case, OSQPost() immediately returns to its caller, and the message is not placed in the queue. If any task is waiting for a message at the queue, the highest priority task receives the message. If the task waiting for the message has a higher priority than the task sending the message, the higher priority task resumes and the task sending the message is suspended; that is, a context switch occurs. Message queues are first-in-first-out (FIFO), which means that the first message sent is the first message received.

Arguments

pevent

is a pointer to the queue into which the message is deposited. This pointer is returned to your application when the queue is created [see OSQCreate()].

msg

is the actual message sent to the task. msg is a pointer-sized variable and is application specific. You must never post a NULL pointer.

Returned Value

OSQPost() returns one of two error codes:

OS_NO_ERR

if the message was deposited in the queue.

OS_Q_FULL

if the queue was already full.

OS_ERR_EVENT_TYPE

pevent is not pointing to a message queue.

OS_ERR_PEVENT_NULL

if pevent is a NULL pointer.

OS_ERR_POST_NULL_PTR

if you are posting a NULL pointer. By convention, a NULL pointer is not supposed to point to anything valid.

Notes/Warnings

  • Queues must be created before they are used.
  • You must never post a NULL pointer.

Example

OS_EVENT *CommQ;
 
INT8U     CommRxBuf[100];
 
void CommTaskRx(void *pdata)
{
      INT8U  err;
      pdata = pdata;
      for (;;) {
         .
         .
         err = OSQPost(CommQ, (void *)&CommRxBuf[0]);
         switch (err) {
             case OS_NO_ERR:
                  /* Message was deposited into queue    */
                  break;
             Case OS_Q_FULL:
                  /* Queue is full                       */
                  Break;
            .
         }
         .
         .
      }
}

OSQPostFront()

INT8U OSQPostFront (OS_EVENT *pevent,
                    void     *msg);
FileCalled FromCode Enabled By
OS_Q.CTask or ISROS_Q_EN and OS_Q_POST_FRONT_EN

OSQPostFront() sends a message to a task through a queue. OSQPostFront() behaves very much like OSQPost() , except that the message is inserted at the front of the queue. This means that OSQPostFront() makes the message queue behave like a last-in-first-out (LIFO) queue instead of a first-in-first-out (FIFO) queue. The message is a pointer-sized variable, and its use is application specific. If the message queue is full, an error code is returned to the caller. OSQPostFront() immediately returns to its caller and the message is not placed in the queue. If any tasks are waiting for a message at the queue, the highest priority task receives the message. If the task waiting for the message has a higher priority than the task sending the message, the higher priority task is resumed and the task sending the message is suspended; that is, a context switch occurs.

Arguments

pevent

is a pointer to the queue into which the message is deposited. This pointer is returned to your application when the queue is created [see OSQCreate()].

msg

is the actual message sent to the task. msg is a pointer-sized variable and is application specific. You must never post a NULL pointer.

Returned Value

OSQPostFront() returns one of two error codes:

OS_NO_ERR

if the message was deposited in the queue.

OS_Q_FULL

if the queue was already full.

OS_ERR_EVENT_TYPE

pevent is not pointing to a message queue.

OS_ERR_PEVENT_NULL

if pevent is a NULL pointer.

OS_ERR_POST_NULL_PTR

if you are posting a NULL pointer. By convention, a NULL pointer is not supposed to point to anything valid.

Notes/Warnings

Queues must be created before they are used.

You must never post a NULL pointer.

Example

OS_EVENT *CommQ;
 
INT8U     CommRxBuf[100];
 
void CommTaskRx(void *pdata)
{
      INT8U  err;
      pdata = pdata;
      for (;;) {
         .
         .
         err = OSQPostFront(CommQ, (void *)&CommRxBuf[0]);
         switch (err) {
             case OS_NO_ERR:
                  /* Message was deposited into queue    */
                  break;
             Case OS_Q_FULL:
                  /* Queue is full                       */
                  Break;
            .
         }
         .
         .
      }
}

OSQPostOpt()

INT8U OSQPostOpt (OS_EVENT *pevent, 
                  void     *msg,
                  INT8U     opt);
FileCalled FromCode Enabled By
OS_Q.CTask or ISROS_Q_EN and OS_Q_POST_OPT_EN

OSQPostOpt() is used to send a message to a task through a queue. A message is a pointer-sized variable and its use is application specific. If the message queue is full, an error code is returned indicating that the queue is full. OSQPostOpt() then immediately returns to its caller, and the message is not placed in the queue. If any task is waiting for a message at the queue, OSQPostOpt() allows you to either post the message to the highest priority task waiting at the queue (opt set to OS_POST_OPT_NONE) or, to all tasks waiting at the queue (opt is set to OS_POST_OPT_BROADCAST). In either case, scheduling will occur, and if any of the task that receives the message has a higher priority than the task that is posting the message then, the higher priority task will be resumed and the sending task will be suspended. In other words, a context switch will occur.

OSQPostOpt() emulates both OSQPost() and OSQPostFront() , and also allows you to post a message to MULTIPLE tasks. In other words, it allows the message posted to be broadcast to ALL tasks waiting on the queue. OSQPostOpt() can actually replace OSQPost() and OSQPostFront() because you specify the mode of operation via an option argument, opt. Doing this allows you to reduce the amount of code space needed by µC/OS-II.

Arguments

pevent

is a pointer to the queue. This pointer is returned to your application when the queue is created (see OSQCreate()).

msg

is the actual message sent to the task(s) msg is a pointer-sized variable and what msg points to is application specific. You must never post a NULL pointer.

opt

determines the type of POST performed:

OS_POST_OPT_NONE

POST to a single waiting task (Identical to OSQPost())

OS_POST_OPT_BROADCAST

POST to ALL tasks that are waiting on the queue

OS_POST_OPT_FRONT

POST as LIFO (Simulates OSQPostFront())

Below is a list of ALL the possible combination of these flags:

OS_POST_OPT_NONE

is identical to OSQPost()

OS_POST_OPT_FRONT

is identical to OSQPostFront()

OS_POST_OPT_BROADCAST

is identical to OSQPost() but will broadcast msg to ALL waiting tasks

OS_POST_OPT_FRONT

is identical to OSQPostFront() except that will broadcast msg to ALL waiting tasks.

OS_POST_OPT_BROADCAST

is identical to OSQPostFront() except that will broadcast msg to ALL waiting tasks.

Returned Value

err

is a pointer to a variable which will be used to hold an error code. The error code can be one of the following:

OS_NO_ERR

if the call was successful and the message was sent.

OS_Q_FULL

if the queue can no longer accept messages because it is full.

OS_ERR_EVENT_TYPE

if pevent is not pointing to a mailbox.

OS_ERR_PEVENT_NULL

if pevent is a NULL pointer.

OS_ERR_POST_NULL_PTR

if you are attempting to post a NULL pointer.

Notes/Warnings

  • Queues must be created before they are used.
  • You must NEVER post a NULL pointer to a queue.
  • If you need to use this function and want to reduce code space, you may disable code generation of OSQPost() (set OS_Q_POST_EN to 0 in OS_CFG.H) and OSQPostFront() (set OS_Q_POST_FRONT_EN to 0 in OS_CFG.H) since OSQPostOpt() can emulate these two functions.
  • The execution time of OSQPostOpt() depends on the number of tasks waiting on the queue if you set opt to OS_POST_OPT_BROADCAST .

Example

OS_EVENT *CommQ;
INT8U     CommRxBuf[100];
void CommRxTask (void *pdata)
{
    INT8U  err;
    pdata = pdata;
    for (;;) {
        .
        .
        err = OSQPostOpt(CommQ, (void *)&CommRxBuf[0], OS_POST_OPT_BROADCAST);
        .
        .
    }
}

OSQQuery()

INT8U OSQQuery (OS_EVENT  *pevent, 
                OS_Q_DATA *pdata);
FileCalled FromCode Enabled By
OS_Q.CTask or ISROS_Q_EN and OS_QUERY_EN

OSQQuery() obtains information about a message queue. Your application must allocate an OS_Q_DATA data structure used to receive data from the event control block of the message queue. OSQQuery() allows you to determine whether any tasks are waiting for messages at the queue, how many tasks are waiting (by counting the number of 1s in the .OSEventTbl[] field), how many messages are in the queue, and what the message queue size is. OSQQuery() also obtains the next message that would be returned if the queue is not empty. Note that the size of .OSEventTbl[] is established by the #define constant OS_EVENT_TBL_SIZE (see uCOS_II.H).

Arguments

pevent

is a pointer to the message queue. This pointer is returned to your application when the queue is created [see OSQCreate()].

pdata

is a pointer to a data structure of type OS_Q_DATA , which contains the following fields:


void  *OSMsg;                  /* Next message if one available               */
INT16U OSNMsgs;                /* Number of messages in the queue             */
INT16U OSQSize;                /* Size of the message queue                   */
INT8U  OSEventTbl[OS_EVENT_TBL_SIZE];      /* Message queue wait list         */
INT8U  OSEventGrp;

Returned Value

OSQQuery() returns one of two error codes:

OS_NO_ERR

if the call was successful.

OS_ERR_EVENT_TYPE

if you didn’t pass a pointer to a message queue.

OS_ERR_PEVENT_NULL

if pevent is a NULL pointer.

Notes/Warnings

Message queues must be created before they are used.

Example

OS_EVENT *CommQ;
 
void Task (void *pdata)
{
      OS_Q_DATA qdata;
      INT8U     err;
      pdata = pdata;
      for (;;) {
         .
         .
         err = OSQQuery(CommQ, &qdata);
         if (err == OS_NO_ERR) {
           .  /* 'qdata' can be examined! */
         }
         .
         .
      }
}

OSSchedLock()

void OSSchedLock (void);
FileCalled FromCode Enabled By
OS_CORE.CTask or ISROS_SCHED_LOCK_EN

OSSchedLock() prevents task rescheduling until its counterpart, OSSchedUnlock() , is called. The task that calls OSSchedLock() keeps control of the CPU even though other higher priority tasks are ready to run. However, interrupts are still recognized and serviced (assuming interrupts are enabled). OSSchedLock() and OSSchedUnlock() must be used in pairs. µC/OS-II allows OSSchedLock() to be nested up to 255 levels deep. Scheduling is enabled when an equal number of OSSchedUnlock() calls have been made.

Arguments

None

Returned Value

None

Notes/Warnings

After calling OSSchedLock() , your application must not make system calls that suspend execution of the current task; that is, your application cannot call OSTimeDly() , OSTimeDlyHMSM() , OSFlagPend() , OSSemPend() , OSMutexPend() , OSMboxPend() , or OSQPend(). Since the scheduler is locked out, no other task is allowed to run and your system will lock up.

Example

void TaskX(void *pdata)
{
      pdata = pdata;
      for (;;) {
         .
         OSSchedLock();         /* Prevent other tasks to run         */
         .
         .                      /* Code protected from context switch */
         .
         OSSchedUnlock();       /* Enable other tasks to run          */
         .
      }
}

OSSchedUnlock()

void OSSchedUnlock (void);
FileCalled FromCode Enabled By
OS_CORE.CTask or ISROS_SCHED_LOCK_EN

OSSchedUnlock() re-enables task scheduling whenever it is paired with OSSchedLock() .

Arguments

None

Returned Value

None

Notes/Warnings

After calling OSSchedLock() , your application must not make system calls that suspend execution of the current task; that is, your application cannot call OSTimeDly() , OSTimeDlyHMSM() , OSFlagPend() , OSSemPend() , OSMutexPend() , OSMboxPend() , or OSQPend() . Since the scheduler is locked out, no other task is allowed to run and your system will lock up.

Example

void TaskX(void *pdata)
{
      pdata = pdata;
      for (;;) {
         .
         OSSchedLock();     /* Prevent other tasks to run         */
         .
         .                  /* Code protected from context switch */
         .
         OSSchedUnlock();   /* Enable other tasks to run          */
         .
      }
}

OSSemAccept()

INT16U OSSemAccept (OS_EVENT *pevent);
FileCalled FromCode Enabled By
OS_SEM.CTask or ISROS_SEM_EN and OS_SEM_ACCEPT_EN

OSSemAccept() checks to see if a resource is available or an event has occurred. Unlike OSSemPend() , OSSemAccept() does not suspend the calling task if the resource is not available. In other words, OSSemAccept() is non-blocking. Use OSSemAccept() from an ISR to obtain the semaphore.

Arguments

pevent

is a pointer to the semaphore that guards the resource. This pointer is returned to your application when the semaphore is created [see OSSemCreate()].

Returned Value

When OSSemAccept() is called and the semaphore value is greater than 0, the semaphore value is decremented and the value of the semaphore before the decrement is returned to your application. If the semaphore value is 0 when OSSemAccept() is called, the resource is not available and 0 is returned to your application.

Notes/Warnings

Semaphores must be created before they are used.

Example

OS_EVENT *DispSem;
void Task (void *pdata)
{
      INT16U value;
      pdata = pdata;
      for (;;) {
         value = OSSemAccept(DispSem);         /* Check resource availability */
         if (value > 0) {
            .                                  /* Resource available, process */
            .
         }
         .
         .
      }
}

OSSemCreate()

OS_EVENT *OSSemCreate (INT16U value);
FileCalled FromCode Enabled By
OS_SEM.CTask or startup codeOS_SEM_EN

OSSemCreate() creates and initializes a semaphore. A semaphore:

  • allows a task to synchronize with either an ISR or a task (you would initialize the semaphore to 0),
  • gains exclusive access to a resource (you would initialize the semaphore to a value greater than 0), and
  • signals the occurrence of an event (you would initialize the semaphore to 0).

Arguments

value

is the initial value of the semaphore and can be between 0 and 65535. A value of 0 indicates that a resource is not available or, an event has not occurred.

Returned Value

OSSemCreate() returns a pointer to the event control block allocated to the semaphore. If no event control block is available, OSSemCreate() returns a NULL pointer.

Notes/Warnings

Semaphores must be created before they are used.

Example

OS_EVENT *DispSem;
void main(void)
{
      .
      .
      OSInit();                     /* Initialize µC/OS-II          */
      .
      .
      DispSem = OSSemCreate(1);     /* Create Display Semaphore     */
      .
      .
      OSStart();                    /* Start Multitasking           */
}

OSSemDel()

OS_EVENT *OSSemDel (OS_EVENT *pevent,
                    INT8U     opt,
                    INT8U    *err);
FileCalled FromCode Enabled By
OS_SEM.CTaskOS_SEM_EN and OS_SEM_DEL_EN

OSSemDel() is used to delete a semaphore. This is a dangerous function to use because multiple tasks could attempt to access a deleted semaphore. You should always use this function with great care. Generally speaking, before you would delete a semaphore, you would first delete all the tasks that can access the semaphore.

Arguments

pevent

is a pointer to the semaphore. This pointer is returned to your application when the semaphore is created (see OSSemCreate()).

opt

specifies whether you want to delete the semaphore only if there are no pending tasks (OS_DEL_NO_PEND) or whether you always want to delete the semaphore regardless of whether tasks are pending or not (OS_DEL_ALWAYS). In this case, all pending task will be readied.

err

is a pointer to a variable which will be used to hold an error code. The error code can be one of the following:

OS_NO_ERR

if the call was successful and the semaphore was deleted.

OS_ERR_DEL_ISR

if you attempted to delete the semaphore from an ISR

OS_ERR_INVALID_OPT

if you didn’t specify one of the two options mentioned above.

OS_ERR_TASK_WAITING

if one or more tasks were waiting on the semaphore

OS_ERR_EVENT_TYPE

if pevent is not pointing to a semaphore.

OS_ERR_PEVENT_NULL

if there are no more OS_EVENT structures available.

Returned Value

A NULL pointer if the semaphore is deleted, or pevent if the semaphore was not deleted. In the latter case, you would need to examine the error code to determine the reason.

Notes/Warnings

You should use this call with care because other tasks may expect the presence of the semaphore.

Interrupts are disabled when pended tasks are readied. This means that interrupt latency depends on the number of tasks that were waiting on the semaphore.

Example

OS_EVENT *DispSem;
void Task (void *pdata)
{
    INT8U  err;
    pdata = pdata;
    while (1) {
        .
        .
        DispSem = OSSemDel(DispSem, OS_DEL_ALWAYS, &err);
        if (DispSem == (OS_EVENT *)0) {
            /* Semaphore has been deleted */
        }
        .
        .
    }
}

OSSemPend()

void OSSemPend (OS_EVENT *pevent, 
                INT16U    timeout, 
                INT8U    *err);
FileCalled FromCode Enabled By
OS_SEM.CTask onlyOS_SEM_EN

OSSemPend() is used when a task wants exclusive access to a resource, needs to synchronize its activities with an ISR or a task, or is waiting until an event occurs. If a task calls OSSemPend() and the value of the semaphore is greater than 0, OSSemPend() decrements the semaphore and returns to its caller. However, if the value of the semaphore is 0, OSSemPend() places the calling task in the waiting list for the semaphore. The task waits until a task or an ISR signals the semaphore or the specified timeout expires. If the semaphore is signaled before the timeout expires, µC/OS-II resumes the highest priority task waiting for the semaphore. A pended task that has been suspended with OSTaskSuspend() can obtain the semaphore. However, the task remains suspended until it is resumed by calling OSTaskResume() .

Arguments

pevent

is a pointer to the semaphore. This pointer is returned to your application when the semaphore is created [see OSSemCreate()].

timeout

allows the task to resume execution if a message is not received from the mailbox within the specified number of clock ticks. A timeout value of 0 indicates that the task will wait forever for the message. The maximum timeout is 65,535 clock ticks. The timeout value is not synchronized with the clock tick. The timeout count begins decrementing on the next clock tick, which could potentially occur immediately.

err

is a pointer to a variable used to hold an error code. OSSemPend() sets *err to one of the following:

OS_NO_ERR

if the semaphore was available.

OS_TIMEOUT

if the semaphore was not signaled within the specified timeout.

OS_ERR_EVENT_TYPE

pevent is not pointing to a semaphore.

OS_ERR_PEND_ISR

if you called this function from an ISR and µC/OS-II would have to suspend it. In general, you should not call OSMboxPend() from an ISR. µC/OS-II checks for this situation.

OS_ERR_PEVENT_NULL

if pevent is a NULL pointer.

Returned Value

None

Notes/Warnings

Semaphores must be created before they are used.

Example

OS_EVENT *DispSem;
 
void DispTask(void *pdata)
{
      INT8U  err;
      pdata = pdata;
      for (;;) {
         .
         .
         OSSemPend(DispSem, 0, &err);
         .              /* The only way this task continues is if ... */
         .              /* ... the semaphore is signaled!             */
      }
}

OSSemPost()

INT8U OSSemPost(OS_EVENT *pevent);
FileCalled FromCode Enabled By
OS_SEM.CTask or ISROS_SEM_EN

A semaphore is signaled by calling OSSemPost() . If the semaphore value is 0 or more, it is incremented and OSSemPost() returns to its caller. If tasks are waiting for the semaphore to be signaled, OSSemPost() removes the highest priority task pending for the semaphore from the waiting list and makes this task ready to run. The scheduler is then called to determine if the awakened task is now the highest priority task ready to run.

Arguments

pevent

is a pointer to the semaphore. This pointer is returned to your application when the semaphore is created [see OSSemCreate()].

Returned Value

OSSemPost() returns one of two error codes:

OS_NO_ERR

if the semaphore was signaled successfully.

OS_SEM_OVF

if the semaphore count overflowed.

OS_ERR_EVENT_TYPE

pevent is not pointing to a semaphore.

OS_ERR_PEVENT_NULL

if pevent is a NULL pointer.

Notes/Warnings

Semaphores must be created before they are used.

Example

OS_EVENT *DispSem;
 
void TaskX(void *pdata)
{
      INT8U  err;
      pdata = pdata;
      for (;;) {
         .
         .
         err = OSSemPost(DispSem);
         switch (err) {
             case OS_NO_ERR:
                  /* Semaphore signaled       */
                  break;
             Case OS_SEM_OVF:
                  /* Semaphore has overflowed */
                  break;
            .
            .
         }
         .
         .
      }
}

OSSemQuery()

INT8U OSSemQuery (OS_EVENT    *pevent, 
                  OS_SEM_DATA *pdata);
FileCalled FromCode Enabled By
OS_SEM.CTask or ISROS_SEM_EN and OS_SEM_QUERY_EN

OSSemQuery() obtains information about a semaphore. Your application must allocate an OS_SEM_DATA data structure used to receive data from the event control block of the semaphore. OSSemQuery() allows you to determine whether any tasks are waiting on the semaphore and how many tasks are waiting (by counting the number of 1s in the .OSEventTbl[] field) and obtains the semaphore count. Note that the size of .OSEventTbl[] is established by the #define constant OS_EVENT_TBL_SIZE (see uCOS_II.H).

Arguments

pevent

is a pointer to the semaphore. This pointer is returned to your application when the semaphore is created [see OSSemCreate()].

pdata

is a pointer to a data structure of type OS_SEM_DATA , which contains the following fields:


INT16U OSCnt;                                /* Current semaphore count     */
INT8U  OSEventTbl[OS_EVENT_TBL_SIZE];        /* Semaphore wait list         */
INT8U  OSEventGrp;

Returned Value

OSSemQuery() returns one of two error codes:

OS_NO_ERR

if the call was successful.

OS_ERR_EVENT_TYPE

if you didn’t pass a pointer to a semaphore.

OS_ERR_PEVENT_NULL

if pevent is is a NULL pointer.

Notes/Warnings

Semaphores must be created before they are used.

Example

In this example, the contents of the semaphore is checked to determine the highest priority task waiting at the time the function call was made.


OS_EVENT *DispSem;
 
void Task (void *pdata)
{
      OS_SEM_DATA sem_data;
      INT8U       err;
      INT8U       highest; /* Highest priority task waiting on sem. */
      INT8U       x;
      INT8U       y;
      pdata = pdata;
      for (;;) {
         .
         .
         err = OSSemQuery(DispSem, &sem_data);
         if (err == OS_NO_ERR) {
            if (sem_data.OSEventGrp != 0x00) {
                y       = OSUnMapTbl[sem_data.OSEventGrp];
                x       = OSUnMapTbl[sem_data.OSEventTbl[y]];
                highest = (y << 3) + x;
                .
                .
            }
         }
         .
         .
      }
}

OSStart()

void OSStart (void);
FileCalled FromCode Enabled By
OS_CORE.CStartup code onlyN/A

OSStart() starts multitasking under µC/OS-II. This function is typically called from your startup code but after you called OSInit() .

Arguments

None

Returned Value

None

Notes/Warnings

OSInit() must be called prior to calling OSStart() . OSStart() should only be called once by your application code. If you do call OSStart() more than once, it will not do anything on the second and subsequent calls.

Example

void main(void)
{
    .                                 /* User Code             */
    .
    OSInit();                          /* Initialize µC/OS-II  */
    .                                 /* User Code             */
    .
    OSStart();                         /* Start Multitasking   */
    /* Any code hers should NEVER be executed! */
}

OSStatInit()

void OSStatInit (void);
FileCalled FromCode Enabled By
OS_CORE.CStartup code onlyOS_TASK_STAT_EN and OS_TASK_CREATE_EXT_EN

OSStatInit() determines the maximum value that a 32-bit counter can reach when no other task is executing. This function must be called when only one task is created in your application and when multitasking has started; that is, this function must be called from the first, and only, task created.

Arguments

None

Returned Value

None

Notes/Warnings

None

Example

void FirstAndOnlyTask (void *pdata)
{
      .
      .
      OSStatInit();            /* Compute CPU capacity with no task running */
      .
      OSTaskCreate(...);       /* Create the other tasks                    */
      OSTaskCreate(...);
      .
      for (;;) {
         .
         .
      }
}

OSTaskChangePrio()

INT8U OSTaskChangePrio (INT8U oldprio, 
                        INT8U newprio);
FileCalled FromCode Enabled By
OS_TASK.CTask only

OSTaskChangePrio() changes the priority of a task.

Arguments

oldprio

is the priority number of the task to change.

newprio

is the new task’s priority.

Returned Value

OSTaskChangePrio() returns one of the following error codes:

OS_NO_ERR

if the task’s priority was changed.

OS_PRIO_INVALID

if either the old priority or the new priority is equal to or exceeds OS_LOWEST_PRIO .

OS_PRIO_EXIST

if newprio already exists.

OS_PRIO_ERR

if no task with the specified “old” priority exists (i.e., the task specified by oldprio does not exist).

Notes/Warnings

The desired priority must not already have been assigned; otherwise, an error code is returned. Also, OSTaskChangePrio() verifies that the task to change exists.

Example

void TaskX(void *data)
{
      INT8U  err;
      for (;;) {
         .
         .
         err = OSTaskChangePrio(10, 15);
         .
         .
      }
}

OSTaskCreate()

INT8U OSTaskCreate (void  (*task)(void *pd),
                    void   *pdata,
                    OS_STK *ptos,
                    INT8U   prio);
FileCalled FromCode Enabled By
OS_TASK.CTask or startup codeOS_TASK_CREATE_EN

OSTaskCreate() creates a task so it can be managed by µC/OS-II. Tasks can be created either prior to the start of multitasking or by a running task. A task cannot be created by an ISR. A task must be written as an infinite loop, as shown below, and must not return. OSTaskCreate() is used for backward compatibility with µC/OS and when the added features of OSTaskCreateExt() are not needed.

Depending on how the stack frame was built, your task will have interrupts either enabled or disabled. You need to check with the processor-specific code for details.

Arguments

task

is a pointer to the task’s code.

pdata

is a pointer to an optional data area used to pass parameters to the task when it is created. Where the task is concerned, it thinks it was invoked and passed the argument pdata. pdata can be used to pass arguments to the task created. For example, you can create a generic task that will handle an asynchronous serial port. pdata can be used to pass this task information about the serial port it has to manage: the port address, the baud rate, the number of bits, the parity and more.


void Task (void *pdata)
{
      .                    /* Do something with 'pdata'                    */
      for (;;) {           /* Task body, always an infinite loop.          */
         .
         .
         /* Must call one of the following services:                       */
         /*    OSMboxPend()                                                */
         /*    OSFlagPend()                                                */
         /*    OSMutexPend()                                               */
         /*    OSQPend()                                                   */
         /*    OSSemPend()                                                 */
         /*    OSTimeDly()                                                 */
         /*    OSTimeDlyHMSM()                                             */
         /*    OSTaskSuspend()     (Suspend self)                          */
         /*    OSTaskDel()         (Delete  self)                          */
         .
         .
      }
}

ptos

is a pointer to the task’s top-of-stack. The stack is used to store local variables, function parameters, return addresses, and CPU registers during an interrupt. The size of the stack is determined by the task’s requirements and the anticipated interrupt nesting. Determining the size of the stack involves knowing how many bytes are required for storage of local variables for the task itself and all nested functions, as well as requirements for interrupts (accounting for nesting). If the configuration constant OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e., from high to low memory). ptos thus needs to point to the highest valid memory location on the stack. If OS_STK_GROWTH is set to 0, the stack is assumed to grow in the opposite direction (i.e., from low to high memory).

prio

is the task priority. A unique priority number must be assigned to each task and the lower the number, the higher the priority (i.e., the task importance).

Returned Value

OSTaskCreate() returns one of the following error codes:

OS_NO_ERR

if the function was successful.

OS_PRIO_EXIST

if the requested priority already exists.

OS_PRIO_INVALID

if prio is higher than OS_LOWEST_PRIO .

OS_NO_MORE_TCB

if µC/OS-II doesn’t have any more OS_TCBs to assign.

Notes/Warnings

The stack for the task must be declared with the OS_STK type.

A task must always invoke one of the services provided by µC/OS-II to either wait for time to expire, suspend the task, or wait for an event to occur (wait on a mailbox, queue, or semaphore). This allows other tasks to gain control of the CPU.

You should not use task priorities 0, 1, 2, 3, OS_LOWEST_PRIO-3 , OS_LOWEST_PRIO-2 , OS_LOWEST_PRIO-1 , and OS_LOWEST_PRIO because they are reserved for use by µC/OS-II. This leaves you with up to 56 application tasks.

Example 1

This example shows that the argument that Task1() receives is not used, so the pointer pdata is set to NULL. Note that I assume the stack grows from high to low memory because I pass the address of the highest valid memory location of the stack Task1Stk[]. If the stack grows in the opposite direction for the processor you are using, pass &Task1Stk[0] as the task’s top-of-stack.

Assigning pdata to itself is used to prevent compilers from issuing a warning about the fact that pdata not being used. In other words, if I had not added this line, some compilers would have complained about ‘WARNING - variable pdata not used’


OS_STK  Task1Stk[1024];
 
void main(void)
{
      INT8U err;
      .
      OSInit();                /* Initialize µC/OS-II             */
      .
      OSTaskCreate(Task1,
                   (void *)0,
                   &Task1Stk[1023],
                   25);
      .
      OSStart();               /* Start Multitasking              */
}
 
void Task1(void *pdata)
{
      pdata = pdata;            /* Prevent compiler warning       */
      for (;;) {
         .                     /* Task code                       */
         .
      }
}

Example 2

You can create a generic task that can be instantiated more than once. For example, a task that handles a serial port could be passed the address of a data structure that characterizes the specific port (i.e., port address, baud rate). Note that each task has it’s own stack space and its own (different) priority. In this example, I arbitrarily decided that COM1 is the most important port of the two.


OS_STK    *Comm1Stk[1024];
COMM_DATA  Comm1Data;           /* Data structure containing COMM port     */
                                /* Specific data for channel 1             */
 
OS_STK    *Comm2Stk[1024];
COMM_DATA  Comm2Data;           /* Data structure containing COMM port     */
                                /* Specific data for channel 2             */
 
void main(void)
{
   INT8U err;
   .
   OSInit();                    /* Initialize µC/OS-II                     */
   .
                                /* Create task to manage COM1              */
   OSTaskCreate(CommTask,
                (void *)&Comm1Data,
                &Comm1Stk[1023],
                25);
                                /* Create task to manage COM2              */
   OSTaskCreate(CommTask,
                (void *)&Comm2Data,
                &Comm2Stk[1023],
                26);
   .
   OSStart();                   /* Start Multitasking                      */
}
 
void CommTask(void *pdata)      /* Generic communication task              */
{
      for (;;) {
         .                      /* Task code                               */
         .
      }
}

OSTaskCreateExt()

INT8U OSTaskCreateExt (void   (*task)(void *pd),
                       void    *pdata,
                       OS_STK  *ptos,
                       INT8U    prio,
                       INT16U   id,
                       OS_STK  *pbos,
                       INT32U   stk_size,
                       void    *pext,
                       INT16U   opt);
FileCalled FromCode Enabled By
OS_TASK.CTask or startup code

OSTaskCreateExt() creates a task to be managed by µC/OS-II. This function serves the same purpose as OSTaskCreate() , except that it allows you to specify additional information about your task to µC/OS-II. Tasks can be created either prior to the start of multitasking or by a running task. A task cannot be created by an ISR. A task must be written as an infinite loop, as shown below, and must not return. Depending on how the stack frame was built, your task will have interrupts either enabled or disabled. You need to check with the processor-specific code for details. Note that the first four arguments are exactly the same as the ones for OSTaskCreate() . This was done to simplify the migration to this new and more powerful function. It is highly recommended that you use OSTaskCreateExt() instead of the older OSTaskCreate() function because it’s much more flexible.

Arguments

task

is a pointer to the task’s code.

pdata

is a pointer to an optional data area, which is used to pass parameters to the task when it is created. Where the task is concerned, it thinks it was invoked and passed the argument pdata. pdata can be used to pass arguments to the task created. For example, you can create a generic task that will handle an asynchronous serial port. pdata can be used to pass this task information about the serial port it has to manage: the port address, the baud rate, the number of bits, the parity and more.


void Task (void *pdata)
{
      .                    /* Do something with 'pdata'                    */
      for (;;) {           /* Task body, always an infinite loop.          */
         .
         .
         /* Must call one of the following services:                       */
         /*    OSMboxPend()                                                */
         /*    OSFlagPend()                                                */
         /*    OSMutexPend()                                               */
         /*    OSQPend()                                                   */
         /*    OSSemPend()                                                 */
         /*    OSTimeDly()                                                 */
         /*    OSTimeDlyHMSM()                                             */
         /*    OSTaskSuspend()     (Suspend self)                          */
         /*    OSTaskDel()         (Delete  self)                          */
         .
         .
      }
}

ptos

is a pointer to the task’s top-of-stack. The stack is used to store local variables, function parameters, return addresses, and CPU registers during an interrupt.

The size of this stack is determined by the task’s requirements and the anticipated interrupt nesting. Determining the size of the stack involves knowing how many bytes are required for storage of local variables for the task itself and all nested functions, as well as requirements for interrupts (accounting for nesting).

If the configuration constant OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e., from high to low memory). ptos thus needs to point to the highest valid memory location on the stack. If OS_STK_GROWTH is set to 0, the stack is assumed to grow in the opposite direction (i.e., from low to high memory).

prio

is the task priority. A unique priority number must be assigned to each task: the lower the number, the higher the priority (i.e., the importance) of the task.

id

is the task’s ID number. At this time, the ID is not currently used in any other function and has simply been added in OSTaskCreateExt() for future expansion. You should set id to the same value as the task’s priority.

pbos

is a pointer to the task’s bottom-of-stack. If the configuration constant OS_STK_GROWTH is set to 1, the stack is assumed to grow downward (i.e., from high to low memory); thus, pbos must point to the lowest valid stack location. If OS_STK_GROWTH is set to 0, the stack is assumed to grow in the opposite direction (i.e., from low to high memory); thus, pbos must point to the highest valid stack location. pbos is used by the stack-checking function OSTaskStkChk() .

stk_size

specifies the size of the task’s stack in number of elements. If OS_STK is set to INT8U, then stk_size corresponds to the number of bytes available on the stack. If OS_STK is set to INT16U, then stk_size contains the number of 16-bit entries available on the stack. Finally, if OS_STK is set to INT32U, then stk_size contains the number of 32-bit entries available on the stack.

pext

is a pointer to a user-supplied memory location (typically a data structure) used as a TCB extension. For example, this user memory can hold the contents of floating-point registers during a context switch, the time each task takes to execute, the number of times the task is switched-in, and so on.

opt

contains task-specific options. The lower 8 bits are reserved by µC/OS-II, but you can use the upper 8 bits for application-specific options. Each option consists of one or more bits. The option is selected when the bit(s) is(are) set. The current version of µC/OS-II supports the following options:

OS_TASK_OPT_STK_CHK

specifies whether stack checking is allowed for the task.

OS_TASK_OPT_STK_CLR

specifies whether the stack needs to be cleared.

OS_TASK_OPT_SAVE_FP

specifies whether floating-point registers will be saved. This option is only valid if your processor has floating-point hardware and the processor-specific code saves the floating-point registers.

Refer to uCOS_II.H for other options.

Returned Value

OSTaskCreateExt() returns one of the following error codes:

OS_NO_ERR

if the function was successful.

OS_PRIO_EXIST

if the requested priority already exist.

OS_PRIO_INVALID

if prio is higher than OS_LOWEST_PRIO .

OS_NO_MORE_TCB

if µC/OS-II doesn’t have any more OS_TCBs to assign.

Notes/Warnings

The stack must be declared with the OS_STK type.

A task must always invoke one of the services provided by µC/OS-II either to wait for time to expire, suspend the task or, wait an event to occur (wait on a mailbox, queue, or semaphore). This allows other tasks to gain control of the CPU.

You should not use task priorities 0, 1, 2, 3, OS_LOWEST_PRIO -3, OS_LOWEST_PRIO-2 , OS_LOWEST_PRIO-1 , and OS_LOWEST_PRIO because they are reserved for use by µC/OS-II. This leaves you with up to 56 application tasks.

Example 1

E1(1)

The task control block is extended using a user-defined data structure called OS_TASK_USER_DATA , which in this case contains the name of the task as well as other fields.

E1(2)

The task name is initialized with the standard library function strcpy() .

E1(4)

Note that stack checking has been enabled for this task, so you are allowed to call OSTaskStkChk() .

E1(3)

Also, assume here that the stack grows downward on the processor used (i.e., OS_STK_GROWTH is set to 1; TOS stands for Top-Of-Stack and BOS stands for Bottom-Of-Stack).


typedef struct {                   /*  User defined data structure        (1)  */
    char    OSTaskName[20];
    INT16U  OSTaskCtr;
    INT16U  OSTaskExecTime;
    INT32U  OSTaskTotExecTime;
} OS_TASK_USER_DATA;
 
OS_STK           TaskStk[1024];
TASK_USER_DATA   TaskUserData;
 
void main(void)
{
      INT8U err;
      .
      OSInit();                              /* Initialize µC/OS-II           */
      .
      strcpy(TaskUserData.TaskName, "MyTaskName");  /* Name of task       (2) */
      err = OSTaskCreateExt(Task,
               (void *)0,
               &TaskStk[1023],               /*  Stack grows down (TOS)   (3) */
               10,
               &TaskStk[0],                  /*  Stack grows down (BOS)   (3) */
               1024,
               (void *)&TaskUserData,        /* TCB Extension                 */
               OS_TASK_OPT_STK_CHK);         /*  Stack checking enabled   (4) */
      .
      OSStart();                             /* Start Multitasking            */
}
 
void Task(void *pdata)
{
      pdata = pdata;              /* Avoid compiler warning                   */
      for (;;) {
         .                       /* Task code                                 */
         .
      }
}

Example 2

E2(1)

Now create a task, but this time on a processor for which the stack grows upward. The Intel MCS-51 is an example of such a processor. In this case, OS_STK_GROWTH is set to 0.

E2(2)

Note that stack checking has been enabled for this task so you are allowed to call OSTask¬StkChk() (TOS stands for Top-Of-Stack and BOS stands for Bottom-Of-Stack).


OS_STK *TaskStk[1024];
void main(void)
{
      INT8U err;
      .
      OSInit();                              /* Initialize µC/OS-II         */
      .
      err = OSTaskCreateExt(Task,
               (void *)0,
               &TaskStk[0],                  /*  Stack grows up (TOS) (1)   */
               10,
               10,
               &TaskStk[1023],               /*  Stack grows up (BOS) (1)   */
               1024,
               (void *)0,
               OS_TASK_OPT_STK_CHK);         /*  Stack checking enabled (2) */
      .
      OSStart();                             /* Start Multitasking          */
}
void Task(void *pdata)
{
      pdata = pdata;              /* Avoid compiler warning                 */
      for (;;) {
         .                       /* Task code                               */
         .
      }
}

OSTaskDel()

INT8U OSTaskDel (INT8U prio);
FileCalled FromCode Enabled By
OS_TASK.CTask onlyOS_TASK_DEL_EN

OSTaskDel() deletes a task by specifying the priority number of the task to delete. The calling task can be deleted by specifying its own priority number or OS_PRIO_SELF (if the task doesn’t know its own priority number). The deleted task is returned to the dormant state. The deleted task can be re-created by calling either OSTaskCreate() or OSTaskCreateExt() to make the task active again.

Arguments

prio

is the priority number of the task to delete. You can delete the calling task by passing OS_PRIO_SELF , in which case, the next highest priority task is executed.

Returned Value

OSTaskDel() returns one of the following error codes:

OS_NO_ERR

if the task didn’t delete itself.

OS_TASK_DEL_IDLE

if you tried to delete the idle task. This is of course not allowed.

OS_TASK_DEL_ERR

if the task to delete does not exist.

OS_PRIO_INVALID

if you specified a task priority higher than OS_LOWEST_PRIO .

OS_TASK_DEL_ISR

if you tried to delete a task from an ISR.

Notes/Warnings

OSTaskDel() verifies that you are not attempting to delete the µC/OS-II idle task.

You must be careful when you delete a task that owns resources. Instead, consider using OSTaskDelReq() as a safer approach.

Example

void TaskX(void *pdata)
{
      INT8U err;
      for (;;) {
         .
         .
         err = OSTaskDel(10);      /* Delete task with priority */
         if (err == OS_NO_ERR) {
            .                     /* Task was deleted           */
            .
         }
         .
         .
      }
}

OSTaskDelReq()

INT8U OSTaskDelReq (INT8U prio);
FileCalled FromCode Enabled By
OS_TASK.CTask onlyOS_TASK_DEL_EN

OSTaskDelReq() requests that a task delete itself. Basically, use OSTaskDelReq() when you need to delete a task that can potentially own resources (e.g., the task may own a semaphore). In this case, you don’t want to delete the task until the resource is released. The requesting task calls OSTaskDelReq() to indicate that the task needs to be deleted. Deletion of the task is, however, deferred to the task being deleted. In other words, the task is actually deleted when it regains control of the CPU. For example, suppose Task 10 needs to be deleted. The task wanting to delete this task (example Task 5) would call OSTaskDelReq(10) . When Task 10 executes, it calls OSTaskDelReq(OS_PRIO_SELF) and monitors the return value. If the return value is OS_TASK_DEL_REQ , then Task 10 is asked to delete itself. At this point, Task 10 calls OSTaskDel(OS_PRIO_SELF). Task 5 knows whether Task 10 has been deleted by calling OSTaskDelReq(10) and checking the return code. If the return code is OS_TASK_NOT_EXIST , then Task 5 knows that Task 10 has been deleted. Task 5 may have to check periodically until OS_TASK_NOT_EXIST is returned.

Arguments

prio is the task’s priority number of the task to delete. If you specify OS_PRIO_SELF , you are asking whether another task wants the current task to be deleted.

Returned Value

OSTaskDelReq() returns one of the following error codes:

OS_NO_ERR

if the task deletion has been registered.

OS_TASK_NOT_EXIST

if the task does not exist. The requesting task can monitor this return code to see if the task was actually deleted.

OS_TASK_DEL_IDLE

if you asked to delete the idle task (this is obviously not allowed).

OS_PRIO_INVALID

if you specified a task priority higher than OS_LOWEST_PRIO or you have not specified OS_PRIO_SELF .

OS_TASK_DEL_REQ

if a task (possibly another task) requested that the running task be deleted.

Notes/Warnings

OSTaskDelReq() verifies that you are not attempting to delete the µC/OS-II idle task.

Example

void TaskThatDeletes (void *pdata)       /* My priority is                     */
{
      INT8U err;
      for (;;) {
         .
         .
         err = OSTaskDelReq(10);         /* Request task #10 to delete itself  */
         if (err == OS_NO_ERR) {
            while (err != OS_TASK_NOT_EXIST) {
               err = OSTaskDelReq(10);
               OSTimeDly(1);             /* Wait for task to be deleted        */
            }
            .                            /* Task #10 has been deleted          */
         }
         .
         .
      }
}
 
void TaskToBeDeleted (void *pdata)       /* My priority is                     */
{
   .
   .
   pdata = pdata;
   for (;;) {
      OSTimeDly(1);
      if (OSTaskDelReq(OS_PRIO_SELF) == OS_TASK_DEL_REQ) {
         /* Release any owned resources;     */
         /* De-allocate any dynamic memory;  */
         OSTaskDel(OS_PRIO_SELF);
      }
   }
}

OSTaskQuery()

INT8U OSTaskQuery (INT8U   prio, 
                   OS_TCB *pdata);
FileCalled FromCode Enabled By
OS_TASK.CTask or ISR

OSTaskQuery() obtains information about a task. Your application must allocate an OS_TCB data structure to receive a “snapshot” of the desired task’s control block. Your copy will contain every field in the OS_TCB structure. You should be careful when accessing the contents of the OS_TCB structure, especially OSTCBNext and OSTCBPrev , because they point to the next and previous OS_TCB in the chain of created tasks, respectively. You could use this function to provide a debugger ‘kernel awareness’.

Arguments

prio

is the priority of the task you wish to obtain data from. You can obtain information about the calling task by specifying OS_PRIO_SELF .

pdata

is a pointer to a structure of type OS_TCB , which contains a copy of the task’s control block.

Returned Value

OSTaskQuery() returns one of three error codes:

OS_NO_ERR

if the call was successful.

OS_PRIO_ERR

if you tried to obtain information from an invalid task.

OS_PRIO_INVALID

if you specified a priority higher than OS_LOWEST_PRIO .

Notes/Warnings

The fields in the task control block depend on the following configuration options (see OS_CFG.H):

  • OS_TASK_CREATE_EN
  • OS_Q_EN
  • OS_FLAG_EN
  • OS_MBOX_EN
  • OS_SEM_EN
  • OS_TASK_DEL_EN

Example

void Task (void *pdata)
{
      OS_TCB  task_data;
      INT8U   err;
      void   *pext;
      INT8U   status;
      pdata = pdata;
      for (;;) {
         .
         .
         err = OSTaskQuery(OS_PRIO_SELF, &task_data);
         if (err == OS_NO_ERR) {
            pext   = task_data.OSTCBExtPtr; /* Get TCB extension pointer   */
            status = task_data.OSTCBStat;   /* Get task status             */
            .
            .
         }
         .
         .
      }
   }

OSTaskResume()

INT8U OSTaskResume (INT8U prio);
FileCalled FromCode Enabled By
OS_TASK.CTask onlyOS_TASK_SUSPEND_EN

OSTaskResume() resumes a task that was suspended through the OSTaskSuspend() function. In fact, OSTaskResume() is the only function that can “unsuspend” a suspended task.

Arguments

prio

specifies the priority of the task to resume.

Returned Value

OSTaskResume() returns one of the following error codes:

OS_NO_ERR

if the call was successful.

OS_TASK_RESUME_PRIO

if the task you are attempting to resume does not exist.

OS_TASK_NOT_SUSPENDED

if the task to resume has not been suspended.

OS_PRIO_INVALID

if prio is higher or equal to OS_LOWEST_PRIO .

Notes/Warnings

None

Example

void TaskX(void *pdata)
{
      INT8U err;
      for (;;) {
         .
         .
         err = OSTaskResume(10);        /* Resume task with priority 10    */
         if (err == OS_NO_ERR) {
            .                           /* Task was resumed                */
            .
         }
         .
         .
      }
}

OSTaskStkChk()

INT8U OSTaskStkChk (INT8U        prio, 
                    OS_STK_DATA *pdata);
FileCalled FromCode Enabled By
OS_TASK.CTask codeOS_TASK_CREATE_EXT

OSTaskStkChk() determines a task’s stack statistics. Specifically, it computes the amount of free stack space as well as the amount of stack space used by the specified task. This function requires that the task be created with OSTaskCreateExt() and that you specify OS_TASK_OPT_STK_CHK in the opt argument.

Stack sizing is done by walking from the bottom of the stack and counting the number of 0 entries on the stack until a nonzero value is found. Of course, this assumes that the stack is cleared when the task is created. For that purpose, you need to set OS_TASK_OPT_STK_CLR to 1 as an option when you create the task. You could set OS_TASK_OPT_STK_CLR to 0 if your startup code clears all RAM and you never delete your tasks. This would reduce the execution time of OSTaskCreateExt() .

Arguments

prio

is the priority of the task you want to obtain stack information about. You can check the stack of the calling task by passing OS_PRIO_SELF .

pdata

is a pointer to a variable of type OS_STK_DATA , which contains the following fields:

Returned Value

INT32U OSFree;        /* Number of bytes free on the stack             */
INT32U OSUsed;        /* Number of bytes used on the stack             */

OSTaskStkChk() returns one of the following error codes:

OS_NO_ERR

if you specified valid arguments and the call was successful.

OS_PRIO_INVALID

if you specified a task priority higher than OS_LOWEST_PRIO , or you didn’t specify OS_PRIO_SELF .

OS_TASK_NOT_EXIST

if the specified task does not exist.

OS_TASK_OPT_ERR

if you did not specify OS_TASK_OPT_STK_CHK when the task was created by OSTaskCreateExt() or if you created the task by using OSTaskCreate() .

Notes/Warnings

Execution time of this task depends on the size of the task’s stack and is thus nondeterministic.

Your application can determine the total task stack space (in number of bytes) by adding the two fields .OSFree and .OSUsed of the OS_STK_DATA data structure.

Technically, this function can be called by an ISR, but because of the possibly long execution time, it is not advisable.

Example

void Task (void *pdata)
{
      OS_STK_DATA stk_data;
      INT32U      stk_size;
      for (;;) {
         .
         .
         err = OSTaskStkChk(10, &stk_data);
         if (err == OS_NO_ERR) {
            stk_size = stk_data.OSFree + stk_data.OSUsed;
         }
         .
         .
      }
}

OSTaskSuspend()

INT8U OSTaskSuspend (INT8U prio);
FileCalled FromCode Enabled By
OS_TASK.CTask onlyOS_TASK_SUSPEND_EN

OSTaskSuspend() suspends (or blocks) execution of a task unconditionally. The calling task can be suspended by specifying its own priority number or OS_PRIO_SELF if the task doesn’t know its own priority number. In this case, another task needs to resume the suspended task. If the current task is suspended, rescheduling occurs and µC/OS-II runs the next highest priority task ready to run. The only way to resume a suspended task is to call OSTaskResume() .

Task suspension is additive. This means that if the task being suspended is delayed until n ticks expire, the task is resumed only when both the time expires and the suspension is removed. Also, if the suspended task is waiting for a semaphore and the semaphore is signaled, the task is removed from the semaphore wait list (if it is the highest priority task waiting for the semaphore) but execution is not resumed until the suspension is removed.

Arguments

prio

specifies the priority of the task to suspend. You can suspend the calling task by passing OS_PRIO_SELF , and the next highest priority task is executed.

Returned Value

OSTaskSuspend() returns one of the following error codes:

OS_NO_ERR

if the call was successful.

OS_TASK_SUSPEND_IDLE

if you attempted to suspend the µC/OS-II idle task, which is not allowed.

OS_PRIO_INVALID

if you specified a priority higher than the maximum allowed (i.e., you specified a priority of OS_LOWEST_PRIO or more) or you didn’t specify OS_PRIO_SELF .

OS_TASK_SUSPEND_PRIO

if the task you are attempting to suspend does not exist.

Notes/Warnings

OSTaskSuspend() and OSTaskResume() must be used in pairs.

A suspended task can only be resumed by OSTaskResume() .

Example

void TaskX(void *pdata)
{
      INT8U err;
      for (;;) {
         .
         .
         err = OSTaskSuspend(OS_PRIO_SELF);      /* Suspend current task   */
         .                   /* Execution continues when ANOTHER task ..   */
         .                   /* .. explicitly resumes this task.           */
         .
      }
}

OSTimeDly()

void OSTimeDly (INT16U ticks);
FileCalled FromCode Enabled By
OS_TIME.CTask onlyN/A

OSTimeDly() allows a task to delay itself for an integral number of clock ticks. Rescheduling always occurs when the number of clock ticks is greater than zero. Valid delays range from one to 65,535 ticks. A delay of 0 means that the task is not delayed and OSTimeDly() returns immediately to the caller. The actual delay time depends on the tick rate (see OS_TICKS_PER_SEC in the configuration file OS_CFG.H).

Arguments

ticks

is the number of clock ticks to delay the current task.

Returned Value

None

Notes/Warnings

Note that calling this function with a value of 0 results in no delay, and the function returns immediately to the caller. To ensure that a task delays for the specified number of ticks, you should consider using a delay value that is one tick higher. For example, to delay a task for at least 10 ticks, you should specify a value of 11.

Example

void TaskX(void *pdata)
{
      for (;;) {
         .
         .
         OSTimeDly(10);                /* Delay task for 10 clock ticks */
         .
         .
      }
}

OSTimeDlyHMSM()

void OSTimeDlyHMSM (INT8U hours,
                    INT8U minutes,
                    INT8U seconds,
                    INT8U milli);
FileCalled FromCode Enabled By
OS_TIME.CTask only

OSTimeDlyHMSM() allows a task to delay itself for a user-specified amount of time specified in hours, minutes, seconds, and milliseconds. This is a more convenient and natural format than ticks. Rescheduling always occurs when at least one of the parameters is nonzero.

Arguments

hours

is the number of hours the task will be delayed. The valid range of values is 0 to 255.

minutes

is the number of minutes the task will be delayed. The valid range of values is 0 to 59.

seconds

is the number of seconds the task will be delayed. The valid range of values is 0 to 59.

milli

is the number of milliseconds the task will be delayed. The valid range of values is 0 to 999. Note that the resolution of this argument is in multiples of the tick rate. For instance, if the tick rate is set to 100 Hz, a delay of 4ms results in no delay. The delay is rounded to the nearest tick. Thus, a delay of 15ms actually results in a delay of 20ms.

Returned Value

OSTimeDlyHMSM() returns one of the following error codes:

OS_NO_ERR

if you specified valid arguments and the call was successful.

OS_TIME_INVALID_MINUTES

if the minutes argument is greater than 59.

OS_TIME_INVALID_SECONDS

if the seconds argument is greater than 59.

OS_TIME_INVALID_MILLI

if the milliseconds argument is greater than 999.

OS_TIME_ZERO_DLY

if all four arguments are 0.

Notes/Warnings

Note that OSTimeDlyHMSM(0,0,0,0) (i.e., hours, minutes, seconds, milli) results in no delay, and the function returns to the caller. Also, if the total delay time is longer than 65,535 clock ticks, you will not be able to abort the delay and resume the task by calling OSTimeDlyResume() .

Example

void TaskX(void *pdata)
{
      for (;;) {
         .
         .
         OSTimeDlyHMSM(0, 0, 1, 0);  /* Delay task for 1 second */
         .
         .
      }
}

OSTimeDlyResume()

INT8U OSTimeDlyResume (INT8U prio);
FileCalled FromCode Enabled By
OS_TIME.CTask only

OSTimeDlyResume() resumes a task that has been delayed through a call to either OSTimeDly() or OSTimeDlyHMSM() .

Arguments

prio

specifies the priority of the task to resume.

Returned Value

OSTimeDlyResume() returns one of the following error codes:

OS_NO_ERR

if the call was successful.

OS_PRIO_INVALID

if you specified a task priority greater than OS_LOWEST_PRIO .

OS_TIME_NOT_DLY

if the task is not waiting for time to expire.

OS_TASK_NOT_EXIST

if the task has not been created.

Notes/Warnings

Note that you must not call this function to resume a task that is waiting for an event with timeout. This situation would make the task look like a timeout occurred (unless you desire this effect).

You cannot resume a task that has called OSTimeDlyHMSM() with a combined time that exceeds 65,535 clock ticks. In other words, if the clock tick runs at 100 Hz, you will not be able to resume a delayed task that called OSTimeDlyHMSM(0, 10, 55, 350) or higher.

(10 minutes * 60 + (55 + 0.35) seconds) * 100 ticks/second

Example

void TaskX(void *pdata)
{
   INT8U err;
   pdata = pdata;
   for (;;) {
      .
      err = OSTimeDlyResume(10);         /* Resume task with priority 10     */
      if (err == OS_NO_ERR) {
         .                               /* Task was resumed                 */
         .
      }
      .
   }
}

OSTimeGet()

INT32U OSTimeGet (void);
FileCalled FromCode Enabled By
OS_TIME.CTask or ISR

OSTimeGet() obtains the current value of the system clock. The system clock is a 32-bit counter that counts the number of clock ticks since power was applied or since the system clock was last set.

Arguments

None

Returned Value

The current system clock value (in number of ticks).

Notes/Warnings

None

Example

void TaskX(void *pdata)
{
      INT32U clk;
      for (;;) {
         .
         .
         clk = OSTimeGet();  /* Get current value of system clock */
         .
         .
      }
}

OSTimeSet()

void OSTimeSet (INT32U ticks);
FileCalled FromCode Enabled By
OS_TIME.CTask or ISR

OSTimeSet() sets the system clock. The system clock is a 32-bit counter that counts the number of clock ticks since power was applied or since the system clock was last set.

Arguments

ticks

is the desired value for the system clock, in ticks.

Returned Value

None

Notes/Warnings

None

Example

void TaskX(void *pdata)
{
      for (;;) {
         .
         .
         OSTimeSet(0L);    /* Reset the system clock  */
         .
         .
      }
}

OSTimeTick()

void OSTimeTick (void);
FileCalled FromCode Enabled By
OS_TIME.CTask or ISRN/A

OSTimeTick() processes a clock tick. µC/OS-II checks all tasks to see if they are either waiting for time to expire [because they called OSTimeDly() or OSTimeDlyHMSM()] or waiting for events to occur until they timeout.

Arguments

None

Returned Value

None

Notes/Warnings

The execution time of OSTimeTick() is directly proportional to the number of tasks created in an application. OSTimeTick() can be called by either an ISR or a task. If called by a task, the task priority should be very high (i.e., have a low priority number) because this function is responsible for updating delays and timeouts.

Example

(Intel 80x86, real mode, large model)


_OSTickISR PROC FAR
               PUSHA                                ; Save processor context
               PUSH ES
               PUSH DS
;
               MOV    AX, SEG(_OSIntNesting)        ; Reload DS
               MOV    DS, AX
               INC    BYTE PTR DS:_OSIntNesting     ; Notify uC/OS-II of ISR
;
               CMP    BYTE PTR DS:_OSIntNesting, 1  ; if (OSIntNesting == 1)
               JNE    SHORT _OSTickISR1
               MOV    AX, SEG(_OSTCBCur)            ;     Reload DS
               MOV    DS, AX
               LES    BX, DWORD PTR DS:_OSTCBCur    ;     OSTCBCur->OSTCBStkPtr = SS:SP
               MOV    ES:[BX+2], SS                 ;
               MOV    ES:[BX+0], SP                 ;
               CALL  FAR  PTR  _OSTimeTick          ; Process clock tick
               .                                   ; User Code to clear interrupt
               .
               CALL FAR PTR _OSIntExit              ; Notify ?C/OS-II of end of ISR
               POP  DS                              ; Restore processor registers
               POP  ES
               POPA
;
               IRET                                ; Return to interrupted task
_OSTickISR     ENDP

OSTmrCreate()

OS_TMR *OSTmrCreate(INT32U           dly,
                    INT32U           period, 
                    INT8U            opt,
                    OS_TMR_CALLBACK  callback,
                    void            *callback_arg,
                    INT8U           *pname,
                    INT8U           *perr); 
FileCalled fromCode enabled by
OS_TMR.CTaskOS_TMR_EN

OSTmrCreate() allows you to create a timer. The timer can be configured to run continuously (opt set to OS_TMR_OPT_PERIODIC) or only once (opt set to OS_TMR_OPT_ONE_SHOT). When the timer counts down to 0 (from the value specified in period), an optional ‘callback’ function can be executed. The callback can be used to signal a task that the timer expired or, perform any other function. However, it’s recommended that you keep the callback function as short as possible.

You MUST call OSTmrStart() to actually start the timer. If you configured the timer for one shot mode and the timer expired, you need to call OSTmrStart() to retrigger the timer or OSTmrDel() to delete the timer if you don’t plan on retriggering it and or not use the timer anymore. Note that you can use the callback function to delete the timer if you use the one shot mode.

Arguments

dly

specifies an initial delay used by the timer (see drawing below).

In ONE-SHOT mode, this is the time of the one-shot.

If in PERIODIC mode, this is the initial delay before the timer enters periodic mode.

The units of this time depends on how often you call OSTmrSignal(). In other words, if OSTmrSignal() is called every 1/10 of a second (i.e. OS_TMR_CFG_TICKS_PER_SEC set to 10) then, dly specifies the number of 1/10 of a second before the delay expires. Note that the timer is NOT started when it is created.

period

specifies the amount of time it will take before the timer expires. You should set the ‘period’ to 0 when you use one-shot mode. The units of this time depends on how often you call OSTmrSignal(). In other words, if OSTmrSignal() is called every 1/10 of a second (i.e. OS_TMR_CFG_TICKS_PER_SEC set to 10) then, period specifies the number of 1/10 of a second before the timer times out.

opt

OS_TMR_OPT_PERIODIC

specifies whether you want to timer to automatically reload itself.

OS_TMR_OPT_ONE_SHOT

specifies to stop the timer when it times out.

Note that you MUST select one of these two options.

callback

specifies the address of a function (optional) that you want to execute when the timer expires or, is terminated before it expires (i.e. by calling OSTmrStop()). The callback function must be declared as follows:

void MyCallback (void *ptmr, void *callback_arg);

When the timer expires, this function will be called and passed the timer ‘handle’ of the expiring timer as well as the argument specified by callback_arg.

You should note that you don’t have to specify a callback and, in this case, simply pass a NULL pointer.

callback_arg

Is the argument passed to the callback function when the timer expires or is terminated. callback_arg can be a NULL pointer if the callback function doesn’t require arguments.

pname

Is a pointer to an ASCII string that allows you to give a name to your timer. You can retrieve this name by calling OSTmrNameGet().

perr

a pointer to an error code and can be any of the following:

OS_ERR_NONE

If the timer was created successfully.

OS_ERR_TMR_INVALID_DLY

You specified a delay of 0 when in ONE SHOT mode.

OS_ERR_TMR_INVALID_PERIOD

You specified a period of 0 when in PERIODIC mode.

OS_ERR_TMR_INVALID_OPT

If you did not specify either OS_TMR_OPT_PERIODIC or OS_TMR_OPT_ONE_SHOT.

OS_ERR_TMR_ISR

If you called this function from an ISR, which you are not allowed to do.

OS_ERR_TMR_NON_AVAIL

You get this error when you cannot start a timer because all timer elements (i.e. objects) have already been allocated.

PERIODIC MODE (see ‘opt’) – dly > 0

PERIODIC MODE (see ‘opt’) – dly == 0

ONE-SHOT MODE (see ‘opt’) – dly MUST be non-zero

Returned Values

A pointer to an OS_TMR object that you MUST use to reference the timer that you just created. A NULL pointer is returned if the timer was not created because of errors (see returned error codes).

Notes/Warnings

  1. You should examine the return value to make sure what you get from this function is valid.
  2. You MUST NOT call this function from an ISR.
  3. Note that the timer is NOT started when it is created. To start the timer, you MUST call OSTmrStart().

Example

OS_TMR  *CloseDoorTmr;
 
 
void Task (void *p_arg)
{
    INT8U     err;
 
    (void)p_arg;
    for (;;) {
        CloseDoorTmr = OSTmrCreate( 10,
                                   100,
                                   OS_TMR_OPT_PERIODIC,
                                   DoorCloseFnct,
                                   (void *)0,
                                   "Door Close",
                                   &err);
        if (err == OS_ERR_NONE) {
            /* Timer was created but NOT started */
        }
    }
}

OSTmrDel()

BOOLEAN OSTmrDel(OS_TMR    *ptmr,
                 INT8U     *perr); 
FileCalled fromCode enabled by
OS_TMR.CTaskOS_TMR_EN

OSTmrDel() allows you to delete a timer. If a timer was running, it will be stopped and then deleted. If the timer has already timed out and is thus stopped, it will simply be deleted.

It is up to you to delete unused timers. If you delete a timer you MUST NOT reference it anymore.

Arguments

ptmr

is a pointer to the timer that you want to delete. This pointer is returned to you when the timer is created (see OSTmrCreate()).

perr

a pointer to an error code and can be any of the following:

OS_ERR_NONE

If the timer was deleted successfully.

OS_ERR_TMR_INVALID

If you passed a NULL pointer for the ptmr argument.

OS_ERR_TMR_INVALID_TYPE

ptmr’ is not pointing to a timer.

OS_ERR_TMR_ISR

You called this function from an ISR which is NOT allowed.

OS_ERR_TMR_INACTIVE

ptmr is pointing to an inactive timer. In other words, you would get this error if you are pointing to a timer that has been deleted or was not created.

OS_ERR_TMR_INVALID_STATE

The timer is in an invalid state.

Returned Values

OS_TRUE if the timer was deleted

OS_FALSE if an error occurred.

Notes/Warnings

  1. You should examine the return value to make sure what you get from this function is valid.
  2. You MUST NOT call this function from an ISR.
  3. If you delete a timer you MUST NOT reference it anymore.

Example

OS_TMR  *CloseDoorTmr;


void Task (void *p_arg)
{
    INT8U     err;

    (void)p_arg;
    for (;;) {
        CloseDoorTmr = OSTmrDel(CloseDoorTmr, 
                                &err);
        if (err == OS_ERR_NONE) {
            /* Timer was deleted ... DO NOT reference it anymore! */
        }
    }
}

OSTmrNameGet()

INT8U  OSTmrNameGet(OS_TMR   *ptmr, 
                    INT8U   **pdest,
                    INT8U    *perr); 
FileCalled fromCode enabled by
OS_TMR.CTaskOS_TMR_EN && OS_TMR_CFG_NAME_EN

OSTmrNameGet() allows you to retrieve the name associated with the specified timer. OSTmrNameGet() places the name of the timer in an array of characters which must be as big as OS_TMR_CFG_NAME_SIZE (see OS_CFG.H).

Arguments

ptmr

is a pointer to the timer that you are inquiring about. This pointer is returned to you when the timer is created (see OSTmrCreate()).

pdest

is a pointer to a pointer to the name of the timer.

perr

a pointer to an error code and can be any of the following:

OS_ERR_NONE

If the name of the task was copied to the array pointed to by pname.

OS_ERR_TMR_INVALID_DEST

If you specified a NULL pointer for pdest.

OS_ERR_TMR_INVALID

If you passed a NULL pointer for the ptmr argument.

OS_ERR_TMR_INVALID_TYPE

ptmr’ is not pointing to a timer.

OS_ERR_NAME_GET_ISR

You called this function from an ISR which is NOT allowed.

OS_ERR_TMR_INACTIVE

ptmr is pointing to an inactive timer. In other words, you would get this error if you are pointing to a timer that has been deleted or was not created.

OS_ERR_TMR_INVALID_STATE

The timer is in an invalid state.

Returned Values

The length of the timer name (in number of characters).

Notes/Warnings

  • You should examine the return value of this function.
  • You MUST NOT call this function from an ISR.

Example

INT8U   *CloseDoorTmrName;
OS_TMR  *CloseDoorTmr;

void Task (void *p_arg)
{
    INT8U     err;

    (void)p_arg;
    for (;;) {
        OSTmrNameGet(CloseDoorTmr, &CloseDoorTmrName, &err);
        if (err == OS_ERR_NONE) {
            /* CloseDoorTmrName points to the name of the timer */
        }
    }
}

OSTmrRemainGet()

INT32U OSTmrRemainGet(OS_TMR *ptmr, 
                      INT8U  *perr); 
FileCalled fromCode enabled by
OS_TMR.CTaskOS_TMR_EN

OSTmrRemainGet() allows you to obtain the time remaining (before it times out) of the specified timer. The value returned depends on the rate (in Hz) at which the timer task is signaled (see OS_TMR_CFG_TICKS_PER_SEC in OS_CFG.H). In other words, if OS_TMR_CFG_TICKS_PER_SEC is set to 10 then the value returned is the number of 1/10 of a second before the timer times out. If the timer has timed out, the value returned will be 0.

Arguments

ptmr

is a pointer to the timer that you are inquiring about. This pointer is returned to you when the timer is created (see OSTmrCreate()).

perr

a pointer to an error code and can be any of the following:

OS_ERR_NONE

If the function returned the time remaining for the timer.

OS_ERR_TMR_INVALID

If you passed a NULL pointer for the ptmr argument.

OS_ERR_TMR_INVALID_TYPE

ptmr’ is not pointing to a timer.

OS_ERR_TMR_ISR

You called this function from an ISR which is NOT allowed.

OS_ERR_TMR_INACTIVE

ptmr is pointing to an inactive timer. In other words, you would get this error if you are pointing to a timer that has been deleted or was not created.

OS_ERR_TMR_INVALID_STATE

The timer is in an invalid state.

Returned Values

The time remaining for the timer. The value returned depends on the rate (in Hz) at which the timer task is signaled (see OS_TMR_CFG_TICKS_PER_SEC in OS_CFG.H). In other words, if OS_TMR_CFG_TICKS_PER_SEC is set to 10 then the value returned is the number of 1/10 of a second before the timer times out. If you specified an invalid timer, the returned value will be 0. If the timer has already expired then the returned value will be 0.

Notes/Warnings

  1. You should examine the return value to make sure what you get from this function is valid.
  2. You MUST NOT call this function from an ISR.

Example

INT32U   TimeRemainToCloseDoor;
OS_TMR  *CloseDoorTmr;

void Task (void *p_arg)
{
    INT8U     err;

    (void)p_arg;
    for (;;) {
        TimeRemainToCloseDoor = OSTmrRemainGet(CloseDoorTmr, &err);
        if (err == OS_ERR_NONE) {
            /* Call was successful */
        }
    }
}

OSTmrSignal()

INT8U OSTmrSignal(void); 
FileCalled fromCode enabled by
OS_TMR.CTask or ISROS_TMR_EN

OSTmrSignal() is called either by a task or an ISR to indicate that it’s time to update the timers. Typically, OSTmrSignal() would be called by OSTimeTickHook() at a multiple of the tick rate. In other words, if OS_TICKS_PER_SEC is set to 1000 in OS_CFG.H then you should call OSTmrSignal() every 10th or 100th tick interrupt (100 Hz or 10 Hz, respectively). You should typically call OSTmrSignal() every 1/10 of a second. The higher the timer rate, of course, the more overhead timer management will impose on your system. Generally, we recommend 10 Hz (1/10 of a second).

You ‘could’ call OSTmrSignal() from the µC/OS-II tick ISR hook function (see example below). If the tick rate occurs at 1000 Hz then you can simply call OSTmrSignal() every 100th tick. Of course, you would have to implement a simple counter to do this.

Arguments

None.

Returned Values

OSTmrSignal()

uses semaphores to implement the signaling mechanism. Because of that, OSTmrSignal() can return one of the following errors. However, it’s very unlikely you will get anything else but OS_ERR_NONE.

OS_ERR_NONE

The call was successful and the timer task was signaled.

OS_ERR_SEM_OVF

If OSTmrSignal() was called more often than OSTmr_Task() can handle the timers. This would indicate that your system is heavily loaded.

OS_ERR_EVENT_TYPE

Unlikely you would get this error because the semaphore used for signaling is created by µC/OS-II.

OS_ERR_PEVENT_NULL

Again, unlikely you would ever get this error because the semaphore used for signaling is created by µC/OS-II.

Notes/Warnings

None.

Example

#if OS_TMR_EN > 0
static  INT16U  OSTmrTickCtr = 0;
#endif



void OSTimeTickHook (void)
{
#if OS_TMR_EN > 0
    OSTmrTickCtr++;
    if (OSTmrTickCtr >= (OS_TICKS_PER_SEC / OS_TMR_CFG_TICKS_PER_SEC)) {
        OSTmrTickCtr = 0;
        OSTmrSignal();
    }
#endif
}

OSTmrStart()

BOOLEAN  OSTmrStart(OS_TMR   *ptmr,
                    INT8U    *perr); 
FileCalled fromCode enabled by
OS_TMR.CTaskOS_TMR_EN

OSTmrStart() allows you to start (or restart) the countdown process of a timer. The timer to start MUST have previously been created.

Arguments

ptmr

is a pointer to the timer that you want to start (or restart). This pointer is returned to you when the timer is created (see OSTmrCreate()).

perr

a pointer to an error code and can be any of the following:

OS_ERR_NONE

If the timer was started.

OS_ERR_TMR_INVALID

If you passed a NULL pointer for the ptmr argument.

OS_ERR_TMR_INVALID_TYPE

ptmr’ is not pointing to a timer.

OS_ERR_TMR_ISR

You called this function from an ISR which is NOT allowed.

OS_ERR_TMR_INACTIVE

ptmr is pointing to an inactive timer. In other words, you would get this error if you are pointing to a timer that has been deleted or was not created.

OS_ERR_TMR_INVALID_STATE

The timer is in an invalid state.

Returned Values

OS_TRUE if the timer was started

OS_FALSE if an error occurred.

Notes/Warnings

  1. You should examine the return value to make sure what you get from this function is valid.
  2. You MUST NOT call this function from an ISR.
  3. The timer to start MUST have previously been created.

Example

OS_TMR  *CloseDoorTmr;
BOOLEAN  status;


void Task (void *p_arg)
{
    INT8U     err;

    (void)p_arg;
    for (;;) {
        status = OSTmrStart(CloseDoorTmr, 
                            &err);
        if (err == OS_ERR_NONE) {
            /* Timer was started */
        }
    }
}

OSTmrStateGet()

INT8U OSTmrStateGet(OS_TMR *ptmr, 
                    INT8U  *perr); 
FileCalled fromCode enabled by
OS_TMR.CTaskOS_TMR_EN

OSTmrStateGet() allows you to obtain the current state of a timer. A timer can be in one of 4 states:

OS_TMR_STATE_UNUSED

The timer has not been created

OS_TMR_STATE_STOPPED

The timer has been created but has not been started or has been stopped.

OS_TMR_STATE_COMPLETED

The timer is in ONE-SHOT mode and has completed its delay.

OS_TMR_STATE_RUNNING

The timer is currently running

Arguments

ptmr

is a pointer to the timer that you are inquiring about. This pointer is returned to you when the timer is created (see OSTmrCreate()).


perr

a pointer to an error code and can be any of the following:

OS_ERR_NONE

If the function returned the time remaining for the timer.

OS_ERR_TMR_INVALID

If you passed a NULL pointer for the ptmr argument.

OS_ERR_TMR_INVALID_TYPE

ptmr’ is not pointing to a timer.

OS_ERR_TMR_ISR

You called this function from an ISR which is NOT allowed.

OS_ERR_TMR_INACTIVE

ptmr is pointing to an inactive timer. In other words, you would get this error if you are pointing to a timer that has been deleted or was not created.

OS_ERR_TMR_INVALID_STATE

The timer is in an invalid state.

Returned Values

The state of the timer (see description).

Notes/Warnings

  1. You should examine the return value to make sure what you get from this function is valid.
  2. You MUST NOT call this function from an ISR.

Example

INT8U    CloseDoorTmrState;
OS_TMR  *CloseDoorTmr;

void Task (void *p_arg)
{
    INT8U     err;

    (void)p_arg;
    for (;;) {
        CloseDoorTmrState = OSTmrStateGet(CloseDoorTmr, &err);
        if (err == OS_ERR_NONE) {
            /* Call was successful */
        }
    }
}

OSTmrStop()

BOOLEAN  OSTmrStop(OS_TMR  *ptmr, 
                   INT8U    opt,
                   void    *callback_arg,
                   INT8U   *perr); 
FileCalled fromCode enabled by
OS_TMR.CTaskOS_TMR_EN

OSTmrStop() allows you to stop (i.e. abort) a timer. You can execute the callback function of the timer when it’s stopped and pass this callback function a different argument than what was specified when the timer was started. This allows your callback function to know that the timer was stopped because the callback argument can be made to indicate this (this, of course, is application specific). If the timer is already stopped, the callback function is not called.

Arguments

ptmr

Is a pointer to the timer you want to stop. This ‘handle’ was returned to your application when you called OSTmrStart() and uniquely identifies the timer.

opt

specifies whether you want the timer to:

1) OS_TMR_OPT_NONE

Do NOT call the callback function.

2) OS_TMR_OPT_CALLBACK

Call the callback function and pass it the callback argument specified when you started the timer (see OSTmrCreate()).

3) OS_TMR_OPT_CALLBACK_ARG

Call the callback function BUT pass it the callback argument specified in the OSTmrStop() function INSTEAD of the one defined in OSTmrCreate().

callback_arg

If you set opt to OS_TMR_OPT_CALLBACK_ARG then this is the argument passed to the callback function when it’s executed.

perr

a pointer to an error code and can be any of the following:

OS_ERR_NONE

If the timer was started.

OS_ERR_TMR_INVALID

If you passed a NULL pointer for the ptmr argument.

OS_ERR_TMR_INVALID_TYPE

ptmr’ is not pointing to a timer.

OS_ERR_TMR_ISR

You called this function from an ISR which is NOT allowed.

OS_ERR_TMR_INVALID_OPT

You specified an invalid option for ‘opt’.

OS_ERR_TMR_STOPPED

The timer was already stopped. However, this is NOT considered an actual error since it’s OK to attempt to stop a timer that is already stopped.

OS_ERR_TMR_INACTIVE

ptmr is pointing to an inactive timer. In other words, you would get this error if you are pointing to a timer that has been deleted or was not created.

OS_ERR_TMR_INVALID_STATE

The timer is in an invalid state.

OS_ERR_TMR_NO_CALLBACK

If you wanted the callback to be called but no callback has been specified for this timer.

Returned Values

OS_TRUE if the timer was stopped (even if it was already stopped).

OS_FALSE if an error occurred.

Notes/Warnings

  1. You should examine the return value to make sure what you get from this function is valid.
  2. You MUST NOT call this function from an ISR.
  3. The callback function is NOT called if the timer is already stopped.

Example

OS_TMR  *CloseDoorTmr;


void Task (void *p_arg)
{
    INT8U     err;

    (void)p_arg;
    for (;;) {
        OSTmrStop(CloseDoorTmr, 
                  OS_TMR_OPT_CALLBACK, 
                  (void *)0,
                  &err);
        if (err == OS_ERR_NONE || err == OS_ERR_TMR_STOPPED) {
            /* Timer was stopped ...                             */
            /* ... callback was called only if timer was running */
        }
    }
}

OSVersion()

FileCalled FromCode Enabled By
OS_CORE.CTask or ISRN/A

OSVersion() obtains the current version of µC/OS-II.

Arguments

None

Return Value

The version is returned as x.yy multiplied by 100. For example, version 2.52 is returned as 252.

Notes/Warnings

None

Example

void TaskX(void *pdata)
{
      INT16U os_version;
      for (;;) {
         .
         .
         os_version = OSVersion();  /* Obtain µC/OS-II's version   */
         .
         .
      }
}