Resource protection

 

Under multi-tasking environment, concurrent accesses to a global resource (i.e. a global variable, hardware) from multiple tasks is a critical issue. nxtOSEK provides OSEK Resource feature to keep data integrity between multiple tasks. resourcetest example under samples\resourcetest directory describes an usage of OSEK GetResource and ReleaseResource API. In resourcetest example, there are two tasks and each of those accesses a global resource (LCD display). Each Task displays numerical value in the LCD display (values with green background color in the below figure) and GetResource API which is invoked in LowTask makes HighTask being blocked at the invocation of GetResource API in the HighTask. OSEK Resource API dynamically change the priority of the Task to protect the shared global resources. This technology is called the OSEK Priority Ceiling Protocol.

samples\resourcetest\resourcetest.c

/* resourcetest.c */
#include "kernel.h"
#include "kernel_id.h"
#include "ecrobot_interface.h"

/* OSEK declarations */
DeclareCounter( SysTimerCnt );
DeclareResource(resource1);
DeclareEvent(event1);
DeclareTask(LowTask);
DeclareTask(HighTask);

/* nxtOSEK hook to be invoked from an ISR in category 2 */
void user_1ms_isr_type2(void)
{
  StatusType ercd;

  ercd = SignalCounter(SysTimerCnt); /* Increment OSEK Alarm Counter */
  if (ercd != E_OK)
  {
    ShutdownOS(ercd);
  }
}

/* Definitions */
#define COUNT 5000000
int digits;
int lowtaskcount;
int hightaskcount;

TASK(LowTask)
{
  int rcount;

  ecrobot_debug1(digits, 1111, 0);
  for(rcount = 0; rcount < COUNT; rcount++);
  ecrobot_debug1(digits, 1119, 0);

  GetResource(resource1); /* Get resource1 */

  for(rcount = 0; rcount < COUNT; rcount++) digits++;
  SetEvent(HighTask, event1); /* Set event1 to execute HighTask */

  ecrobot_debug1(digits, 1199, 0);
  for(rcount=0; rcount < COUNT; rcount++) digits--;

  ReleaseResource(resource1); /* Release resource1 */

  ecrobot_debug1(digits, 1999, 0);

  TerminateTask();
}

TASK(HighTask)
{
  int rcount;

  ecrobot_debug2(digits, 2222, 1);
  for(rcount=0; rcount < COUNT; rcount++) digits++;
  ecrobot_debug2(digits, 2228, 1);
  for(rcount=0; rcount < COUNT; rcount++) digits++;

  WaitEvent(event1); /* Waiting for event1 */
  ClearEvent(event1);
  ecrobot_debug2(digits, 2288, 1);
  for(rcount=0; rcount < COUNT; rcount++) digits++;

  GetResource(resource1); /* Get resource1 */

  ecrobot_debug2(digits, 2888, 1);
  for(rcount = 0; rcount < COUNT; rcount++);

  ReleaseResource(resource1); /* Release resource1 */

  ecrobot_debug2(digits,8888 , 1);

  TerminateTask();
}

samples\resourcetest\resourcetest.oil

#include "implementation.oil"

CPU ATMEL_AT91SAM7S256
{
  OS LEJOS_OSEK
  {
    STATUS = EXTENDED;
    STARTUPHOOK = TRUE;
    ERRORHOOK = FALSE;
    SHUTDOWNHOOK = FALSE;
    PRETASKHOOK = FALSE;
    POSTTASKHOOK = FALSE;
    USEGETSERVICEID = FALSE;
    USEPARAMETERACCESS = FALSE;
    USERESSCHEDULER = FALSE;
  };

  /* Definition of application mode */
  APPMODE appmode1{};

  /* Definition of resource */
  RESOURCE resource1
  {
    RESOURCEPROPERTY = STANDARD;
  };

  /* Definition of event */
  EVENT event1
  {
    MASK = AUTO;
  };

  /* Definition of HighTask */
  TASK HighTask
  {
    AUTOSTART = FALSE;
    SCHEDULE = FULL;
    PRIORITY = 3;
    ACTIVATION = 1;
    SCHEDULE = FULL;
    RESOURCE = resource1;
    EVENT = event1;
    STACKSIZE = 512;
  };

  /* Definition of LowTask */
  TASK LowTask
  {
    AUTOSTART = FALSE;
    PRIORITY = 2;
    ACTIVATION = 1;
    SCHEDULE = FULL;
    RESOURCE = resource1;
    STACKSIZE = 512;
  };

  /* Definition of OSEK Alarm Counter */
  COUNTER SysTimerCnt
  {
    MINCYCLE = 1;
    MAXALLOWEDVALUE = 100000;
    TICKSPERBASE = 1;
  };

  ALARM cyclic_alarm1
  {
    COUNTER = SysTimerCnt;
    ACTION = ACTIVATETASK
    {
      TASK = HighTask;
    };
    AUTOSTART = TRUE
    {
      ALARMTIME = 3000;
      CYCLETIME = 10000;
      APPMODE = appmode1;
    };
  };

  ALARM cyclic_alarm2
  {
    COUNTER = SysTimerCnt;
    ACTION = ACTIVATETASK
    {
      TASK = LowTask;
    };
    AUTOSTART = TRUE
    {
      ALARMTIME = 3000;
      CYCLETIME = 10000;
      APPMODE = appmode1;
    };
  };
};

 

 

 

Back to Samples