FreeRTOS 이해 2 (단추를 누르면 작업 표시줄 중 하나 전환)

10881 단어 nucleoFreeRTOS

FreeRTOS 실습 2


1로 기재되지는 않았지만 여기.의 계속.처음부터 거절했지만 좋은 절차가 아닌가(개선의 여지가 있다).

할 일


단추를 눌렀을 때 작업 전환을 실현하는 프로그램입니다.

쓰던 물건


스위치과학선생님을 통해 구매Nucleo-F303RE했습니다.사용자용 버튼이 처음부터 탑재됐다는 단순한 이유에서다.

코드


작업 관련 선언


처리 버튼을 누른 작업과 LED 연결 끊긴 작업 두 개.
#include <STM32FreeRTOS.h>

const uint8_t Led = LED_BUILTIN;
const uint8_t Btn = USER_BTN;

TaskHandle_t TaskButton_Handler;
TaskHandle_t TaskBlink1_Handler;
TaskHandle_t TaskBlink0_Handler;

void TaskButton(void *pvParameters);
void TaskBlink1(void *pvParameters);
void TaskBlink0(void *pvParameters);

아두노 환경에 익숙한 부분.


퀘스트 생성 등.

void setup() {
  Serial.begin(9600);  
  while (!Serial) {}

  pinMode(Led, OUTPUT);

  xTaskCreate(TaskButton, "Button", 128, NULL, 2, &TaskButton_Handler);
  xTaskCreate(TaskBlink1, "Blink1", 128, NULL, 1, &TaskBlink1_Handler);
  xTaskCreate(TaskBlink0, "Blink0", 128, NULL, 1, &TaskBlink0_Handler);    

  vTaskStartScheduler(); 
}  

void loop() {
  // Empty. Things are done in Tasks.
}

버튼을 눌러 작업 처리

void TaskButton(void *pvParameters) {
  (void) pvParameters;
  int pressed = 0;

  pinMode(Btn, INPUT);
  vTaskSuspend(TaskBlink1_Handler);  
  vTaskSuspend(TaskBlink0_Handler);  
  for (;;) {
    if (pressed == 0) {
      if (digitalRead(Btn) == LOW){
        Serial.println("Button Pushed for Blink1");
        pressed = 1;
        vTaskSuspend(TaskBlink0_Handler); 
        vTaskResume(TaskBlink1_Handler);
      }
    } else { // pressed == 1
      if (digitalRead(Btn) == LOW){
        Serial.println("Button Pushed for Blink0");
        pressed = 0;
        vTaskSuspend(TaskBlink1_Handler); 
        vTaskResume(TaskBlink0_Handler); 
      }
    }
    vTaskDelay(500/portTICK_PERIOD_MS); // wait for 500ms
  }
}
먼저 vTaskSuspend()로 2개의 LED 작업을 중지했습니다.버튼을 누르면 두 작업이 서로 잠들고(vTaskSuspend), 깨우기(vTaskResume()됩니다.

LED 작업


두 작업의 차이는 LED가 깜박이는 간격이 다르다는 것이다.
void TaskBlink1(void *pvParameters) {
  (void) pvParameters;

  for (;;) {
    digitalWrite(Led, HIGH);
    delay(500);
    digitalWrite(Led, LOW);
    delay(500);
    Serial.println("Blink1");
    vTaskDelay(1);
  }
}

void TaskBlink0(void *pvParameters) {
  (void) pvParameters;

  for (;;) {
    digitalWrite(Led, HIGH);
    delay(1000);
    digitalWrite(Led, LOW);
    delay(1000);
    Serial.println("Blink0");
    vTaskDelay(1);
  }
}
vTaskDelay () 는 단추를 누르면 작업의 전환 여지를 유지하기 위해 사용됩니다.

실험


콘솔에서 다음과 같은 느낌이 든다.버튼을 누르자마자 전환하고 있다.

그렇지만


이 프로그램은 단추의 베끼기를 방지할 수 없으며, 단추 스위치를 눌러도 (특히 바로 누르고 떠날 때) 작업이 바뀌지 않는 경우도 있다.이것을 해결하는 것은 다음의 셋째이다.

참고 자료


FreeRTOS API 그룹

좋은 웹페이지 즐겨찾기