RTOSに぀いおの真実。 蚘事20。 セマフォ補助サヌビスずデヌタ構造



この蚘事では、セマフォのレビュヌを続けおいたす。

ヘルパヌセマフォサヌビス


Nucleus RTOSには、セマフォ関連の機胜を提䟛する4぀のAPIコヌルがありたす。セマフォのリセット、セマフォ情報の取埗、アプリケヌション内のセマフォの数の取埗、アプリケヌション内のすべおのセマフォぞのポむンタの取埗です。 それらの最初の3぀はNucleus SEで実装されおいたす。

シリヌズの以前の蚘事
蚘事19。 セマフォ玹介ず基本サヌビス
蚘事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はじめに。

セマフォをリセットする


このAPI呌び出しは、セマフォを初期の未䜿甚状態にリセットしたす。 このAPI関数は、リセットを実行するずいう事実にもかかわらず、カりンタヌを初期倀に蚭定するだけでなく、新しい初期カりンタヌ倀が呌び出しで枡されるため、他のカヌネルオブゞェクトの関数ず比范するず異垞です。 セマフォで䞭断されたタスクはすべお再開され、Nucleus SEおよびNucleus RTOSのNU_SEMAPHORE_RESETでNUSE_SEMAPHORE_WAS_RESETコヌドが返されたす。

Nucleus RTOSでセマフォをリセットするための呌び出し

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

STATUS NU_Reset_SemaphoreNU_SEMAPHORE *セマフォ、未眲名initial_count;

パラメヌタ

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

戻り倀

NU_SUCCESS-呌び出しは正垞に完了したした。
NU_INVALID_SEMAPHORE-無効なセマフォポむンタヌ。

Nucleus SEでセマフォをリセットするための呌び出し
このAPIコヌルは、Nucleus RTOS APIのコア機胜をサポヌトしおいたす。

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

STATUS NUSE_Semaphore_ResetNUSE_SEMAPHOREセマフォ、U8 initial_count;

パラメヌタ

semaphore-ダンプされたセマフォのむンデックスID。
initial_count-セマフォが蚭定される倀。

戻り倀

NUSE_SUCCESS-呌び出しは正垞に完了したした。
NUSE_INVALID_SEMAPHORE-無効なセマフォむンデックス。

Nucleus SEでセマフォリセットを実装する

NUSE_Semaphore_Reset API関数の䞻なタスクは、察応するNUSE_Semaphore_Counter []芁玠を指定された倀に蚭定するこずですパラメヌタヌを確認した埌。

タスクのロックが有効になっおいる堎合、タスクのロックを解陀するには次のコヌドが必芁です。

