2013-12-08 10 views
1

Я пытаюсь разработать приложение для пользовательского пространства C/C++ на Raspberry Pi, которое обрабатывает данные, поступающие с устройства SPI. Я использую WiringPi Библиотека (функция wiringPiISR), которая регистрирует функцию (реального обработчика прерываний), которая будет вызываться из обработчика прерываний pthreaded в событии IRQ.Что такое безопасный и простой способ обмена данными с резьбовым 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 загрязняют вопрос. Вызовите его обработчиком, как кажется вашим реальным вопросом, нормально ли использовать контейнеры STL в многопоточном приложении, если они защищены мьютексом. – shodanex

ответ

0

Действительно ли это ISR? В любом случае мьютексы не подходят для ISR, потому что они приводят к инверсии приоритета. Давайте посмотрим на нормальное использование мьютекса, с двумя нити:

  1. пробегов Пронизывайте и возьмите mmutex
  2. по какой-то причине, поток А выгружается, и поток B выполняет.
  3. нить B попытаться взять мьютекс, но не может.
  4. нить Б усыплять, позволяя другой поток для запуска, например, нить C или нить A
  5. ...
  6. В какой-то момент, поток А Wille быть перенесено, возобновит его эксплуатации, а также освободить мьютекс.
  7. Когда поток B снова запланирован, он принимает мьютекс.

Теперь сценарий сильно отличается от ISR. ISR не будет спать в пользу потока с более низким приоритетом, поэтому поток с правами мьютекса не будет работать, пока вы находитесь в ISR, и вы никогда не сможете выйти из третьей точки.

Итак, настоящий вопрос: «При запуске IRQ-обработчика можно ли запустить другой код?» В противном случае вы находитесь в тупике!

+0

Я не понимаю, почему ISR снова не будет спать? Я имею в виду, что ISR должен иметь более высокий приоритет, чем основной поток, но если он не может принять мьютекс, он будет спать до тех пор, пока основной поток не отпустит блокировку, не так ли? Я думаю, что этот ISR не похож на атомный ISR в микроконтроллере. До тех пор, пока это потоки пользовательского пространства в базовом ядре Linux, выполнение реальных ISR-ядер, таких как переключение потоков потоков, должно быть возможно, или я ошибаюсь в этом? – kloetpatra

+0

Если ISR может спать, тогда нет никаких проблем, но тогда, возможно, его не следует назвать таким образом. – shodanex