@CHIP-RTOS - RTOS Overview

    IPC@CHIP® Documentation Index

RTOS Overview

The @CHIP-RTOS-x86 RTX API services split into the following groups:

  • Task_Control Services
  • Semaphore_Services
  • Time_/ Date Services
  • Timer_Procedures
  • Event_Manager
  • Message_Exchange Manager
  • Global_Data Registry

  • Task Control Services

    Top of list
    Index page

    Semaphore Services

      Semaphores are used to guarantee a task mutually exclusive access to a critical resource.   Semaphores synchronize asynchronous occurring activities. They are an essential part of a multitasking system.   A good description of multitasking systems and semaphores is available in the book "Operating systems" from Andrew Tanenbaum.

      The @CHIP-RTOS API provides two types of semaphores:

      • A counting semaphore is a semaphore with an associated counter, which can be incremented (signal) and decremented (wait).   The resource controlled by the semaphore is free (available) when the counter is greater than 0.

      • A resource semaphore is a counting semaphore with a maximum count of one.   It can be used to provide mutually exclusive access to a single resource.   A resource semaphore is also called a binary semaphore.   It differs from a counting semaphore in one significant feature: The resource ownership is tied to a specific task.   No other task except the task owning the resource is allowed to signal the associated semaphore to release the resource.

      The counting and resource semaphores provide automatic timeout.   Tasks can specify the maximum time for waiting on a semaphore.   The tasks wait in FIFO order for a resource.   A semaphore is created with the RTX_Create_Sem() API.   The @CHIP-RTOS needs a unique four byte semaphore name and on success returns a new semaphore ID (or handle) to the caller.   This handle is needed for the other semaphore services.

      Using a counting semaphore:

      A counting semaphore is created by specifying an initial count greater or equal to zero in the call to RTX_Create_Sem().   If a semaphore is initialized with a value n, it can be used to control access to n resources, e.g. a counting semaphore with the initial value three assures that no more than three tasks can own a resource at any one time.   Access to a resource controlled by a counting semaphore is acquired with a call to RTX_Wait_Sem() or RTX_Get_Sem().   If the resource is available the @CHIP-RTOS gives it to the task immediately.   When the task is finished using the resource, it signals its release by calling RTX_Signal_Sem().

      Using a resource semaphore:

      A resource semaphore is created by specifying an initial count of -1 in the call of RTX_Create_Sem().   The @CHIP-RTOS creates a resource semaphore and automatically gives it an initial value of one indicating that the resource is free.   A resource is reserved by calling RTX_Reserve_Sem() with the semaphore ID returned by RTX_Create_Sem().   The resource is released with a call to RTX_Release_Sem().  

      Semaphore Services:

      RTX_Create_Sem()          Create a semaphore
      RTX_Delete_Sem()          Delete a semaphore
      RTX_Get_Sem()             Get access to semaphore (no wait)
      RTX_Wait_Sem()            Wait on a semaphore (optional timeout)
              --- Resource Semaphore API ----
      RTX_Free_Sem()            Free a resource semaphore
      RTX_Release_Sem()         Release a resource semaphore
      RTX_Reserve_Sem()         Get a resource semaphore
              --- Counting Semaphore API ----
      RTX_Signal_Sem()          Signal a counting semaphore

    Top of list
    Index page

    Time / Date Services

    Related Topics

    TimeDate_Structure type definition

    Top of list
    Index page

    Timer Procedures

    Top of list
    Index page

    Event Manager

      The internal @CHIP-RTOS Event Manager provides a convenient mechanism for coordinating tasks waiting for events.   The events can be signalled by other tasks or timer procedures.   The Event Manager allows more than one task to simultaneously wait for a particular event.   Tasks can also wait for a particular combination of events or for any one in a set of events.

      The Event Manager provides a set of event flags which can be associated with specific events in your system.   These event flags are provided in groups with 16 event flags per group.   The number of event groups which can be created is limited by the total number of kernel objects available.   One kernel object is expended to create a semaphore, event group or timer procedure.

      The Event Manager is useful when two or more tasks will wait for the same event, e.g. waiting for the start of a motor.   An event flag is defined to represent the state of the motor (off or on).   When tasks must wait for the motor, they do so by calling the Event Manager requesting a wait until the motor control event flag indicates that the motor is on.   When the motor control task or timer procedure detects that the motor is on, it signals the event with a call to the Event Manager.   The Event Manager then wakes up all tasks which are waiting for the motor to be on.   For further explanations read the function description in the API call specifications.  

      Event Services:

      RTX_Create_EventGroup()      Create an event group
      RTX_Delete_EventGroup()      Delete an event group
      RTX_Signal_Events()          Signal one or more events in a group
      RTX_Wait_For_Event()      Wait for all/any of a set of events in a group
      RTX_Get_EventGroup_State()   Read current state of events in a group
      RTX_Get_Saved_Events()        Get saved event flags
      RTX_Find_EventGroup()        Find Event Group by name

    Top of list
    Index page

    Message Exchange Manager

      The @CHIP-RTOS Message Exchange Manager provides a mechanism for interprocess communication and synchronization.   In particular, it offers an instant solution to a common producer/consumer problem:

        One or more processes (producers) having to asynchronously deliver requests for service to one or more servers (consumers) whose identity is unknown to the producer.

      An often cited example of using Message Exchange is a print request queue.   Assume that there are two different server tasks (consumers), each of which is connected to a different printer.   There are some other tasks (producers) which want to asynchronously use one of the two servers for printing and they don't care which of the two printers is used.   The solution is to synchronize those requests: The producer tasks send their requests (messages) to the Message Exchange Manager.   The two server tasks waiting for messages take a message (if any) from the message queue and execute the requested print job.

      The Message Exchange Manager uses a Message Exchange to deliver messages.   A Message Exchange consists of four mailboxes into which messages can be deposited.   The mailboxes are ordered according to priority (0-3), where mailbox 0 has the highest priority.  The maximum depth of a mailbox is specified when the Message Exchange is created, which indicates the maximum number of messages which can be stored in that particular mailbox.

      Messages are delivered to the mailboxes of the Message Exchange in message envelopes.   The system's maximum number of available messages envelopes is 64 (or 128 for SC1x3/SC2x).   The maximum number of message exchanges is 10 (or 32 for SC1x3/SC2x).   The maximum message length is 12 bytes.   (Note: Larger messages can be implemented with a pointer and a length parameter in the message.)   Any task or timer procedure can send a message to a Message Exchange.   The sender indicates the priority of its message (0-3), thereby identifying the mailbox into which the message will be delivered.

      Any task or timer procedure can request a message from a Message Exchange, but only tasks are allowed to wait for the arrival of a message, if none is available.   A task can specify the maximum time that it is willing to wait for a message.   When more than one message is available at the exchange, a task requesting a message will be given the message at the head of the higest priority non-empty mailbox FIFO (of which there are four).

      The task also specifies a priority at which it should receive the next message, allowing either for that task to cut in line ahead of other tasks that were waiting at the same message exchange or to yield to other tasks that later come looking for a message with a higher wait priority (lower numeric value).   So conceptually, there are 2**16 FIFO priority queues at each Message Exchange where tasks wait for a message.   When a message becomes available, this message will be handed to the first task waiting in the highest priority non-empty task wait queue.

      What can be confusing here is that there are two concepts of priority involved here with Message Exchanges (neither of which is related to task priority).

      1. Message Priority - Ranges 0 through 3 (identifies which mailbox)
      2. Wait Priority - Ranges 0 through 0xFFFF (identifies priority queue)

      Message Exchange Services:

      RTX_Create_Msg()        Create a Message Exchange
      RTX_Delete_Msg()        Delete a Message Exchange
      RTX_Send_Msg()          Send a message to a Message Exchange
      RTX_Get_Msg()           Get a message, if any (no wait)
      RTX_Wait_For_Msg()      Wait for message to arrive (optional timeout)
      RTX_Find_Msg()          Find a Message Exchange, specified by name

    Top of list
    Index page

    Global Data Registry

      The @CHIP-RTOS-x86 maintains a global data registry for use by application programs.   This pair of API allow a program to publish data for use by other programs.   However, unlike the Message Exchange facilities, no task synchronization is provided here.   Only interprocess communication is provided.

      When a program wants to communicate with one other program, a Message Exchange could have been used to easily accomplish this.   When one program wants to make information available to an unspecified number of client programs, the Message Exchange mechanism becomes less attractive.   The program providing the information must keep pumping messages into the Message Exchange, one message for each new client that may come along.

      The mechanism provided by these data publication API allow a program to broadcast its data to what ever number of programs care to access the published data.

      For visibility, the MEM console command lists entries in this global data registry by name.

      Global Data Registry API:

      RTX_Publish()      Post a global data entry
      RTX_GetPublication()      Get a global data entry

    Top of list
    Index page

    End of document