Help us understand the problem. What is going on with this article?

IAR Embedded WorkbenchでCppUTestを試す

More than 3 years have passed since last update.

テストフレームワークの一つであるCppUTestを実機(STM32F4DISCOVERY)で動作させてみる。

準備

ターゲットとサンプル

ターゲットはCortex-M4コアのSTMicro社製マイクロコントローラSTM32F407VGを搭載した「STM32F4DISCOVERY」とする。ターゲット基板の詳細はこの辺りに記載されている。このページ下部にある「Related Tools and Software」という項目があり、そこにあるファームウェアパッケージSTSW-STM32068をベースにして進める事とする。クリックしてリンクを進むとドキュメントAN3983: STM32F4DISCOVERY peripheral firmware examplesとサンプル(Part Number : STSW-STM32068)をダウンロードするボタンがあるので、クリックして「stsw-stm32068.zip」をダウンロードする。
ダウンロードしたファイルを全て解凍しても良いが、ここでは次のディレクトリ(☆マークのあるディレクトリ以下全て)のみ解凍したものとして進める。なお、解凍場所は任意のディレクトリで良いが、ここでは便宜的にsample_rootに解凍したものとする。

sample_root
├─Libraries
│  ├─CMSIS
│  │  ├─Include ☆
│  │  ├─Lib ☆
│  │  └─ST ☆
│  ├─STM32F4xx_StdPeriph_Driver ☆
│  ├─STM32_USB_Device_Library ☆
│  └─STM32_USB_OTG_Driver ☆
├─Project
│  ├─Demonstration ☆
│  ├─Master_Workspace
│  │  └─EWARM ☆
│  └─Peripheral_Examples
│      └─IO_Toggle ☆
└─Utilities
    └─STM32F4-Discovery ☆

開発環境

今回、開発環境はIAR社のEmbedded Workbenchを使用し、まずはコード制限付きの評価版で可能かどうか検証してみる。Embedded Workbench ver.6.6 for ARM(以下、EWARM)をこの辺りからダウンロードしてきて、IAR社からライセンスを取得する。インストール及びライセンスの取得に関する部分はこの辺りこの辺りが参考になる。

ワークス-ペース

マスターワークスペースを開く。インストールが完了している場合、エクスプローラ等から次のファイルを開けばEWARMが起動する。
sample_root/Project/Master_Workspace/EWARM/STM32F4-Discovery.eww
解凍しなかったファイルある場合は警告表示が出るので全てOKで切り抜ける。成功すると次のようなプロジェクトが登録されているのをみる事ができる。
image001.png
プロジェクト「STM32F4-Discovery_Demo」は工場出荷時に書き込まれているものと同じである(と思う)。最後に元に戻しておくために組み込んでいる。今回、ベースにするのはプロジェクト「IO_Toggle」で、LEDをON/OFFするだけの単純なものである。ここでそれぞれプロジェクトを右クリックからmakeを実行しビルドが成功することを確認しておくと良い。

ライブラリの生成

ライブラリプロジェクトの作成

Project ⇒ Create New Projectを選んで新規のプロジェクトを生成する。
image003.png
ツールチェーンはARM、テンプレートは Empty project を選んでOKボタンを押下し、空のプロジェクトを作成する。
image005.png
プロジェクトファイルの格納場所を聞いてくるが、ディレクトリ構造は自動的に決定されないので自力でディレクトリ構造を構築する必要がある。フォルダの作成等を駆使しつつ次のようにディレクトリ構造を構築し、プロジェクトファイルを決めて確定する。
続いて、ファイルをCppUTestからコピーする。

├─include
│  ├─CppUTest
│  │      CommandLineArguments.h
│  │      CommandLineTestRunner.h
│  │      JUnitTestOutput.h
│  │      MemoryLeakAllocator.h
│  │      MemoryLeakDetector.h
│  │      MemoryLeakDetectorMallocMacros.h
│  │      MemoryLeakDetectorNewMacros.h
│  │      MemoryLeakWarningPlugin.h
│  │      PlatformSpecificFunctions.h
│  │      SimpleString.h
│  │      TestFailure.h
│  │      TestHarness.h
│  │      TestHarness_c.h
│  │      TestOutput.h
│  │      TestPlugin.h
│  │      TestRegistry.h
│  │      TestResult.h
│  │      TestTestingFixture.h
│  │      Utest.h
│  │      UtestMacros.h
│  │      VirtualCall.h
│  └─Platforms
│      └─Gcc
│              Platform.h
└─src
    ├─CppUTest
    │      CommandLineArguments.cpp
    │      CommandLineTestRunner.cpp
    │      JUnitTestOutput.cpp
    │      MemoryLeakAllocator.cpp
    │      MemoryLeakDetector.cpp
    │      MemoryLeakWarningPlugin.cpp
    │      SimpleString.cpp
    │      TestFailure.cpp
    │      TestHarness_c.cpp
    │      TestOutput.cpp
    │      TestPlugin.cpp
    │      TestRegistry.cpp
    │      TestResult.cpp
    │      Utest.cpp
    └─Platforms
        └─Iar
                UtestPlatform.cpp

ファイルの追加

分かりやすいようにGroupを追加しておく。プロジェクトを右クリックからコンテキストメニューを開き、Add⇒Add Groupを選ぶ。
image007.png
ここではグループ名を Src とした。OKボタンを押下して確定する。
image009.png
続いて追加したグループを右クリックからコンテキストメニューを開き、Add⇒Add Filesでファイル選択ダイアログを開く。
image011.png
先ほどコピーしたファイルからソースコードを選択して追加する。
image013.png
プラットフォーム固有のソースコードも追加する。
image015.png
バージョンなどの違いによりtolower()関数が定義されているヘッダファイルが異なっているので、プロジェクトのsrc/Platforms/Iar/UtestPlatform.cppを開き、インクルードファイルにctype.hを追加する。

