는 비트 밴딩 (특히, 그것은 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() - lock . . -이게 안전한 코드 야? (맞습니까?) . semop() - unlock 이제이 작업을 수행해야합니까? a.take() . . - 내 보안 코드는 여기 입니다. a.release() 감사합니다, Martin –
세마포어를 사용하기 때문에 코드가 "안전"하지 않습니다. 필요한 경우 사용해야합니다. 일반적으로 동시 코드 경로를 통해 동시 액세스로부터 공통 리소스를 보호하기 위해이를 사용합니다. 어떤 종류의 RTOS 나 스케쥴러가 없다면 세마포어가 필요하지 않을 것입니다. 새로운 질문을하고 해결하고자하는 _ 실제 문제를 기술 한 다음 세마포어가 필요한지, 그리고 그렇다면 어떻게 적용 하는지를 알 수 있습니다. –
안녕 과르, 답변 주셔서 감사 드리며 잠시 응답을하지 못해 죄송합니다 ... 저는 freeRTOS를 사용하며 세마포어가 필요합니다. 세마포어에 대한 간단한 점검을 통해 내 문제를 이해했습니다. 물론 이전 질문은 똑똑하지 않았습니다 :) 어쨌든 도움을 주셔서 감사합니다. –