while (NUSE_Semaphore_Blocking_Count[semaphore] != 0) { U8 index; /* check whether any tasks are blocked */ /* on this 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_SEMAPHORE_WAS_RESET; NUSE_Task_Status[index] = NUSE_READY; break; } } NUSE_Semaphore_Blocking_Count[semaphore]--; } #if NUSE_SCHEDULER_TYPE == NUSE_PRIORITY_SCHEDULER NUSE_Reschedule(NUSE_NO_TASK); #endif 

セマフォで䞭断された各タスクは「終了」ずマヌクされ、タスク䞭断コヌドはNUSE_SEMAPHORE_WAS_RESETを返したす。 このプロセスが完了した埌、Priorityスケゞュヌラが䜿甚されおいる堎合、コヌルはNUSE_Rescheduleを初期化したす。優先床の高い1぀以䞊のタスクが準備完了状態になり、再開を埅機する可胜性があるためです。

セマフォ情報


このナヌティリティ呌び出しはセマフォ情報を返したす。 Nucleus SEでのこの呌び出しの実装は、オブゞェクトの呜名ず䞀時停止順序がサポヌトされおおらず、タスクの䞭断自䜓を無効にできるため、返される情報が少ないずいう点でNucleus RTOSず異なりたす。

Nucleus RTOSでのセマフォ情報の呌び出し

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

STATUS NU_Semaphore_InformationNU_SEMAPHORE *セマフォ、CHAR *名前、UNSIGNED * current_count、OPTION * suspend_type、UNSIGNED * tasks_waiting、NU_TASK ** first_task;

パラメヌタ

セマフォ -情報が必芁なセマフォ制埡ブロックぞのポむンタ。
name-セマフォの8文字の名前ぞのポむンタ。この領域にはヌル終了バむトが含たれたす。
current_count-セマフォカりンタの珟圚の倀を取埗する倉数ぞのポむンタ。
suspend_type-䞭断タスクのタむプを受け入れる倉数ぞのポむンタヌ。倀NU_FIFOおよびNU_PRIORITYを取るこずができたす。
task_waiting-セマフォ内の䞭断されたタスクの数を取る倉数ぞのポむンタ。
first_task - NU_TASK型の倉数ぞのポむンタヌ。これは、最初に䞭断されたタスクの制埡ナニットぞのポむンタヌを取りたす。

戻り倀

NU_SUCCESS-呌び出しは正垞に完了したした。
NU_INVALID_SEMAPHORE-無効なセマフォポむンタヌ。

Nucleus SEでのセマフォ情報の呌び出し
このAPIコヌルは、Nucleus RTOS APIのコア機胜をサポヌトしおいたす。

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

STATUS NUSE_Semaphore_InformationNUSE_SEMAPHOREセマフォ、U8 * current_count、U8 * tasks_waiting、NUSE_TASK * first_task;

パラメヌタ

セマフォ -情報を提䟛するために必芁なセマフォのむンデックス。
current_count-セマフォカりンタの珟圚の倀を取埗する倉数ぞのポむンタ。
tasks_waiting-このセマフォで䞭断されたタスクの数を受け入れる倉数ぞのポむンタタスクの䞭断のサポヌトが無効になっおいる堎合、䜕も返されたせん。
first_task - NUSE_TASK型の倉数ぞのポむンタヌ。最初の䞀時停止タスクのむンデックスを取埗したす䞀時停止タスクのサポヌトが無効になっおいる堎合は䜕も返されたせん。

戻り倀

NUSE_SUCCESS-呌び出しは正垞に完了したした。
NUSE_INVALID_SEMAPHORE-セマフォむンデックスが無効です。
NUSE_INVALID_POINTER -1぀以䞊のポむンタヌパラメヌタヌが正しくありたせん。

Nucleus SEでのセマフォ情報の実装

このAPI呌び出しの実装は非垞に簡単です。

 NUSE_CS_Enter(); *current_count = NUSE_Semaphore_Counter[semaphore]; #if NUSE_BLOCKING_ENABLE *tasks_waiting = NUSE_Semaphore_Blocking_Count[semaphore]; if (NUSE_Semaphore_Blocking_Count[semaphore] != 0) { U8 index; for (index=0; index<NUSE_TASK_NUMBER; index++) { if ((LONIB(NUSE_Task_Status[index]) == NUSE_SEMAPHORE_SUSPEND) && (HINIB(NUSE_Task_Status[index]) == semaphore)) { *first_task = index; break; } } } else { *first_task = 0; } #else *tasks_waiting = 0; *first_task = 0; #endif NUSE_CS_Exit(); return NUSE_SUCCESS; 

関数はセマフォのステヌタスを返したす。 次に、APIコヌルブロッキング機胜がアクティブになっおいる堎合、保留䞭のタスクの数ず最初のタスクのむンデックスが返されたすそうでない堎合、これらのパラメヌタヌは0に蚭定されたす。

セマフォの数を取埗する


このナヌティリティ呌び出しは、アプリケヌション内のセマフォの数を返したす。 Nucleus RTOSでは、この倀は時間ずずもに倉化し、戻り倀は珟圚のセマフォの数に察応したす。NucleusSEでは、戻り倀はアセンブリ段階で蚭定され、倉曎されたせん。

Nucleus RTOSでセマフォカりンタヌを呌び出す

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

UNSIGNED NU_Established_SemaphoresVOID;

パラメヌタ
欠垭しおいたす。

戻り倀
アプリケヌションで䜜成されたセマフォの数。

Nucleus SEでセマフォカりンタヌを呌び出す
このAPIコヌルは、Nucleus RTOS APIのコア機胜をサポヌトしおいたす。

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

U8 NUSE_Semaphore_Countvoid;

パラメヌタ
欠垭しおいたす。

戻り倀
アプリケヌションで構成されおいるセマフォの数。

Nucleus SEでのセマフォカりンタの実装
このAPI呌び出しの実装は非垞に簡単です。 #define NUSE_SEMAPHORE_NUMBERシンボルの倀が返されたす。

デヌタ構造


セマフォは、2぀たたは3぀のデヌタ構造の配列RAMおよびROMを䜿甚したす。これは、他のすべおのNucleus SEオブゞェクトず同様に、サむズがアプリケヌションのセマフォの数ず遞択したパラメヌタに䟝存するテヌブルのセットです。

アプリケヌションコヌドはこれらのデヌタ構造ぞの盎接アクセスを䜿甚せず、提䟛されたAPI関数を介しおそれらを参照するこずを匷くお勧めしたす。 これにより、Nucleus SEの将来のバヌゞョンずの非互換性および䞍芁な副䜜甚を回避し、Nucleus RTOSぞのアプリケヌションの移怍を簡玠化したす。 サヌビス呌び出しコヌドの仕組みを理解し、デバッグするために、デヌタ構造の詳现な抂芁を以䞋に瀺したす。

RAMデヌタ


このデヌタの構造は次のずおりです。
NUSE_Semaphore_Counter [] -構成されたセマフォごずに1぀の゚ントリを持぀タむプU8の配列。カりンタヌの倀を栌玍したす。
NUSE_Semaphore_Blocking_Count []-U8型の配列には、各セマフォでブロックされたタスクのカりンタヌが含たれたす。 この配列は、API呌び出しのブロック機胜が有効になっおいる堎合にのみ存圚したす。
NUSE_Semaphore_Counter []は初期倀に初期化され以䞋の「ROMのデヌタ」を参照、 NUSE_Semaphore_Blocking_Count []は Nucleus SEの起動時にNUSE_Init_Semaphoreを䜿甚しおリセットされたす。 次の蚘事のいずれかで、Nucleus SEの起動手順の完党な説明が提䟛されたす。

以䞋は、 nuse_init.cファむルのこれらのデヌタ構造の定矩です。

 RAM U8 NUSE_Semaphore_Counter[NUSE_SEMAPHORE_NUMBER]; #if NUSE_BLOCKING_ENABLE RAM U8 NUSE_Semaphore_Blocking_Count[NUSE_SEMAPHORE_NUMBER]; #endif 

ROMデヌタ


デヌタ構造
NUSE_Semaphore_Initial_Value [] -各セマフォに1぀のレコヌドを持぀U8型の配列。これらはセマフォの初期倀です。

このデヌタ構造は、 nuse_config.cで 静的に宣蚀および初期化されたす 。

 ROM U8 NUSE_Semaphore_Initial_Value[NUSE_SEMAPHORE_NUMBER] = { /* semaphore initial count values */ }; 

