From 0e4f0ae52e847bc7e6d6305556ab8d00dd1d4ef8 Mon Sep 17 00:00:00 2001 From: dreamsourcelabTAI Date: Mon, 8 Nov 2021 19:56:35 +0800 Subject: [PATCH] decode task save stop anddestory --- DSView/main.cpp | 2 + DSView/pv/appcontrol.cpp | 9 +- DSView/pv/appcontrol.h | 2 + DSView/pv/data/decode/decoder.cpp | 19 +- DSView/pv/data/decode/decoder.h | 24 +- DSView/pv/data/decode/rowdata.cpp | 8 +- DSView/pv/data/decoderstack.cpp | 152 +++++----- DSView/pv/data/decoderstack.h | 57 ++-- DSView/pv/data/dsosnapshot.cpp | 4 +- DSView/pv/data/snapshot.cpp | 25 +- DSView/pv/data/snapshot.h | 6 + DSView/pv/device/devinst.cpp | 5 + DSView/pv/device/devinst.h | 2 + DSView/pv/device/file.cpp | 2 +- DSView/pv/dock/dsotriggerdock.cpp | 12 +- DSView/pv/dock/protocoldock.cpp | 9 +- DSView/pv/mainwindow.cpp | 32 +- DSView/pv/mainwindow.h | 2 +- DSView/pv/sigsession.cpp | 466 +++++++++++++++++++---------- DSView/pv/sigsession.h | 209 +++++++++---- DSView/pv/storesession.cpp | 53 ++-- DSView/pv/storesession.h | 2 +- DSView/pv/view/decodetrace.cpp | 144 ++++----- DSView/pv/view/decodetrace.h | 14 +- DSView/pv/view/view.cpp | 66 ++-- DSView/pv/view/viewstatus.cpp | 2 +- libsigrok4DSL/hardware/demo/demo.h | 2 +- libsigrok4DSL/session.c | 15 +- 28 files changed, 810 insertions(+), 535 deletions(-) diff --git a/DSView/main.cpp b/DSView/main.cpp index 862befdf..c0a15a47 100755 --- a/DSView/main.cpp +++ b/DSView/main.cpp @@ -183,6 +183,8 @@ int main(int argc, char *argv[]) //Run the application ret = a.exec(); + + control->Stop(); } catch (const std::exception &e) { diff --git a/DSView/pv/appcontrol.cpp b/DSView/pv/appcontrol.cpp index 6fa5f704..dff58bc7 100644 --- a/DSView/pv/appcontrol.cpp +++ b/DSView/pv/appcontrol.cpp @@ -95,11 +95,14 @@ bool AppControl::Start() return true; } -void AppControl::UnInit() -{ + void AppControl::Stop() + { _session->Close(); _device_manager->UnInitAll(); - + } + +void AppControl::UnInit() +{ // Destroy libsigrokdecode srd_exit(); diff --git a/DSView/pv/appcontrol.h b/DSView/pv/appcontrol.h index ff2742b5..8e0e1ac0 100644 --- a/DSView/pv/appcontrol.h +++ b/DSView/pv/appcontrol.h @@ -48,6 +48,8 @@ public: bool Start(); + void Stop(); + void UnInit(); const char* GetLastError(); diff --git a/DSView/pv/data/decode/decoder.cpp b/DSView/pv/data/decode/decoder.cpp index a9e4c66e..4c2e80f0 100755 --- a/DSView/pv/data/decode/decoder.cpp +++ b/DSView/pv/data/decode/decoder.cpp @@ -29,11 +29,15 @@ namespace pv { namespace data { namespace decode { -Decoder::Decoder(const srd_decoder *const dec) : - _decoder(dec), - _shown(true), - _setted(true) +Decoder::Decoder(const srd_decoder *const dec): + _decoder(dec) { + _shown = true; + _setted = true; + _decode_start = 0; + _decode_end = 0; + _decode_start_back = 0; + _decode_end_back = 0; } Decoder::~Decoder() @@ -65,9 +69,10 @@ void Decoder::set_decode_region(uint64_t start, uint64_t end) { _decode_start_back = start; _decode_end_back = end; - if (_decode_start != start || - _decode_end != end) - _setted = true; + + if (_decode_start != start || _decode_end != end){ + _setted = true; + } } //apply setting diff --git a/DSView/pv/data/decode/decoder.h b/DSView/pv/data/decode/decoder.h index 3d723bdb..1f737f90 100755 --- a/DSView/pv/data/decode/decoder.h +++ b/DSView/pv/data/decode/decoder.h @@ -44,6 +44,8 @@ class Decoder public: Decoder(const srd_decoder *const decoder); +public: + virtual ~Decoder(); inline const srd_decoder* decoder(){ @@ -92,19 +94,19 @@ public: private: const srd_decoder *const _decoder; + + std::map _probes; + std::map _options; + std::map _probes_back; + std::map _options_back; - bool _shown; + uint64_t _decode_start; + uint64_t _decode_end; + uint64_t _decode_start_back; + uint64_t _decode_end_back; - std::map _probes; - std::map _options; - - std::map _probes_back; - std::map _options_back; - - uint64_t _decode_start, _decode_end; - uint64_t _decode_start_back, _decode_end_back; - - bool _setted; + bool _setted; + bool _shown; }; } // namespace decode diff --git a/DSView/pv/data/decode/rowdata.cpp b/DSView/pv/data/decode/rowdata.cpp index e8ac9278..7dbe30a3 100755 --- a/DSView/pv/data/decode/rowdata.cpp +++ b/DSView/pv/data/decode/rowdata.cpp @@ -42,7 +42,7 @@ RowData::RowData() : RowData::~RowData() { - clear(); + //stack object can not destory the sources } void RowData::clear() @@ -108,10 +108,8 @@ uint64_t RowData::get_annotation_index(uint64_t start_sample) } bool RowData::push_annotation(Annotation *a) -{ - if (a == NULL){ - return false; - } +{ + assert(a); std::lock_guard lock(_global_visitor_mutex); diff --git a/DSView/pv/data/decoderstack.cpp b/DSView/pv/data/decoderstack.cpp index 09d3dcf4..4aa6a86e 100755 --- a/DSView/pv/data/decoderstack.cpp +++ b/DSView/pv/data/decoderstack.cpp @@ -46,12 +46,9 @@ namespace data { const double DecoderStack::DecodeMargin = 1.0; const double DecoderStack::DecodeThreshold = 0.2; -const int64_t DecoderStack::DecodeChunkLength = 4 * 1024; -//const int64_t DecoderStack::DecodeChunkLength = 1024 * 1024; +const int64_t DecoderStack::DecodeChunkLength = 4 * 1024; const unsigned int DecoderStack::DecodeNotifyPeriod = 1024; - -std::mutex DecoderStack::_global_decode_mutex; - + DecoderStack::DecoderStack(pv::SigSession *session, const srd_decoder *const dec, DecoderStatus *decoder_status) : _session(session) @@ -61,22 +58,17 @@ DecoderStack::DecoderStack(pv::SigSession *session, assert(decoder_status); _samples_decoded = 0; - _sample_count = 0; - _frame_complete = false; + _sample_count = 0; _decode_state = Stopped; _options_changed = false; _no_memory = false; _mark_index = -1; _decoder_status = decoder_status; - _bThreadStop = false; - _decode_thread = NULL; + _stask_stauts = NULL; - connect(_session, SIGNAL(frame_began()), - this, SLOT(on_new_frame())); - connect(_session, SIGNAL(data_received()), - this, SLOT(on_data_received())); - connect(_session, SIGNAL(frame_ended()), - this, SLOT(on_frame_ended())); + connect(_session, SIGNAL(frame_began()), this, SLOT(on_new_frame())); + + connect(_session, SIGNAL(data_received()), this, SLOT(on_data_received())); _stack.push_back(new decode::Decoder(dec)); @@ -84,16 +76,21 @@ DecoderStack::DecoderStack(pv::SigSession *session, } DecoderStack::~DecoderStack() -{ - stop_decode(); - +{ + //release source for (auto &kv : _rows) { + kv.second->clear(); delete kv.second; } _rows.clear(); + //Decoder + for (auto *p : _stack){ + delete p; + } _stack.clear(); + _rows_gshow.clear(); _rows_lshow.clear(); _class_rows.clear(); @@ -117,7 +114,10 @@ void DecoderStack::remove(Decoder *decoder) // Delete the element if (iter != _stack.end()) + { _stack.erase(iter); + delete decoder; + } build_row(); _options_changed = true; @@ -125,7 +125,7 @@ void DecoderStack::remove(Decoder *decoder) void DecoderStack::build_row() { - //destory data + //release source for (auto &kv : _rows) { delete kv.second; @@ -357,8 +357,7 @@ void DecoderStack::clear() void DecoderStack::init() { - _sample_count = 0; - _frame_complete = false; + _sample_count = 0; _samples_decoded = 0; _error_message = QString(); _no_memory = false; @@ -370,30 +369,44 @@ void DecoderStack::init() set_mark_index(-1); } - -void DecoderStack::stop_decode() -{ - _bThreadStop = true; - - if (_decode_thread && _decode_thread->joinable()) { - _decode_thread->join(); + +void DecoderStack::stop_decode_work() +{ + //set the flag to exit from task thread + if (_stask_stauts){ + _stask_stauts->m_bStop = true; } - DESTROY_OBJECT(_decode_thread); - - if(_decode_state != Stopped) { - _decode_state = Stopped; - } + _decode_state = Stopped; } -void DecoderStack::begin_decode() +void DecoderStack::begin_decode_work() { + assert(_decode_state == Stopped); + + _decode_state = Running; + do_decode_work(); + _decode_state = Stopped; +} + +void DecoderStack::do_decode_work() +{ + //set the flag to exit from task thread + if (_stask_stauts){ + _stask_stauts->m_bStop = true; + } + _stask_stauts = new decode_task_status(); + _stask_stauts->m_bStop = false; + pv::view::LogicSignal *logic_signal = NULL; pv::data::Logic *data = NULL; if (!_options_changed) + { + qDebug()<<"data not be ready"; return; + } _options_changed = false; - stop_decode(); + init(); // Check that all decoders have the required channels @@ -427,6 +440,7 @@ void DecoderStack::begin_decode() const auto &snapshots = data->get_snapshots(); if (snapshots.empty()) return; + _snapshot = snapshots.front(); if (_snapshot->empty()) return; @@ -435,15 +449,8 @@ void DecoderStack::begin_decode() _samplerate = data->samplerate(); if (_samplerate == 0.0) return; - - if (_decode_thread && _decode_thread->joinable()) { - _bThreadStop = true; - _decode_thread->join(); - } - DESTROY_OBJECT(_decode_thread); - - _bThreadStop = false; //reset stop flag - _decode_thread = new std::thread(&DecoderStack::decode_proc, this); + + decode_proc(); } uint64_t DecoderStack::get_max_sample_count() @@ -457,10 +464,10 @@ uint64_t DecoderStack::get_max_sample_count() return max_sample_count; } -void DecoderStack::decode_data( - const uint64_t decode_start, const uint64_t decode_end, - srd_session *const session) +void DecoderStack::decode_data(const uint64_t decode_start, const uint64_t decode_end, srd_session *const session) { + decode_task_status *status = _stask_stauts; + //uint8_t *chunk = NULL; uint64_t last_cnt = 0; uint64_t notify_cnt = (decode_end - decode_start + 1)/100; @@ -480,8 +487,16 @@ void DecoderStack::decode_data( uint64_t i = decode_start; char *error = NULL; - while(!_bThreadStop && i < decode_end && !_no_memory) - { + if( i >= decode_end){ + qDebug()<<"decode data index have been end:"<m_bStop){ + break; + } + std::vector chunk; std::vector chunk_const; uint64_t chunk_end = decode_end; @@ -523,21 +538,19 @@ void DecoderStack::decode_data( new_decode_data(); } entry_cnt++; - } + } + if (error) g_free(error); - decode_done(); + + qDebug()<<"decode tack proc end"; + + if (!_session->is_closed()) + decode_done(); } void DecoderStack::decode_proc() -{ - std::lock_guard decode_lock(_global_decode_mutex); - - if (_bThreadStop){ - return; - } - - optional sample_count; +{ srd_session *session; srd_decoder_inst *prev_di = NULL; uint64_t decode_start = 0; @@ -547,12 +560,13 @@ void DecoderStack::decode_proc() // Create the session srd_session_new(&session); + assert(session); - - _decode_state = Running; - + // Get the intial sample count - sample_count = _sample_count = _snapshot->get_sample_count(); + _sample_count = _snapshot->get_sample_count(); + + qDebug()<<"sample count:"<<_sample_count; // Create the decoders for(auto &dec : _stack) @@ -592,9 +606,7 @@ void DecoderStack::decode_proc() if (error) { g_free(error); } - srd_session_destroy(session); - - _decode_state = Stopped; + srd_session_destroy(session); } uint64_t DecoderStack::sample_count() @@ -662,18 +674,16 @@ void DecoderStack::annotation_callback(srd_proto_data *pdata, void *decoder) } void DecoderStack::on_new_frame() -{ - //begin_decode(); +{ } void DecoderStack::on_data_received() { } -void DecoderStack::on_frame_ended() +void DecoderStack::frame_ended() { - _options_changed = true; - begin_decode(); + _options_changed = true; } int DecoderStack::list_rows_size() diff --git a/DSView/pv/data/decoderstack.h b/DSView/pv/data/decoderstack.h index c30455b7..c8a2b929 100755 --- a/DSView/pv/data/decoderstack.h +++ b/DSView/pv/data/decoderstack.h @@ -21,23 +21,24 @@ #ifndef DSVIEW_PV_DATA_DECODERSTACK_H #define DSVIEW_PV_DATA_DECODERSTACK_H + #include - #include - -#include - - +#include #include #include -#include -#include +#include #include "decode/row.h" #include "../data/signaldata.h" class DecoderStatus; +struct decode_task_status +{ + volatile bool m_bStop; +}; + namespace DecoderStackTest { class TwoDecoderStack; } @@ -62,6 +63,7 @@ class RowData; class Logic; + //a torotocol have a DecoderStack, destroy by DecodeTrace class DecoderStack : public QObject, public SignalData { Q_OBJECT @@ -133,14 +135,21 @@ public: QString error_message(); void clear(); + void init(); uint64_t get_max_sample_count(); - void begin_decode(); + inline bool IsRunning(){ + return _decode_state == Running; + } + + void begin_decode_work(); - void stop_decode(); + void do_decode_work(); + void stop_decode_work(); + int list_rows_size(); bool options_changed(); @@ -154,6 +163,8 @@ public: void set_mark_index(int64_t index); int64_t get_mark_index(); + void frame_ended(); + private: void decode_data(const uint64_t decode_start, const uint64_t decode_end, srd_session *const session); @@ -164,14 +175,12 @@ private: private slots: void on_new_frame(); - void on_data_received(); - - void on_frame_ended(); + void on_data_received(); signals: void new_decode_data(); void decode_done(); - + private: std::list _stack; @@ -184,28 +193,18 @@ private: SigSession *_session; decode_state _decode_state; - bool _options_changed; - bool _no_memory; + volatile bool _options_changed; + volatile bool _no_memory; int64_t _mark_index; DecoderStatus *_decoder_status; QString _error_message; int64_t _samples_decoded; - uint64_t _sample_count; - bool _frame_complete; - volatile bool _bThreadStop; + uint64_t _sample_count; + + decode_task_status *_stask_stauts; - - std::thread *_decode_thread; mutable std::mutex _output_mutex; - - /** - * This mutex prevents more than one decode operation occuring - * concurrently. - * @todo A proper solution should be implemented to allow multiple - * decode operations. - */ - static std::mutex _global_decode_mutex; - + friend class DecoderStackTest::TwoDecoderStack; }; diff --git a/DSView/pv/data/dsosnapshot.cpp b/DSView/pv/data/dsosnapshot.cpp index db56da10..a3649f8f 100755 --- a/DSView/pv/data/dsosnapshot.cpp +++ b/DSView/pv/data/dsosnapshot.cpp @@ -200,9 +200,9 @@ const uint8_t *DsoSnapshot::get_samples( (void)end_sample; assert(start_sample >= 0); - assert(start_sample < (int64_t)get_sample_count()); + assert(start_sample < (int64_t)sample_count()); assert(end_sample >= 0); - assert(end_sample < (int64_t)get_sample_count()); + assert(end_sample < (int64_t)sample_count()); assert(start_sample <= end_sample); diff --git a/DSView/pv/data/snapshot.cpp b/DSView/pv/data/snapshot.cpp index 773ea130..bac3cc16 100755 --- a/DSView/pv/data/snapshot.cpp +++ b/DSView/pv/data/snapshot.cpp @@ -92,19 +92,34 @@ uint64_t Snapshot::get_sample_count() std::lock_guard lock(_mutex); return _sample_count; } - + uint64_t Snapshot::get_ring_start() { std::lock_guard lock(_mutex); - if (_sample_count < _total_sample_count) - return 0; - else - return _ring_sample_count; + return ring_start(); } uint64_t Snapshot::get_ring_end() { std::lock_guard lock(_mutex); + return ring_end(); +} + +uint64_t Snapshot::sample_count() +{ + return _sample_count; +} + +uint64_t Snapshot::ring_start() +{ + if (_sample_count < _total_sample_count) + return 0; + else + return _ring_sample_count; +} + +uint64_t Snapshot::ring_end() +{ if (_sample_count == 0) return 0; else if (_ring_sample_count == 0) diff --git a/DSView/pv/data/snapshot.h b/DSView/pv/data/snapshot.h index 79de9589..b3447b89 100755 --- a/DSView/pv/data/snapshot.h +++ b/DSView/pv/data/snapshot.h @@ -64,6 +64,12 @@ public: protected: virtual void free_data(); + uint64_t sample_count(); + + uint64_t ring_start(); + + uint64_t ring_end(); + protected: mutable std::mutex _mutex; diff --git a/DSView/pv/device/devinst.cpp b/DSView/pv/device/devinst.cpp index 124ab2ef..a17b6098 100755 --- a/DSView/pv/device/devinst.cpp +++ b/DSView/pv/device/devinst.cpp @@ -204,6 +204,11 @@ void DevInst::run() sr_session_run(); } +void DevInst::stop() +{ + sr_session_stop(); +} + bool DevInst::is_usable() { return _usable; diff --git a/DSView/pv/device/devinst.h b/DSView/pv/device/devinst.h index 5ad51bf0..83b1a884 100755 --- a/DSView/pv/device/devinst.h +++ b/DSView/pv/device/devinst.h @@ -117,6 +117,8 @@ public: virtual void run(); + virtual void stop(); + virtual void* get_id(); virtual sr_dev_inst* dev_inst() = 0; diff --git a/DSView/pv/device/file.cpp b/DSView/pv/device/file.cpp index 88dd0cb5..c24233e2 100755 --- a/DSView/pv/device/file.cpp +++ b/DSView/pv/device/file.cpp @@ -96,7 +96,7 @@ QJsonArray File::get_decoders() } } - zip_close(archive); + zip_close(archive); } return dec_array; diff --git a/DSView/pv/dock/dsotriggerdock.cpp b/DSView/pv/dock/dsotriggerdock.cpp index 29698f19..03e1a8ee 100755 --- a/DSView/pv/dock/dsotriggerdock.cpp +++ b/DSView/pv/dock/dsotriggerdock.cpp @@ -343,10 +343,12 @@ void DsoTriggerDock::device_change() void DsoTriggerDock::init() { if (_session->get_device()->name().contains("virtual")) { - foreach(QAbstractButton * btn, _source_group->buttons()) + for(QAbstractButton * btn : _source_group->buttons()) btn->setDisabled(true); - foreach(QAbstractButton * btn, _type_group->buttons()) + + for(QAbstractButton * btn : _type_group->buttons()) btn->setDisabled(true); + _holdoff_slider->setDisabled(true); _holdoff_spinBox->setDisabled(true); _holdoff_comboBox->setDisabled(true); @@ -354,10 +356,12 @@ void DsoTriggerDock::init() _channel_comboBox->setDisabled(true); return; } else { - foreach(QAbstractButton * btn, _source_group->buttons()) + for(QAbstractButton * btn : _source_group->buttons()) btn->setDisabled(false); - foreach(QAbstractButton * btn, _type_group->buttons()) + + for(QAbstractButton * btn : _type_group->buttons()) btn->setDisabled(false); + _holdoff_slider->setDisabled(false); _holdoff_spinBox->setDisabled(false); _holdoff_comboBox->setDisabled(false); diff --git a/DSView/pv/dock/protocoldock.cpp b/DSView/pv/dock/protocoldock.cpp index 85150806..04888b4a 100755 --- a/DSView/pv/dock/protocoldock.cpp +++ b/DSView/pv/dock/protocoldock.cpp @@ -319,6 +319,9 @@ void ProtocolDock::add_protocol(bool silent) DecoderStatus *dstatus = new DecoderStatus(); dstatus->m_format = (int)DecoderDataFormat::hex; + int numm= _protocol_items.size(); + numm += 0; + if (_session->add_decoder(decoder, silent, dstatus)) { //crate item layer @@ -360,11 +363,13 @@ void ProtocolDock::del_all_protocol() { if (_protocol_items.size() > 0) { + _session->clear_all_decoder(); + for (auto it = _protocol_items.begin(); it != _protocol_items.end(); it++) { DESTROY_QT_LATER((*it)); //destory control - _session->remove_decode_signal(0); } + _protocol_items.clear(); protocol_updated(); } @@ -772,7 +777,7 @@ void ProtocolDock::OnProtocolDelete(void *handle){ if ((*it) == handle){ DESTROY_QT_LATER(*it); _protocol_items.remove(dex); - _session->remove_decode_signal(dex); + _session->remove_decoder(dex); protocol_updated(); break; } diff --git a/DSView/pv/mainwindow.cpp b/DSView/pv/mainwindow.cpp index fe69e51d..79b986a4 100755 --- a/DSView/pv/mainwindow.cpp +++ b/DSView/pv/mainwindow.cpp @@ -246,7 +246,8 @@ void MainWindow::setup_ui() // update device update_device_list(); - _session->start_hotplug_proc(boost::bind(&MainWindow::session_error, this, + + _session->start_hotplug_work(boost::bind(&MainWindow::session_error, this, QString(tr("Hotplug failed")), _1)); retranslateUi(); @@ -375,13 +376,12 @@ void MainWindow::update_device_list() } - // load decoders + // load decoders StoreSession ss(_session); - ss.load_decoders(_protocol_widget, file_dev->get_decoders()); - + bool bFlag = ss.load_decoders(_protocol_widget, file_dev->get_decoders()); // load session - load_session_json(file_dev->get_session(), true); + load_session_json(file_dev->get_session(), true, !bFlag); // load data const QString errorMessage( @@ -957,7 +957,7 @@ bool MainWindow::on_load_session(QString name) return load_session_json(sessionDoc, false); } -bool MainWindow::load_session_json(QJsonDocument json, bool file_dev) +bool MainWindow::load_session_json(QJsonDocument json, bool file_dev, bool bDecoder) { QJsonObject sessionObj = json.object(); @@ -976,9 +976,9 @@ bool MainWindow::load_session_json(QJsonDocument json, bool file_dev) return false; } - // clear decoders - - if (sdi->mode == LOGIC) { + // clear decoders + if (sdi->mode == LOGIC && !file_dev) + { _protocol_widget->del_all_protocol(); } @@ -1011,7 +1011,8 @@ bool MainWindow::load_session_json(QJsonDocument json, bool file_dev) for (const GSList *l = _session->get_device()->dev_inst()->channels; l; l = l->next) { sr_channel *const probe = (sr_channel*)l->data; assert(probe); - foreach (const QJsonValue &value, sessionObj["channel"].toArray()) { + + for (const QJsonValue &value : sessionObj["channel"].toArray()) { QJsonObject obj = value.toObject(); if ((strcmp(probe->name, g_strdup(obj["name"].toString().toStdString().c_str())) == 0) && (probe->type == obj["type"].toDouble())) { @@ -1031,7 +1032,8 @@ bool MainWindow::load_session_json(QJsonDocument json, bool file_dev) sr_channel *const probe = (sr_channel*)l->data; assert(probe); bool isEnabled = false; - foreach (const QJsonValue &value, sessionObj["channel"].toArray()) { + + for (const QJsonValue &value : sessionObj["channel"].toArray()) { QJsonObject obj = value.toObject(); if ((probe->index == obj["index"].toDouble()) && (probe->type == obj["type"].toDouble())) { @@ -1058,8 +1060,9 @@ bool MainWindow::load_session_json(QJsonDocument json, bool file_dev) // load signal setting if (file_dev && (sdi->mode == DSO)) { + for(auto &s : _session->get_signals()) { - foreach (const QJsonValue &value, sessionObj["channel"].toArray()) { + for (const QJsonValue &value : sessionObj["channel"].toArray()) { QJsonObject obj = value.toObject(); if ((strcmp(s->get_name().toStdString().c_str(), g_strdup(obj["name"].toString().toStdString().c_str())) == 0) && (s->get_type() == obj["type"].toDouble())) { @@ -1078,7 +1081,7 @@ bool MainWindow::load_session_json(QJsonDocument json, bool file_dev) } } else { for(auto &s : _session->get_signals()) { - foreach (const QJsonValue &value, sessionObj["channel"].toArray()) { + for (const QJsonValue &value : sessionObj["channel"].toArray()) { QJsonObject obj = value.toObject(); if ((s->get_index() == obj["index"].toDouble()) && (s->get_type() == obj["type"].toDouble())) { @@ -1123,12 +1126,11 @@ bool MainWindow::load_session_json(QJsonDocument json, bool file_dev) // load decoders - if (sessionObj.contains("decoder")) { + if (bDecoder && sessionObj.contains("decoder")) { StoreSession ss(_session); ss.load_decoders(_protocol_widget, sessionObj["decoder"].toArray()); } - // load measure if (sessionObj.contains("measure")) { _view->get_viewstatus()->load_session(sessionObj["measure"].toArray()); diff --git a/DSView/pv/mainwindow.h b/DSView/pv/mainwindow.h index 7dee5f3a..68f2dd6d 100755 --- a/DSView/pv/mainwindow.h +++ b/DSView/pv/mainwindow.h @@ -96,7 +96,7 @@ private: void session_error(const QString text, const QString info_text); bool eventFilter(QObject *object, QEvent *event); - bool load_session_json(QJsonDocument json, bool file_dev); + bool load_session_json(QJsonDocument json, bool file_dev,bool bDecoder=true); void update_device_list(); diff --git a/DSView/pv/sigsession.cpp b/DSView/pv/sigsession.cpp index b75f55c9..b63d1aa9 100755 --- a/DSView/pv/sigsession.cpp +++ b/DSView/pv/sigsession.cpp @@ -64,6 +64,7 @@ #include #include #include +#include #include "data/decode/decoderstatus.h" @@ -95,12 +96,8 @@ SigSession::SigSession(DeviceManager *device_manager) : _hot_attach = false; _hot_detach = false; _group_cnt = 0; - _bHotplugStop = false; - _hotplug = NULL; - _sampling_thread = NULL; - - - _feed_timer.stop(); + _bHotplugStop = false; + _noData_cnt = 0; _data_lock = false; _data_updated = false; @@ -111,7 +108,9 @@ SigSession::SigSession(DeviceManager *device_manager) : _math_trace = NULL; _saving = false; _dso_feed = false; - _stop_scale = 1; + _stop_scale = 1; + _bDecodeRunning = false; + _bClose = false; // Create snapshots & data containers _cur_logic_snapshot = new data::LogicSnapshot(); @@ -126,13 +125,15 @@ SigSession::SigSession(DeviceManager *device_manager) : _group_data = new data::Group(); _group_cnt = 0; + _feed_timer.stop(); + connect(&_feed_timer, SIGNAL(timeout()), this, SLOT(feed_timeout())); } //SigSession::SigSession(SigSession &o){(void)o;} SigSession::~SigSession() -{ +{ } DevInst* SigSession::get_device() @@ -142,7 +143,11 @@ DevInst* SigSession::get_device() void SigSession::deselect_device() { + for (auto p : _decode_traces){ + delete p; + } _decode_traces.clear(); + _group_traces.clear(); _dev_inst = NULL; } @@ -153,8 +158,7 @@ void SigSession::deselect_device() void SigSession::set_device(DevInst *dev_inst) { // Ensure we are not capturing before setting the device - //stop_capture(); - + assert(dev_inst); if (_dev_inst){ @@ -168,6 +172,9 @@ void SigSession::set_device(DevInst *dev_inst) _dev_inst = dev_inst; + for (auto p : _decode_traces){ + delete p; + } _decode_traces.clear(); _group_traces.clear(); @@ -358,6 +365,7 @@ void SigSession::capture_init() _trigger_flag = false; _trigger_ch = 0; _hw_replied = false; + if (_dev_inst->dev_inst()->mode != LOGIC) _feed_timer.start(FeedInterval); else @@ -418,8 +426,7 @@ void SigSession::container_init() //decoder_model->setDecoderStack(NULL); // DecoderStack for(auto &d : _decode_traces) - { - assert(d); + { d->decoder()->init(); } @@ -427,7 +434,7 @@ void SigSession::container_init() void SigSession::start_capture(bool instant, boost::function error_handler) -{ +{ // Check that a device instance has been selected. if (!_dev_inst) { qDebug() << "No device selected"; @@ -445,6 +452,7 @@ void SigSession::start_capture(bool instant, // stop previous capture stop_capture(); + // reset measure of dso signal for(auto &s : _signals) { @@ -455,10 +463,13 @@ void SigSession::start_capture(bool instant, } // update setting + qDebug()<<"device name:"<<_dev_inst->name(); + if (_dev_inst->name() != "virtual-session") _instant = instant; else _instant = true; + capture_init(); // Check that at least one probe is enabled @@ -477,30 +488,59 @@ void SigSession::start_capture(bool instant, return; } - if (_sampling_thread && _sampling_thread->joinable()){ - _sampling_thread->join(); + if (_sampling_thread.joinable()){ + _sampling_thread.join(); + } + _sampling_thread = std::thread(&SigSession::sample_thread_proc, this, _dev_inst, error_handler); +} + + +void SigSession::sample_thread_proc(DevInst *dev_inst, + boost::function error_handler) +{ + assert(dev_inst); + assert(dev_inst->dev_inst()); + assert(error_handler); + + try { + dev_inst->start(); + } catch(const QString e) { + error_handler(e); + return; } - DESTROY_OBJECT(_sampling_thread); - _sampling_thread = new std::thread(&SigSession::sample_thread_proc, this, _dev_inst, error_handler); + + receive_data(0); + set_capture_state(Running); + + dev_inst->run(); + + set_capture_state(Stopped); + + // Confirm that SR_DF_END was received + assert(_cur_logic_snapshot->last_ended()); + assert(_cur_dso_snapshot->last_ended()); + assert(_cur_analog_snapshot->last_ended()); } void SigSession::stop_capture() { - data_unlock(); + do_stop_capture(); + int dex = 0; + clear_all_decode_task(dex); +} - for (auto i = _decode_traces.begin(); i != _decode_traces.end(); i++) - (*i)->decoder()->stop_decode(); +void SigSession::do_stop_capture() +{ + data_unlock(); - if (get_capture_state() != Running) - return; - - sr_session_stop(); + if (_dev_inst){ + _dev_inst->stop(); + } // Check that sampling stopped - if (_sampling_thread && _sampling_thread->joinable()){ - _sampling_thread->join(); + if (_sampling_thread.joinable()){ + _sampling_thread.join(); } - DESTROY_OBJECT(_sampling_thread); } bool SigSession::get_capture_status(bool &triggered, int &progress) @@ -561,37 +601,10 @@ void SigSession::set_capture_state(capture_state state) data_updated(); capture_state_changed(state); } - -void SigSession::sample_thread_proc(DevInst *dev_inst, - boost::function error_handler) -{ - assert(dev_inst); - assert(dev_inst->dev_inst()); - assert(error_handler); - - try { - dev_inst->start(); - } catch(const QString e) { - error_handler(e); - return; - } - - receive_data(0); - set_capture_state(Running); - - dev_inst->run(); - - set_capture_state(Stopped); - - // Confirm that SR_DF_END was received - assert(_cur_logic_snapshot->last_ended()); - assert(_cur_dso_snapshot->last_ended()); - assert(_cur_analog_snapshot->last_ended()); -} - + void SigSession::check_update() { - std::lock_guard lock(_data_mutex); + ds_lock_guard lock(_data_mutex); if (_capture_state != Running) return; @@ -699,6 +712,9 @@ void SigSession::init_signals() // Clear the decode traces + for (auto p : _decode_traces){ + delete p; + } _decode_traces.clear(); @@ -842,7 +858,7 @@ void SigSession::reload() void SigSession::refresh(int holdtime) { - std::lock_guard lock(_data_mutex); + ds_lock_guard lock(_data_mutex); data_lock(); @@ -850,8 +866,7 @@ void SigSession::refresh(int holdtime) _logic_data->init(); for(auto &d : _decode_traces) - { - assert(d); + { d->decoder()->init(); } @@ -1062,6 +1077,7 @@ void SigSession::feed_in_dso(const sr_datafeed_dso &dso) if (!_instant) data_lock(); + _data_updated = true; } @@ -1103,18 +1119,18 @@ void SigSession::feed_in_analog(const sr_datafeed_analog &analog) //data_updated(); _data_updated = true; } - + void SigSession::data_feed_in(const struct sr_dev_inst *sdi, const struct sr_datafeed_packet *packet) { assert(sdi); assert(packet); - - std::lock_guard lock(_data_mutex); - + + ds_lock_guard lock(_data_mutex); + if (_data_lock && packet->type != SR_DF_END) return; - + if (packet->type != SR_DF_END && packet->status != SR_PKT_OK) { _error = Pkt_data_err; @@ -1162,34 +1178,40 @@ void SigSession::data_feed_in(const struct sr_dev_inst *sdi, break; } case SR_DF_END: - { + { + if (!_cur_logic_snapshot->empty()) { - - if (!_cur_logic_snapshot->empty()) { - for(auto &g : _group_traces) - { - assert(g); + for (auto &g : _group_traces) + { + assert(g); - auto p = new data::GroupSnapshot(_logic_data->get_snapshots().front(), g->get_index_list()); - _group_data->push_snapshot(p); - } + auto p = new data::GroupSnapshot(_logic_data->get_snapshots().front(), g->get_index_list()); + _group_data->push_snapshot(p); } - _cur_logic_snapshot->capture_ended(); - _cur_dso_snapshot->capture_ended(); - _cur_analog_snapshot->capture_ended(); - - for(auto &d : _decode_traces) - d->frame_ended(); - } + _cur_logic_snapshot->capture_ended(); + _cur_dso_snapshot->capture_ended(); + _cur_analog_snapshot->capture_ended(); + + qDebug()<<"data frame end"; + + for (auto trace : _decode_traces){ + trace->decoder()->frame_ended(); + trace->frame_ended(); + add_decode_task(trace); + } if (packet->status != SR_PKT_OK) { _error = Pkt_data_err; session_error(); } + frame_ended(); - if (get_device()->dev_inst()->mode != LOGIC) - set_session_time(QDateTime::currentDateTime()); + + if (get_device()->dev_inst()->mode != LOGIC){ + set_session_time(QDateTime::currentDateTime()); + } + break; } } @@ -1276,7 +1298,7 @@ void SigSession::deregister_hotplug_callback() libusb_hotplug_deregister_callback(NULL, _hotplug_handle); } -void SigSession::start_hotplug_proc(boost::function error_handler) +void SigSession::start_hotplug_work(boost::function error_handler) { // Begin the session @@ -1284,20 +1306,18 @@ void SigSession::start_hotplug_proc(boost::function error_ _hot_attach = false; _hot_detach = false; - if (_hotplug && _hotplug->joinable()){ - _hotplug->join(); - } - DESTROY_OBJECT(_hotplug); - _hotplug = new std::thread(&SigSession::hotplug_proc, this, error_handler); + if (_hotplug_thread.joinable()){ + return; + } + _hotplug_thread = std::thread(&SigSession::hotplug_proc, this, error_handler); } -void SigSession::stop_hotplug_proc() +void SigSession::stop_hotplug_work() { _bHotplugStop = true; - if (_hotplug && _hotplug->joinable()){ - _hotplug->join(); - } - DESTROY_OBJECT(_hotplug); + if (_hotplug_thread.joinable()){ + _hotplug_thread.join(); + } } uint16_t SigSession::get_ch_num(int type) @@ -1337,8 +1357,11 @@ uint16_t SigSession::get_ch_num(int type) return num_channels; } +bool SigSession::add_decoder(srd_decoder *const dec, bool silent, DecoderStatus *dstatus){ + return do_add_decoder(dec, silent, dstatus); +} -bool SigSession::add_decoder(srd_decoder *const dec, bool silent, DecoderStatus *dstatus) +bool SigSession::do_add_decoder(srd_decoder *const dec, bool silent, DecoderStatus *dstatus) { try { @@ -1370,22 +1393,21 @@ bool SigSession::add_decoder(srd_decoder *const dec, bool silent, DecoderStatus break; } } - if (silent) { - _decode_traces.push_back(trace); + if (silent) { ret = true; - } else if (trace->create_popup()) { - _decode_traces.push_back(trace); + } else if (trace->create_popup()) { ret = true; } if (ret) { + _decode_traces.push_back(trace); + add_decode_task(trace); signals_changed(); - // Do an initial decode - decoder_stack->begin_decode(); data_updated(); } - else{ + else + { delete trace; } @@ -1397,71 +1419,46 @@ bool SigSession::add_decoder(srd_decoder *const dec, bool silent, DecoderStatus return false; } - + std::vector& SigSession::get_decode_signals() { return _decode_traces; } -void SigSession::remove_decode_signal(view::DecodeTrace *signal) +void SigSession::remove_decoder(int index) { - for (auto i = _decode_traces.begin(); i != _decode_traces.end(); i++) - if ((*i) == signal) - { - _decode_traces.erase(i); - signals_changed(); - return; - } -} + int size = (int)_decode_traces.size(); + assert(index < size); -void SigSession::remove_decode_signal(int index) -{ - int cur_index = 0; + auto it = _decode_traces.begin() + index; + auto trace = (*it); + _decode_traces.erase(it); - for (auto i = _decode_traces.begin(); i != _decode_traces.end(); i++) - { - if (cur_index == index) - { - auto d = (*i)->decoder(); - d->stop_decode(); //stop decoder thread - _decode_traces.erase(i); - signals_changed(); - return; - } - cur_index++; + bool isRunning = trace->decoder()->IsRunning(); + + remove_decode_task(trace); + + if (isRunning){ + //destroy it in thread + trace->_delete_flag = true; } + else{ + delete trace; + signals_changed(); + } } void SigSession::rst_decoder(int index) { - if (index >= 0 && index < (int)_decode_traces.size()){ - auto p = _decode_traces[index]; - if (p->create_popup()) - { - p->decoder()->stop_decode(); - p->decoder()->begin_decode(); - data_updated(); - } + auto trace = get_decoder_trace(index); + + if (trace && trace->create_popup() ){ + remove_decode_task(trace); //remove old task + add_decode_task(trace); + data_updated(); } } - -void SigSession::rst_decoder(view::DecodeTrace *signal) -{ - for (auto p : _decode_traces) - { - if (p == signal) - { - if (p->create_popup()) - { - p->decoder()->stop_decode(); - p->decoder()->begin_decode(); - data_updated(); - } - break; - } - } -} - + pv::data::DecoderModel* SigSession::get_decoder_model() { return _decoder_model; @@ -1521,7 +1518,8 @@ void SigSession::math_rebuild(bool enable,view::DsoSignal *dsoSig1, view::DsoSignal *dsoSig2, data::MathStack::MathType type) { - std::lock_guard lock(_data_mutex); + ds_lock_guard lock(_data_mutex); + auto math_stack = new data::MathStack(this, dsoSig1, dsoSig2, type); DESTROY_OBJECT(_math_trace); _math_trace = new view::MathTrace(enable, math_stack, dsoSig1, dsoSig2); @@ -1581,7 +1579,7 @@ void SigSession::nodata_timeout() } void SigSession::feed_timeout() -{ +{ data_unlock(); if (!_data_updated) { if (++_noData_cnt >= (WaitShowTime/FeedInterval)) @@ -1783,11 +1781,15 @@ void SigSession::set_stop_scale(float scale) } void SigSession::Close() - { - if (_session == NULL) - return; + { + if (_bClose) + return; + + _bClose = true; - stop_capture(); + do_stop_capture(); //stop capture + + clear_all_decoder(); //clear all decode task, and stop decode thread ds_trigger_destroy(); @@ -1799,12 +1801,158 @@ void SigSession::set_stop_scale(float scale) // TODO: This should not be necessary _session = NULL; + stop_hotplug_work(); + if (_hotplug_handle) - { - stop_hotplug_proc(); + { deregister_hotplug_callback(); _hotplug_handle = 0; } } +//append a decode task, and try create a thread + void SigSession::add_decode_task(view::DecodeTrace *trace) + { + qDebug()<<"add a decode task"; + + std::lock_guard lock(_decode_task_mutex); + _decode_tasks.push_back(trace); + + if (!_bDecodeRunning) + { + if (_decode_thread.joinable()) + _decode_thread.join(); + + _decode_thread = std::thread(&SigSession::decode_task_proc, this); + _bDecodeRunning = true; + } + } + + void SigSession::remove_decode_task(view::DecodeTrace *trace) + { + std::lock_guard lock(_decode_task_mutex); + + for (auto it = _decode_tasks.begin(); it != _decode_tasks.end(); it++){ + if ((*it) == trace){ + (*it)->decoder()->stop_decode_work(); + _decode_tasks.erase(it); + qDebug()<<"remove a wait decode task"; + return; + } + } + + //the task maybe is running + qDebug()<<"remove a running decode task"; + trace->decoder()->stop_decode_work(); + } + + void SigSession::clear_all_decoder() + { + //create the wait task deque + int dex = -1; + clear_all_decode_task(dex); + + view::DecodeTrace *runningTrace = NULL; + if (dex != -1){ + runningTrace = _decode_traces[dex]; + runningTrace->_delete_flag = true; //destroy it in thread + } + + for (auto trace : _decode_traces) + { + if (trace != runningTrace){ + delete trace; + } + } + _decode_traces.clear(); + + //wait thread end + if (_decode_thread.joinable()) + { + qDebug() << "wait the decode thread end"; + _decode_thread.join(); + } + + if (!is_closed()) + signals_changed(); + } + + void SigSession::clear_all_decode_task(int &runningDex) + { + std::lock_guard lock(_decode_task_mutex); + + //remove wait task + for (auto trace : _decode_tasks){ + trace->decoder()->stop_decode_work(); //set decode proc stop flag + } + _decode_tasks.clear(); + + //make sure the running task can stop + runningDex = -1; + int dex = 0; + for (auto trace : _decode_traces) + { + if (trace->IsRunning()) + { + trace->decoder()->stop_decode_work(); + runningDex = dex; + } + dex++; + } + } + + view::DecodeTrace* SigSession::get_decoder_trace(int index) + { + int size = (int)_decode_traces.size(); + assert(index < size); + return _decode_traces[index]; + } + + view::DecodeTrace* SigSession::get_top_decode_task() + { + std::lock_guard lock(_decode_task_mutex); + + auto it = _decode_tasks.begin(); + if (it != _decode_tasks.end()){ + auto p = (*it); + _decode_tasks.erase(it); + return p; + } + + return NULL; + } + + //the decode task thread proc + void SigSession::decode_task_proc(){ + + qDebug()<<"decode thread start"; + auto task = get_top_decode_task(); + + while (task != NULL) + { + qDebug()<<"one decode task be actived"; + + if (!task->_delete_flag){ + task->decoder()->begin_decode_work(); + } + + if (task->_delete_flag){ + qDebug()<<"desroy a decoder in task thread"; + + DESTROY_QT_LATER(task); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + if (!_bClose){ + signals_changed(); + } + } + + task = get_top_decode_task(); + } + + qDebug()<<"decode thread end"; + _bDecodeRunning = false; + } + + + } // namespace pv diff --git a/DSView/pv/sigsession.h b/DSView/pv/sigsession.h index 2ae6c63c..9e1d124e 100755 --- a/DSView/pv/sigsession.h +++ b/DSView/pv/sigsession.h @@ -54,6 +54,8 @@ struct srd_channel; class DecoderStatus; +typedef std::lock_guard ds_lock_guard; + namespace pv { class DeviceManager; @@ -157,22 +159,31 @@ public: capture_state get_capture_state(); uint64_t cur_samplerate(); + uint64_t cur_snap_samplerate(); + uint64_t cur_samplelimits(); + double cur_sampletime(); + double cur_snap_sampletime(); + double cur_view_time(); void set_cur_snap_samplerate(uint64_t samplerate); + void set_cur_samplelimits(uint64_t samplelimits); + void set_session_time(QDateTime time); + QDateTime get_session_time(); + uint64_t get_trigger_pos(); - void start_capture(bool instant, - boost::function error_handler); - void capture_init(); + void start_capture(bool instant, boost::function error_handler); + bool get_capture_status(bool &triggered, int &progress); + void container_init(); std::set get_data(); @@ -183,16 +194,12 @@ public: bool add_decoder(srd_decoder *const dec, bool silent, DecoderStatus *dstatus); + void remove_decoder(int index); + std::vector& get_decode_signals(); - - void remove_decode_signal(view::DecodeTrace *signal); - - void remove_decode_signal(int index); - + void rst_decoder(int index); - - void rst_decoder(view::DecodeTrace *signal); - + pv::data::DecoderModel* get_decoder_model(); std::vector& get_spectrum_traces(); @@ -207,53 +214,78 @@ public: void del_group(); - void start_hotplug_proc(boost::function error_handler); - void stop_hotplug_proc(); - + void start_hotplug_work(boost::function error_handler); + + void stop_hotplug_work(); uint16_t get_ch_num(int type); bool get_instant(); bool get_data_lock(); + void data_auto_lock(int lock); + void data_auto_unlock(); + bool get_data_auto_lock(); + void spectrum_rebuild(); + void lissajous_rebuild(bool enable, int xindex, int yindex, double percent); + void lissajous_disable(); + void math_rebuild(bool enable,pv::view::DsoSignal *dsoSig1, pv::view::DsoSignal *dsoSig2, data::MathStack::MathType type); + void math_disable(); bool trigd(); + uint8_t trigd_ch(); data::Snapshot* get_snapshot(int type); error_state get_error(); + void set_error(error_state state); + void clear_error(); + uint64_t get_error_pattern(); run_mode get_run_mode(); + void set_run_mode(run_mode mode); + int get_repeat_intvl(); + void set_repeat_intvl(int interval); + bool isRepeating(); + bool repeat_check(); + int get_repeat_hold(); int get_map_zoom(); void set_save_start(uint64_t start); + void set_save_end(uint64_t end); + uint64_t get_save_start(); + uint64_t get_save_end(); + bool get_saving(); + void set_saving(bool saving); + void set_stop_scale(float scale); + float stop_scale(); void exit_capture(); @@ -264,12 +296,37 @@ public: void Close(); + void clear_all_decoder(); + + inline bool is_closed(){ + return _bClose; + } + private: void set_capture_state(capture_state state); void register_hotplug_callback(); + void deregister_hotplug_callback(); + bool do_add_decoder(srd_decoder *const dec, bool silent, DecoderStatus *dstatus); + + void add_decode_task(view::DecodeTrace *trace); + + void remove_decode_task(view::DecodeTrace *trace); + + void clear_all_decode_task(int &runningDex); + + view::DecodeTrace* get_decoder_trace(int index); + + void decode_task_proc(); + + view::DecodeTrace* get_top_decode_task(); + + void capture_init(); + + void do_stop_capture(); + private: /** * Attempts to autodetect the format. Failing that @@ -291,11 +348,16 @@ private: // data feed void feed_in_header(const sr_dev_inst *sdi); + void feed_in_meta(const sr_dev_inst *sdi, const sr_datafeed_meta &meta); + void feed_in_trigger(const ds_trigger_pos &trigger_pos); + void feed_in_logic(const sr_datafeed_logic &logic); + void feed_in_dso(const sr_datafeed_dso &dso); + void feed_in_analog(const sr_datafeed_analog &analog); void data_feed_in(const struct sr_dev_inst *sdi, @@ -306,6 +368,7 @@ private: // thread for hotplug void hotplug_proc(boost::function error_handler); + static int hotplug_callback(struct libusb_context *ctx, struct libusb_device *dev, libusb_hotplug_event event, void *user_data); @@ -321,6 +384,7 @@ signals: void receive_data(quint64 length); void device_attach(); + void device_detach(); void receive_trigger(quint64 trigger_pos); @@ -338,6 +402,7 @@ signals: void device_setted(); void zero_adj(); + void progressSaveFileValueChanged(int percent); void decode_done(); @@ -351,6 +416,7 @@ signals: void session_error(); void repeat_hold(int percent); + void repeat_resume(); void cur_snap_samplerate_changed(); @@ -359,22 +425,29 @@ signals: public slots: void reload(); + void refresh(int holdtime); + void stop_capture(); + void check_update(); // repeat void set_repeating(bool repeat); + void set_map_zoom(int index); // OSC auto void auto_end(); private slots: void data_lock(); + void data_unlock(); + void nodata_timeout(); + void feed_timeout(); - void repeat_update(); - + + void repeat_update(); private: DeviceManager *_device_manager; @@ -382,73 +455,77 @@ private: /** * The device instance that will be used in the next capture session. */ - DevInst *_dev_inst; + DevInst *_dev_inst; + mutable std::mutex _sampling_mutex; + mutable std::mutex _data_mutex; + mutable std::mutex _decode_task_mutex; + + std::thread _hotplug_thread; + std::thread _sampling_thread; + std::thread _decode_thread; - mutable std::mutex _sampling_mutex; - capture_state _capture_state; - bool _instant; - uint64_t _cur_snap_samplerate; - uint64_t _cur_samplelimits; + volatile bool _bHotplugStop; + volatile bool _bDecodeRunning; - //mutable std::mutex _signals_mutex; - std::vector _signals; + capture_state _capture_state; + bool _instant; + uint64_t _cur_snap_samplerate; + uint64_t _cur_samplelimits; + + std::vector _signals; std::vector _group_traces; std::vector _decode_traces; - pv::data::DecoderModel *_decoder_model; + std::vector _decode_tasks; + pv::data::DecoderModel *_decoder_model; std::vector _spectrum_traces; - view::LissajousTrace *_lissajous_trace; - view::MathTrace *_math_trace; - - mutable std::mutex _data_mutex; - data::Logic *_logic_data; - data::LogicSnapshot *_cur_logic_snapshot; - data::Dso *_dso_data; - data::DsoSnapshot *_cur_dso_snapshot; - data::Analog *_analog_data; - data::AnalogSnapshot *_cur_analog_snapshot; - data::Group *_group_data; - int _group_cnt; - - std::thread *_sampling_thread; - std::thread *_hotplug; - volatile bool _bHotplugStop; - + view::LissajousTrace *_lissajous_trace; + view::MathTrace *_math_trace; + + data::Logic *_logic_data; + data::LogicSnapshot *_cur_logic_snapshot; + data::Dso *_dso_data; + data::DsoSnapshot *_cur_dso_snapshot; + data::Analog *_analog_data; + data::AnalogSnapshot *_cur_analog_snapshot; + data::Group *_group_data; + int _group_cnt; + libusb_hotplug_callback_handle _hotplug_handle; - bool _hot_attach; - bool _hot_detach; + bool _hot_attach; + bool _hot_detach; - QTimer _feed_timer; - int _noData_cnt; - bool _data_lock; - bool _data_updated; - int _data_auto_lock; + QTimer _feed_timer; + int _noData_cnt; + bool _data_lock; + bool _data_updated; + int _data_auto_lock; - QDateTime _session_time; - uint64_t _trigger_pos; - bool _trigger_flag; - uint8_t _trigger_ch; - bool _hw_replied; + QDateTime _session_time; + uint64_t _trigger_pos; + bool _trigger_flag; + uint8_t _trigger_ch; + bool _hw_replied; error_state _error; - uint64_t _error_pattern; + uint64_t _error_pattern; - run_mode _run_mode; - int _repeat_intvl; - bool _repeating; - int _repeat_hold_prg; + run_mode _run_mode; + int _repeat_intvl; + bool _repeating; + int _repeat_hold_prg; - int _map_zoom; + int _map_zoom; - uint64_t _save_start; - uint64_t _save_end; - bool _saving; + uint64_t _save_start; + uint64_t _save_end; + bool _saving; - bool _dso_feed; - float _stop_scale; - + bool _dso_feed; + float _stop_scale; + bool _bClose; private: // TODO: This should not be necessary. Multiple concurrent diff --git a/DSView/pv/storesession.cpp b/DSView/pv/storesession.cpp index c99d2efe..1540affb 100755 --- a/DSView/pv/storesession.cpp +++ b/DSView/pv/storesession.cpp @@ -83,14 +83,12 @@ SigSession* StoreSession::session() } std::pair StoreSession::progress() -{ - //lock_guard lock(_mutex); +{ return std::make_pair(_units_stored, _unit_count); } const QString& StoreSession::error() -{ - //lock_guard lock(_mutex); +{ return _error; } @@ -878,6 +876,7 @@ QJsonArray StoreSession::json_decoders() QJsonArray ch_array; const srd_decoder *const d = dec->decoder();; const bool have_probes = (d->channels || d->opt_channels) != 0; + if (have_probes) { for(auto i = dec->channels().begin(); i != dec->channels().end(); i++) { @@ -946,29 +945,38 @@ QJsonArray StoreSession::json_decoders() return dec_array; } -void StoreSession::load_decoders(dock::ProtocolDock *widget, QJsonArray dec_array) +bool StoreSession::load_decoders(dock::ProtocolDock *widget, QJsonArray dec_array) { - if (_session->get_device()->dev_inst()->mode != LOGIC || - dec_array.empty()) - return; + if (_session->get_device()->dev_inst()->mode != LOGIC || dec_array.empty()) + { + return false; + } + - foreach (const QJsonValue &dec_value, dec_array) { - QJsonObject dec_obj = dec_value.toObject(); + for (const QJsonValue &dec_value : dec_array) { - auto &pre_dsigs = _session->get_decode_signals(); + QJsonObject dec_obj = dec_value.toObject(); + std::vector &pre_dsigs = _session->get_decode_signals(); + + //set current protocol if (widget->sel_protocol(dec_obj["id"].toString())) - widget->add_protocol(true); + { + widget->add_protocol(true); + } + else{ + continue; //protocol is not exists; + } - auto &aft_dsigs = _session->get_decode_signals(); + std::vector &aft_dsigs = _session->get_decode_signals(); - if (aft_dsigs.size() > pre_dsigs.size()) { + if (aft_dsigs.size() >= pre_dsigs.size()) { const GSList *l; auto new_dsig = aft_dsigs.back(); auto stack = new_dsig->decoder(); if (dec_obj.contains("stacked decoders")) { - foreach(const QJsonValue &value, dec_obj["stacked decoders"].toArray()) { + for(const QJsonValue &value : dec_obj["stacked decoders"].toArray()) { QJsonObject stacked_obj = value.toObject(); GSList *dl = g_slist_copy((GSList*)srd_decoder_list()); @@ -995,9 +1003,9 @@ void StoreSession::load_decoders(dock::ProtocolDock *widget, QJsonArray dec_arra std::map probe_map; // Load the mandatory channels for(l = d->channels; l; l = l->next) { - const struct srd_channel *const pdch = - (struct srd_channel *)l->data; - foreach (const QJsonValue &value, dec_obj["channel"].toArray()) { + const struct srd_channel *const pdch = (struct srd_channel *)l->data; + + for (const QJsonValue &value : dec_obj["channel"].toArray()) { QJsonObject ch_obj = value.toObject(); if (ch_obj.contains(pdch->id)) { probe_map[pdch] = ch_obj[pdch->id].toInt(); @@ -1008,9 +1016,9 @@ void StoreSession::load_decoders(dock::ProtocolDock *widget, QJsonArray dec_arra // Load the optional channels for(l = d->opt_channels; l; l = l->next) { - const struct srd_channel *const pdch = - (struct srd_channel *)l->data; - foreach (const QJsonValue &value, dec_obj["channel"].toArray()) { + const struct srd_channel *const pdch = (struct srd_channel *)l->data; + + for (const QJsonValue &value : dec_obj["channel"].toArray()) { QJsonObject ch_obj = value.toObject(); if (ch_obj.contains(pdch->id)) { probe_map[pdch] = ch_obj[pdch->id].toInt(); @@ -1021,7 +1029,7 @@ void StoreSession::load_decoders(dock::ProtocolDock *widget, QJsonArray dec_arra dec->set_probes(probe_map); options_obj = dec_obj["options"].toObject(); } else { - foreach(const QJsonValue &value, dec_obj["stacked decoders"].toArray()) { + for(const QJsonValue &value : dec_obj["stacked decoders"].toArray()) { QJsonObject stacked_obj = value.toObject(); if (QString::fromUtf8(d->id) == stacked_obj["id"].toString()) { options_obj = stacked_obj["options"].toObject(); @@ -1087,6 +1095,7 @@ void StoreSession::load_decoders(dock::ProtocolDock *widget, QJsonArray dec_arra } } + return true; } diff --git a/DSView/pv/storesession.h b/DSView/pv/storesession.h index c4a49448..c7ef0e1d 100755 --- a/DSView/pv/storesession.h +++ b/DSView/pv/storesession.h @@ -80,7 +80,7 @@ private: public: QJsonArray json_decoders(); - void load_decoders(dock::ProtocolDock *widget, QJsonArray dec_array); + bool load_decoders(dock::ProtocolDock *widget, QJsonArray dec_array); QString MakeSaveFile(bool bDlg); QString MakeExportFile(bool bDlg); diff --git a/DSView/pv/view/decodetrace.cpp b/DSView/pv/view/decodetrace.cpp index babe8024..8cc1b1a8 100755 --- a/DSView/pv/view/decodetrace.cpp +++ b/DSView/pv/view/decodetrace.cpp @@ -117,31 +117,30 @@ const QString DecodeTrace::RegionEnd = QT_TR_NOOP("End "); DecodeTrace::DecodeTrace(pv::SigSession *session, pv::data::DecoderStack *decoder_stack, int index) : - Trace(QString::fromUtf8( - decoder_stack->stack().front()->decoder()->name), index, SR_CHANNEL_DECODER), - _session(session), - _decoder_stack(decoder_stack), - _decode_start(0), - _decode_end(INT64_MAX), - _start_index(0), - _end_index(0), - _start_count(0), - _end_count(0), - _progress(0), - _popup(NULL) + Trace(QString::fromUtf8(decoder_stack->stack().front()->decoder()->name), index, SR_CHANNEL_DECODER) { - assert(_decoder_stack); + assert(decoder_stack); - _colour = DecodeColours[index % countof(DecodeColours)]; + _colour = DecodeColours[index % countof(DecodeColours)]; + _start_comboBox = NULL; + _end_comboBox = NULL; + _pub_input_layer = NULL; + _progress = 0; - connect(_decoder_stack, SIGNAL(new_decode_data()), - this, SLOT(on_new_decode_data())); - connect(_decoder_stack, SIGNAL(decode_done()), - this, SLOT(on_decode_done())); + _decode_start = 0; + _decode_end = INT64_MAX; + _end_count = 0; + _start_count = 0; + _end_index = 0; + _start_index = 0; - _start_comboBox = NULL; - _end_comboBox = NULL; - _pub_input_layer = NULL; + _decoder_stack = decoder_stack; + _session = session; + _delete_flag = false; + + connect(_decoder_stack, SIGNAL(new_decode_data()), this, SLOT(on_new_decode_data())); + + connect(_decoder_stack, SIGNAL(decode_done()), this, SLOT(on_decode_done())); } DecodeTrace::~DecodeTrace() @@ -150,10 +149,7 @@ DecodeTrace::~DecodeTrace() _probe_selectors.clear(); _bindings.clear(); - if (_popup){ - delete _popup; - _popup = NULL; - } + DESTROY_OBJECT(_decoder_stack); } bool DecodeTrace::enabled() @@ -351,18 +347,13 @@ void DecodeTrace::paint_fore(QPainter &p, int left, int right, QColor fore, QCol //to show decoder's property setting dialog bool DecodeTrace::create_popup() -{ - if (_popup != NULL){ - _popup->reload(); - return true; - } +{ + int ret = false; //setting have changed flag + + dialogs::DSDialog dlg; + create_popup_form(&dlg); - int ret = false; - _popup = new dialogs::DSDialog(); - - create_popup_form(); - - if (QDialog::Accepted == _popup->exec()) + if (QDialog::Accepted == dlg.exec()) { for(auto &dec : _decoder_stack->stack()) { @@ -375,26 +366,25 @@ bool DecodeTrace::create_popup() } } - //destroy object return ret; } -void DecodeTrace::create_popup_form() +void DecodeTrace::create_popup_form(dialogs::DSDialog *dlg) { // Clear the layout // Transfer the layout and the child widgets to a temporary widget // which then goes out of scope destroying the layout and all the child // widgets. - QFormLayout *_popup_form = new QFormLayout(); - _popup_form->setVerticalSpacing(5); - _popup_form->setFormAlignment(Qt::AlignLeft); - _popup_form->setLabelAlignment(Qt::AlignLeft); - _popup_form->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow); - _popup->layout()->addLayout(_popup_form); - _popup->setTitle(tr("Decoder Options")); + QFormLayout *form = new QFormLayout(); + form->setVerticalSpacing(5); + form->setFormAlignment(Qt::AlignLeft); + form->setLabelAlignment(Qt::AlignLeft); + form->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow); + dlg->layout()->addLayout(form); + dlg->setTitle(tr("Decoder Options")); - populate_popup_form(_popup, _popup_form); + populate_popup_form(dlg, form); } void DecodeTrace::populate_popup_form(QWidget *parent, QFormLayout *form) @@ -424,15 +414,14 @@ void DecodeTrace::populate_popup_form(QWidget *parent, QFormLayout *form) form->addRow(new QLabel( tr("* Required channels"), parent)); - } - - + } //Add region combobox _start_comboBox = new QComboBox(parent); _end_comboBox = new QComboBox(parent); _start_comboBox->addItem(RegionStart); _end_comboBox->addItem(RegionEnd); + if (_view) { int index = 1; for(std::list::iterator i = _view->get_cursorList().begin(); @@ -443,6 +432,7 @@ void DecodeTrace::populate_popup_form(QWidget *parent, QFormLayout *form) index++; } } + if (_start_count > _start_comboBox->count()) _start_index = 0; if (_end_count > _end_comboBox->count()) @@ -452,10 +442,7 @@ void DecodeTrace::populate_popup_form(QWidget *parent, QFormLayout *form) _start_comboBox->setCurrentIndex(_start_index); _end_comboBox->setCurrentIndex(_end_index); - connect(_start_comboBox, SIGNAL(currentIndexChanged(int)), - this, SLOT(on_region_set(int))); - connect(_end_comboBox, SIGNAL(currentIndexChanged(int)), - this, SLOT(on_region_set(int))); + on_region_set(_start_index); form->addRow(_start_comboBox, new QLabel( tr("Decode Start From"))); @@ -465,11 +452,8 @@ void DecodeTrace::populate_popup_form(QWidget *parent, QFormLayout *form) // Add stacking button pv::widgets::DecoderMenu *const decoder_menu = new pv::widgets::DecoderMenu(parent); - connect(decoder_menu, SIGNAL(decoder_selected(srd_decoder*)), - this, SLOT(on_stack_decoder(srd_decoder*))); - //connect(decoder_menu, SIGNAL(selected()), - // parent, SLOT(accept())); + QPushButton *const stack_button = new QPushButton(tr("Stack Decoder"), parent); stack_button->setMenu(decoder_menu); @@ -481,12 +465,21 @@ void DecodeTrace::populate_popup_form(QWidget *parent, QFormLayout *form) // Add ButtonBox (OK/Cancel) QDialogButtonBox *button_box = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, parent); - connect(button_box, SIGNAL(accepted()), parent, SLOT(accept())); - connect(button_box, SIGNAL(rejected()), parent, SLOT(reject())); + QHBoxLayout *confirm_button_box = new QHBoxLayout; confirm_button_box->addWidget(button_box, 0, Qt::AlignRight); form->addRow(confirm_button_box); + + connect(_start_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(on_region_set(int))); + + connect(_end_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(on_region_set(int))); + + connect(decoder_menu, SIGNAL(decoder_selected(srd_decoder *)), this, SLOT(on_stack_decoder(srd_decoder *))); + + connect(button_box, SIGNAL(accepted()), parent, SLOT(accept())); + + connect(button_box, SIGNAL(rejected()), parent, SLOT(reject())); } void DecodeTrace::draw_annotation(const pv::data::decode::Annotation &a, @@ -733,14 +726,15 @@ void DecodeTrace::create_decoder_form( const struct srd_channel *const pdch = (struct srd_channel *)l->data; QComboBox *const combo = create_probe_selector(parent, dec, pdch); - connect(combo, SIGNAL(currentIndexChanged(int)), - this, SLOT(on_probe_selected(int))); + decoder_form->addRow(tr("%1 (%2) *") .arg(QString::fromUtf8(pdch->name)) .arg(QString::fromUtf8(pdch->desc)), combo); const ProbeSelector s = {combo, dec, pdch}; _probe_selectors.push_back(s); + + connect(combo, SIGNAL(currentIndexChanged(int)), this, SLOT(on_probe_selected(int))); } // Add the optional channels @@ -748,14 +742,15 @@ void DecodeTrace::create_decoder_form( const struct srd_channel *const pdch = (struct srd_channel *)l->data; QComboBox *const combo = create_probe_selector(parent, dec, pdch); - connect(combo, SIGNAL(currentIndexChanged(int)), - this, SLOT(on_probe_selected(int))); + decoder_form->addRow(tr("%1 (%2)") .arg(QString::fromUtf8(pdch->name)) .arg(QString::fromUtf8(pdch->desc)), combo); const ProbeSelector s = {combo, dec, pdch}; _probe_selectors.push_back(s); + + connect(combo, SIGNAL(currentIndexChanged(int)), this, SLOT(on_probe_selected(int))); } // Add the options @@ -767,12 +762,11 @@ void DecodeTrace::create_decoder_form( // pv::widgets::DecoderGroupBox *const group = new pv::widgets::DecoderGroupBox(decoder_stack, dec, decoder_form, parent); - - connect(group, SIGNAL(del_stack(data::decode::Decoder*)), - this, SLOT(on_del_stack(data::decode::Decoder*))); - + form->addRow(group); _decoder_forms.push_back(group); + + connect(group, SIGNAL(del_stack(data::decode::Decoder*)), this, SLOT(on_del_stack(data::decode::Decoder*))); } QComboBox* DecodeTrace::create_probe_selector( @@ -873,19 +867,11 @@ int DecodeTrace::get_progress() } void DecodeTrace::on_decode_done() -{ -// if (_view) { -// _view->set_update(_viewport, true); -// _view->signals_changed(); -// } +{ on_new_decode_data(); _session->decode_done(); } - -void DecodeTrace::on_delete() -{ - _session->remove_decode_signal(this); -} + void DecodeTrace::on_probe_selected(int) { @@ -899,7 +885,7 @@ void DecodeTrace::on_stack_decoder(srd_decoder *decoder) _decoder_stack->push(new data::decode::Decoder(decoder)); - create_popup_form(); + // create_popup_form(); } void DecodeTrace::on_del_stack(data::decode::Decoder *dec) @@ -908,7 +894,7 @@ void DecodeTrace::on_del_stack(data::decode::Decoder *dec) assert(_decoder_stack); _decoder_stack->remove(dec); - create_popup_form(); + // create_popup_form(); } int DecodeTrace::rows_size() diff --git a/DSView/pv/view/decodetrace.h b/DSView/pv/view/decodetrace.h index d2d59f37..5b361e5c 100755 --- a/DSView/pv/view/decodetrace.h +++ b/DSView/pv/view/decodetrace.h @@ -58,6 +58,7 @@ class DecoderGroupBox; namespace view { +//create by SigSession class DecodeTrace : public Trace { Q_OBJECT @@ -98,6 +99,8 @@ public: DecodeTrace(pv::SigSession *session, pv::data::DecoderStack *decoder_stack, int index); + +public: ~DecodeTrace(); bool enabled(); @@ -147,7 +150,7 @@ protected: void paint_type_options(QPainter &p, int right, const QPoint pt, QColor fore); private: - void create_popup_form(); + void create_popup_form(dialogs::DSDialog *dlg); void populate_popup_form(QWidget *parent, QFormLayout *form); @@ -191,9 +194,7 @@ signals: private slots: void on_new_decode_data(); - - void on_delete(); - + void on_probe_selected(int); void on_stack_decoder(srd_decoder *decoder); @@ -204,6 +205,9 @@ private slots: void on_region_set(int index); +public: + volatile bool _delete_flag; //detroy it when deocde task end + private: pv::SigSession *_session; pv::data::DecoderStack *_decoder_stack; @@ -214,6 +218,7 @@ private: int _end_index; int _start_count; int _end_count; + QComboBox *_start_comboBox; QComboBox *_end_comboBox; QFormLayout *_pub_input_layer; @@ -224,7 +229,6 @@ private: std::vector _decoder_forms; std::vector _cur_row_headings; - dialogs::DSDialog *_popup; }; } // namespace view diff --git a/DSView/pv/view/view.cpp b/DSView/pv/view/view.cpp index 5ee7244f..91b53b5b 100755 --- a/DSView/pv/view/view.cpp +++ b/DSView/pv/view/view.cpp @@ -100,12 +100,7 @@ View::View(SigSession *session, pv::toolbars::SamplingBar *sampling_bar, QWidget assert(session); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - - connect(horizontalScrollBar(), SIGNAL(valueChanged(int)), - this, SLOT(h_scroll_value_changed(int))); - connect(verticalScrollBar(), SIGNAL(valueChanged(int)), - this, SLOT(v_scroll_value_changed(int))); - + // trace viewport map _trace_view_map[SR_CHANNEL_LOGIC] = TIME_VIEW; _trace_view_map[SR_CHANNEL_GROUP] = TIME_VIEW; @@ -128,16 +123,12 @@ View::View(SigSession *session, pv::toolbars::SamplingBar *sampling_bar, QWidget _time_viewport = new Viewport(*this, TIME_VIEW); _time_viewport->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); _time_viewport->setMinimumHeight(100); - connect(_time_viewport, SIGNAL(measure_updated()), - this, SLOT(on_measure_updated())); - connect(_time_viewport, SIGNAL(prgRate(int)), this, SIGNAL(prgRate(int))); + _fft_viewport = new Viewport(*this, FFT_VIEW); _fft_viewport->setVisible(false); _fft_viewport->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); _fft_viewport->setMinimumHeight(100); - connect(_fft_viewport, SIGNAL(measure_updated()), - this, SLOT(on_measure_updated())); - + _vsplitter = new QSplitter(this); _vsplitter->setOrientation(Qt::Vertical); _vsplitter->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); @@ -162,35 +153,6 @@ View::View(SigSession *session, pv::toolbars::SamplingBar *sampling_bar, QWidget _viewbottom->setFixedHeight(StatusHeight); layout->addWidget(_viewbottom, 1, 0); setViewport(_viewcenter); - connect(_vsplitter, SIGNAL(splitterMoved(int,int)), - this, SLOT(splitterMoved(int, int))); - - connect(_session, SIGNAL(device_setted()), - _devmode, SLOT(set_device())); - connect(_session, SIGNAL(signals_changed()), - this, SLOT(signals_changed()), Qt::DirectConnection); - connect(_session, SIGNAL(data_updated()), - this, SLOT(data_updated())); - connect(_session, SIGNAL(receive_trigger(quint64)), - this, SLOT(receive_trigger(quint64))); - connect(_session, SIGNAL(frame_ended()), - this, SLOT(receive_end())); - connect(_session, SIGNAL(frame_began()), - this, SLOT(frame_began())); - connect(_session, SIGNAL(show_region(uint64_t, uint64_t, bool)), - this, SLOT(show_region(uint64_t, uint64_t, bool))); - connect(_session, SIGNAL(show_wait_trigger()), - _time_viewport, SLOT(show_wait_trigger())); - connect(_session, SIGNAL(repeat_hold(int)), - this, SLOT(repeat_show())); - - connect(_devmode, SIGNAL(dev_changed(bool)), - this, SLOT(dev_changed(bool)), Qt::DirectConnection); - - connect(_header, SIGNAL(traces_moved()), - this, SLOT(on_traces_moved())); - connect(_header, SIGNAL(header_updated()), - this, SLOT(header_updated())); _time_viewport->installEventFilter(this); _fft_viewport->installEventFilter(this); @@ -213,6 +175,28 @@ View::View(SigSession *session, pv::toolbars::SamplingBar *sampling_bar, QWidget _cali = new pv::dialogs::Calibration(this); _cali->hide(); + + connect(horizontalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(h_scroll_value_changed(int))); + connect(verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(v_scroll_value_changed(int))); + + connect(_time_viewport, SIGNAL(measure_updated()),this, SLOT(on_measure_updated())); + connect(_time_viewport, SIGNAL(prgRate(int)), this, SIGNAL(prgRate(int))); + connect(_fft_viewport, SIGNAL(measure_updated()), this, SLOT(on_measure_updated())); + + connect(_vsplitter, SIGNAL(splitterMoved(int,int)), this, SLOT(splitterMoved(int, int))); + connect(_session, SIGNAL(device_setted()), _devmode, SLOT(set_device())); + connect(_session, SIGNAL(signals_changed()), this, SLOT(signals_changed()), Qt::DirectConnection); + connect(_session, SIGNAL(data_updated()), this, SLOT(data_updated())); + connect(_session, SIGNAL(receive_trigger(quint64)), this, SLOT(receive_trigger(quint64))); + connect(_session, SIGNAL(frame_ended()), this, SLOT(receive_end())); + connect(_session, SIGNAL(frame_began()), this, SLOT(frame_began())); + connect(_session, SIGNAL(show_region(uint64_t, uint64_t, bool)), this, SLOT(show_region(uint64_t, uint64_t, bool))); + + connect(_session, SIGNAL(show_wait_trigger()), _time_viewport, SLOT(show_wait_trigger())); + connect(_session, SIGNAL(repeat_hold(int)), this, SLOT(repeat_show())); + connect(_devmode, SIGNAL(dev_changed(bool)),this, SLOT(dev_changed(bool)), Qt::DirectConnection); + connect(_header, SIGNAL(traces_moved()),this, SLOT(on_traces_moved())); + connect(_header, SIGNAL(header_updated()),this, SLOT(header_updated())); } SigSession& View::session() diff --git a/DSView/pv/view/viewstatus.cpp b/DSView/pv/view/viewstatus.cpp index 3a1cf19f..cfad21d2 100755 --- a/DSView/pv/view/viewstatus.cpp +++ b/DSView/pv/view/viewstatus.cpp @@ -237,7 +237,7 @@ void ViewStatus::load_session(QJsonArray measure_array) measure_array.empty()) return; - foreach (const QJsonValue &measure_value, measure_array) { + for (const QJsonValue &measure_value : measure_array) { QJsonObject m_obj = measure_value.toObject(); int index = m_obj["site"].toInt(); int sig_index = m_obj["index"].toInt(); diff --git a/libsigrok4DSL/hardware/demo/demo.h b/libsigrok4DSL/hardware/demo/demo.h index 7fbb87e5..0a9cb52e 100755 --- a/libsigrok4DSL/hardware/demo/demo.h +++ b/libsigrok4DSL/hardware/demo/demo.h @@ -168,7 +168,7 @@ static const struct DEMO_profile supported_Demo[] = { (1 << DEMO_LOGIC100x16) | (1 << DEMO_ANALOG10x2) | (1 << DEMO_DSO200x2), - //SR_Mn(100), + //SR_Mn(100), SR_Gn(16), SR_Kn(20), 0, diff --git a/libsigrok4DSL/session.c b/libsigrok4DSL/session.c index 34923f4c..ce46fcb9 100755 --- a/libsigrok4DSL/session.c +++ b/libsigrok4DSL/session.c @@ -36,6 +36,8 @@ int bExportOriginalData = 0; //able export all data +int session_loop_stop_flag = 0; + /** * @file * @@ -403,12 +405,14 @@ SR_API int sr_session_run(void) session->running = TRUE; + session_loop_stop_flag = 0; + sr_info("Running..."); /* Do we have real sources? */ if (session->num_sources == 1 && session->pollfds[0].fd == -1) { /* Dummy source, freewheel over it. */ - while (session->num_sources) { + while (session->num_sources && !session_loop_stop_flag) { if (session->abort_session) { session->sources[0].cb(-1, -1, session->sources[0].cb_data); break; @@ -418,8 +422,9 @@ SR_API int sr_session_run(void) } } else { /* Real sources, use g_poll() main loop. */ - while (session->num_sources) - sr_session_iteration(TRUE); + while (session->num_sources && !session_loop_stop_flag){ + sr_session_iteration(TRUE); + } } g_mutex_lock(&session->stop_mutex); @@ -484,9 +489,11 @@ SR_API int sr_session_stop(void) return SR_ERR_BUG; } + session_loop_stop_flag = 1; //set flag, the run loop will exit + g_mutex_lock(&session->stop_mutex); if (session->running) - session->abort_session = TRUE; + session->abort_session = TRUE; g_mutex_unlock(&session->stop_mutex); return SR_OK;