2
0
forked from Ivasoft/DSView

decode task save stop anddestory

This commit is contained in:
dreamsourcelabTAI
2021-11-08 19:56:35 +08:00
parent 1d3b8accfd
commit 0e4f0ae52e
28 changed files with 810 additions and 535 deletions

View File

@@ -183,6 +183,8 @@ int main(int argc, char *argv[])
//Run the application
ret = a.exec();
control->Stop();
}
catch (const std::exception &e)
{

View File

@@ -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();

View File

@@ -48,6 +48,8 @@ public:
bool Start();
void Stop();
void UnInit();
const char* GetLastError();

View File

@@ -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

View File

@@ -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<const srd_channel*, int> _probes;
std::map<std::string, GVariant*> _options;
std::map<const srd_channel*, int> _probes_back;
std::map<std::string, GVariant*> _options_back;
bool _shown;
uint64_t _decode_start;
uint64_t _decode_end;
uint64_t _decode_start_back;
uint64_t _decode_end_back;
std::map<const srd_channel*, int> _probes;
std::map<std::string, GVariant*> _options;
std::map<const srd_channel*, int> _probes_back;
std::map<std::string, GVariant*> _options_back;
uint64_t _decode_start, _decode_end;
uint64_t _decode_start_back, _decode_end_back;
bool _setted;
bool _setted;
bool _shown;
};
} // namespace decode

View File

@@ -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<std::mutex> lock(_global_visitor_mutex);

View File

@@ -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:"<<i;
}
while(i < decode_end && !_no_memory)
{
if (status->m_bStop){
break;
}
std::vector<const uint8_t *> chunk;
std::vector<uint8_t> 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<std::mutex> decode_lock(_global_decode_mutex);
if (_bThreadStop){
return;
}
optional<uint64_t> 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()

View File

@@ -21,23 +21,24 @@
#ifndef DSVIEW_PV_DATA_DECODERSTACK_H
#define DSVIEW_PV_DATA_DECODERSTACK_H
#include <libsigrokdecode4DSL/libsigrokdecode.h>
#include <list>
#include <boost/optional.hpp>
#include <boost/optional.hpp>
#include <QObject>
#include <QString>
#include <mutex>
#include <thread>
#include <mutex>
#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<decode::Decoder*> _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;
};

View File

@@ -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);

View File

@@ -92,19 +92,34 @@ uint64_t Snapshot::get_sample_count()
std::lock_guard<std::mutex> lock(_mutex);
return _sample_count;
}
uint64_t Snapshot::get_ring_start()
{
std::lock_guard<std::mutex> 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<std::mutex> 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)

View File

@@ -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;

View File

@@ -204,6 +204,11 @@ void DevInst::run()
sr_session_run();
}
void DevInst::stop()
{
sr_session_stop();
}
bool DevInst::is_usable()
{
return _usable;

View File

@@ -117,6 +117,8 @@ public:
virtual void run();
virtual void stop();
virtual void* get_id();
virtual sr_dev_inst* dev_inst() = 0;

View File

@@ -96,7 +96,7 @@ QJsonArray File::get_decoders()
}
}
zip_close(archive);
zip_close(archive);
}
return dec_array;

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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());

View File

@@ -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();

View File

@@ -64,6 +64,7 @@
#include <QJsonDocument>
#include <QFuture>
#include <QtConcurrent/QtConcurrent>
#include <QDebug>
#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<void (const QString)> 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<void (const QString)> 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<void (const QString)> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<void (const QString)> error_handler)
void SigSession::start_hotplug_work(boost::function<void (const QString)> error_handler)
{
// Begin the session
@@ -1284,20 +1306,18 @@ void SigSession::start_hotplug_proc(boost::function<void (const QString)> 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<view::DecodeTrace*>& 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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

View File

@@ -54,6 +54,8 @@ struct srd_channel;
class DecoderStatus;
typedef std::lock_guard<std::mutex> 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<void (const QString)> error_handler);
void capture_init();
void start_capture(bool instant, boost::function<void (const QString)> error_handler);
bool get_capture_status(bool &triggered, int &progress);
void container_init();
std::set<data::SignalData*> 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<view::DecodeTrace*>& 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<view::SpectrumTrace*>& get_spectrum_traces();
@@ -207,53 +214,78 @@ public:
void del_group();
void start_hotplug_proc(boost::function<void (const QString)> error_handler);
void stop_hotplug_proc();
void start_hotplug_work(boost::function<void (const QString)> 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<void (const QString)> 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<view::Signal*> _signals;
capture_state _capture_state;
bool _instant;
uint64_t _cur_snap_samplerate;
uint64_t _cur_samplelimits;
std::vector<view::Signal*> _signals;
std::vector<view::GroupSignal*> _group_traces;
std::vector<view::DecodeTrace*> _decode_traces;
pv::data::DecoderModel *_decoder_model;
std::vector<view::DecodeTrace*> _decode_tasks;
pv::data::DecoderModel *_decoder_model;
std::vector<view::SpectrumTrace*> _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

View File

@@ -83,14 +83,12 @@ SigSession* StoreSession::session()
}
std::pair<uint64_t, uint64_t> StoreSession::progress()
{
//lock_guard<mutex> lock(_mutex);
{
return std::make_pair(_units_stored, _unit_count);
}
const QString& StoreSession::error()
{
//lock_guard<mutex> 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<view::DecodeTrace*> &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<view::DecodeTrace*> &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<const srd_channel*, int> 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;
}

View File

@@ -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);

View File

@@ -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("<i>* Required channels</i>"), 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<Cursor*>::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("<b>%1</b> (%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("<b>%1</b> (%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()

View File

@@ -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<pv::widgets::DecoderGroupBox*> _decoder_forms;
std::vector<QString> _cur_row_headings;
dialogs::DSDialog *_popup;
};
} // namespace view

View File

@@ -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()

View File

@@ -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();

View File

@@ -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,

View File

@@ -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;