状態とイベント|状態遷移・タイマー・割込み・メッセージの順序を追う
タイマーを止めたはずなのに、次の測定がエラーになる。その原因は、期限切れの通知が既にキューへ入っていて、後から処理されたことかもしれません。状態、イベント、測定の識別番号を対応付けると、通知の発生時刻と処理時刻の違いを説明できます。
この記事で理解すること
状態・イベント・条件・動作を分け、状態遷移表から次の処理を決める。
割込みとタスク、ソフトウェアタイマーの実行文脈を区別する。
キューの順序と通知の識別番号から、古い応答やタイムアウトを無効にする。
架空の温度記録装置を例にします。状態は待機・測定中・エラーです。STARTで一回の測定を始め、DATAで結果を受け取り、TIMEOUTで期限切れ、RESETでエラーを解除します。装置の安全性や測定精度の設計ではなく、イベント制御の基本を扱います。
状態・イベント・条件・動作:一つの遷移を分解する
状態は、現在どの振る舞いが許されるかを決める状況です。イベントは開始要求、データ到着、期限切れ等の出来事を表す通知です。条件は遷移を許す判定で、動作は遷移に伴って行う処理です。同じイベントでも、現在の状態と条件が違えば結果は変わります。
待機中のSTARTなら測定を始めますが、測定中のSTARTはこの仕様では無視します。イベント名だけから処理を決めず、現在の状態を先に確認します。状態に入るときの処理と、個別イベントで行う処理も、どの時点で一回だけ実行するかを明確にします。
現在 | イベント・条件 | 動作 | 次の状態 |
|---|---|---|---|
待機 | START | 測定番号を増加、タイマー設定、測定要求 | 測定中 |
測定中 | DATA・番号一致 | タイマー停止、値を保存 | 待機 |
測定中 | TIMEOUT・番号一致 | エラーを記録、表示を更新 | エラー |
エラー | RESET | エラー表示を解除 | 待機 |
全状態 | 上記以外 | この例では無視して必要に応じ記録 | 同じ状態 |
この表ではDATAとTIMEOUTの番号一致は、開始した測定の番号と等しいことです。RESETはエラー状態でだけ受け付けます。無視するという仕様も表に含め、行がないから自由に状態を変えてよい、と解釈しないようにします。
正常時の流れ:状態を更新してから応答を待つ
制御タスクは測定番号と状態を更新し、測定の応答を受け付ける条件を確定してから通知を処理します。矢印は概略の処理順です。
制御タスクが状態を一元管理し、センサ側はDATAを通知します。DATA番号1を処理する時点で測定中かつ番号1なら、値を保存して待機へ戻ります。DATAを受けたからといって、どの状態でも値を保存するわけではありません。
状態の更新と周辺機器への操作が別々に進む場合、途中で通知が来ることがあります。この例は制御タスクだけが状態を書き換え、届いたイベントを一つずつ処理する方式です。割込み側も同じ状態を書き換える方式なら、同期や原子性の条件を追加して検討します。
メッセージキュー:発生と処理の間に時間差がある
キューは通知を保持して、受信側が順番に取り出すための構造です。この例は成功した投入の順に処理するFIFOを使います。複数の送信元がある場合、物理的な出来事の時刻と、キューに入った順序が同じとは限りません。
メッセージはイベントの種類、測定番号、必要な値等を持ちます。値をコピーして渡す方式と、バッファへの参照を渡す方式では、有効な期間が違います。参照を送った直後にバッファを再利用すると、受信側が別の値を見る危険があります。
通知 | 確認する情報 |
|---|---|
START | 開始を認める状態か |
DATA | 測定番号と値、バッファの有効期間 |
TIMEOUT | どの測定の期限か |
RESET | エラー解除が許される状態か |
投入失敗 | キューが満杯のときの代替・記録・復旧方法 |
キューを使えば通知が無限に保存できるわけではありません。容量上限と投入失敗を検査し、重要なイベントを黙って捨てない運用を設計します。訪問済み管理やキュー自体の基本はデータ構造の記事、複数タスクの同期は別の主担当記事へ分けます。
割込み:短い処理でタスクへ通知する
割込みは、機器やタイマー等の要求で通常の実行を中断し、割込み処理ISRを行う仕組みです。割込み処理では必要な機器状態やデータを取得し、後続の処理をタスクへ渡す設計がよく使われます。長い計算や待機をISRへ入れると、他の割込みやタスクに遅れを与える場合があります。
FreeRTOSではタスク用APIとISR用APIを区別します。たとえばキューへ送る場合は、割込みで使える専用API、許される割込み優先度、必要なタスク切替の処理を確認します。任意のAPIを呼べると考えたり、割込み内で空き待ちのブロックを行ったりしません。
割込み優先度、タスク優先度、イベントを処理する順序は同じ概念ではありません。高優先度ISRで発生した通知でも、その後に制御タスクが動くまで待つことがあります。タスク切替の条件がない資料から、厳密な実行時刻を断定しないようにします。
タイマー:期限を迎えることと動作の開始を分ける
ハードウェアタイマーは周辺回路で時刻等を数え、割込みを発生させることがあります。ソフトウェアタイマーはOS等が管理する期限とコールバックの仕組みです。FreeRTOSのソフトウェアタイマーのコールバックは、ISRではなくタイマーサービス用タスクで実行されます。
タイマー用タスクが他の処理を待てば、期限とコールバック開始に差が生じます。FreeRTOSのタイマーコールバックでブロックする操作を行うと、他のタイマー処理まで遅らせる原因になります。重い処理は通知して別タスクへ渡し、実行文脈の制約を確認します。
tickが10msで、25msの待ちを3tickへ切り上げて設定する設計なら、設定上は30msです。ただしtickの位相、開始処理やタスクの遅れがあり、開始から厳密に30msで動く保証ではありません。実時間の期限を守る要件なら、単調な時刻情報と期限比較なども含めて設計します。
古いタイムアウト:状態と測定番号を同時に検査する
測定1のTIMEOUTが既にキューへ入った後、DATA1を処理してタイマー停止を要求する場合があります。タイマー停止は、別のキューへ渡済みの通知を自動で取り除くとは限りません。その後STARTで測定2を始め、古いTIMEOUT1を受け取ったら、状態だけでは現在の期限切れと区別できません。
目的と処理する場所を対応付けて読みます。
通知には、その測定開始時の番号を付けます。通知を処理する時に現在番号を後付けすると、古いイベントにも新しい番号が付き、識別の意味を失います。タイマー側の通知元の情報も、該当する測定に結び付けて保持する必要があります。
受信イベントの処理条件
DATAまたはTIMEOUTなら:
現在状態が測定中か確認
通知の測定番号が現在番号と一致するか確認
両方を満たすときだけ遷移を実行
STARTは待機、RESETはエラーでだけ受け付ける番号の再利用・桁あふれや、長く残る通知があるなら、同じ番号で別の処理を誤認しない条件を考えます。この教材では検討期間に番号が重複しない前提です。識別番号を付けたことだけで、全ての遅延・欠落・重複が解決するわけではありません。
同時に見えるイベント:仕様で判定規則を決める
この例はキューから取り出した順序で処理し、測定中かつ番号一致のDATAとTIMEOUTのうち先に処理された方を有効にします。DATA1の後のTIMEOUT1は待機状態で無視し、TIMEOUT1の後のDATA1はエラー状態で無視します。
実際の要求が「物理的に期限前に到着した値を必ず採用する」なら、FIFOだけでは不十分です。到着時刻の取得、期限との比較、同時刻の優先規則を決めます。仕様で与えられた時刻の意味と遷移条件を、実装のキュー順へ勝手に置き換えないことが大切です。
演習1:同じSTART
条件:測定中に新しいSTARTが届く。上の遷移表を使う。
問い:次の状態と処理を答える。
解答例:測定中のまま、STARTを無視する。開始は待機中だけ認める。
根拠と誤答の確認:イベント名だけで毎回新しい測定を始めません。
演習2:正常な応答
条件:測定中、現在番号は1。DATA1が届く。
問い:行う動作と次状態を答える。
解答例:タイマー停止を要求して値を保存し、待機へ戻る。
根拠と誤答の確認:番号だけでなく現在の状態も条件に含めます。
演習3:古い通知
条件:測定2の測定中に、キューに残っていたTIMEOUT1が届く。
問い:どう扱うか。
解答例:現在番号2と一致しないので、遷移せず無視・記録する。
根拠と誤答の確認:状態が測定中という条件だけでは古い期限を誤認します。
演習4:停止の限界
条件:TIMEOUT1は既にメッセージキューへ入っている。その後タイマー停止を要求した。
問い:その通知が自動で消えるといえるか。
解答例:いえない。渡済みの通知は残る場合があり、受信側の状態・番号確認が必要。
根拠と誤答の確認:タイマー自体の停止と別キュー内のデータを区別します。
演習5:コールバックの文脈
条件:FreeRTOSのソフトウェアタイマーを使う。
問い:コールバックは常に割込み内で動くか。
解答例:動かない。タイマーサービス用タスクで実行される。
根拠と誤答の確認:ハードウェアタイマーのISRと区別します。
演習6:設定値と実時間
条件:tickは10ms。25msを切り上げて3tickで設定する方式を使う。
問い:設定上の時間と、その限界を答える。
解答例:30ms。tick位相や実行待ちがあり、厳密な開始からの実時間は保証しない。
根拠と誤答の確認:処理を始める時刻まで式だけで断定しません。
参照資料とこの記事の範囲
事例・図・演習は教材用に独自に作成しました。公式・教育機関の資料で仕組みを確認し、特定年度の問題本文を前提にせず学べる構成にしています。
関連テーマを続けて学ぶ
この記事についてAIに深掘り質問する
ChatGPT、Claude、Perplexityにこの記事を参照させ、要点の確認や疑問点を自由に質問できます。
次におすすめの学習
編集・検証について
編集・検証:IT資格ラボ編集部
IPAが公開する試験要綱・シラバス・過去問題と、各技術の公式資料を優先して内容を確認しています。制度変更や誤りを確認した場合は、記事を見直して更新します。
編集方針・情報源・訂正方針を見る