メインコンテンツまでスキップ
Knowledgebase
Home
Renesas Electronics Japan - Knowledgebase

セマフォ(Semaphore)でBlinkyを実行する方法

最終更新日:2017/07/05

Question:

セマフォ(Semaphore)でBlinkyを実行する方法は?

Answer:

このサンプルデザインでは、点滅するLED (Blinking LED) を制御するための、セマフォと2つのスレッドの簡単な使い方について解説します。
このガイドでは、ツールフロー内で共通する複数のアクションについて簡単に説明します。このガイドは、お客様が e2 studioの操作についてある程度ご理解されていることを前提としています。
随時、e2 studioの非スレッド形式のサンプルデザインをご参照ください。そこではすべてのステップを段階的に、より詳細にご説明しています。

このガイドの内容を修得すれば、2つのスレッド間で制御情報をやり取りする簡単なセマフォの実装方法に対する理解が深まります。
これはお客様が、スレッドとセマフォを使用して独自のデザインを作成する際に役立ちます。

デザインに関する説明
本デザインでは、2つのスレッドがセマフォを使用して通信します。1つのスレッドはタイミング関数を受け持ち、1秒に1回共有セマフォを生成します。
もう一方のスレッドはセマフォを待ち、利用可能になったら、LED制御信号を切り換えます。
下記のブロック図で、全体のフローを示します。


初期設定
まずハードウェア内でBlinkyが動作しているかどうか確認するため、Synergy開発ツールとSSPをPCにインストールし、Synergyのターゲットボードを利用できるようにする必要があります。
そうでない場合は、以下に示すSynergy Knowledge BaseのGetting Started Guideへのリンクに従います。

<Getting Started with the Synergy Platform>

プロジェクトを作成する
上記の手順に行えば、Synergyプラットフォームのツールフローが実行され、非スレッドバージョンのBlinkyがターゲットボード上で動作するようになります。
以上で、2つのスレッドとセマフォを使用して、スレッドバージョンに対応する準備が整います。

1.e2 studioを開いて、Synergyプロジェクトを新規作成します(必要に応じて、上記手引きをご参照ください)。
2.ボードをターゲットとして、Thread-Xオプション対応のBSPを選択します。
3.これで新しいBlinkyコードを追加する準備が整いました。

セマフォのBlinkyコードを追加する
この手順では、セマフォバージョンのBlinkyを実装するためのコードを追加します。2つのスレッドにコードを追加します。1つのスレッドはTimerを管理し、もう1つはLEDを管理します。
2つのスレッドは、共有セマフォを使用して通信を行います。

1.ConfigurationウィンドウのThreadsタブを開きます。
2.Newをクリックして、New Threadを立ち上げます。名称をTimer Threadに編集し、シンボルをtimer_threadに編集します。
3.ThreadsウィンドウでTimer Threadを選択し、Timer_Thread Objectsウィンドウの隣にあるNew>を選択します。
Semaphoreを選択し、g_new_semaphoreというセマフォをTimer_Thread Objectsリストに追加します。
4.Threadsウィンドウの隣にあるNewをクリックして別のスレッドを作成し、名称をLED Threadに、シンボル名をled_threadにします。

5.Generate Project Contentボタンを押します。
6.ここで、timer_thread_entry.cおよびled_thread_entry.cというファイルがあるはずです。
7.timer_thread_entry.cを開いて、ファイル内の1行目より下の全てのコード、以下のコードに変更します。

#include"timer_thread.h"
void timer_thread_entry (void)
{
while (1)
{
tx_semaphore_put (&g_new_semaphore);
tx_thread_sleep (100);
}
}
8.ファイルに対して行った変更を保存します。
9.led_thread_entry.c内のコードをファイル内の1行目から以下のコードに変更します。
#include"led_thread.h"
#include"timer_thread.h"
#include<stdio.h>
#include"r_ioport.h"
bsp_leds_t Leds;
void led_thread_entry (void) {
/* Get LED information for this board */
R_BSP_LedsGet(&Leds);
/* If this board has no LEDs then trap here */
if (!Leds.led_count) {
while(1); // There are no LEDs on this board
}
ioport_level_t level = IOPORT_LEVEL_HIGH;
while (1) {
/* Toggle the LED */
tx_semaphore_get (&g_new_semaphore, TX_WAIT_FOREVER);
g_ioport_on_ioport.pinWrite(Leds.p_leds[0], level);
level = !level;
}
}

