応用情報技術者 2012年 春期 午後 問07
オーディオプレーヤの組込みソフトウェアの設計に関する次の記述を読んで、設問1〜3に答えよ。
G社では、ハードディスクを内蔵した携帯型のオーディオプレーヤ(以下、プレーヤという)の組込みソフトウェアを開発することになった。
プレーヤの本体には再生ボタン及び停止ボタンがある。再生ボタンを押すと、あらかじめハードディスクに圧縮して保存しておいた音声ファイルから、音声データを読み出して再生する。停止ボタンを押すと、音声ファイルの再生を停止する。
開発する組込みソフトウェアは、メインタスク、再生処理タスク、データ読出しタスク及びDSP(Digital Signal Processor)ドライバから成る。タスク間の通信にはメッセージを使用する。プレーヤの構成を図1に示す。
開発する組込みソフトウェアでは、再生中に音声が途切れるのを防ぐために、バッファメモリを使用する。音声ファイルを再生する際には、データ読出しタスクが音声データをバッファメモリに書き込む。再生処理タスクは、書き込まれた音声データを順次読み出し、DSPドライバに転送する。DSPドライバは圧縮されている音声データをDSPに供給して伸張する。伸張された音声データはスピーカに出力される。

〔バッファメモリの制御〕
バッファメモリの領域は、0〜n−1のn個に等分割し、その一つ一つをメモリブロックとして取り扱う。バッファメモリへの書込み及びDSPドライバへの転送は、メモリブロック単位で行う。
バッファメモリの制御の様子を図2に示す。pは、再生処理タスクが次に読み出してDSPドライバに転送するメモリブロックの番号である。pからm個のメモリブロックは使用中、それ以外のメモリブロックは未使用である。
データ読出しタスクの書込みと再生処理タスクの読出しのいずれも、メモリブロックの番号が0のメモリブロックから順に使用する。データ読出しタスクの書込み先のメモリブロックの番号がn-1に達したら、次はメモリブロックの番号が0のメモリブロックを使用する。また、再生処理タスクが読み出すメモリブロックの番号も、n-1に達したら、次はメモリブロックの番号が0のメモリブロックを使用する。

〔ハードディスクの制御〕
電力消費を抑えるために、ハードディスクは読出し処理で必要なときだけディスクを回転させ、読出しが終わったら回転を停止させる。ハードディスクの制御に用いる関数を表1に示す。

〔DSPドライバの制御〕
DSPドライバは、DSPを駆動する他、状況に応じて再生処理タスクにメッセージを送信する。DSPドライバの制御に用いる関数を表2に示す。

