본문 바로가기
Embedded/OSEK Real-Time OS

Alarm & Event

by kjy1010 2024. 1. 20.

Alarm

OSEK RTOS에서 알람(Alarm)은 시간 주기에 따라 태스크를 활성화하는 데 사용되는 메커니즘입니다. 알람은 특정 카운터와 연결되어 있으며, 카운터가 특정 값에 도달하면 알람이 트리거되어 해당 알람과 연결된 태스크가 실행됩니다.
Alarm을 추가하는 실습을 진행하며 이해하는 시간을 가지겠습니다.

OIL파일을 수정하여 Counter와 alarm을 추가

COUNTER counter1{
    	MINCYCLE = 1;
    	MAXALLOWEDVALUE = 127;
    	TICKSPERBASE = 1;
    };
    
    ALARM alarm1{
    	COUNTER = counter1;
    	ACTION=ACTIVATETASK{
    		TASK=Task1;
    	};
    	AUTOSTART = TRUE{
    		ALARMTIME = 5;
    		CYCLETIME = 10;
    	};
    };
    
      ALARM alarm2{
    	COUNTER = counter1;
    	ACTION=ACTIVATETASK{
    		TASK=Task2;
    	};
    	AUTOSTART = TRUE{
    		ALARMTIME = 5;
    		CYCLETIME = 20;
    	};
    };


Timer ISR에서 conter증가

ISR2(TimerISR)
{
	static long c=-4;
	IncrementCounter(counter1);
		printfSerial("\n%4ld: ",c++);
}


Task1, Task2 수정

TASK(Task1){

   printfSerial("Task1 Begins...\n");
   mdelay(3000);
   printfSerial("Task1 Finishes...\n");
   TerminateTask();
}

TASK(Task2){

   printfSerial("Task2 Begins...\n");
   mdelay(6000);
   printfSerial("Task2 Finishes...\n");
   TerminateTask();
}


실행결과

주기적으로 Task가 실행됨을 확인 할 수 있습니다.

Alarm Callback
OSEK RTOS에서 Alarm Callback은 알람이 트리거될 때 호출되는 사용자 정의 함수를 나타냅니다. Alarm Callback은 알람의 설정 또는 취소와 관련된 이벤트가 발생할 때마다 실행되는 함수로서, 이를 통해 사용자는 특정 동작을 수행할 수 있습니다.

asw.c파일에 콜백함수 등록

ALARMCALLBACK(MyCallback)
{
   printfSerial("MyCallback Begins...");
   printfSerial("MyCallback Finishes...");
}


OIL파일에 콜백함수에 사용할 Alarm 추가

ALARM alarm3{
       COUNTER = counter1;
       ACTION = ALARMCALLBACK{
          ALARMCALLBACKNAME = "MyCallback";
          
       };
       AUTOSTART = TRUE{
          ALARMTIME = 5;
          CYCLETIME = 15;
       };
    };


실행결과

다음과 같이 콜백함수가 동작함을 확인 할 수 있습니다.

Event
OSEK RTOS에서 Event(이벤트)는 태스크 간의 통신 및 동기화를 위한 메커니즘 중 하나입니다. 이벤트는 특정 상황이나 조건이 발생했음을 나타내며, 해당 이벤트를 기다리고 있는 태스크가 이를 감지하여 특정 동작을 수행할 수 있도록 합니다.
Task2에 Event를 등록하여 사용하는 실습을 진행하겠습니다.

asw.c에서 Task2수정

TASK(Task2){
   EventMaskType mask;
   printfSerial("Task2 Begins...\n");
   printfSerial("Task2 Waits...\n");
   WaitEvent(Event1 | Event2);
   printfSerial("Task2 Wakes Up...\n");
   GetEvent(Task2, &mask);
   if(mask & Event1){
      printfSerial("[Event1]\n");
      ClearEvent(Event1);
   }
   if(mask & Event2){
      printfSerial("[Event2]\n");
      ClearEvent(Event2);
   }
   printfSerial("Task2 Finishes...\n");
   TerminateTask();
}


