質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.50%

  • 同期

    30questions

    複数のディレクトリに存在するファイルを更新した場合に、すべてのファイルにも更新が行われる事、又は、同じ記憶領域に同時にアクセスして内容の整合性が失われてしまう事をを防ぐ制御などを同期と呼びます。

  • RTOS

    3questions

    RTOS(リアルタイムOS)は、リアルタイムシステムのためのOSです。実時間システムや実時間OSとも呼ばれ、時間的な制限のある処理を行うための機能・特性を備えています。組み込みシステムの制御に多く用いられています。

RTOSを使用した組込みソフトでタスク間で同期する方法(イベント通知が使えない制約下)

受付中

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 123

drao0113

score 3

RTOSを使用して組み込みソフトの設計をしています。
タスク間でのデータの同期方法で分からないことがあるので、
教えていただけないでしょうか。

下記のようなタスクが存在するとします。

タスクA 10ms周期 データD,Eを10ms周期で更新
タスクB 100ms周期 データD,EをタスクB先頭でラッチ

※タスクBはイベントによる起床は許されないとする(過去のソースコード資産を流用するため)

質問1
以下の考え方は一般的ですか?
もっといい方法があれば知りたいです。

タスクB先頭でデータD,Eをラッチするのは、
タスクB実行中にデータD,Eのどちらかが更新され、
新旧混在したデータD,EがタスクBで使用されることを防ぐため

具体的に書くと、
前周期のデータDと今周期のデータEをもとに
制御ゲインを演算すると制御が破綻するようなケースがあり、
これを避けるため上記のような方法をとっています。

質問2
データDが0,1の2値をとる場合(例えば0:正常, 1:異常を表すような異常情報)、
下記のようにデータDが0から1に変化したことを、タスクBで確実に補足する良い方法はありますか?

データDが0から1に変化した場合に
タスクAからタスクBへイベントで通知するような方法が考えられますが、
タスクBはイベントによる起床は許されない場合、こうするのが一般的というような方法はありますか?

データDをタスクB起床までラッチしておくための別変数を定義し(データD’とする)、
タスクAでデータDが0から1に変化したときにデータD’=1とし、
タスクBでデータD'を参照後、データDが0であればデータD’=0とする、
のようにすれえば実現可能と思いますが、もっといい方法はないでしょうか?

経過時間: データD
0ms: データD=0
10ms: データD=0
20ms: データD=1
30ms: データD=1
40ms:  データD=1
50ms: データD=1
60ms: データD=0
70ms: データD=0
80ms: データD=0
90ms: データD=0
100ms: タスクB起床

よろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

0

回答1:
データの整合性をとるために、先頭で一気にデータを取得するということはあり得ることです。
ただ、タスクの優先度や割り込みの発生可能性などで、タスクB実行中にデータD,Eが変更されないことが保証されているのなら、「先頭で取得する」必要はないですね。つまり、タスクBの方がタスクAより優先度が高く、タスクBの実行中にタスクAがデータD、Eを書き換えることがないなら、問題ないわけです。
ただし、関連性の強い二つのデータをわざわざ別々に取得する必要もなく、特に問題が無ければ、タスクBの先頭で両データを取得する方がわかりやすいと思います。

タスクAがデータDを変更後、タスクBが動き出すことはないですか?それを防ぐことはできますか?

回答2:
100ms周期以外でタスクBが動いてはマズイと言うことなのでしょう。
イベントフラグは使えないのですか?
タスクAがイベントフラグを送る。
タスクBは100ms起動ごとにイベントフラグをチェックする(フラグ待ちにはしないで、読み出すだけにする)
が出来るのではないでしょうか?

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/26 13:04

    回答ありがとうございます。

    さきに回答2の回答させてください。

    おっしゃるととおりです。
    タスクBは100ms周期以外では動いてはいけないです。

    イベントフラグのフラグ待ちをしない方法があるのですね。

    イベントフラグを使用した場合でも、
    データDがイベントフラグに置き換わるのみで、タスクBで取り漏らす可能性がありますよね。

    データキュー等、
    使用すればいいのでしょうか?

    データD'を1から0にするタイミングを
    どのように判断するかが、わかっていません。

    もう少し考えてみます。

    キャンセル

  • 2018/07/26 23:05

    回答1の回答をします。
    すみません、タスクの優先度を記載してませんでした。
    タスクAの優先度>タスクBの優先度です。

    タスクBを実行中に、タスクAがデータD,Eを書き換える可能性があるので、
    タスクBでデータD,Eを取得するときだけ、ミューテックス等で排他制御が必要になりますね。

    データD,Eをばらばらで取得すると、それだけ排他制御される期間が増えるので、
    できるだけ1か所で取得したほうがいいですね

    キャンセル

  • 2018/07/26 23:15

    回答2の回答の続きです。

    メッセージバッファを使用すれば問題なさそうですね。

    データEが変化したタイミングでタスクAからタスクBへメッセージ送信し、
    タスクBで受けたメッセージを使用してデータD’を作ってやればいいですね。

    タスクBを実行するまでに、データEが0->1->0と変化した場合には、
    メッセージバッファでタスクBは1と0を受け取るので、これをもとに、
    今周期はデータD'=1とし、次の周期でデータD'=0にすれば、
    タスクBでデータDの変化を取り漏らすことはなさそうですね。

    あとは、メッセージバッファがあふれることを考慮しないとダメですね。。
    次の周期のタスクBが実行されるまでに、
    データDがハンチングして0と1を行ったり来たりすると、メッセージバッファがふれるリスクが高まります。


    タスクBが周期実行を前提としている場合、
    メッセージバッファのサイズを決めるのが難しいように思うのですが、
    ここらへんの設計指針はありますでしょうか?

    キャンセル

  • 2018/07/27 10:45

    仕様をよく理解していませんが・・・
    10msごとのデータ×10回 分をタスクBで100msごとに処理しよう
    ということなのでしょうか?
    バッファのサイズは10回分、タスクの起動遅れが最大どの程度かによりますが、11回分あれば大丈夫なようなきがします。

    というか、10回分のデータが必要なのですか?
    100msごとのデータとその間にエラーが発生したかどうかが分かればいいのなら、セマフォで排他制御すればいいような気がしますが。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.50%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • 同期

    30questions

    複数のディレクトリに存在するファイルを更新した場合に、すべてのファイルにも更新が行われる事、又は、同じ記憶領域に同時にアクセスして内容の整合性が失われてしまう事をを防ぐ制御などを同期と呼びます。

  • RTOS

    3questions

    RTOS(リアルタイムOS)は、リアルタイムシステムのためのOSです。実時間システムや実時間OSとも呼ばれ、時間的な制限のある処理を行うための機能・特性を備えています。組み込みシステムの制御に多く用いられています。