An event set is a means to synchronise tasks with other tasks and interrupt service routines. An event set contains a set of events (one per bit) which tasks can wait to become set (value 1). When a task waits on an event set the events it is waiting for are matched against the current values - if they match then the task can still execute. If they don't match then the task is put on the task list together with details of the event set and the events that the task is waiting for.

An event set is defined as follows

typedef unsigned CTL_EVENT_SET_t;

i.e. on an 8/16 bit machine an event set will contain 16 events and on a 32 bit machine an event set will contain 32 events.

You can set and clear events of an event set using the ctl_set_clear_events function.

void 
ctl_set_clear_events(CTL_EVENT_SET_t *eventSet,
                     CTL_EVENT_SET_t set,
                     CTL_EVENT_SET_t clear);

This will set the events defined in set, clear the events defined in clear of the event set at *eventSet. This function will then search the task list, matching tasks that are waiting on the *eventSet and make them runnable if the match is successful.

You can wait for a timeout and/or an event set using the ctl_task_wait function.

unsigned 
ctl_task_wait(unsigned waitType,
              CTL_TIME_t timeout,
              CTL_EVENT_SET_t *eventSet,
              CTL_EVENT_SET_t events);

The waitType can be one of the following.

If you specify an event wait you can also use the following modifiers

The ctl_task_wait function returns the *eventSet value before any auto clearing occurred or zero if the timeout occurred or a co-operative task switch was requested.

Example Task Synchronisation

The following example illustrates synchronising a task with a function called from an ISR.

EventSet e1;
Task t1;

void ISRfn()
{
  // do work
  ctl_set_clear_events(&e1, 1, 0);
}
void task1(void *p)
{
  while (1)
    {
      ctl_task_wait(TaskStateEventWait, 0, &e1, 1);
      ...
      ctl_set_clear_events(&e1, 0, 1);
    }
}

Example Task Synchronisation

The following example illustrates synchronising a task with functions called from two ISR's.

EventSet e1;
Task t1;

void ISRfn1()
{
  // do work
  ctl_set_clear_events(&e1, 1, 0);
}
void ISRfn2()
{
  // do work
  ctl_set_clear_events(&e1, 2, 0);
}
void task1(void *p)
{
  while (1)
    {
      unsigned e;
      e=ctl_task_wait(CTL_STATE_EVENT_WAIT | CTL_STATE_EVENT_ANY_NOT_ALL | CTL_STATE_EVENT_AUTO_CLEAR, 0, &e1, 1|2);
      if (e & 1)
        ; // ISRfn1 completed
      else if (e & 2)
        ; // ISRfn2 completed
      else
        ; // error
    }
}

Example Resource Serialisation

The following example illustrates resource serialisation of two tasks.

CTL_EVENT_SET_t e1=1;
void task1()
{
  while (1)
    {
      ctl_task_wait(CTL_STATE_EVENT_WAIT | CTL_STATE_EVENT_AUTO_CLEAR, 0, &e1, 1);
      // resource has now been acquired
      ctl_set_clear_events(&e1, 1, 0);
      // resource has now been released
    }
}
void task2()
{
  while (1)
    {
      ctl_task_wait(CTL_STATE_EVENT_WAIT | CTL_STATE_EVENT_AUTO_CLEAR, 0, &e1, 1);
      // resource has now been acquired
      ctl_set_clear_events(&e1, 1, 0);
      // resource has now been released
    }
}

Note that e1 is initialised with the event set - without this neither task would acquire the resource.