10.すべてのファイルを保存し、プロジェクトのデバッグコンフィギュレーションをビルドします。これには数分かかる場合があります。
11.デザインは、エラーが発生することなくビルドされます。もしもエラーが発生した場合は、追加したコードを慎重にご確認ください。何らかの文字抜けや追加が生じている可能性があります。
お客様のコードがエラーなくビルドされると、ターゲットボード上でセマフォのBlinkyを実行させることができます。

ボード上でセマフォのBlinkyを実行する
1.以前のサンプルデザインで実行したとおりに、ボードを接続します。
2.デバッガを初期化し、新しいプロジェクトのビルドコンフィギュレーションを選択します。
3.Debugボタンをクリックしてデバッグパースペクティブを立ち上げます。
4.デバッグセッションは、デザイン開始時に停止しますので、Resumeボタンを2回押してボード上での実行を開始します。
5.ここで、LEDが点滅します。デバッグセッションを一時停止または終了するまで点灯1秒と消灯1秒を繰り返します。
6.これで、Synergyを使った初めてのセマフォデザインが完了です。

セマフォBlinkyの仕組み
以前のサンプル(Hal Blinkyなど)でお気づきかも知れませんが、セマフォBlinkyはhal_entry内ではなく、スレッドで動作を開始します。
LEDスレッドとTimerスレッドは、両方ともプログラム実行時に起動します。

Timerスレッドは、LEDを点滅させる遅延処理を制御します。これは共有セマフォを設定して、LEDスレッドがLED信号を切り換えることで制 御します。このとき、tx_semaphore_put関数はセマフォ変数を使いますが、このセマフォ変数は、コンフィギュレーション中にセマフォを Timerスレッドに追加したときに作成されます(g_new_semaphoreは、セマフォのデフォルト名です。セマフォは、 timer_thread.c内で定義されて作成されます。セマフォの詳しい使い方については、Synergy Knowledge Base内のセマフォに関するFAQをご参照ください)。

セマフォを「put」すると、Timerスレッドが100「チック」(1チックは10msのため、1秒間)待機します。
Whileループが実行され続けるため、1秒ごとに「put」が配置されます。

LEDスレッドはBSP関数R_BSP_LedsGetを使用し、ボード上で利用可能なLEDを最初に見つけると開始されます。
LEDを利用できない場合は、プログラムがトラップされた状態になります。LEDが利用可能であれば、LED制御信号のレベルを”High”に設定してWhileループに入ることで、実行(execution)を継続します。
Whileループ内でtx_semaphore_get関数は、セマフォが利用可能(これがget関数が実行する処理)になるまで待機していますが、このときtx_semaphore_get関数はTimerスレッドルーチンで使用したときと同じ変数を使用します。

TX_WAIT_ FOREVERは、セマフォが利用可能になるまで関数を待機させ、「タイムアウト」にならないように指示します。
一度セマフォが取得されると(Timerスレッドが1秒ごとにセマフォを作成することにご留意ください)、g_ioport_on_ioport.pinWrite関数を使ってLED制御信号に書き込みが行われます。
次いで、Whileループの次回実行時に、LED駆動信号を「flip(反転)」させるようにレベルが切り換えられます。

本サンプルデザインで使用したセマフォは、別々のスレッド間で通信を行うためのスレッド形式のアプリケーションで頻繁に使用されます。
セマフォは、整数値を取ることができるため(通常32ビット)、マルチスレッド間で共有されるリソース(待ち行列メモリブロックやペリフェラルチャネルなど)をカウントすることができます。
また、本サンプルで示したとおり、単純な通信機構として使用することもできます。

以上で、このサンプルデザインは終了です。

適用製品

Renesas Synergy™ プラットフォーム
Renesas Synergy™ ソフトウェア