세 개의 태스크를 수행한다. LED를 깜빡이게 하는 테스크 현재 남은 스택크기와 힙의 크기를 시리얼로 출력하는 태스크 IDLE 루프 // Simple demo of three threads // LED blink thread, print thread, and idle loop #include const uint8_t LED_PIN = 13; volatile uint32_t count = 0; // handle for blink task TaskHandle_t blink; //------------------------------------------------------------------------------ //LED를 깜빡이게 하는 태스크가 우선순위가 가장 높다. static void vLEDFl..
LED 2개가 번갈아 가며 켜지는 예제를 세마포어 2개를 이용하여 만들어봤습니다. 세마포어를 얻으면 서로 상대방의 LED를 끄고 자신의 LED를 켜는 구조입니다. 처음에 어쩔 수 없이 한쪽 LED켜는 태스크에 세마포어를 주어서 시작하는 방식을 이용했습니다.. 아직 공부 중이라 이게 올바른 방법인지는 모르겠군요. 많은 구현 방법 중 하나라고 생각됩니다. #include //LED를 연결하는 핀 번호 const uint8_t LED_PIN = 13; const uint8_t LED_PIN2 = 9; //세마포어 핸들을 선언 SemaphoreHandle_t sem; SemaphoreHandle_t sem2; static void Thread1(void* arg) { pinMode(LED_PIN2, OUTPUT..
역시 마찬가지로 아래 포스팅에서 설치했던 라이브러리에 포함되어있던 예제를 분석합니다. 이제 여섯 개가 남았군요.. Arduino Uno에서 freeRTOS 올려보기(http://webnautes.tistory.com/595 ) 우선순위 높은 Thread1이 먼저 실행되지만 사용 가능한 세마포어가 없어 무한정 기다리게 된다. 이때 우선순위 낮은 Thread2가 실행되어 LED 를 켜고 200밀리세컨드 대기했다가 세마포어를 놓아주면 다시 우선순위 높은 Thread1이 실행되어 세마포어를 획득한 후 LED를 끄게 되고 다시 세마포어를 기다리는 상태가 된다. 그러면 다시 Thread2에서 200밀리세컨드 더 기다렸다가 다시 LED를 켜게 된다. 결과적으로 LED를 200밀리세컨드 주기로 깜빡이게 만든다. /* ..
우선순위 높은 Print2 태스크가 실행되어 자신에 해당되는 문자열을 큐에 넣고 임의의 시간 대기한다. 그 사이 태스크 1이 실행되어 자신에 해당되는 문자열을 넣고 임의의 시간 대기한다. 태스크2의 대기 시간보다 짧아서 여러 번 실행될 수 있다. 다른 태스크들이 블록되어 있는 동안 우선순위 가장 낮은 Gatekeeper 태스크가 큐에 있는 데이터를 출력한다. 틱 후크 인터럽트가 발생하면 틱 인터럽트 서비스 루틴이 실행되어 큐에 대응되는 문자열을 넣는다. 역시 나중에 Gatekeeper 태스크에서 출력되어 진다. /* FreeRTOS.org includes. */ #include "FreeRTOS_AVR.h" //#include "task.h" //#include "semphr.h" /* Compiler ..
처음 실행시키면 vIntegerGenerator태스크보다 vStringPrinter태스크의 우선순위가 높기때문에 먼저 실행이 되나 큐가 비어있기때문에 블록 상태가 된다. 따라서 vIntegerGenerator태스크가 실행되지만 vTaskDelayUntil함수를 사용했기 때문에 정해준 값인 200밀리세컨드마다 대기상태에서 벗어나와 작업을 시작할 수 있다. vIntegerGenerator에서 증가시킨 정수값을 큐에 넣는 것을 5번 반복한 후 인터럽트를 발생시킨다. 인터럽트 서비스 루틴인 vExampleInterruptHandler 함수가 호출된다. vExampleInterruptHandler에서 정수값을 넣은 큐에서 데이터를 꺼내와서 정수에 대응되는 문자열을 큐에 문자열을 넣는 큐에 넣는다. 정수값을 꺼내오..
Periodic태스크에서 주기적으로 소프트웨어적으로 인터럽트를 발생시킨다. 인터럽트가 발생하면 인터럽트를 위한 서비스 루틴인 vExampleInterruptHandler함수가 호출되어 세마포어를 놓아주고 컨택스트 스위치를 한다. 바로 Handler 태스크에서 세마포어를 획득하고는 필요한 처리작업을 하게 된다. 이후 다시 세마포어를 기다리는 블록상태에 빠지고 다시 Periodic태스크에서 인터럽트 발생 후 해야 할 작업을 이어서 계속한다. 지난번 예제와 차이점이 있다면 한번에 세마포어를 세 개씩 주지만 이벤트를 놓치지 않고 잘 처리해주는 것이다. Handler에서 작업하던 중 인터럽트가 발생되면 다시 Handler를 처리하려 하고 하다 보니 결국 마지막에 발생한 인터럽트 처리부터 하기 때문에 count값이..
Periodic태스크에서 주기적으로 소프트웨어적으로 인터럽트를 발생시킨다. 인터럽트가 발생하면 인터럽트를 위한 서비스 루틴인 vExampleInterruptHandler함수가 호출되어 세마포어를 놓아주고 컨택스트 스위치를 한다. 바로 Handler 태스크에서 세마포어를 획득하고는 필요한 처리작업을 하게 된다. 이후 다시 세마포어를 기다리는 블록상태에 빠지고 다시 Periodic태스크에서 인터럽트 발생 후 해야 할 작업을 이어서 계속한다. /* FreeRTOS.org includes. */ #include "FreeRTOS_AVR.h" //#include "task.h" //#include "semphr.h" //#include "portasm.h" /* Demo includes. */ #include "..
큐에 값을 넣는 태스크를 두 개 선언하는데 파라메터로 자신을 나타내는 ID와 출력할 값을 구조체에 넣어 넘겨줍니다. 다른 하나의 태스크가 구조체를 꺼내어 ID와 값을 출력합니다. /* FreeRTOS.org includes. */ #include "FreeRTOS_AVR.h" //#include "task.h" //#include "queue.h" /* Demo includes. */ #include "basic_io_avr.h" #define mainSENDER_1 1 #define mainSENDER_2 2 //큐에 값을 넣는 함수 static void vSenderTask( void *pvParameters ); //큐에서 값을 가져오는 함수 static void vReceiverTask( void..
우선순위 높은 태스크1만 실행되야 하는데 태스크 1에서 태스크2의 우선순위를 높여서 태스크 2를 실행되도록 하고 태스크1은 우선순위가 그보다 낮아서 실행이 안됩니다. 다시 태스크 2에서 자신의 우선순위를 낮추어서 태스크1만 실행되게 해주는데 결국 태스크1과 태스크2가 번갈아 가며 실행되게 됩니다. 첨에 이해가 잘 안되서 단계별로 코드를 나누어서 분석해봤습니다. 1단계 /* FreeRTOS.org includes. */ #include "FreeRTOS_AVR.h" //#include "task.h" /* Demo includes. */ #include "basic_io_avr.h" //두 개의 태스크 함수 선언 void vTask1( void *pvParameters ); void vTask2( void..
태스크들이 딜레이 함수에 의해서 대기상태가 되면 IDLE 태스크가 실행되면서 후크 함수 vApplicationIdleHook 가 호출된다. 이때 마다 이 함수 내부에서 카운터를 증가시킨다. 즉 아래에서 보이는 숫자는 후크 함수가 호출된 횟수이다. 두 개의 태스크에서 모두 딜레이 함수를 뺴버리면 후크함수가 한번도 호출되지 않는 것을 볼 수 있다. /* FreeRTOS.org includes. */ #include "FreeRTOS_AVR.h" //#include "task.h" /* Demo includes. */ #include "basic_io_avr.h" //태스크에서 사용될 함수 void vTaskFunction( void *pvParameters ); //idle task hook 함수에 의해서 ..