반응형

 

 

Periodic태스크에서 주기적으로 소프트웨어적으로 인터럽트를 발생시킨다.

인터럽트가 발생하면 인터럽트를 위한 서비스 루틴인 vExampleInterruptHandler함수가 호출되어 세마포어를 놓아주고 컨택스트 스위치를 한다.

바로 Handler 태스크에서 세마포어를 획득하고는 필요한 처리작업을 하게 된다. 이후 다시 세마포어를 기다리는 블록상태에 빠지고

다시 Periodic태스크에서 인터럽트 발생 후 해야 할 작업을 이어서 계속한다.

  1. /* FreeRTOS.org includes. */  
  2. #include "FreeRTOS_AVR.h"  
  3. //#include "task.h"  
  4. //#include "semphr.h"  
  5. //#include "portasm.h"  
  6.     
  7. /* Demo includes. */  
  8. #include "basic_io_avr.h"  
  9.     
  10. /* Compiler includes. */  
  11. //#include <dos.h>  
  12.     
  13. //인터럽트 발생  실제 작업을 처리하는 함수  
  14. static void vHandlerTask( void *pvParameters );  
  15.     
  16. //주기적으로 소프트웨어적으로 인터럽트를 발생시킴  
  17. static void vPeriodicTask( void *pvParameters );  
  18.     
  19. //인터럽트를 위한 서비스 루틴  
  20. static void vExampleInterruptHandler( void );  
  21.     
  22. /*-----------------------------------------------------------*/  
  23.     
  24. /* Declare a variable of type SemaphoreHandle_t.  This is used to reference the 
  25. semaphore that is used to synchronize a task with an interrupt. */  
  26. SemaphoreHandle_t xBinarySemaphore;  
  27.     
  28. // pin to generate interrupts  
  29. #if defined(CORE_TEENSY)  
  30. const uint8_t interruptPin = 0;  
  31. #elfif defined(__AVR_ATmega32U4__)  
  32. const uint8_t interruptPin = 3;  
  33. #else  // interruptPin  
  34. const uint8_t interruptPin = 2;  
  35. #endif  // interruptPin  
  36.     
  37. void setup( void )  
  38. {  
  39.     Serial.begin(9600);  
  40.      
  41.     //바이너리 세마포어 생성  
  42.     vSemaphoreCreateBinary( xBinarySemaphore );  
  43.     
  44.    //인터럽트 핀을 출력으로 설정  
  45.    pinMode(interruptPin, OUTPUT);  
  46.        
  47.    //인터럽트 서비스 루틴을 지정한다. LOW->HIGH  전압이 변화시 인터럽트 발생  
  48.    attachInterrupt(0, vExampleInterruptHandler, RISING);  
  49.     
  50.     
  51.   //세마포어가 성공적으로 생성되었다면  
  52.   if( xBinarySemaphore != NULL )  
  53.   {  
  54.     //Handler 태스크를 생성한다.인터럽트가 발생하면 즉시 실행되도록 우선순위를   
  55.     //다른 태스크보다 높게해서 생성한다.  
  56.     xTaskCreate( vHandlerTask, "Handler", 200, NULL, 3, NULL );  
  57.     
  58.     //주기적으로 소프트웨어 인터럽트를 발생시키는 Periodic태스크를 생성한다.  
  59.     /* Create the task that will periodically generate a software interrupt. 
  60.     This is created with a priority below the handler task to ensure it will 
  61.     get preempted each time the handler task exist the Blocked state. */  
  62.     xTaskCreate( vPeriodicTask, "Periodic", 200, NULL, 1, NULL );  
  63.     
  64.     //스케줄러를 시작한다.  
  65.     vTaskStartScheduler();  
  66.   }  
  67.     
  68.    //메모리가 부족하지 않는한 여기에 도달하지 않는다.  
  69.        
  70.   for( ;; );  
  71. //  return 0;  
  72. }  
  73. /*-----------------------------------------------------------*/  
  74.     
  75. static void vHandlerTask( void *pvParameters )  
  76. {  
  77.   /* Note that when you create a binary semaphore in FreeRTOS, it is ready 
  78.   to be taken, so you may want to take the semaphore after you create it 
  79.   so that the task waiting on this semaphore will block until given by 
  80.   another task. */  
  81.   //세마포어를 획득하기 위해 대기한다.  
  82.   //두번째 파라메터가 0인경우에는 사용가능한 세마포어를 찾아 폴링한다.  
  83.   xSemaphoreTake( xBinarySemaphore, 0);  
  84.     
  85.   for( ;; )  
  86.   {  
  87.      //이벤트를 기다리기 위해서 세마포어를 이용한다.  
  88.      //세마포어를 얻을떄 까지 대기하게 된다.  
  89.      //첫번째 파라메터는 세마포어 핸들러  
  90.      //두번째 파라메터는 세마포어를 획득할때 까지 기다리는 최대 틱수  
  91.      //portMAX_DELAY 설정하면 무한히 기다리게 된다.  
  92.     xSemaphoreTake( xBinarySemaphore, portMAX_DELAY );  
  93.     
  94.     //세마포어를 획득했으므로 이제 이벤트를 처리한다.  
  95.     vPrintString( "Handler task - Processing event.\r\n" );  
  96.   }  
  97. }  
  98. /*-----------------------------------------------------------*/  
  99.     
  100. static void vPeriodicTask( void *pvParameters )  
  101. {  
  102.   //주기적으로 소프트웨어적으로 인터럽트를 발생시키기위해 사용되는 태스크이다.  
  103.   for( ;; )  
  104.   {  
  105.     vTaskDelay( 500 / portTICK_PERIOD_MS );  
  106.     
  107.     //인터럽트를 발생시킨다.  
  108.     vPrintString( "Perodic task - About to generate an interrupt.\r\n" );  
  109.     
  110.     digitalWrite(interruptPin, LOW);  
  111.     digitalWrite(interruptPin, HIGH);  
  112.     
  113.     vPrintString( "Periodic task - Interrupt generated.\r\n\r\n\r\n" );  
  114.   }  
  115. }  
  116. /*-----------------------------------------------------------*/  
  117.     
  118. static void  vExampleInterruptHandler( void )  
  119. {  
  120. static signed portBASE_TYPE xHigherPriorityTaskWoken;  
  121.     
  122.   xHigherPriorityTaskWoken = pdFALSE;  
  123.     
  124.   //세마포어를 놓아주기 위한 함수이다.  
  125.   xSemaphoreGiveFromISR( xBinarySemaphore, (signed portBASE_TYPE*)&xHigherPriorityTaskWoken );  
  126.     
  127.   if( xHigherPriorityTaskWoken == pdTRUE )  
  128.   {  
  129.     //세마포어를 놓아준 걸로 인해서 우선순위 높은 태스크가 블록상태에서 빠져나왔다.  
  130.     //컨텍스트 스위치를 통해 해당 태스크가 실행될  있도록한다.  
  131.     vPortYield();  
  132.   }  
  133. }  
  134. //------------------------------------------------------------------------------  
  135. void loop() {}  


반응형

문제 발생시 지나치지 마시고 댓글 남겨주시면 가능한 빨리 답장드립니다.

도움이 되셨다면 토스아이디로 후원해주세요.
https://toss.me/momo2024


제가 쓴 책도 한번 검토해보세요 ^^

+ Recent posts