RTOSに぀いおの真実。 蚘事19。 セマフォ玹介ず基本サヌビス





セマフォに぀いおは、以前の蚘事5で蚀及されおいたす。 䞻なタスクは、リ゜ヌスぞのアクセスを制埡するこずです。



シリヌズの以前の蚘事

蚘事18。 むベントフラググルヌプヘルパヌサヌビスずデヌタ構造

蚘事17。 むベントフラググルヌプ玹介ず基本サヌビス

蚘事16。 信号

蚘事15。 メモリパヌティションサヌビスずデヌタ構造

蚘事14。 メモリのセクション玹介ず基本サヌビス

蚘事13。 タスクデヌタ構造ずサポヌトされおいないAPI呌び出し

蚘事12。 タスクを操䜜するためのサヌビス

蚘事11。 タスクAPIの構成ず玹介

蚘事10。 スケゞュヌラ高床な機胜ずコンテキストの保存

蚘事9。 スケゞュヌラ実装

蚘事8。 Nucleus SE内郚蚭蚈ず展開

蚘事7。 Nucleus SEはじめに

蚘事6。 その他のRTOSサヌビス

蚘事5。 タスクの盞互䜜甚ず同期

蚘事4。 タスク、コンテキストの切り替え、および割り蟌み

蚘事3。 タスクず蚈画

蚘事2。 RTOS構造ずリアルタむム

蚘事1。 RTOSはじめに。



セマフォの䜿甚



Nucleus SEでは、セマフォはアセンブリ段階で定矩されたす。 アプリケヌションには最倧16個のセマフォを含めるこずができたす。 セマフォが指定されおいない堎合、サヌビス呌び出しずデヌタ構造のコヌドはアプリケヌションに含たれたせん。



セマフォはU8型のカりンタであり、耇数のタスクが䜿甚できるようにアクセスが制埡されたす。 タスクは、セマフォカりンタの倀を枛らすキャプチャか、増やすリリヌスこずができたす。 倀がれロのセマフォをキャプチャしようずするず、遞択したAPI呌び出しパラメヌタずNucleus SEの蚭定によっおは、゚ラヌたたはタスクの䞀時停止が発生する堎合がありたす。



セマフォのセットアップ



セマフォの数



ほずんどのNucleus SEオブゞェクトず同様に、セマフォの蚭定はnuse_config.hの #defineディレクティブによっお決定されたす 。 䞻なパラメヌタヌはNUSE_SEMAPHORE_NUMBERで、アプリケヌション内のセマフォの数を決定したす。 デフォルトでは、パラメヌタヌは0に蚭定されアプリケヌションではセマフォは䜿甚されたせん、最倧16の倀をずるこずができたす。䞍正な倀はコンパむル゚ラヌに぀ながりたす。このモゞュヌルずずもに、その結果、 #errorディレクティブが起動したす。



れロ以倖の倀を遞択するず、セマフォの䞻芁なアクティベヌタずしお機胜したす。 このパラメヌタヌは、デヌタ構造を定矩するずきに䜿甚され、そのサむズはその倀に䟝存したす詳现に぀いおは、この蚘事の詳现を参照しおください。 さらに、れロ以倖の倀はAPI蚭定をアクティブにしたす。



API呌び出しをアクティブにする



Nucleus SEの各API関数ナヌティリティ呌び出しは、 nuse_config.hの #defineディレクティブによっおアクティブにされたす 。 セマフォの堎合、次のものが含たれたす。



NUSE_SEMAPHORE_OBTAIN

NUSE_SEMAPHORE_RELEASE

NUSE_SEMAPHORE_RESET

NUSE_SEMAPHORE_INFORMATION

NUSE_SEMAPHORE_COUNT









デフォルトでは、これらはFALSEに蚭定されおいるため、各サヌビス呌び出しを無効にし、それらを実装するコヌドの組み蟌みをブロックしたす。 セマフォを蚭定するには、必芁なAPI呌び出しを遞択し、察応するディレクティブをTRUEに蚭定する必芁がありたす。



以䞋は、デフォルトのnuse_config.hファむルからの抜粋です。



 #define NUSE_SEMAPHORE_NUMBER 0 /* Number of semaphores in the system - 0-16 */ #define NUSE_SEMAPHORE_OBTAIN FALSE /* Service call enabler */ #define NUSE_SEMAPHORE_RELEASE FALSE /* Service call enabler */ #define NUSE_SEMAPHORE_RESET FALSE /* Service call enabler */ #define NUSE_SEMAPHORE_INFORMATION FALSE /* Service call enabler */ #define NUSE_SEMAPHORE_COUNT FALSE /* Service call enabler */
      
      





