BluePill+FreeRTOSのテスト

スケッチ例のFreeRTOS900をベースにLED点滅+ラジコンサーボ制御をさせてみました。オンボードのLED(PC13)と、PB0、PB1に接続したLEDを異なる周期で点滅させると同時に、PWM出力を使ってPA7に接続したラジコンサーボをゆっくり動かしています。RTOSを使ってそれぞれ独立したタスクとして制御していて、今回は4つのタスクを起動しています。setup()の最後のvTaskStartScheduler();は帰ってこないようで、loop()の中は実行されません。
4つのタスクを動作させてもこのくらいなら問題ないようですが、configMINIMAL_STACK_SIZEは120になっていますので、処理を増やしていくとどっかでスタックオーバーランすることと思います。このサンプルには記述していないですが、ハードウェアシリアル(テストではSerial3を使用)も各タスクで動かしてもとりあえず動くようで、デバッグの際に使えそうです。

//#include <wirish/wirish.h>
//#include "libraries/FreeRTOS/MapleFreeRTOS.h"
#include <MapleFreeRTOS900.h>

#define BOARD_LED_PIN LED_BUILTIN

static void vLEDFlashTask(void *pvParameters) {
    for (;;) {
        vTaskDelay(1000-50);
        digitalWrite(BOARD_LED_PIN, LOW);
        vTaskDelay(50);
        digitalWrite(BOARD_LED_PIN, HIGH);
    }
}

static void vLEDFlashTask2(void *pvParameters) {
    for (;;) {
        vTaskDelay(50);
        digitalWrite(PB0, LOW);
        vTaskDelay(500-50);
        digitalWrite(PB0, HIGH);
    }
}

static void vLEDFlashTask3(void *pvParameters) {
    for (;;) {
        vTaskDelay(50);
        digitalWrite(PB1, LOW);
        vTaskDelay(250-50);
        digitalWrite(PB1, HIGH);
    }
}

#include <Servo.h>
// 端子割付けは STM32F1/variants/generic_stm32f103c/board.cpp を参照
Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0;    // variable to store the servo position

static void vServoTask(void *pvParameters) {
  for(;;){
    for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
      // in steps of 1 degree
      myservo.write(pos);              // tell servo to go to position in variable 'pos'
      if(pos == 90) vTaskDelay(500);
      vTaskDelay(50);                       // waits 15ms for the servo to reach the position
    }
    vTaskDelay(500);
    for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
      myservo.write(pos);              // tell servo to go to position in variable 'pos'
      if(pos == 90) vTaskDelay(500);
      vTaskDelay(50);                       // waits 15ms for the servo to reach the position
    }
    vTaskDelay(500);
  }
}

void setup() {
    // initialize the digital pin as an output:
    pinMode(BOARD_LED_PIN, OUTPUT);
    pinMode(PB0          , OUTPUT);
    pinMode(PB1          , OUTPUT);
    myservo.attach(PA7);  // attaches the servo on pin PA7 to the servo object
  
    xTaskCreate(vLEDFlashTask,
                "Task1",
                configMINIMAL_STACK_SIZE,
                NULL,
                tskIDLE_PRIORITY + 2,
                NULL);
    xTaskCreate(vLEDFlashTask2,
                "Task2",
                configMINIMAL_STACK_SIZE,
                NULL,
                tskIDLE_PRIORITY + 2,
                NULL);
    xTaskCreate(vLEDFlashTask3,
                "Task3",
                configMINIMAL_STACK_SIZE,
                NULL,
                tskIDLE_PRIORITY + 2,
                NULL);
    xTaskCreate(vServoTask,
                "Task4",
                configMINIMAL_STACK_SIZE,
                NULL,
                tskIDLE_PRIORITY + 2,
                NULL);
    vTaskStartScheduler();
}

void loop() {
    // Insert background code here
}

ソースコードは下記

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)