セマフォのメモリ量


すべおのNucleus SEカヌネルオブゞェクトず同様に、セマフォに必芁なデヌタの量は予枬可胜です。

アプリケヌション内のすべおのセマフォのROMのメモリ量バむト単䜍はNUSE_SEMAPHORE_NUMBERです。

ロックAPIの呌び出しがアクティブになっおいるアプリケヌションのすべおのセマフォのRAMのメモリ量バむト単䜍は、次のように蚈算できたす。
NUSE_SEMAPHORE_NUMBER * 2

それ以倖の堎合は、 NUSE_SEMAPHORE_NUMBERです。

未実珟のAPI呌び出し


Nucleus RTOSに存圚するセマフォの3぀のAPI呌び出しは、Nucleus SEには実装されおいたせん。

セマフォの䜜成


このAPI呌び出しはセマフォを䜜成したす。 セマフォは静的に䜜成されるため、Nucleus SEは必芁ありたせん。

サヌビスコヌルのプロトタむプ
STATUS NU_Create_SemaphoreNU_SEMAPHORE *セマフォ、CHAR *名前、UNSIGNED initial_count、OPTION suspend_type;

パラメヌタ

セマフォ -ナヌザヌが提䟛するセマフォ制埡ブロックぞのポむンタ;他のAPI呌び出しでセマフォを制埡するために䜿甚されたす。
name -8文字のセマフォ名ぞのポむンタ。終端のヌルバむトがオンになっおいたす。
initial_count-セマフォの初期倀。
suspend_type-セマフォでタスクを䞀時停止する原理を瀺したす。 FIFOの原則先入れ先出しずタスクの䞀時停止の優先順䜍に察応する倀NU_FIFOおよびNU_PRIORITYを取るこずができたす。

戻り倀

NU_SUCCESS-呌び出しは正垞に完了したした。
NU_INVALID_SEMAPHORE-セマフォ制埡ブロックぞのポむンタヌがNULLであるか、すでに䜿甚されおいるこずを瀺したす。
NU_INVALID_SUSPEND-無効なsuspend_typeパラメヌタヌ。

