工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Industrial Internet of Things >> 埋め込み

Nucleus SEのセマフォ:概要、設定、API要点

Nucleus SEのセマフォ:概要、設定、API要点
RTOS Revealedシリーズを表示

セマフォは組み込みシステムにおける共有リソースへのアクセス同期のための基礎的メカニズムです。タスクが競合なくリソースの制御を安全に取得・解放できるようにします。

セマフォの使用

Nucleus SEでは、セマフォサポートはビルドプロセスで有効化されます。単一アプリケーションで最大16個のセマフォを設定可能。セマフォを使用しない場合、関連データ構造とAPIコードは最終バイナリから除外され、フットプリントを削減できます。

セマフォは単純に、複数タスクが安全に操作できるよう保護された8ビットカウンタです。タスクはObtainを呼んでカウンタをデクリメントし、Releaseでインクリメントします。カウンタがゼロのセマフォを取得しようとした場合、APIオプションとシステム設定に応じて、エラーを返すか、セマフォが利用可能になるまでタスクをサスペンドします。

セマフォの設定

セマフォ数

セマフォはnuse_config.h内の#define文で定義されます。鍵となるマクロはNUSE_SEMAPHORE_NUMBERで、アプリケーションが使用するセマフォスロット数を指定します。デフォルト値は0で、セマフォサポートなしを意味します。有効値は0~16。無効値はnuse_config_check.h(nuse_config.c経由でインクルード)によりコンパイル時#errorをトリガーします。

NUSE_SEMAPHORE_NUMBERを非ゼロに設定すると、セマフォサブシステムが活性化:データ構造が適切にサイズ設定され、API有効化シンボルが処理されます。

API有効化

各Nucleus SE API呼び出しは、nuse_config.hの専用有効化マクロでガードされます。セマフォ関連のシンボルは:

デフォルトではすべてFALSEで、対応するサービスコールを無効化し、実装をビルドから除外します。特定のAPIを有効にするには、そのマクロをTRUEに設定します。

デフォルトnuse_config.hからの抜粋:

#define NUSE_SEMAPHORE_NUMBER 0 /* システム内のセマフォ数 – 0-16 */ #define NUSE_SEMAPHORE_OBTAIN FALSE /* サービスコール有効化 */ #define NUSE_SEMAPHORE_RELEASE FALSE /* サービスコール有効化 */ #define NUSE_SEMAPHORE_RESET FALSE /* サービスコール有効化 */ #define NUSE_SEMAPHORE_INFORMATION FALSE /* サービスコール有効化 */ #define NUSE_SEMAPHORE_COUNT FALSE /* サービスコール有効化 */

セマフォを設定せずにAPIを有効化すると(NUSE_Semaphore_Count()は常に利用可能)、コンパイルエラーになります。有効化されていないAPIを呼び出すと、実装が省略されているためリンクエラーが発生します。

セマフォサービスコール

Nucleus SEには8つのセマフォ関連サービスコールがあります。最初の5つが完全実装され、残り3つは将来の拡張用プレースホルダーです。

ObtainとRelease操作

セマフォの核心操作は、Obtain(デクリメント)とRelease(インクリメント)です。Nucleus RTOSはオプションのサスペンドとタイムアウト付きの柔軟なObtain APIを提供します。Nucleus SEはこの振る舞いを模倣しますが、タスクサスペンドはオプションでタイムアウトは非サポート。

Nucleus RTOS Obtain API

プロトタイプ:

STATUS NU_Obtain_Semaphore(NU_SEMAPHORE *semaphore, UNSIGNED suspend);

パラメータ:

semaphore – セマフォ制御ブロックへのポインタ。

suspend – NU_NO_SUSPEND、NU_SUSPEND、またはタイムアウト値。

戻り値:

NU_SUCCESS – 操作成功。

NU_UNAVAILABLE – セマフォ値がゼロ。

NU_INVALID_SEMAPHORE – 無効なセマフォポインタ。

NU_INVALID_SUSPEND – 非タスクコンテキストからのサスペンド試行。

NU_SEMAPHORE_WAS_RESET – タスクサスペンド中にセマフォリセット。

Nucleus SE Obtain API

プロトタイプ:

STATUS NUSE_Semaphore_Obtain(NUSE_SEMAPHORE semaphore, U8 suspend);

パラメータ:

semaphore – セマフォインデックス。

suspend – NUSE_NO_SUSPENDまたはNUSE_SUSPEND。

戻り値:

NUSE_SUCCESS – 操作成功。

NUSE_UNAVAILABLE – セマフォ値がゼロ。

NUSE_INVALID_SEMAPHORE – 無効なセマフォインデックス。

NUSE_INVALID_SUSPEND – 非タスクからのサスペンド試行、またはブロッキングAPI無効。

NUSE_SEMAPHORE_WAS_RESET – サスペンド中にセマフォリセット。

実装のハイライト

