FreeRTOSをGoogleTestでUnitTestする with CMake


概要

CMakeを使って、FreeRTOS最小構成のVisualStudioプロジェクト作る
CMakeで作るようにした既存のVisualStudioプロジェクトに、GoogleTestを追加する
を使って
FreeRTOSをGoogleTestで走らせてみます。

手順

FreeRTOS動作コード

FreeRTOSのカーネルオブジェクト生成、スケジューラ起動をユニットテストの裏で走らせます。
タスクを1つ生成して、"Task 1 is running"を表示させ続けるコードにしておきます。

test_freertos.c
#include "test_freertos.h"
#include <stdio.h>
#include "FreeRTOS.h"
#include "task.h"

/* Used as a loop counter to create a very crude delay. */
#define mainDELAY_LOOP_COUNT        ( 0xffffff )

/* The task functions. */
void vTaskSample(void* pvParameters);

void drive_freertos(void)
{
    /* Create one of the two tasks. */
    xTaskCreate(vTaskSample, "Task 1", 1000, NULL, 1, NULL); /* We are not using the task handle. */

    /* Start the scheduler to start the tasks executing. */
    vTaskStartScheduler();

    for (;; );
    return 0;
}
void vTaskSample(void* pvParameters)
{
    const char* pcTaskName = "Task 1 is running\r\n";
    volatile uint32_t ul;

    /* As per most tasks, this task is implemented in an infinite loop. */
    for (;; )
    {
        /* Print out the name of this task. */
        printf(pcTaskName);

        /* Delay for a period. */
        for (ul = 0; ul < mainDELAY_LOOP_COUNT; ul++)
        {
            /* This loop is just a very crude delay implementation.  There is
            nothing to do in here.  Later exercises will replace this crude
            loop with a proper delay/sleep function. */
        }
    }
}

SetUpで drive_freertos をスレッドで動かす

ユニットテスト実行の間、FreeRTOSを動作させます。
先ほど定義したdrive_freertosをSetUpで動かしdetachします。(SetUpに関してはgoogletestのドキュメント参照にしてください。ユニットテストの前の準備です。)
※ FreeRTOSはCコードなので extern "C" で囲ってあります。

freertos_unittest.cpp
#include <thread>
#include "gtest/gtest.h"
extern "C"
{
#include "test_freertos.h"
}

class FreeRtosUnitTest : public testing::Test {
protected:
    void SetUp() override {
        std::thread th_freertos(drive_freertos);
        th_freertos.detach();
    }
    void TearDown() override {
    }
};

ユニットテストの実装

バックグラウンドでFreeRTOSタスクが動作していることを買う人するためにsleepを入れています。

test_sample1.cpp
TEST(FactorialTest, HandlesZeroInput) {
    EXPECT_EQ(1, 1);
}

TEST_F(FreeRtosUnitTest, Sample1) {
    _sleep(100);
    EXPECT_EQ(1, 1);
}

int main(int argc, char** argv) {
    ::testing::InitGoogleTest(&argc, argv);
    int ret =  RUN_ALL_TESTS();
    return ret;
}

実行結果は以下のようになります。
ユニットテストの間に、FreeRTOSタスクが動いていることが分かります。

後はこれを応用して
FreeRTOSアプリケーションのIF経由でテストするようなテストドライバを書けばよいです。

上記のコード

CMakenのファイルとか全体的に動かしただけなので汚いですが、、
https://github.com/azukibar0713/cmake_freertos_visualstudio/tree/54f9b66d30bc763bf1a041401851b64bf563c6f4
buildフォルダ以下で cmake .. して、作成されたslnファイルを立ち上げれば動きます。