そのビットバンディングは、(特に、それはNXPのLPC1xxxシリーズに欠けている)すべての実装では利用できませんのでご注意ください。
LDREX/STREXを使用してセマフォを実装する正式な方法については、ARM Synchronization Primitives Development Articleを参照してください。 ARMアセンブリを使用します。
以下は、コンパイラ組み込み関数(テストされていない!)を使用した簡単なクラスです。実際にはミューテックスのように機能するので、名前はおそらく誤った名前です。また、必要なDMB命令もありません。
class Semaphore
{
enum { SemFree, SemTaken };
// semaphore value
int s;
public:
// constructor
Semaphore(): s(SemFree) {};
// try to take the semaphore and return success
// by default block until succeeded
bool take(bool block = true)
{
int oldval;
#if defined(TARGET_LPC1768) // on Cortex-M3 we can use ldrex/strex
do {
// read the semaphore value
oldval = __ldrex(&s);
// loop again if it is locked and we are blocking
// or setting it with strex failed
}
while ((block && oldval == SemTaken) || __strex(SemTaken, &s) != 0);
if (!block) __clrex(); // clear exclusive lock set by ldrex
#else // on arm7 there's only swp
do {
// swp sets the pointed data to the given value and returns the previous one
oldval = __swp(SemTaken, &s);
// if blocking, loop until the previous value becomes 0
// which would mean we have successfully taken the lock
}
while (block && oldval == SemTaken);
#endif
return oldval == SemFree;
}
// release the semaphore
void release()
{
s = SemFree;
}
};
こんにちは。私はあなたのコードをどのように使うことができるか分かりません。私がセマフォについて読んだのは、関数semop()があり、次のようなことができるということでした。 semop() - ロック 。 。これは安全なコードですか? (私は正しい?) 。 semop() - unlock これで、このようなことをする必要がありますか? a.take() 。 。 - 私の安全なコードはここに 。 a.release() ありがとう、 Martin –
セマフォを使用しているという理由だけでコードは「安全」になりません。必要がある場合にはそれらを使用すべきです。通常は、それらを使用して、並行コードパスによる同時アクセスから共通リソースを保護します。何らかの種類のRTOSやスケジューラがない場合は、セマフォを必要としません。私はあなたに新しい質問をし、あなたが解決しようとしている_actual_問題を記述することをお勧めします。そして、セマフォーが必要かどうか、もしそうなら、それらを適用する方法がわかります。 –
こんにちはイゴール、あなたの答えをありがとう、しばらくの間応答していないの申し訳ありません...私はfreeRTOSを使用して、私はセマフォが必要と思われる。セマフォーについて簡単に確認したところ、私は自分の問題を理解していました。もちろん、私の前の質問はスマートではありませんでした:)とにかく、ありがとうございました。 –