アプリケヌションにセマフォがない堎合にアクティブ化されたAPI関数は、コンパむル゚ラヌになりたす垞に有効になっおいるNUSE_Semaphore_Countを陀く。 アクティブ化されおいないAPI呌び出しをコヌドが䜿甚する堎合、実装コヌドがアプリケヌションに含たれおいなかったため、レむアりト゚ラヌが発生したす。



ナヌティリティセマフォ呌び出し



Nucleus RTOSは、次の機胜を提䟛する8぀のサヌビスコヌルをサポヌトしおいたす。





各サヌビスコヌルの実装に぀いおは、以䞋で詳しく説明したす。



セマフォをキャプチャおよびリリヌスするナヌティリティ呌び出し



セマフォで実行できる基本的な操䜜は、キャプチャずリリヌス倀の増枛です。 Nucleus RTOSおよびNucleus SEは、これらの操䜜に察しお2぀の基本的なAPI呌び出しを提䟛したす。



セマフォのキャプチャ



セマフォをキャプチャするためのNucleus RTOSナヌティリティ呌び出しは非垞に柔軟で、珟圚倀がれロのセマフォをキャプチャしようずした堎合など、操䜜を珟時点で実行できない堎合、暗黙的たたは特定のタむムアりトでタスクを䞀時停止できたす。 Nucleus SEは同じ機胜を提䟛したす。タスクの䞀時停止のみがオプションであり、タむムアりトは実装されおいたせん。



Nucleus RTOSでセマフォをキャプチャするための課題

サヌビスコヌルのプロトタむプ

STATUS NU_Obtain_SemaphoreNU_SEMAPHORE *セマフォ、UNSIGNEDサスペンド;



パラメヌタ



セマフォ -ナヌザヌが提䟛するセマフォ制埡ブロックぞのポむンタ。

suspend-タスクの䞀時停止パラメヌタ。倀NU_NO_SUSPENDたたはNU_SUSPENDずタむムアりト倀を取るこずができたす。



戻り倀



NU_SUCCESS-呌び出しは正垞に完了したした。

NU_UNAVAILABLE-セマフォにヌル倀がありたした。

NU_INVALID_SEMAPHORE-セマフォぞの無効なポむンタ。

NU_INVALID_SUSPEND-非タスク関連スレッドから䞀時停止を詊みたす。

NU_SEMAPHORE_WAS_RESET-タスクの䞭断䞭にセマフォがリセットされたした。



Nucleus SEでセマフォをキャプチャするための課題

このAPIコヌルは、Nucleus RTOS APIのコア機胜をサポヌトしおいたす。



サヌビスコヌルのプロトタむプ



STATUS NUSE_Semaphore_ObtainNUSE_SEMAPHOREセマフォ、U8サスペンド;



パラメヌタ



semaphore-䜿甚されおいるセマフォのむンデックスID。

suspend-タスク䞀時停止パラメヌタヌ。NUSE_NO_SUSPENDたたはNUSE_SUSPENDになりたす。



戻り倀



NUSE_SUCCESS-呌び出しは正垞に完了したした。

NUSE_UNAVAILABLE-セマフォにヌル倀がありたした。

NUSE_INVALID_SEMAPHORE-セマフォむンデックスが無効です。

NUSE_INVALID_SUSPEND-非タスク関連スレッドからの䞀時停止の詊行、たたはAPIブロック機胜が無効になっおいる堎合。

NUSE_SEMAPHORE_WAS_RESET-タスクの䞭断䞭にセマフォがリセットされたした。



Nucleus SEでのセマフォキャプチャの実装

機胜コヌドNUSE_Semaphore_Obtain パラメヌタヌの確認埌のバヌゞョンは、ブロック䞀時停止タスクのサポヌトがアクティブかどうかに応じお、条件付きコンパむルを䜿甚しお遞択されたす。 䞡方のオプションを怜蚎しおください。



ロックが有効になっおいない堎合、このAPI呌び出しのロゞックは非垞に簡単です。



 if (NUSE_Semaphore_Counter[semaphore] != 0) /* semaphore available */ { NUSE_Semaphore_Counter[semaphore]--; return_value = NUSE_SUCCESS; } else /* semaphore unavailable */ { return_value = NUSE_UNAVAILABLE; }
      
      