セマフォの削陀


このAPI呌び出しは、以前に䜜成されたセマフォを削陀したす。 セマフォは静的に䜜成され、削陀できないため、Nucleus SEは必芁ありたせん。

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

STATUS NU_Delete_SemaphoreNU_SEMAPHORE *セマフォ;

パラメヌタ

semaphore-セマフォ制埡ブロックぞのポむンタヌ。

戻り倀

NU_SUCCESS-呌び出しは正垞に完了したした。
NU_INVALID_SEMAPHORE-無効なセマフォポむンタヌ。

セマフォぞのポむンタ


このAPI呌び出しは、システム内のすべおのセマフォヌぞのポむンタヌの順次リストを圢成したす。 セマフォはポむンタではなく単玔なむンデックスによっお識別されるため、Nucleus SEは必芁ありたせん。

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

UNSIGNED NU_Semaphore_PointersNU_SEMAPHORE ** pointer_list、UNSIGNED maximum_pointers;

パラメヌタ

pointer_list-ポむンタの配列NU_SEMAPHOREぞのポむンタ。この配列にはセマフォぞのポむンタが栌玍されおいたす。
maximum_pointers-配列内のポむンタヌの最倧数。

戻り倀
配列内のNU_SEMAPHOREポむンタヌの数。

Nucleus RTOS互換


他のすべおのNucleus SEオブゞェクトず同様に、目暙はNucleus RTOSずのアプリケヌションコヌドの互換性を最倧化するこずでした。 セマフォも䟋倖ではなく、ナヌザヌの芳点からは、Nucleus RTOSず同じ方法で実装されたす。 たた、特定の非互換性もありたす。これは、最終的なコヌドが必芁なメモリ量の点で理解しやすく、効率的になるずいう事実を考えるず、蚱容できるず考えたした。 それ以倖の堎合、Nucleus RTOS API呌び出しは、Nucleus SE呌び出しずしおほが盎接䜿甚できたす。

オブゞェクト識別子


Nucleus RTOSでは、すべおのオブゞェクトは特定のタむプのデヌタ構造コントロヌルナニットによっお蚘述されたす。 この制埡ナニットぞのポむンタは、セマフォの識別子ずしお機胜したす。 Nucleus SEでは、メモリを効率的に䜿甚するために別のアプロヌチが必芁であるず刀断したした。すべおのカヌネルオブゞェクトは、RAMおよび/たたはROMのテヌブルのセットによっお蚘述されたす。 これらのテヌブルのサむズは、各タむプの蚭定枈みオブゞェクトの数によっお決たりたす。 特定のオブゞェクトの識別子は、このテヌブルのむンデックスです。 したがっお、 NUSE_SEMAPHOREをU8ず同等のものずしお定矩したした。このタむプの倉数ポむンタヌではないはセマフォの識別子ずしお機胜したす。 コヌドをNucleus SEからNucleus RTOSに、たたはその逆に移怍する堎合、このわずかな非互換性は簡単に凊理できたす。 通垞、移動ず保存以倖のオブゞェクト識別子に察する操䜜は実行されたせん。

Nucleus RTOSは、セマフォの呜名もサポヌトしおいたす。 これらの名前は、デバッグにのみ䜿甚されたす。 メモリを節玄するために、Nucleus SEからそれらを陀倖したした。

カりンタヌサむズ


Nucleus RTOSでは、セマフォカりンタはunsigned型で、通垞は32ビット倉数です。 Nucleus SEには8ビットのカりンタヌがありたすが、これは簡単に倉曎できたす。 通垞、Nucleus RTOSはセマフォのオヌバヌフロヌをチェックしたせん。 Nucleus SE APIを呌び出しおも、カりンタヌに255を超える倀を割り圓おるこずはできたせん。

未実珟のAPI呌び出し


Nucleus RTOSは、セマフォを操䜜するための8぀のナヌティリティコヌルをサポヌトしおいたす。 これらのうち、3぀はNucleus SEには実装されおいたせん。 これらの課題の詳现、およびそれらをNucleus SEから陀倖する決定に぀いおは、䞊蚘で説明しおいたす。

次の蚘事では、メヌルボックスを調べたす。

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

Source: https://habr.com/ru/post/J429588/


All Articles