OIL파일 수정
OS 시작 15초 후 Event1, 그 다음 25초 후 Event2 발생 반복 (20초 간격으로 Event1, Event2반복 발생)
Event1,2를 선언하고 콜백함수 추가

CPU mySystem {
    OS myOs {
      EE_OPT = "OS_EE_APPL_BUILD_DEBUG";
      EE_OPT = "OS_EE_BUILD_DEBUG";

        USERESSCHEDULER = TRUE;
        CPU_DATA = AVR8 {
            MULTI_STACK = TRUE;
        };
        MCU_DATA = MEGA {
            MODEL = MEGA_328p;
        };
        LIB = ARDUINO {
            SDK_BOARD = UNO;
            VARIANT = CC {
                VERSION = "1.8.5";
            };
            STAND_ALONE = TRUE;        // Generate arduino libraries
        };
        KERNEL_TYPE = OSEK {
            CLASS = ECC2;    // Default
        };
    };
    EVENT Event1 {MASK = AUTO;};
    EVENT Event2 {MASK = AUTO;};
    
    APPDATA myApp {
        APP_SRC = "bsw.cpp";
        APP_SRC = "asw.c";
    };
    
    TASK Task1{
       PRIORITY = 1;
       STACK = SHARED;
       SCHEDULE = FULL;
       AUTOSTART = FALSE;
       ACTIVATION = 1;
    };
    
    TASK Task2{
        PRIORITY = 2;
       STACK = PRIVATE{
          SIZE = 512;
       };
       SCHEDULE = FULL;
       EVENT = Event1;
       EVENT = Event2;
       AUTOSTART = FALSE;
       ACTIVATION = 1;
    };

       ISR TimerISR{
       CATEGORY = 2;
       SOURCE = "TIMER1_COMPA";
    };
    COUNTER counter1{
       MINCYCLE = 1;
       MAXALLOWEDVALUE = 127;
       TICKSPERBASE = 1;
    };
    ALARM alarm1{
       COUNTER = counter1;
       ACTION = ACTIVATETASK{
          TASK = Task1;
       };
       AUTOSTART = TRUE{
          ALARMTIME = 5;
          CYCLETIME = 10;
       };
    };
    ALARM alarm2{
       COUNTER = counter1;
       ACTION = ACTIVATETASK{
          TASK = Task2;
       };
       AUTOSTART = TRUE{
          ALARMTIME = 5;
          CYCLETIME = 20;
       };
    };
        ALARM alarm3{
       COUNTER = counter1;
       ACTION = ALARMCALLBACK{
          ALARMCALLBACKNAME = "MyCallback1";
          
       };
       AUTOSTART = TRUE{
          ALARMTIME = 15;
          CYCLETIME = 40;
       };
    };
     ALARM alarm4{
       COUNTER = counter1;
       ACTION = ALARMCALLBACK{
          ALARMCALLBACKNAME = "MyCallback2";
          
       };
       AUTOSTART = TRUE{
          ALARMTIME = 35;
          CYCLETIME = 40;
       };
    };
};


실행결과


Task2는 Event1과 Event2를 WaitEvent()하며 정해진 순서대로 Alarm과 Event가 발생함을 확인 할 수 있습니다.

Alarm SetEvent
Alarm안에 Event를 등록하여 동작시킬수도 있습니다.
실습을 통해 자세하게 알아보겠습니다.

OIL파일의 alarm을 수정하여 SetEvent Action을 등록

ALARM alarm3{
       COUNTER = counter1;
       ACTION = ALARMCALLBACK{
         TASK = Task2;
         EVENT = Event1;
       };
       AUTOSTART = TRUE{
          ALARMTIME = 7;
          CYCLETIME = 20;
       };


실행결과


다음과 같이 Task2가 wait상태에서 Task1이 시작되다 event가 발생하면 Task2를 wake up는 결과를 확인 할 수 있습니다.

'Embedded > OSEK Real-Time OS' 카테고리의 다른 글

Race condition & Resource  (0) 2024.01.21
Hook  (0) 2024.01.21
Task  (0) 2024.01.20
OSEK project 기초  (0) 2024.01.20
OSEK project 생성과 파일구조  (0) 2024.01.18