2015-02-02 7 views
0

Я работаю в классе C++ 11, который будет получать через I2C значение температурного датчика в малиновом Pi. Он будет опросить значение до тех пор, пока оно не будет остановлено. Он выполняет опрос в отдельном потоке, так что он не останавливает поток приложения. Проблема заключается в том, что в строке 64 этого файла: https://github.com/OpenStratos/server/blob/feature/temperature/temperature/Temperature.cpp#L64Ошибка сегментации при изменении значения атрибута

void Temperature::read_temperature() 
{ 
    while (this->reading) 
    { 
     #ifndef OS_TESTING 
      int value = wiringPiI2CRead(this->filehandle); 
     #else 
      int value = 16000; 
     #endif 

     float voltage = value * 5/32768; // 2^15 
     float temp = r_to_c(TEMP_R * (TEMP_VIN/voltage - 1)); 
     this->temperature = temp; // Gives segmentation fault 

     this_thread::sleep_for(chrono::milliseconds(50)); 
    } 
} 

это дает ошибку сегментации. Любопытство заключается в том, что это не всегда происходит. После компиляции, запуск двоичного файла много раз примерно в 75% случаев будет сбой.

Это файл, который invoques код: https://github.com/OpenStratos/server/blob/feature/temperature/testing/temperature_test.cpp

Temperature temp(20); 
temp.start_reading(); 
AssertThat(temp.is_reading(), Equals(true)); 

// this_thread::sleep_for(chrono::milliseconds(100)); if uncommented less segmentation faults 

temp.stop_reading(); 
AssertThat(temp.is_reading(), Equals(false)); 

Что могло случиться? Как это можно исправить?

+1

Пожалуйста, размещайте соответствующий код вместо (или дополнительно) ссылок. Ссылки могут быть мертвыми, и читать их гораздо лучше, если посмотреть, что это такое. – Soana

+0

Я добавил соответствующий код к сообщению :) – Razican

+0

Похоже, что экземпляр «Температура» может выйти из области видимости во время работы потока. Ваш тест, возможно, придется ждать выхода потока. – quamrana

ответ

1

Вы должны ждать Temperature::read_temperature(), чтобы бросить курить, так что вам нужно:

bool reading; 
volatile bool stopped; // volatile required to make the compiler re-read 
         // the value everytime we expect it to. 
// 
bool is_stopped(){ return stopped; } 

и

void Temperature::start_reading() 
{ 
    if (!reading) 
    { 
     stopped = false; 
     reading = true; 
     // etc 

и

void Temperature::read_temperature() 
{ 
    while (this->reading) 
    { 
    // etc 
    } 
    stopped=true; 
} 

и

temp.stop_reading(); 
while(!temp.is_stopped(); 
AssertThat(temp.is_reading(), Equals(false)); 
+0

Спасибо! Я не думал об этом. Но у меня есть новая проблема, скрипты входят в бесконечный цикл в 'while (! Temp.is_stopped();' этого не происходит, если я изменяю его на 'while (! Temp.is_stopped() {this_thread :: sleep_for (chrono :: milliseconds (100));}; 'Почему это происходит? – Razican

+0

Я еще не эксперт с' C++ 11', но вы можете попробовать перейти на «volatile bool stopped;» или 'std :: atomic остановился;' Посмотрите, что происходит. – quamrana

+0

Идеальное! volatile ключевое слово сделало трюк. while() не проверял значение на каждой итерации, поскольку компилятор рассматривал его так, как если бы он не менялся в коде , но другая нить меняла его. Большое спасибо! – Razican

Смежные вопросы