UtestPlatform.cpp
#include <ctype.h>

プロジェクトの設定

プロジェクトを右クリックからoptionを選ぶ。先ずはGeneral Optionsから設定していく。Processor variantはDeviceを選択し、右のボタン押下でコンテキストメニューを開き、ST ⇒ STM32F407 ⇒ ST STM32F407VGと選択する。
image017.png
Output fileは Library を選択する。
image019.png
Use CMSISにチェックを入れる。
image021.png
CategoryでC/C++ Compilerを選び、Languageを C++ 、C++ dialectで C++ を選択する。
image023.png
Enable multibyte supportはチェックマークが外れていることを確認。
image025.png
Optimizationではサイズ制限評価版を使っているので可能な限りコードサイズを小さくするため、Levelを High にして Size 優先を選択しておく。
image027.png
インクルードパスに $PROJ_DIR$\include を通しておく。OKボタンを押下して設定内容を確定する。
image029.png
プロジェクトを右クリックからmakeを起動するとライブラリが生成される。30個くらい警告が出るが今回は無視した。
image031.png

テストケースの作成

IO_Toggleプロジェクトをアクティブに切り替える。
C++でコンパイルするため、プロジェクトに含まれるmain.cをmain.cppに変更する。実際にはRemoveして名前を変更してからAddする。

プロジェクトの設定

コンパイラの指定を C++ に変更する。
image033.png
インクルードパスに $PROJ_DIR$\..\..\..\Test_Framework\CppUTest\include を追加。
image035.png
Linkerの設定でLinker configuration fileをプロジェクトのファイルでオーバーライドして個別設定する。Editボタンを押下してLinker configuration file editorを開く。
image037.png
デフォルトのヒープサイズでは不足するのでここでは 0x2000 確保している。Saveボタンを押下し、configuration fileに書き込む。
image039.png
追加のライブラリに $PROJ_DIR$\..\..\..\Test_Framework\CppUTest\Debug\Exe\CppUTest.a を加える。
image037.png
STM32F4xx_StdPeriph_Driverにある stm32f4xx_usart.c を追加。
image039.png

出力先をシリアルにする

シリアルへの接続この辺りを参考に組み込む。
この辺りにも情報がある。

main.cpp
#include <stdio.h>
#include <CppUTest/CommandLineTestRunner.h>

USART_InitTypeDef USART_InitStructure;

void USART_Configuration(void){
  // sort out clocks
  RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA, ENABLE);
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
  /* Configure USART2 Tx (PA.02) as alternate function push-pull */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  // Map USART2 to A.02
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
  // Initialize USART
  USART_InitStructure.USART_BaudRate = 9600;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity = USART_Parity_No;
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Tx;
  /* Configure USART */
  USART_Init(USART2, &USART_InitStructure);
  /* Enable the USART */
  USART_Cmd(USART2, ENABLE);
}

/**
* @brief Function that printf uses to push characters to serial port
* @param ch: ascii character
* @retval character
*/
int putcharx(int ch)
{
  while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
  USART_SendData(USART2, (uint8_t)ch);
  return ch;
}

int main(void)
{
  USART_Configuration();

  static char *argv[] = { "main" };
  CommandLineTestRunner::RunAllTests(sizeof(argv)/sizeof(*argv), argv);
}

テストケースの記述

プロジェクトにtest.cppを追加し、テストケースを記述する。

test.cpp
#include <CppUTest/TestHarness.h>

int hoge(void)
{
    return 3;
}

int hoge(int a)
{
    return a+1;
}

TEST_GROUP(TestSuiteHoge)
{};

TEST(TestSuiteHoge, TestCaseHoge)
{
    LONGS_EQUAL(3, hoge());
}

TEST(TestSuiteHoge, TestCaseHoge2)
{
    LONGS_EQUAL(3, hoge(2));
}

ビルドと実行

ビルド

プロジェクトのコンテキストメニューからMakeを選んでビルドする。ビルドに成功すればIO_Toggle.outが生成される。

デバッグ実行

USBポートにSTM32F4 DISCOVERYを接続する。初めて接続した場合や、接続するUSBポートを変更した場合はST-Linkドライバのセットアップが必要になる。ST-Linkドライバのセットアップに関してはこの辺りが参考になる。今回のセットアップ環境では C:\Program Files\IAR Systems\Embedded Workbench 6.5\arm\drivers\ST-Link\ST-Link_V2_USBdriver.exe を実行した。
正常にデバイスが使用できるようになったら、IO_Toggleプロジェクトを選択しProject⇒Download and Debug(Ctrl+D)を選択する。自動的にダウンロードされmain関数で一時停止する。
image047.png
テスト結果を表示させるため、View⇒Terminal I/OでTerminal I/Oビューを表示しておく。
image049.png
Debug⇒Go(F5)で実行すると、次のようにTerminal I/Oにテスト結果が表示される。
image053.png

コードサイズ

ちなみに今回の実装でコードサイズは28.5KB程度となった。コードサイズ限定版を使っている場合は、コードサイズが32KB以下にならないとビルドできないようになっているため、残り3.5KB程度となっている。

  29,163 bytes of readonly  code memory
   6,073 bytes of readonly  data memory
  19,136 bytes of readwrite data memory
Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away