[メモ] TrampolineRTOSでLチカ (OSEK/VDX & AUTOSAR APIにあわせたRTOS)


Arduinoで、TrampolineというRTOSでblinkのexampleを動かしたときのメモ

> Trampoline is a static RTOS for small embedded systems. Its API is aligned with OSEK/VDX OS and AUTOSAR OS 4.1 standards.

[前記事](http://qiita.com/mt08/items/adc90efbbfc938be7cc4)のERIKA Enterpriseと同様にOSEK/VDXに対応RTOS 

## 環境
- Windows7 64bit
- Arduino互換機: Seeeduino v3.0 
- Arduino Software 1.6.7 (C:\EERT\arduino-1.6.7\ ... [前記事](http://qiita.com/mt08/items/adc90efbbfc938be7cc4)のを流用)
- git, makeが必要 ([前記事](http://qiita.com/mt08/items/adc90efbbfc938be7cc4)のGNUPACKでいけるのでは..)


## 開発環境の準備
0. コマンドプロンプトを開く(`cmd.exe`)
1. trampolineのソース取得
  - `git clone https://github.com/TrampolineRTOS/trampoline.git`<br>
  => 今回は、Commit: [289d197]を取得
2. コンパイル済みgoilというOILコンパイラを取得
  - https://github.com/TrampolineRTOS/trampoline の下のほうにリンクあり<br>
=> Windows: [goil-windows.zip](https://dl.dropboxusercontent.com/u/67740546/goil/goil-windows.zip)
  - zipから、"goil.exe"を解凍してパスの通ったところにおく。

    ```shell-session:Version確認
% goil.exe --version --no-dialog
goil.exe : 2.1.27, build with GALGAS 3.1.4
No warning, no error.
```

3. `avr-gcc`へのPATHを通す
 `set PATH=C:\EERT\arduino-1.6.7\hardware\tools\avr\bin;%PATH%`

```shell-session
% set PATH=C:\EERT\arduino-1.6.7\hardware\tools\avr\bin;%PATH%

% avr-gcc -v
Using built-in specs.
COLLECT_GCC=avr-gcc
COLLECT_LTO_WRAPPER=c:/eert/arduino-1.6.7/hardware/tools/avr/bin/../libexec/gcc/
avr/4.8.1/lto-wrapper.exe
Target: avr
Configured with: ../gcc-4.8.1/configure --enable-fixed-point --enable-languages= c,c++ --prefix=/c/jenkins/workspace/toolchain-avr-windows/objdir --enable-long-l ong --disable-nls --disable-checking --disable-libssp --disable-libada --disable -shared --enable-lto --with-avrlibc=yes --with-dwarf2 --disable-doc --target=avr

Thread model: single
gcc version 4.8.1 (GCC)

```

## ビルド 

1. example - blinkのフォルダへ移動して
  - `cd C:\EERT\trampoline\examples\avr\arduinoUno\blink`
2. `runGoil.bat` をしてみる

    ```shell-session:runGoil.bat
C:\EERT\trampoline\examples\avr\arduinoUno\blink>runGoil.bat
C:\EERT\trampoline\examples\avr\arduinoUno\blink>goil --target=avr/arduino --tem
plates=../../../../goil/templates/ blink.oil
/C/EERT/trampoline/goil/templates/root.goilTemplate:1:1:
2.1.26%
^
semantic error #1:
  The version of Trampoline does not correspond to the version of goil
    Version of Trampoline: 2.1.26
    Version of goil      : 2.1.27
Created '/C/EERT/trampoline/examples/avr/arduinoUno/blink/build/blink.oil.dep'.
No warning, 1 error.
```
  - と、このようにおこられる。(Versionがあわない？)

3. `C:\EERT\trampoline\goil\templates\root.goilTemplate`の一行目の修正する
  - `2.1.26%` => `2.1.27%`

    ```diff:root.goilTemplate
C:\EERT\trampoline\examples\avr\arduinoUno\blink>git diff
diff --git a/goil/templates/root.goilTemplate b/goil/templates/root.goilTemplate
index ec3b88c..607b596 100644
--- a/goil/templates/root.goilTemplate
+++ b/goil/templates/root.goilTemplate
@@ -1,4 +1,4 @@
-2.1.26%
+2.1.27%
 # @file root.goilTemplate
 #
 # @section desc File description
```

4. 再度、`runGoil.bat`

    ```shell-session:runGoil.bat
C:\EERT\trampoline\examples\avr\arduinoUno\blink>runGoil.bat
C:\EERT\trampoline\examples\avr\arduinoUno\blink>goil --target=avr/arduino --tem
plates=../../../../goil/templates/ blink.oil
Created 'blink/tpl_dispatch_table.c'.
Created 'blink/tpl_invoque.S'.
Created 'blink/tpl_invoque_isr.S'.
Created 'blink/tpl_os.h'.
Created 'blink/tpl_service_ids.h'.
Created 'Makefile'.
Created 'blink/tpl_app_custom_types.h'.
Created 'blink/tpl_app_config.c'.
Created 'blink/tpl_app_config.h'.
Created 'blink/tpl_ioc_api_config.c'.
Created 'blink/tpl_ioc_api_config.h'.
Created 'blink/tpl_app_define.h'.
Created 'blink/stm_structure.c'.
Replaced '/C/EERT/trampoline/examples/avr/arduinoUno/blink/build/blink.oil.dep'.
No warning, no error.
```
  - => うまくいった

5. `make`する

    ```shell-session
% make
...
> make
compiling blink.cpp
avr-gcc -MD -MF build/blink.cpp.dep -Wall -Os -g -DF_CPU=16000000 -mmcu=atmega328p -I/usr/local/CrossPack-AVR/avr/include/ -I../../../../machines/avr/arduino//hardware/variants/standard -I../../../../machines/avr/arduino//hardware/cores/arduino -I../../../../machines/avr/arduino//hardware/libraries/EEPROM -I../../../../machines/avr/arduino//hardware/libraries/SoftwareSerial -I../../../../machines/avr/arduino//hardware/libraries/SPI -I../../../../machines/avr/arduino//hardware/libraries/Wire -I../../../../machines/avr -I../../../../machines/avr/arduino -Iblink -I../../../../os -I../../../../com -I../../../../ioc -I../../../../debug -c blink.cpp -o build/blink.cpp.o
...
...
...
generate hex file trampuinoBlink.hex
avr-objcopy -R .eeprom -O ihex trampuinoBlink trampuinoBlink.hex
```
=> `trampuinoBlink.hex`が生成される


## 書き込み・実演
生成された`arduino.hex`を`avrdude`を使って書き込む。
- 書き込み

```shell-session:コマンドラインで
% avrdude.exe -CC:\EERT\arduino-1.6.7\hardware\tools\avr\etc\avrdude.conf -v -patmega328p -carduino -PCOM7 -b57600 -D -Uflash:w:trampuinoBlink.hex:i
```
- `-PCOM7` ってとこは、Arduinoを接続して、認識されたCOMポート番号。(Device Managerとかで確認する)
- 書き込み後、自動でスタートして、LEDが約１秒ごとにON/OFFする。
- `avrdude.exe: writing flash (23514 bytes):` ちとサイズでかい？


## ソースコード

- OIL(OSEK Implementation Language)というファイルでアプリケーションの設定(コンフィギュレーション)を行い、`goil`という、システムジェネレータ（SG)を使用して、C言語のソースファイルを出力する。
- OILファイルを変更したら、`goil`を実行しないといけない。
- blinkサンプルでは、`ALARM`を使用して、`SystemCounter`を`COUNTER`とし、1000カウント毎に、`periodicTask`タスクをおこしている(ActivateTask)
- SystemCounterは周期1.024ms
- ALARMTIME = 250, CYCLETIME = 250 とかにすると、はやくなる。

```text:blink.oil
/* Running the following example:
...
 */
OIL_VERSION = "2.5" : "test" ;

CPU test {    
  OS config {
    STATUS = STANDARD;
    ARDUINO = TRUE {
      BOARD = UNO;
      SERIAL = TRUE;
      PORT = "/dev/tty.usbmodem1411";
      AVR_LIBC = "/usr/local/CrossPack-AVR/avr/include/";
    };
    BUILD = TRUE {
      TRAMPOLINE_BASE_PATH = "../../../..";
      APP_NAME = "trampuinoBlink";
      APP_SRC = "blink.cpp";
      COMPILER = "avr-gcc";
      LINKER = "avr-gcc";
      ASSEMBLER = "avr-gcc";
    };
    SYSTEM_CALL = TRUE;
  };

  APPMODE std {};
  
  ALARM periodicAl {
    COUNTER= SystemCounter;
    ACTION = ACTIVATETASK {
      TASK = periodicTask;
    };
    AUTOSTART = TRUE {
      ALARMTIME = 1000; //activated each 1024 ms
      CYCLETIME = 1000; //activated each 1024 ms
      APPMODE = std;
    };
  };

  TASK periodicTask {
    PRIORITY = 20;
    AUTOSTART = FALSE;
    //AUTOSTART = TRUE {APPMODE=std;};
    ACTIVATION = 1;
    SCHEDULE = FULL;
    STACKSIZE = 256;
  };

};
```

```cpp:blink.cpp
// see blink.oil head of file for information about the compilation process.

#include "tpl_os.h"
#include "Arduino.h"

void setup()
{
	// initialize digital pin 13 as an output.
	pinMode(13, OUTPUT);
}

//The TASK is activated by the alarm "periodicAl":
//* The alarm "periodicAl" is configured in the .oil file to activate task 
//"periodicTask" each 1000 pulses of counter SystemCounter.
//* The SystemCounter is the same as the systick used in Arduino, a tick each 1024us on a 16MHz arduino.
//* This task is periodic, with a period of 1024ms.
TASK(periodicTask)
{
	static unsigned int nb = 0;
	nb++;
	if(nb & 1) digitalWrite(13, HIGH); //odd
	else digitalWrite(13, LOW);        //even
}
```