2
0
forked from Ivasoft/DSView

fix: The oscilloscope incorrectly parses the data package

This commit is contained in:
dreamsourcelabTAI
2023-02-10 10:16:33 +08:00
parent 1cff13075e
commit 3fee3fab50
4 changed files with 97 additions and 68 deletions

View File

@@ -48,7 +48,7 @@ DsoSnapshot::DsoSnapshot() :
_envelope_en = false;
_envelope_done = false;
_instant = false;
_threshold = 0;
_threshold = 0;
memset(_envelope_levels, 0, sizeof(_envelope_levels));
}
@@ -81,8 +81,7 @@ void DsoSnapshot::init_all()
_ring_sample_count = 0;
_memory_failed = false;
_last_ended = true;
_envelope_done = false;
_ch_enable.clear();
_envelope_done = false;
for (unsigned int i = 0; i < _channel_num; i++) {
for (unsigned int level = 0; level < ScaleStepCount; level++) {
@@ -112,41 +111,57 @@ void DsoSnapshot::free_data()
}
void DsoSnapshot::first_payload(const sr_datafeed_dso &dso, uint64_t total_sample_count,
std::map<int, bool> ch_enable, bool instant)
GSList *channels, bool instant)
{
bool re_alloc = false;
unsigned int channel_num = 0;
assert(channels);
//dsv_info("first total_sample_count:%llu", total_sample_count);
for (auto& iter:ch_enable) {
if (iter.second)
channel_num++;
bool channel_changed = false;
uint16_t channel_num = 0;
for (const GSList *l = channels; l; l = l->next) {
sr_channel *const probe = (sr_channel*)l->data;
if (probe->type == SR_CHANNEL_DSO) {
if (probe->enabled){
channel_num++;
if (!channel_changed){
channel_changed = !has_data(probe->index);
}
}
}
}
assert(channel_num != 0);
if (total_sample_count != _total_sample_count || channel_num != _channel_num){
re_alloc = true;
}
_total_sample_count = total_sample_count;
_channel_num = channel_num;
_instant = instant;
_ch_enable = ch_enable;
bool isOk = true;
uint64_t size = _total_sample_count * _channel_num + sizeof(uint64_t);
if (re_alloc || size != _capacity) {
if (total_sample_count != _total_sample_count
|| channel_num != _channel_num
|| channel_changed){
free_data();
for (int ch=0; ch<_channel_num; ch++){
uint8_t *buf = (uint8_t*)malloc(_total_sample_count + 1);
if (buf == NULL){
isOk = false;
dsv_err("DsoSnapshot::first_payload, Malloc memory failed!");
break;
_ch_index.clear();
_total_sample_count = total_sample_count;
_channel_num = channel_num;
for (const GSList *l = channels; l; l = l->next) {
sr_channel *const probe = (sr_channel*)l->data;
if (probe->type == SR_CHANNEL_DSO && probe->enabled) {
uint8_t *chan_buffer = (uint8_t*)malloc(total_sample_count + 1);
if (chan_buffer == NULL){
isOk = false;
dsv_err("DsoSnapshot::first_payload, Malloc memory failed!");
break;
}
_ch_data.push_back(chan_buffer);
_ch_index.push_back(probe->index);
}
_ch_data.push_back(buf);
}
}
if (isOk) {
free_envelop();
@@ -171,7 +186,6 @@ void DsoSnapshot::first_payload(const sr_datafeed_dso &dso, uint64_t total_sampl
}
if (isOk) {
_capacity = size;
_memory_failed = false;
append_payload(dso);
_last_ended = false;
@@ -187,7 +201,9 @@ void DsoSnapshot::append_payload(const sr_datafeed_dso &dso)
{
std::lock_guard<std::mutex> lock(_mutex);
if (_channel_num > 0 && dso.num_samples > 0) {
//dsv_info("write sample_count:%llu", dso.num_samples);
if (_channel_num > 0 && dso.num_samples > 0) {
append_data(dso.data, dso.num_samples, _instant);
// Generate the first mip-map from the data
@@ -211,10 +227,8 @@ void DsoSnapshot::append_data(void *data, uint64_t samples, bool instant)
_sample_count = samples;
}
assert(samples <= _total_sample_count);
uint8_t *end = (uint8_t*)data + samples * _channel_num;
assert(_sample_count <= _total_sample_count);
for (int ch = 0; ch < _channel_num; ch++)
{
uint8_t *src = (uint8_t*)data + ch;
@@ -224,11 +238,11 @@ void DsoSnapshot::append_data(void *data, uint64_t samples, bool instant)
dest += old_sample_count;
}
while (src < end)
for (int i = 0; i < samples; i++)
{
*dest++ = *src;
src += _channel_num;
}
}
}
}
@@ -250,11 +264,14 @@ const uint8_t *DsoSnapshot::get_samples(int64_t start_sample, int64_t end_sample
assert(end_sample < (int64_t)_sample_count);
assert(start_sample <= end_sample);
if (index < 0 || index >= _ch_data.size()){
assert(false);
}
int order = get_ch_order(index);
return (uint8_t*)_ch_data[index] + start_sample;
if (order == -1){
dsv_err("The channel index is not exist:%d", index);
assert(false);
}
return (uint8_t*)_ch_data[order] + start_sample;
}
void DsoSnapshot::get_envelope_section(EnvelopeSection &s,
@@ -449,14 +466,6 @@ double DsoSnapshot::cal_vmean(int index)
return vmean;
}
bool DsoSnapshot::has_data(int index)
{
if (_ch_enable.find(index) != _ch_enable.end())
return _ch_enable[index];
else
return false;
}
int DsoSnapshot::get_block_num()
{
const uint64_t size = _sample_count * get_unit_bytes() * get_channel_num();
@@ -504,5 +513,24 @@ bool DsoSnapshot::get_max_min_value(uint8_t &maxv, uint8_t &minv, int chan_index
return true;
}
bool DsoSnapshot::has_data(int sig_index)
{
return get_ch_order(sig_index) != -1;
}
int DsoSnapshot::get_ch_order(int sig_index)
{
uint16_t order = 0;
for (uint16_t i : _ch_index) {
if (i == sig_index)
return order;
else
order++;
}
return -1;
}
} // namespace data
} // namespace pv

View File

@@ -25,11 +25,10 @@
#include <utility>
#include <vector>
#include <map>
#include <libsigrok.h>
#include "snapshot.h"
namespace DsoSnapshotTest {
class Basic;
}
@@ -87,7 +86,7 @@ public:
void init();
void first_payload(const sr_datafeed_dso &dso, uint64_t total_sample_count,
std::map<int, bool> ch_enable, bool instant);
GSList *channels, bool instant);
void append_payload(const sr_datafeed_dso &dso);
const uint8_t* get_samples(int64_t start_sample, int64_t end_sample, uint16_t index);
@@ -98,7 +97,7 @@ public:
void enable_envelope(bool enable);
double cal_vrms(double zero_off, int index);
double cal_vmean(int index);
bool has_data(int index);
bool has_data(int sig_index);
int get_block_num();
uint64_t get_block_size(int block_index);
@@ -117,14 +116,14 @@ private:
void free_envelop();
void reallocate_envelope(Envelope &l);
void append_payload_to_envelope_levels(bool header);
void free_data();
void free_data();
int get_ch_order(int sig_index);
private:
struct Envelope _envelope_levels[2*DS_MAX_DSO_PROBES_NUM][ScaleStepCount];
bool _envelope_en;
bool _envelope_done;
bool _instant;
std::map<int, bool> _ch_enable;
bool _instant;
std::vector<uint8_t*> _ch_data;
float _threshold;

View File

@@ -29,16 +29,17 @@
namespace pv {
namespace data {
Snapshot::Snapshot(int unit_size, uint64_t total_sample_count, unsigned int channel_num) :
_capacity(0),
_channel_num(channel_num),
_sample_count(0),
_total_sample_count(total_sample_count),
_ring_sample_count(0),
_unit_size(unit_size),
_memory_failed(false)
Snapshot::Snapshot(int unit_size, uint64_t total_sample_count, unsigned int channel_num)
{
assert(_unit_size > 0);
assert(unit_size > 0);
_capacity = 0;
_channel_num = channel_num;
_sample_count = 0;
_total_sample_count = total_sample_count;
_ring_sample_count = 0;
_unit_size = unit_size;
_memory_failed = false;
_last_ended = true;
_unit_bytes = 1;
_unit_pitch = 0;

View File

@@ -971,20 +971,21 @@ namespace pv
}
if (_capture_data->get_dso()->last_ended())
{
std::map<int, bool> sig_enable;
{
// reset scale of dso signal
for (auto s : _signals)
{
if (s->signal_type() == DSO_SIGNAL){
view::DsoSignal *dsoSig = (view::DsoSignal*)s;
dsoSig->set_scale(dsoSig->get_view_rect().height());
sig_enable[dsoSig->get_index()] = dsoSig->enabled();
dsoSig->set_scale(dsoSig->get_view_rect().height());
}
}
// first payload
_capture_data->get_dso()->first_payload(o, _device_agent.get_sample_limit(), sig_enable, _is_instant);
_capture_data->get_dso()->first_payload(o,
_device_agent.get_sample_limit(),
_device_agent.get_channels(),
_is_instant);
}
else
{