メインコンテンツに移動

GR-PEACH 特設:TOPPERS/ASPでマルチタスク!

概要

オープンソースのリアルタイムOSとしてTOPPERS/ASPをGR-PEACHで動かすことができます。Webコンパイラでの使い方をご紹介します。 

こちらのgithub wikiにサンプルプログラムの説明がありますので、合わせて参照してください。


準備

GR-PEACH、USBケーブル(マイクロBタイプ)の2つを準備します。

gr-peach-full-board
usb-cable

サンプル実行までの手順

プロジェクト作成

WebコンパイラにTOPPERS/ASP用のプロジェクトテンプレートがありますので、それを利用してプロジェクトを作成します。Webコンパイラが初めての方は「Webコンパイラでスケッチ」を参照してください。

テンプレートの「GR-PEACH_TOPPERS_ASP_***.zip」(xxxは任意のバージョン)を選択し、適当にプロジェクト名を付けてプロジェクト作成ボタンを押します。

GR-PEACH TOPPERSプロジェクトの作成

スケッチの表示

デフォルトの状態ではプロジェクトにあるサンプル「examples/blinky」がビルドされるようになっています。blinkyフォルダにblinky.cppがありますので、ダブルクリックしてファイルを開いてみましょう。

peach-sp-toppers-example

ビルドから書き込み

ビルドボタンを押してください。初回のビルドは全てのソースをコンパイルするため30秒ほど時間がかかります。

ビルドが終了すると、プロジェクトツリーにblinky.binが生成されますので、ダウンロードしてGR-PEACHに書き込んでください。赤、緑、青、ユーザーLEDがそれぞれ定めれた時間ごとに点滅を繰り返します。

GR-PEACH TOPPERSビルド実行

マルチタスクなArduinoスケッチ

Arduinoでは基本的に1回のsetup関数と繰り返し実行されるloop関数からなりますが、loop関数の中で並列に行いたい処理をプログラミングするのは困難です。

TOPPERS/ASPによるスケジューラにより、複数のloop関数を並列で動かすサンプルがありますので試してみましょう。

ビルドプロジェクトの切り替え

ビルドするプロジェクトの切り替えをします。プロジェクトツリーにある「build_target」を開いてください。デフォルトでは「./examples/blinky」が記載されています。

peach-sp-toppers-buildswitch-target

「./examples/multitask_arduino」に書き換えてください。

peach-sp-toppers-buildswitch

スケッチの表示

プロジェクトツリーのexamples/multitask_arduinoフォルダにあるmultitask_arduino.cppを開いてみてください。loop, loop1, loop2の3つのloop関数があることが分かります。

peach-sp-toppers-multitask

ビルドから書き込み

ビルド実行するとmultitask_arduino.binが生成されますので、GR-PEACHに書き込んでみてください。loopが赤LED、loop1が緑LED、loop2が青LEDをそれぞれ点滅させています。

loopの追加

loopを追加するには、examples/multitask_arduinoフォルダにある「arduino_app.h」にあるマクロ「ADDITIONAL_LOOP_NUM」の値を増やします。例えば数値を5にした場合、loop3, loop4, loop5が追加できます。

peach-sp-toppers-multi-arduino

温湿度計測サンプル

参考として、以下のプログラムは温湿度センサーHDC1000のシリアル出力、LED制御を独立して行う例です。動作するにはHDC1000のSCL/SDAをWireのピン、RDYをピン2につなげる必要があります。


#include <kernel.h>
#include <t_syslog.h>
#include <t_stdlib.h>
#include "syssvc/serial.h"
#include "syssvc/syslog.h"
#include "kernel_cfg.h"
 
#include "arduino_app.h"
#include "arduino_main.h"
 
#include <Arduino.h>
#include <Wire.h>
  
#define HDC1000_ADDRESS 0x40
#define HDC1000_RDY_PIN 2
   
#define HDC1000_TEMPERATURE_POINTER     0x00
#define HDC1000_HUMIDITY_POINTER        0x01
#define HDC1000_CONFIGURATION_POINTER   0x02
#define HDC1000_SERIAL_ID1_POINTER      0xfb
#define HDC1000_SERIAL_ID2_POINTER      0xfc
#define HDC1000_SERIAL_ID3_POINTER      0xfd
#define HDC1000_MANUFACTURER_ID_POINTER 0xfe
  
#define HDC1000_CONFIGURE_MSB 0x10 /* Get both temperature and humidity */
#define HDC1000_CONFIGURE_LSB 0x00 /* 14 bit resolution */
  
void getTemperatureAndHumidity(float *temperature, float *humidity) {
  unsigned int tData, hData;
   
  Wire.beginTransmission(HDC1000_ADDRESS);
  Wire.write(HDC1000_TEMPERATURE_POINTER);
  Wire.endTransmission();
  while (digitalRead(HDC1000_RDY_PIN) == HIGH);
  Wire.requestFrom(HDC1000_ADDRESS, 4);
  while (Wire.available() < 4);
   
  tData = Wire.read() << 8;
  tData |= Wire.read();
   
  hData = Wire.read() << 8;
  hData |= Wire.read();
   
  *temperature = tData / 65536.0 * 165.0 - 40.0;
  *humidity = hData / 65536.0 * 100.0;
}
  
#define INTERVAL       100
#define INTERVAL_RED   100
#define INTERVAL_BLUE  150
#define INTERVAL_GREEN 200
 
void setup()
{
    pinMode(PIN_LED_RED   , OUTPUT);
    pinMode(PIN_LED_GREEN , OUTPUT);
    pinMode(PIN_LED_BLUE  , OUTPUT);
    pinMode(PIN_LED_USER  , OUTPUT);
      pinMode(PIN_SW        , INPUT);
    pinMode(HDC1000_RDY_PIN, INPUT);
    
    Serial.begin(9600);
  //Put the HDC1000 IC into the correct operating mode
    Wire.beginTransmission(HDC1000_ADDRESS);
    Wire.write(HDC1000_CONFIGURATION_POINTER);
    Wire.write(HDC1000_CONFIGURE_MSB);
    Wire.write(HDC1000_CONFIGURE_LSB);
    Wire.endTransmission();
}
 
void loop(){
  float temperature, humidity;
   
  getTemperatureAndHumidity(&temperature, &humidity);
  Serial.print("Temperature = ");
  Serial.print(temperature);
  Serial.print(" degree, Humidity = ");
  Serial.print(humidity);
  Serial.println("%");
  Serial.flush();
   
  delay(1000);
}
 
void loop1()
{
    while(digitalRead(PIN_SW) == 0){
        digitalWrite(PIN_LED_USER, 1);
        delay(INTERVAL);
        digitalWrite(PIN_LED_USER, 0);
        delay(INTERVAL);
    }
}
 
void loop2(){
    digitalWrite(PIN_LED_BLUE, 1);
    delay(INTERVAL_BLUE);
      digitalWrite(PIN_LED_BLUE, 0);
      delay(INTERVAL_BLUE);
}
 
/*
 *  Cyclic Handler
 * 
 *  This handler is called every 10 [ms] as specified in
 *  multitask_arduino.cfg.
 */
void cyclic_handler(intptr_t exinf) {
    irot_rdq(LOOP_PRI); /* change the running loop. */
}