請注意,bit-banding的是並非所有的實現(最明顯的是,它缺少的恩智浦的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() - 解鎖 所以,現在我必須做這樣的事情? a.take() 。 。 - 我的安全代碼 。 a.release() 謝謝, Martin – 2012-01-17 14:26:21
代碼不會因爲您使用信號而變得「安全」;如果需要的話,應該使用它們。通常情況下,您可以使用它們來保護公共資源免受可能的併發代碼路徑的同時訪問。如果您沒有某種RTOS或調度程序,則不太可能需要信號量。我建議你提出一個新問題並描述你正在嘗試解決的_actual_問題,然後我們可以看到你是否需要信號量,如果是的話,如何應用它們。 – 2012-01-17 18:02:53
嗨伊戈爾,感謝您的回答,併爲一段時間沒有響應抱歉...我使用freeRTOS,似乎我需要信號量。在對信號量進行快速檢查之後,我瞭解了我的問題 - 當然,我之前的問題並不聰明:)無論如何,感謝您的幫助。 – 2012-01-23 09:49:05