5

それを考えると、ARM Cortex M3では、次のことができます。

  • 1ビットをアトミックに読み取る
  • 1ビットをアトミックに設定
  • 1ビットをアトミックにクリア

これらを組み合わせてミューテックススタイルの操作セットを作成するにはどうすればよいですか。

try lock
take lock
release lock

アトミックではない2つの操作が必要になるようtry_lockです。take_lock

これを達成するために、より多くの制御が必要ですか?グローバル割り込みを無効にすることでそれが可能になりますが、より外科的なアプローチが必要なようです。

4

4 に答える 4

4

呼び出し時にロックが既に保持されている場合、必ずしも失敗を返すとは限りませrwl_TryLock()ん (コンパイラーは、戻り値のないコード パスについて少なくとも警告を発する必要があります)。次のことを試してください。

int rwl_TryLock(volatile uint32_t *lock, int who){

    Var_SetBit_BB((uint32_t)lock, who);
    if(*lock == (1<<who)){ // check that we have exclusive access
        // got the lock!
        return 1;
    } 

    // do not have the lock
    Var_ResetBit_BB((uint32_t)lock, who); // clear the lock flag
    return 0;
}

上記は、同じロックを再帰的に要求する場合には機能しないことに注意してください (つまり、で指定されたタスクがwho == 1既にロックを取得していて、再度要求しようとすると、上記のコードは正しく機能しません)。良い。

また、割り込みは Cortex M3 で非常に迅速に無効化/有効化できます (これは NVIC レジスタへの単純な更新です)。ロック データ構造を処理するためのコードを単純に保つために (一般的には、修正が容易になることを意味します)、システムが追加の数サイクルの割り込みレイテンシーに対応できないと確信していますか?

于 2010-05-22T07:45:39.583 に答える
2

いくつかの検索後の情報のためのいくつか:

" ARM Cortex-M3 ビットバンディング ARM のマイクロコントローラ コアは、セマフォを実装するさらに別の方法を提供します。システムバスレベル. それはどのようにセマフォに変換されますか? ビットバンド領域の変数はセマフォのコンテナとして機能します. すべてのクライアントはそのコンテナ内のビットを「所有」します. クライアントがセマフォを要求する必要があるときはいつでも, クライアントはそれ自身を設定します.ビットバンド エイリアス領域の対応する位置に 1 を書き込むことにより、ビット. 次に、コンテナー (ビットバンド領域) を読み取り、他のビットが設定されていないことを確認します。他のビットが設定されている場合、クライアントは自身のビットを再度クリアし、(おそらく待機後に) 再試行する必要があります。」(ソース

これが私の大雑把な(テストされていない)解釈です:

/*
 * Frees a lock.
 *
 * @note lock must point to a fully aligned 32 bit integer.
 * (atomically set to 0)
 *
 * @returns 1 if successfull
 */
int rwl_FreeLock(volatile uint32_t *lock){
    *lock = 0;
    return 1; // always successful
}

/*
 * Attempts to acquire a lock
 * @param who is the client taking the lock
 * @lock pointer to the mutex (uint32_t value in memory)
 * @note lock must point to a fully aligned 32 bit integer.
 * (atomically set to 1 only if set to 0)
 */
int rwl_TryLock(volatile uint32_t *lock, int who){
    // initial check of lock
    if(*lock == 0){
        Var_SetBit_BB((uint32_t)lock, who);
        if(*lock == (1<<who)){ // check that we still have exclusive access
            // got the lock!
            return 1;
        } else {
                    // do not have the lock
            Var_ResetBit_BB((uint32_t)lock, who); // clear the lock flag
            return 0;
        }
    }
}

Var_Set_BB / Var_Reset_BB: ビット バンディングを使用してビットをセット / クリアします。(アトミック)

しかし、うまくいきません!!!

于 2010-05-21T15:26:59.187 に答える
0

ARM でビットバンディングを使用したことはありません。私の傾向は、代わりに、そのようなすべての操作に load-exclusive/store-conditional を使用することです。ループを使用して古い値を排他的にロードし、新しい値を計算し、条件付きストアを使用してそれを書き戻します。条件付きストアが成功するまでループします (1 回目でなくても、おそらく 2 回目は成功するでしょう)。

于 2011-12-16T18:30:34.183 に答える