Using a stream

The following example shows how to use a stream to transfer data from one task to another.

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "OS_API.h"


HANDLE StreamHandle;


void Printf(char *Message, ...)
{
  va_list ap;
  BOOL PrevLockState;

  /* Disable interrupts */
  PrevLockState = arLock();

  /* Print string on the console or send it via RS-232 */
  va_start(ap, Message);
  vprintf(Message, ap);
  va_end(ap);

  /* Restore interrupts */
  arRestore(PrevLockState);
}


static ERROR SenderTask(PVOID Arg)
{
  char Buffer[48];
  SIZE NumberOfBytes;
  int RandomNumber;

  /* Sleep for specified amount of time */
  osSleep(((TIME) Arg) * 100 * AR_TICKS_PER_SECOND / 1000);

  /* Initialize random number generator */
  srand((unsigned) arGetTickCount());

  /* Fill whole buffer with bytes representing task ID */
  stMemSet(Buffer, (UINT8) ('0' + ((char) Arg)), sizeof(Buffer));

  /* Infinite loop */
  while(1)
  {
    /* Get a square of random number in range from 0 to 20 */
    RandomNumber = rand() % 21;
    RandomNumber *= RandomNumber;

    /* Number of bytes to send */
    NumberOfBytes =
      (SIZE) (1 + (RandomNumber * (sizeof(Buffer) - 1)) / 400);

    /* Print received bytes */
    Printf("Task %i sends %i bytes\n", (int) Arg, NumberOfBytes);

    /* Store bytes in the stream */
    osWrite(StreamHandle, Buffer, NumberOfBytes, NULL);

    /* Sleep for one second */
    osSleep(AR_TICKS_PER_SECOND);
  }
}


static ERROR ReceiverTask(PVOID Arg)
{
  char Buffer[17];

  /* Infinite loop */
  while(1)
  {
    /* Read continously 16 bytes from the stream */
    osRead(StreamHandle, Buffer, 16, NULL);

    /* Store string termination symbol */
    Buffer[16] = '\0';

    /* Print received bytes */
    Printf("Task %i receives %s\n", (int) Arg, Buffer);
  }
}


int main(void)
{
  /* Initialization */
  arInit();
  stInit();
  osInit();
                  
  /* Create stram */
  StreamHandle = osCreateStream(NULL, OS_IPC_PROTECT_MUTEX |
    OS_IPC_WAIT_IF_EMPTY | OS_IPC_WAIT_IF_FULL | OS_IPC_DIRECT_READ_WRITE,
    32);

  /* Create sender tasks */
  osCreateTask(SenderTask, (PVOID) 1, 0, 0, FALSE);
  osCreateTask(SenderTask, (PVOID) 2, 0, 0, FALSE);
  osCreateTask(SenderTask, (PVOID) 3, 0, 0, FALSE);

  /* Create receiver tasks */
  osCreateTask(ReceiverTask, (PVOID) 4, 0, 0, FALSE);
  osCreateTask(ReceiverTask, (PVOID) 5, 0, 0, FALSE);

  /* Start the operating system */
  osStart();

  /* Deinitialization */
  osDeinit();
  arDeinit();
  return 0;
}

The example result on the console should look as follows:

Task 1 sends 12 bytes
Task 2 sends 2 bytes
Task 3 sends 2 bytes
Task 4 receives 1111111111112233
Task 1 sends 8 bytes
Task 2 sends 20 bytes
Task 5 receives 1111111122222222
Task 3 sends 43 bytes
Task 4 receives 2222222222223333
Task 5 receives 3333333333333333
Task 4 receives 3333333333333333
Task 1 sends 1 bytes
Task 2 sends 6 bytes
Task 3 sends 1 bytes
Task 1 sends 34 bytes
Task 5 receives 3333333122222231
Task 4 receives 1111111111111111
Task 5 receives 1111111111111111
Task 2 sends 43 bytes
Task 4 receives 1222222222222222
Task 5 receives 2222222222222222
Task 3 sends 2 bytes
Task 1 sends 27 bytes
Task 4 receives 2222222222223311
Task 5 receives 1111111111111111
Task 2 sends 1 bytes
Task 3 sends 43 bytes
Task 4 receives 1111111112333333
Task 5 receives 3333333333333333
Task 4 receives 3333333333333333
Task 1 sends 10 bytes
Task 2 sends 3 bytes
Task 5 receives 3333311111111112
Task 3 sends 31 bytes
Task 4 receives 2233333333333333
Task 5 receives 3333333333333333
Task 1 sends 5 bytes
Task 2 sends 20 bytes
Task 4 receives 3111112222222222
SpaceShadow documentation