セマフォカりンタの倀がチェックされ、れロに等しくない堎合は枛少したす。



タスクのロックが有効になっおいる堎合、ロゞックはより耇雑になりたす。



 do { if (NUSE_Semaphore_Counter[semaphore] != 0) /* semaphore available */ { NUSE_Semaphore_Counter[semaphore]--; return_value = NUSE_SUCCESS; suspend = NUSE_NO_SUSPEND; } else /* semaphore unavailable */ { if (suspend == NUSE_NO_SUSPEND) { return_value = NUSE_UNAVAILABLE; } else { /* block task */ 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);
      
      





いく぀かの説明が圹立぀堎合がありたす。



コヌドはdo ... whileルヌプに配眮されたす 。このルヌプは、 suspendパラメヌタヌがNUSE_SUSPENDの間に実行されたす。



セマフォにれロ以倖の倀がある堎合、倀は枛少したす。 サスペンド倉数はNUSE_NO_SUSPENDに蚭定され、API呌び出しは終了し、 NUSE_SUCESSを返したす。



セマフォがnullで、 サスペンド倉数がNUSE_NO_SUSPENDに蚭定されおいる堎合、API呌び出しはNUSE_UNAVAILABLEを返したす。 䞀時停止がNUSE_SUSPENDに蚭定されおいる堎合、タスクは䞀時停止したす。 呌び出しが完了した埌タスクの再開時など、戻り倀がNUSE_SUCCESS リセット埌ではなく、セマフォの解攟埌にタスクが再開されたこずを瀺すの堎合、サむクルは最初から始たりたす。



セマフォ解攟



Nucleus RTOS APIを呌び出しおセマフォを解攟するナヌティリティは非垞に簡単です。セマフォカりンタの倀が増加し、成功メッセヌゞが返されたす。 Nucleus SEは同じ機胜を提䟛したすが、远加のオヌバヌフロヌチェックがありたす。



Nucleus RTOSでセマフォを解攟する課題

サヌビスコヌルのプロトタむプ



STATUS NU_Release_SemaphoreNU_SEMAPHORE *セマフォ;



パラメヌタ



semaphore-ナヌザヌが提䟛するセマフォ制埡ブロックぞのポむンタ。



戻り倀



NU_SUCCESS-呌び出しは正垞に完了したした。

NU_INVALID_SEMAPHORE-無効なセマフォポむンタヌ。



Nucleus SEでセマフォを解攟するための課題

このAPIコヌルは、Nucleus RTOS APIのコア機胜をサポヌトしおいたす。



サヌビスコヌルのプロトタむプ



STATUS NUSE_Semaphore_ReleaseNUSE_SEMAPHOREセマフォ;



パラメヌタ



セマフォ -解攟されたセマフォのむンデックスID。



戻り倀



NUSE_SUCCESS-呌び出しは正垞に完了したした。

NUSE_INVALID_SEMAPHORE-セマフォむンデックスが無効です。

NUSE_UNAVAILABLE-セマフォの倀は255であり、増やすこずはできたせん。



Nucleus SEでのセマフォリリヌスの実装

機胜ロックNUSE_Semaphore_Release パラメヌタをチェックした埌は、タスクロックがアクティブになっおいるかどうかに関係なく䞀般的です。 セマフォカりンタの倀がチェックされ、255未満の堎合は増加したす。



API呌び出しのブロックタスクの䞭断のサポヌトが有効になっおいる堎合、条件付きコンパむルを䜿甚しおさらにコヌドが遞択されたす。



 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) { U8 index; /* check whether a task is blocked */ /* on this semaphore */ NUSE_Semaphore_Blocking_Count[semaphore]--; for (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;
      
      





このセマフォでタスクが䞭断されるず、最初のタスクが再開したす。



次の蚘事では、セマフォずそのデヌタ構造に関連する远加のAPI呌び出しに぀いお説明したす。



著者に぀いお Colin Wallsは電子業界で30幎以䞊働いおおり、ほずんどの時間をファヌムりェアに費やしおいたす。 珟圚、Mentor EmbeddedMentor Graphicsの䞀郚門のファヌムりェア゚ンゞニアです。 Colin Wallsは、カンファレンスやセミナヌ、倚くの技術蚘事の著者、ファヌムりェアに関する2冊の本でよく話したす。 英囜に䜏んでいたす。 Colinのプロフェッショナルブログ 、電子メヌルcolin_walls@mentor.com。



All Articles