BaseType_t xTaskCreate(TaskFunction_t pvTaskCode, const char const pcName,
unsigned short usStackDepth, void pvParameters, UBaseType_t uxPriority, TaskHandle_t *pxCreatedTask);
void vTaskStartScheduler(void); => 멀티 태스킹을 시작. 생성된 태스크의 스케쥴링 시작
void vTaskDelay(portTickType xTicksToDelay);
=> 스케쥴러에 상대 시간동안 delay를 요청(waiting state로 만듬)
=> 함수가 호출된 시점부터 xTicksToDelay동안 태스크 실행을 block
void vTaskDelayUntil(portTickType *pxPreviousWakeTime, portTickType xTimeIncrement);
=> 스케쥴러에 절대 시간동안 delay를 요청(waiting state로 만듬
=> 특정 시점인 pxPreviousWakeTime부터 xTimeIncrement 만큼 더한 시간까지 태스크 실행을
블록
LED와 Buzzer을 동시에 제어
< FreeRTOS1.c >
#include <FreeRTOS_AVR.h>
// FreeRTOS Delay함수에서 사용하기 위한 메크로 함수: ms -> ticks로 변환
#define MS2TICKS(ms)(ms / porTICK_PERIOD_MS)
#define LED 5
#define BUZZER 9
// 음계 정의
enum { REST=0, DO=262, RE=294, MI=330, FA=349, SOL=392, LA=440, SHI=494, DO2=523 };
int Num = 9;
int Frequency[] = { DO, RE, MI, REST, FA, SOL, LA, SHI, DO2 }; // 음계 정의
int Delay[] = { 500, 0, 500, 500, 500, 500, 1000, 0, 500 }; // 유지시간 정의
void LedTask(void* arg){
while(1){
// LED on
digitalWrite(LED, HIGH);
// 500ms 지연
vTaskDelay(MS2TICKS(500));
// LED off
digitalWrite(LED, LOW);
// 500ms 지연
vTaskDelay(MS2TICKS(500));
}
}
void BuzzerTask(void* arg){
int i;
while(1){
for(i=0; i<Num; i++){
// 9번핀을 통해 출력
tone(BUZEER, Frequency[i]);
// 유지 시간
vTaskDelay(MS2TICKS(Delay[i]));
}
}
}
void setup(){
pinMode(LED, OUTPUT);
pinMode(BUZEER, OUTPUT);
// Task 생성
xTaskCreate(LedTask, NULL, 200, NULL, 1, NULL);
xTaskCreate(BuzzerTask, NULL, 200, NULL, 2, NULL); // BuzzerTask의 우선순위가 LED보다 더 높다
// 스케쥴러 시작
vTaskStartScheduler();
}
void loop(){}
LED 1개씩 ON/OFF task 2개 동작
- 500ms 간격으로 on/off
< FreeRTOS2.c >
#include <FreeRTOS_AVR.h>
#define MS2TICKS(ms) (ms/portTICK_PERIOD_MS)
#define LED1 5
#define LED2 6
void LedTask(int* pParam){
int led, turn, param = *pParam; // pParam 포인터로 param정보 입력받음
// 초기 LED1, LED2 작동 정의
if(param==1){
led = LED1; turn=HIGH;
}
else{
led = LED2; turn=LOW;
}
// 루프 반복
while(1){
digitalWrite(led, turn);
// 500ms 지연
vTaskDelay(MS2TICKS(500));
turn = (turn==HIGH) ? LOW : HIGH; // 현재 turn상태와 반대로 지정
}
}
void setup(){
int param[2] = {1,2};
pinMode(LED1, OUTPUT);
pinMode(LED2, OUTPUT);
// Task 생성
vTaskCreate(LedTask, NULL, 200, ¶m[0], 1, NULL);
vTaskCreate(LedTask, NULL, 200, ¶m[1], 1, NULL);
// 스케쥬러 시작
vTaskStartScheduler();
}
void loop(){}
위 코드에서는 먼저 param=2일때의 task2가 먼저 실행되며, led=LED2, turn=LOW인 상태로 digitalWrite가 진행되다가 vTaskDelay에 의해 block되며, param=1일때의 task1가 실행된다. led=LED1인 상태로 digitalWrite가 진행되며 led1이 점등되며, 이것도 다시 block되면서 task2가 다시 실행되고, turn의 상태가 바뀌어 LED2가 점등되고 block, 다시 task1이 실행되어 LED1이 소등되고 block을 반복하게 된다. 따라서 LED1개씩 0.5ms씩 점/소등이 반복된다.