〔組込みソフトウェアのタスク構成〕
開発する組込みソフトウェアのタスクの動作内容を表3に示す。各タスクには実行状態、待ち状態及び停止状態があり、実行権はラウンドロビン方式で与えられる。
再生処理タスクの流れ図を図3に、データ読出しタスクの流れ図を図4に、図3及び図4で使用しているサブルーチンBuffering(s, t) の流れ図を図5に示す。
なお、図3中の下線①の判定条件は、音声データの追加読出しを開始する条件である。また、図4中のmodは剰余の演算子で、a mod bはaをbで割った余りである。
↩設問3
↩設問3設問1:
問題文を見る模範解答
a:再生処理
b:STOPメッセージ
解説
解答の論理構成
- 停止時にメインタスクが操作する相手
表3のメインタスク説明には
「再生ボタンが押され、音声ファイルの再生を開始するときには、再生処理タスクを立ち上げる。」
とあり、再生の開始・終了を直接担当しているタスクが “再生処理タスク” であることが読み取れます。したがって a には「再生処理」が入ります。 - メインタスクが送るべきメッセージ種別
停止を指示するのに用意されている標準メッセージは、表2で定義されている
「STOP:音声データの終端に到達したことを示す。」
です。再生を強制的に止める場面でも同じ “STOP” を使えば、再生処理タスクの分岐(STOP受信時にdsp_end() 実行)をそのまま活用できます。したがって b には「STOPメッセージ」が入ります。 - 以上より
a:再生処理
b:STOPメッセージ
誤りやすいポイント
- 「データ読出しタスク」と混同する
停止させたい対象は再生を実際に制御する “再生処理タスク” です。ハードディスクからの読み出しを行うタスクにSTOPを送ってもDSPは止まりません。 - READYとSTOPを取り違える
READYは「次のメモリブロック処理準備完了」の通知であり、再生続行を意味します。「停止」にはふさわしくありません。 - タスク名の一部を省略する
解答は「再生処理タスク」ではなく、設問内空欄 a の位置に合わせた「再生処理」という字句が正解です。
FAQ
Q: STOPメッセージはDSPドライバ専用ではないのですか?
A: 表2の説明に「DSPドライバは、再生処理タスクに…STOP…を送信する」とあり、送受信相手は“再生処理タスク”です。メインタスクが同じメッセージ種別を送っても問題なく解釈されます。
A: 表2の説明に「DSPドライバは、再生処理タスクに…STOP…を送信する」とあり、送受信相手は“再生処理タスク”です。メインタスクが同じメッセージ種別を送っても問題なく解釈されます。
Q: メインタスクが直接dsp_end() を呼ばないのはなぜ?
A: 再生処理タスク内部でSTOP受信後にdsp_end() と後処理(バッファ残処理・タスク同期など)を一元的に実行する設計だからです。
A: 再生処理タスク内部でSTOP受信後にdsp_end() と後処理(バッファ残処理・タスク同期など)を一元的に実行する設計だからです。
Q: 再生ボタン連打による多重起動はどう防ぐ?
A: メインタスク側で再生処理タスクの状態を管理し、実行中は新規起動を許可しないフラグを持たせる実装が一般的です。
A: メインタスク側で再生処理タスクの状態を管理し、実行中は新規起動を許可しないフラグを持たせる実装が一般的です。
関連キーワード: タスク間通信, メッセージ駆動, 組込みOS, ラウンドロビン, バッファリング
設問2:
問題文を見る次にDSPドライバに転送するメモリブロックの番号がp、使用中のメモリブロック数がm個のとき、図4中のd、eに入れる適切な式を答えよ。
模範解答
d:p+m
e:n−m
解説
解答の論理構成
-
使用中領域の定義
【問題文】では「pは、再生処理タスクが次に読み出してDSPドライバに転送するメモリブロックの番号である。pからm個のメモリブロックは使用中、それ以外のメモリブロックは未使用である。」と規定しています。従って使用中ブロックはp, p+1, … , p+m−1です。 -
Bufferingの目的
データ読出しタスクは「サブルーチンBuffering(s, t) を呼び出して、全ての未使用のメモリブロックを使って、ハードディスクから音声データを読み出す。」(表3)とあります。すなわち
• s:先頭の未使用ブロック番号
• t:未使用ブロック数
を与える必要があります。 -
s(d)の導出
未使用領域の先頭は使用中最後尾「p+m−1」の次のブロックです。よってs = p + mただしバッファはリング構造で「n−1に達したら、次はメモリブロックの番号が0」(バッファメモリの制御)となるため、Fig.4では (d mod n) でラップさせています。結論:d = p + m -
t(e)の導出
総ブロック数は【問題文】「0〜n−1のn個」。このうちm個が使用中なので未使用はn − mだけです。Bufferingへ渡すブロック数は未使用ブロックを余さず全部読む必要があるためe = n − m -
以上から
d:p+m
e:n−m
が妥当であると示せます。
誤りやすいポイント
- 「pからm個が使用中」を「p+mが最後尾」と読み違え、開始位置をp+m+1としてしまう。
- 未使用ブロック数を「インデックス差」と誤解しn−m−1としてしまう。
- リングバッファであることを忘れmod nを考慮しない。
- Bufferingが「一部の未使用ブロックだけを埋める」と勘違いし、tに固定値を置く。
FAQ
Q: pがn−1のときでもd=p+mで良いのですか?
A: はい。Fig.4では (d mod n) としており、nで割った余りを取るので自動的に0番に回り込みます。
A: はい。Fig.4では (d mod n) としており、nで割った余りを取るので自動的に0番に回り込みます。
Q: mが0の場合はありますか?
A: 再生開始直後などBuffering完了直後はm=nになるため0にはなりません。mが0になるのは再生が完全に停止しバッファを空にしたときです。この状態でデータ読出しタスクは動きません。
A: 再生開始直後などBuffering完了直後はm=nになるため0にはなりません。mが0になるのは再生が完全に停止しバッファを空にしたときです。この状態でデータ読出しタスクは動きません。
Q: n−mが連続しない空き領域を越えて読むことは?
A: 使用中領域は常に連続(サーキュラバッファ方式)なので、未使用領域も連続しn−m個を一括で読めます。結果的に追加読出しは一度のHDDReadで済み、余計なディスク回転を抑えられます。
A: 使用中領域は常に連続(サーキュラバッファ方式)なので、未使用領域も連続しn−m個を一括で読めます。結果的に追加読出しは一度のHDDReadで済み、余計なディスク回転を抑えられます。
関連キーワード: サーキュラバッファ, 剰余演算, データストリーム, タスク間メッセージ, 省電力制御
設問3:
問題文を見る模範解答
c:データ読出しタスクの終了を待つ
解説
解答の論理構成
- 【問題文】の表3に「再生処理タスクが停止すると、このタスクも同時に強制的に終了させられる。」という記述があります。ここでいう「このタスク」とは表3の「データ読出しタスク」です。
- データ読出しタスクがHDDからデータを取得する一連の処理は、図5のBuffering(s, t) で示されます。Bufferingの途中には【問題文】表1の関数SpinUp() とStandBy() があり、StandBy() が実行されて初めてハードディスクの回転停止が指示されます。
- もし再生処理タスク側がdsp_end() 直後に自タスクを終了してしまうと、データ読出しタスクがBufferingの途中(SpinUp() とStandBy() の間)で強制終了される可能性があります。するとStandBy() が呼ばれず、【問題文】にある「ハードディスクは…読出しが終わったら回転を停止させる」という制御が実行されず、結果として「ハードディスクの回転が長時間停止しなくなってしまう」状態が発生します。
- したがって、STOPメッセージを受け取った再生処理タスクは、自身を終了する前にデータ読出しタスクが正常終了したことを確認しなければなりません。この待機動作を流れ図の c に入れる必要があります。
- よって c には「データ読出しタスクの終了を待つ」が入ります。これは再生処理タスクがHDD制御の完了を保証し、ハードディスクを確実に停止させるために必須の処理です。
誤りやすいポイント
- 「再生処理が終わった時点でHDD動作も終わっている」と早合点し、タスク同期の必要性を見落とす。
- Buffering(s, t) が常に短時間で終わると想定し、強制終了してもStandBy() が必ず呼ばれると誤解する。
- c に「StandBy() を呼ぶ」など関数呼出しを書いてしまい、タスクのライフサイクル制御が問題の本質であることに気付かない。
- 「2個以上同時に存在してはならない」という制約から c を「データ読出しタスクの起動を禁止する」と勘違いする。
FAQ
Q: dsp_end() を呼んだ後にHDDが回り続けるのはなぜですか?
A: HDDの回転停止はStandBy() によって行われます。再生処理タスクが先に終了すると、データ読出しタスクがStandBy() を呼ぶ前に強制終了されることがあり、結果としてモータ停止指示が出せません。
A: HDDの回転停止はStandBy() によって行われます。再生処理タスクが先に終了すると、データ読出しタスクがStandBy() を呼ぶ前に強制終了されることがあり、結果としてモータ停止指示が出せません。
Q: データ読出しタスクが存在しない場合でも c は必要ですか?
A: 必要です。存在しない場合は「終了を待つ」処理が即時に通過するだけで副作用はありませんが、存在する場合の安全動作を保証できます。
A: 必要です。存在しない場合は「終了を待つ」処理が即時に通過するだけで副作用はありませんが、存在する場合の安全動作を保証できます。
Q: READYメッセージとSTOPメッセージの違いは何ですか?
A: READYはDSPが次のメモリブロックを処理する準備ができたことを示し、再生処理タスクは対応するデータ転送を行います。STOPは音声データの終端に到達したことを示し、再生処理タスク側でDSP停止とタスク終了処理(c を含む)が行われます。
A: READYはDSPが次のメモリブロックを処理する準備ができたことを示し、再生処理タスクは対応するデータ転送を行います。STOPは音声データの終端に到達したことを示し、再生処理タスク側でDSP停止とタスク終了処理(c を含む)が行われます。
関連キーワード: タスク同期, バッファリング, ハードディスク制御, SpinUp, StandBy




