2013-12-08 7 views
1

SPI 장치에서 나오는 데이터를 처리하는 Raspberry Pi에서 C/C++ 사용자 공간 응용 프로그램을 개발하려고합니다. IRQ 이벤트에서 pthread 된 인터럽트 핸들러에서 호출 할 함수 (실제 인터럽트 핸들러)를 등록하는 WiringPi 라이브러리 (함수 wiringPiISR)를 사용하고 있습니다.스레드 ISR에서 데이터를 안전하고 간편하게 교환하는 방법은 무엇입니까? (Raspberry Pi)

STL 컨테이너는 스레드 안전하지 않지만 내 콜백 함수를 실행하는 동안 뮤텍스 잠금을 가지고 있고 버퍼/컨테이너에 액세스하는 동안 메인 스레드에서 잠금을 수행하는 것으로 충분하다고 들었습니까? wiringPiISR을 통해 등록

내 "실제 인터럽트 핸들러는"이

std::deque<uint8_t> buffer; 

static void irq_handler() 
{ 
    uint8_t data; 
    while (digitalRead(IRQ_PIN)==0) 
    { 
     data = spi_txrx(CMD_READBYTE); 
     pthread_mutex_lock(&mutex1); 
     callback(data); 
     pthread_mutex_unlock(&mutex1); 
    } 
} 

static void callback(uint8_t byte) 
{ 
    buffer.push_back(byte); 
} 

모양 또는 스레드 ISR 및 메인 쓰레드 사이의 데이터 교환을 달성하는 쉬운 방법은 무엇입니까?

+0

ISR에서 뮤텍스를 사용할 수 없습니다. ISR은 잠금을 기다릴 수 없습니다. –

+0

그래서 당신의 제안은 무엇입니까? – kloetpatra

+0

모든 ISR이 문제를 오염시키고 있다고 생각합니다. 핸들러를 호출하면 실제 질문이되는 것처럼 보입니다. mutex로 보호되는 STL 컨테이너를 다중 스레드 응용 프로그램에서 사용하는 것이 좋습니다. – shodanex

답변

0

진짜 ISR입니까? 아무튼 뮤텍스는 우선 순위 반전을 유도하기 때문에 ISR에 적합하지 않습니다. 의 두 개의 스레드 정상 뮤텍스 사용법을 살펴 보자 :

  1. 스레드 A를 실행하고 어떤 이유로 mmutex
  2. 을, 스레드 A가 선점하고, 스레드 B가 실행됩니다.
  3. 스레드 B 뮤텍스를 가져 오려고하지만 시도 할 수 없습니다.
  4. 스레드 B는 인스턴스 스레드 C에 대한 또 다른 스레드를 실행할 수 있도록 잠을 넣어 또는 일부 지점에서
  5. ...
  6. 스레드가 작업의 재개하는 WILLE이 다시 예약 스레드 및 해제된다 뮤텍스.
  7. 스레드 B가 다시 예약되면 뮤텍스를 가져옵니다.

이제 시나리오는 ISR과 매우 다릅니다. ISR은 우선 순위가 낮은 스레드를 위해 잠들지 않으므로 ISR에있는 동안 mutex 소유 스레드가 실행되지 않고 결코 3 점을 벗어나지 않습니다.

그래서 진짜 질문은 "IRQ 처리기를 실행할 때 다른 코드를 실행할 수 있습니까?"입니다. 그렇지 않으면 교착 상태에 빠졌습니다!

+0

ISR이 다시 잠들지 않는 이유는 무엇입니까? 내 말은 ISR이 메인 쓰레드보다 더 높은 우선 순위를 가져야한다는 뜻이다. 그러나 뮤텍스를 취할 수 없다면 메인 쓰레드가 락을 풀 때까지 잠들 것이다. 나는이 ISR이 마이크로 컨트롤러의 원자 ISR과 같지 않다고 생각한다. 이것이 기본 리눅스 커널의 사용자 공간 스레드 인 한, 스레드의 컨텍스트 스위칭과 같은 실제 커널 ISR의 실행은 여전히 ​​가능해야하며, 그렇지 않습니까? – kloetpatra

+0

ISR이 잠들 수 있다면 아무런 문제가 없지만 그런 식으로 지정하면 안됩니다. – shodanex