ブロッキング無効時、実装はカウンタが非ゼロかチェックし、デクリメントしてNUSE_SUCCESSを返します。ゼロならNUSE_UNAVAILABLEを返します。

if (NUSE_Semaphore_Counter[semaphore] != 0) { NUSE_Semaphore_Counter[semaphore]--; return_value = NUSE_SUCCESS; } else { return_value = NUSE_UNAVAILABLE; }
ブロッキング有効時、ルーチンはdo…whileループに入り、セマフォ取得を試みます。カウンタがゼロでsuspendがNUSE_SUSPENDならタスクをブロック。解放時に最初の待機タスクがウェイクアップし、ループが取得をリトライします。
do { if (NUSE_Semaphore_Counter[semaphore] != 0) { NUSE_Semaphore_Counter[semaphore]--; return_value = NUSE_SUCCESS; suspend = NUSE_NO_SUSPEND; } else { if (suspend == NUSE_NO_SUSPEND) { return_value = NUSE_UNAVAILABLE; } else { NUSE_Semaphore_Blocking_Count[semaphore]++; NUSE_Suspend_Task(NUSE_Task_Active, semaphore << 4 | NUSE_SEMAPHORE_SUSPEND); return_value = NUSE_Task_Blocking_Return[NUSE_Task_Active]; if (return_value != NUSE_SUCCESS) { suspend = NUSE_NO_SUSPEND; } } } } while (suspend == NUSE_SUSPEND);

Nucleus RTOS Release API

プロトタイプ:

STATUS NU_Release_Semaphore(NU_SEMAPHORE *semaphore);

パラメータ:

semaphore – セマフォ制御ブロックへのポインタ。

戻り値:

NU_SUCCESS – 操作成功。

NU_INVALID_SEMAPHORE – 無効なセマフォポインタ。

Nucleus SE Release API

プロトタイプ:

STATUS NUSE_Semaphore_Release(NUSE_SEMAPHORE semaphore);

パラメータ:

semaphore – セマフォインデックス。

戻り値:

NUSE_SUCCESS – 操作成功。

NUSE_INVALID_SEMAPHORE – 無効なセマフォインデックス。

NUSE_UNAVAILABLE – カウンタが既に255;インクリメント不可。

実装のハイライト

リリースルーチンはまずカウンタが最大値(255)未満かチェック。そうならインクリメント。ブロッキング有効でこのセマフォで待機タスクがいれば、最初の1つをウェイクアップ。

NUSE_CS_Enter(); if (NUSE_Semaphore_Counter[semaphore] < 255) { NUSE_Semaphore_Counter[semaphore]++; return_value = NUSE_SUCCESS; #if NUSE_BLOCKING_ENABLE if (NUSE_Semaphore_Blocking_Count[semaphore] != 0) { NUSE_Semaphore_Blocking_Count[semaphore]--; for (U8 index = 0; index < NUSE_TASK_NUMBER; index++) { if ((LONIB(NUSE_Task_Status[index]) == NUSE_SEMAPHORE_SUSPEND) && (HINIB(NUSE_Task_Status[index]) == semaphore)) { NUSE_Task_Blocking_Return[index] = NUSE_SUCCESS; NUSE_Wake_Task(index); break; } } } #endif } else { return_value = NUSE_UNAVAILABLE; } NUSE_CS_Exit(); return return_value;

タスクがセマフォでサスペンドされている場合、リリースすると最初の待機タスクがウェイクアップし、実行を継続できます。

次の記事ではイベントフラググループとその関連データ構造を探ります。


Colin Wallsは電子業界で30年以上の経験を持ち、主に組み込みソフトウェアに注力。会議で頻繁に講演し、技術記事を執筆し、組み込みソフトウェアに関する2冊の著書がある。Mentor Embedded(Mentor Graphics組み込みソフトウェア部門)の組み込みソフトウェアテクノロジストで、英国在住。ブログはhttps://blogs.mentor.com/colinwalls。メールはcolin_walls@mentor.com。

埋め込み

  1. UCAS、インフォシスとの契約を3年延長し自動化を推進
  2. カムロック完全解説:キャビネットを目立たず確実に施錠する仕組み
  3. アイボルト(アイスクリュー)とは:設計と用途のプロフェッショナルガイド
  4. ステンレス鋼解説:組成・製造プロセス・グローバルインパクト
  5. 自動車サービスライター(フロント受付)の役割、業務、キャリアパス
  6. Nucleus SEのメールボックス:設定と使用の実践ガイド
  7. Nucleus RTOSのセマフォ:ユーティリティサービスとデータ構造
  8. イベントフラググループの習得:Nucleus RTOS/SEのユーティリティサービスとデータ構造
  9. Nucleus SEのイベントフラググループ:設定とAPI使用の入門ガイド
  10. Nucleus SEのキュー:導入とコアサービスコール
  11. C# 入出力の基礎:ユーザー入力と出力の基本をマスター