From 258fa4dfd3cfa2a8386b04dd82316dce4a7d8d92 Mon Sep 17 00:00:00 2001 From: dreamsourcelabTAI Date: Wed, 30 Nov 2022 19:43:52 +0800 Subject: [PATCH] Load data in sections for each channel --- DSView/pv/data/logicsnapshot.cpp | 155 +++------- DSView/pv/data/logicsnapshot.h | 13 +- DSView/pv/data/snapshot.cpp | 10 +- DSView/pv/data/snapshot.h | 1 - libsigrok4DSL/session_driver.c | 514 +++++++++++++++++++++++-------- 5 files changed, 437 insertions(+), 256 deletions(-) diff --git a/DSView/pv/data/logicsnapshot.cpp b/DSView/pv/data/logicsnapshot.cpp index 35025d39..cf4e0424 100644 --- a/DSView/pv/data/logicsnapshot.cpp +++ b/DSView/pv/data/logicsnapshot.cpp @@ -91,7 +91,6 @@ void LogicSnapshot::init_all() _block_num = 0; _byte_fraction = 0; _ch_fraction = 0; - _src_ptr = NULL; _dest_ptr = NULL; _data = NULL; _memory_failed = false; @@ -140,9 +139,11 @@ void LogicSnapshot::capture_ended() // calc root of current block if (*((uint64_t *)iter[index0].lbp[index1]) != 0) iter[index0].value += 1ULL << index1; + if (*((uint64_t *)iter[index0].lbp[index1] + LeafBlockSpace / sizeof(uint64_t) - 1) != 0) { iter[index0].tog += 1ULL << index1; - } else { + } + else { // trim leaf to free space free(iter[index0].lbp[index1]); iter[index0].lbp[index1] = NULL; @@ -206,7 +207,7 @@ void LogicSnapshot::first_payload(const sr_datafeed_logic &logic, uint64_t total } } - assert(_channel_num < LOGIC_TMP_BUF_MAX_SIZE); + assert(_channel_num < CHANNEL_MAX_COUNT); _sample_count = 0; @@ -225,10 +226,7 @@ void LogicSnapshot::append_payload(const sr_datafeed_logic &logic) { std::lock_guard lock(_mutex); - if (logic.format == LA_CROSS_DATA) - append_cross_payload(logic); - else if (logic.format == LA_SPLIT_DATA) - append_split_payload(logic); + append_cross_payload(logic); _have_data = true; } @@ -241,7 +239,7 @@ void LogicSnapshot::append_cross_payload(const sr_datafeed_logic &logic) if (_sample_count >= _total_sample_count) return; - _src_ptr = logic.data; + void *data_src_ptr = logic.data; uint64_t len = logic.length; // samples not accurate, lead to a larger _sampole_count // _sample_count should be fixed in the last packet @@ -249,16 +247,16 @@ void LogicSnapshot::append_cross_payload(const sr_datafeed_logic &logic) uint64_t samples = ceil(logic.length * 8.0 / _channel_num); if (_sample_count + samples < _total_sample_count) { _sample_count += samples; - } else { - //len = ceil((_total_sample_count - _sample_count) * _channel_num / 8.0); + } + else { _sample_count = _total_sample_count; } while (_sample_count > _block_num * LeafBlockSamples) { uint8_t index0 = _block_num / RootScale; uint8_t index1 = _block_num % RootScale; - for(auto& iter : _ch_data) { + for(auto& iter : _ch_data) { if (iter[index0].lbp[index1] == NULL){ iter[index0].lbp[index1] = malloc(LeafBlockSpace); @@ -268,8 +266,7 @@ void LogicSnapshot::append_cross_payload(const sr_datafeed_logic &logic) } } - uint64_t *mipmap_ptr = (uint64_t *)iter[index0].lbp[index1] + - (LeafBlockSamples / Scale); + uint64_t *mipmap_ptr = (uint64_t *)iter[index0].lbp[index1] + (LeafBlockSamples / Scale); memset(mipmap_ptr, 0, LeafBlockSpace - (LeafBlockSamples / 8)); } _block_num++; @@ -278,17 +275,21 @@ void LogicSnapshot::append_cross_payload(const sr_datafeed_logic &logic) // bit align while (((_ch_fraction != 0) || (_byte_fraction != 0)) && (len != 0)) { uint8_t *dp_tmp = (uint8_t *)_dest_ptr; - uint8_t *sp_tmp = (uint8_t *)_src_ptr; + uint8_t *sp_tmp = (uint8_t *)data_src_ptr; + + if (_dest_ptr == NULL){ + assert(false); + } do { - //*(uint8_t *)_dest_ptr++ = *(uint8_t *)_src_ptr++; *dp_tmp++ = *sp_tmp++; _byte_fraction = (_byte_fraction + 1) % ScaleSize; len--; - } while ((_byte_fraction != 0) && (len != 0)); + } + while ((_byte_fraction != 0) && (len != 0)); _dest_ptr = dp_tmp; - _src_ptr = sp_tmp; + data_src_ptr = sp_tmp; if (_byte_fraction == 0) { const uint64_t index0 = _ring_sample_count / RootNodeSamples; @@ -307,24 +308,25 @@ void LogicSnapshot::append_cross_payload(const sr_datafeed_logic &logic) assert(_ch_fraction == 0); assert(_byte_fraction == 0); assert(_ring_sample_count % Scale == 0); + uint64_t pre_index0 = _ring_sample_count / RootNodeSamples; uint64_t pre_index1 = (_ring_sample_count >> LeafBlockPower) % RootScale; uint64_t pre_offset = (_ring_sample_count % LeafBlockSamples) / Scale; uint64_t *src_ptr = NULL; uint64_t *dest_ptr; int order = 0; - const uint64_t align_size = len / ScaleSize / _channel_num; + const uint64_t align_size = len / _channel_num / ScaleSize; _ring_sample_count += align_size * Scale; - - for(auto& iter : _ch_data) { + for(auto& iter : _ch_data) + { uint64_t index0 = pre_index0; uint64_t index1 = pre_index1; - src_ptr = (uint64_t *)_src_ptr + order; + src_ptr = (uint64_t *)data_src_ptr + order; _dest_ptr = iter[index0].lbp[index1]; dest_ptr = (uint64_t *)_dest_ptr + pre_offset; - while (src_ptr < (uint64_t *)_src_ptr + (align_size * _channel_num)) { + while (src_ptr < (uint64_t *)data_src_ptr + (align_size * _channel_num)) { const uint64_t tmp_u64 = *src_ptr; *dest_ptr++ = tmp_u64; src_ptr += _channel_num; @@ -355,8 +357,9 @@ void LogicSnapshot::append_cross_payload(const sr_datafeed_logic &logic) } order++; } + len -= align_size * _channel_num * ScaleSize; - _src_ptr = src_ptr - _channel_num + 1; + data_src_ptr = src_ptr - _channel_num + 1; } // fraction data append @@ -367,7 +370,7 @@ void LogicSnapshot::append_cross_payload(const sr_datafeed_logic &logic) _dest_ptr = (uint8_t *)_ch_data[_ch_fraction][index0].lbp[index1] + offset; uint8_t *dp_tmp = (uint8_t *)_dest_ptr; - uint8_t *sp_tmp = (uint8_t *)_src_ptr; + uint8_t *sp_tmp = (uint8_t *)data_src_ptr; while(len-- != 0) { *dp_tmp++ = *sp_tmp++; if (++_byte_fraction == ScaleSize) { @@ -380,79 +383,6 @@ void LogicSnapshot::append_cross_payload(const sr_datafeed_logic &logic) } } -void LogicSnapshot::append_split_payload(const sr_datafeed_logic &logic) -{ - assert(logic.format == LA_SPLIT_DATA); - - uint64_t samples = logic.length * 8; - uint16_t order = logic.order; - assert(order < _ch_data.size()); - - if (_sample_cnt[order] >= _total_sample_count) - return; - - if (_sample_cnt[order] + samples < _total_sample_count) { - _sample_cnt[order] += samples; - } else { - samples = _total_sample_count - _sample_cnt[order]; - _sample_cnt[order] = _total_sample_count; - } - - while (_sample_cnt[order] > _block_cnt[order] * LeafBlockSamples) { - uint8_t index0 = _block_cnt[order] / RootScale; - uint8_t index1 = _block_cnt[order] % RootScale; - - if (_ch_data[order][index0].lbp[index1] == NULL) - { - _ch_data[order][index0].lbp[index1] = malloc(LeafBlockSpace); - if (_ch_data[order][index0].lbp[index1] == NULL) - { - _memory_failed = true; - return; - } - } - - memset(_ch_data[order][index0].lbp[index1], 0, LeafBlockSpace); - _block_cnt[order]++; - } - - while(samples > 0) { - const uint64_t index0 = _ring_sample_cnt[order] / RootNodeSamples; - const uint64_t index1 = (_ring_sample_cnt[order] >> LeafBlockPower) % RootScale; - const uint64_t offset = (_ring_sample_cnt[order] % LeafBlockSamples) / 8; - _dest_ptr = (uint8_t *)_ch_data[order][index0].lbp[index1] + offset; - - uint64_t bblank = (LeafBlockSamples - (_ring_sample_cnt[order] & LeafMask)); - if (samples >= bblank) { - memcpy((uint8_t*)_dest_ptr, (uint8_t *)logic.data, bblank/8); - _ring_sample_cnt[order] += bblank; - samples -= bblank; - - // calc mipmap of current block - calc_mipmap(order, index0, index1, LeafBlockSamples); - - // calc root of current block - if (*((uint64_t *)_ch_data[order][index0].lbp[index1]) != 0) - _ch_data[order][index0].value += 1ULL<< index1; - if (*((uint64_t *)_ch_data[order][index0].lbp[index1] + LeafBlockSpace / sizeof(uint64_t) - 1) != 0) { - _ch_data[order][index0].tog += 1ULL << index1; - - } else { - // trim leaf to free space - free(_ch_data[order][index0].lbp[index1]); - _ch_data[order][index0].lbp[index1] = NULL; - } - } else { - memcpy((uint8_t*)_dest_ptr, (uint8_t *)logic.data, samples/8); - _ring_sample_cnt[order] += samples; - samples = 0; - } - } - - _sample_count = array::find_min_uint64(_sample_cnt, _channel_num); - _ring_sample_count = array::find_min_uint64(_ring_sample_cnt, _channel_num); -} - void LogicSnapshot::calc_mipmap(unsigned int order, uint8_t index0, uint8_t index1, uint64_t samples) { uint8_t offset; @@ -485,8 +415,7 @@ void LogicSnapshot::calc_mipmap(unsigned int order, uint8_t index0, uint8_t inde } } -const uint8_t *LogicSnapshot::get_samples(uint64_t start_sample, uint64_t &end_sample, - int sig_index) +const uint8_t *LogicSnapshot::get_samples(uint64_t start_sample, uint64_t &end_sample, int sig_index) { uint64_t sample_count = get_sample_count(); assert(start_sample < sample_count); @@ -496,6 +425,7 @@ const uint8_t *LogicSnapshot::get_samples(uint64_t start_sample, uint64_t &end_s int order = get_ch_order(sig_index); uint64_t root_index = start_sample >> (LeafBlockPower + RootScalePower); uint8_t root_pos = (start_sample & RootMask) >> LeafBlockPower; + uint64_t block_offset = (start_sample & LeafMask) / 8; end_sample = (root_index << (LeafBlockPower + RootScalePower)) + (root_pos << LeafBlockPower) + @@ -520,8 +450,12 @@ bool LogicSnapshot::get_sample(uint64_t index, int sig_index) uint64_t root_index = index >> (LeafBlockPower + RootScalePower); uint8_t root_pos = (index & RootMask) >> LeafBlockPower; uint64_t root_pos_mask = 1ULL << root_pos; + + uint64_t index0_r = _ring_sample_count >> (LeafBlockPower + RootScalePower); + uint64_t index1_r = (_ring_sample_count >> LeafBlockPower) % RootScale; + bool bAble = root_index < index0_r || (root_index == index0_r && root_pos <= index1_r); - if ((_ch_data[order][root_index].tog & root_pos_mask) == 0) { + if (bAble && (_ch_data[order][root_index].tog & root_pos_mask) == 0) { return (_ch_data[order][root_index].value & root_pos_mask) != 0; } else { uint64_t *lbp = (uint64_t *)_ch_data[order][root_index].lbp[root_pos]; @@ -589,9 +523,7 @@ bool LogicSnapshot::get_display_edges(std::vector > &edges return start_sample; } -bool LogicSnapshot::get_nxt_edge( - uint64_t &index, bool last_sample, uint64_t end, - double min_length, int sig_index) +bool LogicSnapshot::get_nxt_edge(uint64_t &index, bool last_sample, uint64_t end, double min_length, int sig_index) { if (index > end) return false; @@ -607,30 +539,39 @@ bool LogicSnapshot::get_nxt_edge( bool edge_hit = false; // linear search for the next transition on the root level - for (int64_t i = root_index; !edge_hit && (index <= end) && i < (int64_t)_ch_data[order].size(); i++) { + for (int64_t i = root_index; !edge_hit && (index <= end) && i < (int64_t)_ch_data[order].size(); i++) + { uint64_t cur_mask = (~0ULL << root_pos); + do { uint64_t cur_tog = _ch_data[order][i].tog & cur_mask; + if (cur_tog != 0) { uint64_t first_edge_pos = bsf_folded(cur_tog); uint64_t *lbp = (uint64_t *)_ch_data[order][i].lbp[first_edge_pos]; uint64_t blk_start = (i << (LeafBlockPower + RootScalePower)) + (first_edge_pos << LeafBlockPower); index = max(blk_start, index); + if (min_level < ScaleLevel) { uint64_t block_end = min(index | LeafMask, end); edge_hit = block_nxt_edge(lbp, index, block_end, last_sample, min_level); - } else { + } + else { edge_hit = true; } + if (first_edge_pos == RootScale - 1) break; cur_mask = (~0ULL << (first_edge_pos + 1)); - } else { + } + else { index = (index + (1 << (LeafBlockPower + RootScalePower))) & (~0ULL << (LeafBlockPower + RootScalePower)); break; } - } while (!edge_hit && index < end); + } + while (!edge_hit && index < end); + root_pos = 0; } return edge_hit; diff --git a/DSView/pv/data/logicsnapshot.h b/DSView/pv/data/logicsnapshot.h index 1e1abdca..10aa9be7 100644 --- a/DSView/pv/data/logicsnapshot.h +++ b/DSView/pv/data/logicsnapshot.h @@ -31,8 +31,7 @@ #include #include -#define CHANNEL_MAX_COUNT 128 -#define LOGIC_TMP_BUF_MAX_SIZE 512 +#define CHANNEL_MAX_COUNT 512 namespace LogicSnapshotTest { class Pow2; @@ -126,7 +125,6 @@ private: void calc_mipmap(unsigned int order, uint8_t index0, uint8_t index1, uint64_t samples); void append_cross_payload(const sr_datafeed_logic &logic); - void append_split_payload(const sr_datafeed_logic &logic); bool block_nxt_edge(uint64_t *lbp, uint64_t &index, uint64_t block_end, bool last_sample, unsigned int min_level); @@ -190,13 +188,12 @@ private: uint64_t _block_num; uint8_t _byte_fraction; uint16_t _ch_fraction; - void *_src_ptr; void *_dest_ptr; - uint64_t _sample_cnt[LOGIC_TMP_BUF_MAX_SIZE]; - uint64_t _block_cnt[LOGIC_TMP_BUF_MAX_SIZE]; - uint64_t _ring_sample_cnt[LOGIC_TMP_BUF_MAX_SIZE]; - uint64_t _last_sample[LOGIC_TMP_BUF_MAX_SIZE]; + uint64_t _sample_cnt[CHANNEL_MAX_COUNT]; + uint64_t _block_cnt[CHANNEL_MAX_COUNT]; + uint64_t _ring_sample_cnt[CHANNEL_MAX_COUNT]; + uint64_t _last_sample[CHANNEL_MAX_COUNT]; friend class LogicSnapshotTest::Pow2; friend class LogicSnapshotTest::Basic; diff --git a/DSView/pv/data/snapshot.cpp b/DSView/pv/data/snapshot.cpp index 25152a0d..8558ea5c 100644 --- a/DSView/pv/data/snapshot.cpp +++ b/DSView/pv/data/snapshot.cpp @@ -44,7 +44,6 @@ Snapshot::Snapshot(int unit_size, uint64_t total_sample_count, unsigned int chan _unit_bytes = 1; _unit_pitch = 0; _have_data = false; - _real_sample_count = 0; } Snapshot::~Snapshot() @@ -59,7 +58,6 @@ void Snapshot::free_data() _data = NULL; _capacity = 0; _sample_count = 0; - _real_sample_count = 0; } _ch_index.clear(); } @@ -75,13 +73,7 @@ bool Snapshot::empty() uint64_t Snapshot::get_sample_count() { std::lock_guard lock(_mutex); - //return _sample_count; - // /* - if (_real_sample_count > 0) - return _real_sample_count; - else - return _sample_count; - // */ + return _sample_count; } uint64_t Snapshot::get_ring_start() diff --git a/DSView/pv/data/snapshot.h b/DSView/pv/data/snapshot.h index 1c3b7ae2..e2ee9dbc 100644 --- a/DSView/pv/data/snapshot.h +++ b/DSView/pv/data/snapshot.h @@ -99,7 +99,6 @@ protected: uint64_t _capacity; unsigned int _channel_num; uint64_t _sample_count; - uint64_t _real_sample_count; uint64_t _total_sample_count; uint64_t _ring_sample_count; int _unit_size; diff --git a/libsigrok4DSL/session_driver.c b/libsigrok4DSL/session_driver.c index 572e0671..822261b2 100644 --- a/libsigrok4DSL/session_driver.c +++ b/libsigrok4DSL/session_driver.c @@ -96,6 +96,8 @@ static void get_file_short_name(const char *file, char *buf, int buflen) *wr = '\0'; } +struct session_packet_buffer; + struct session_vdev { int version; @@ -122,6 +124,22 @@ struct session_vdev uint32_t ref_max; uint8_t max_height; struct sr_status mstatus; + struct session_packet_buffer *packet_buffer; +}; + +#define SESSION_MAX_CHANNEL_COUNT 512 + +struct session_packet_buffer +{ + void *post_buf; + uint64_t post_buf_len; + uint64_t post_len; + + uint64_t block_buf_len; + uint64_t block_chan_read_pos; + uint64_t block_data_len; + void *block_bufs[SESSION_MAX_CHANNEL_COUNT]; + uint64_t block_poss[SESSION_MAX_CHANNEL_COUNT]; }; static const int hwoptions[] = { @@ -234,7 +252,7 @@ static int receive_data(int fd, int revents, const struct sr_dev_inst *sdi) assert(sdi->priv); (void)fd; - //(void)revents; + (void)revents; sr_detail("Feed chunk."); @@ -242,150 +260,145 @@ static int receive_data(int fd, int revents, const struct sr_dev_inst *sdi) packet.status = SR_PKT_OK; vdev = sdi->priv; + + assert(vdev->unit_bits > 0); + assert(vdev->cur_channel >= 0); + assert(vdev->archive); - if (vdev != NULL) + if (vdev->cur_channel < vdev->num_probes) { - assert(vdev->unit_bits > 0); - assert(vdev->cur_channel >= 0); - assert(vdev->archive); - - if (vdev->cur_channel < vdev->num_probes) + if (vdev->version == 1) { - if (vdev->version == 1) + ret = unzReadCurrentFile(vdev->archive, vdev->buf, CHUNKSIZE); + if (-1 == ret) + { + sr_err("%s: Read inner file error!", __func__); + send_error_packet(sdi, vdev, &packet); + return FALSE; + } + } + else if (vdev->version == 2) + { + channel = vdev->cur_channel; + pl = sdi->channels; + + while (channel--){ + pl = pl->next; + } + + probe = (struct sr_channel *)pl->data; + + if (vdev->capfile == 0) + { + char *type_name = (probe->type == SR_CHANNEL_LOGIC) ? "L" : (probe->type == SR_CHANNEL_DSO) ? "O" + : (probe->type == SR_CHANNEL_ANALOG) ? "A" + : "U"; + + snprintf(file_name, sizeof(file_name)-1, "%s-%d/%d", type_name, + sdi->mode == LOGIC ? probe->index : 0, vdev->cur_block); + + if (unzLocateFile(vdev->archive, file_name, 0) != UNZ_OK) + { + sr_err("cant't locate zip inner file:%s", file_name); + send_error_packet(sdi, vdev, &packet); + return FALSE; + } + if (unzOpenCurrentFile(vdev->archive) != UNZ_OK) + { + sr_err("cant't open zip inner file:%s", file_name); + send_error_packet(sdi, vdev, &packet); + return FALSE; + } + vdev->capfile = 1; + } + + if (vdev->capfile) { ret = unzReadCurrentFile(vdev->archive, vdev->buf, CHUNKSIZE); + if (-1 == ret) { - sr_err("%s: Read inner file error!", __func__); + sr_err("read zip inner file error:%s", file_name); send_error_packet(sdi, vdev, &packet); return FALSE; } } - else if (vdev->version == 2) + } + + if (ret > 0) + { + if (sdi->mode == DSO) { - channel = vdev->cur_channel; - pl = sdi->channels; - - while (channel--) - pl = pl->next; - - probe = (struct sr_channel *)pl->data; - - if (vdev->capfile == 0) - { - char *type_name = (probe->type == SR_CHANNEL_LOGIC) ? "L" : (probe->type == SR_CHANNEL_DSO) ? "O" - : (probe->type == SR_CHANNEL_ANALOG) ? "A" - : "U"; - - snprintf(file_name, 31, "%s-%d/%d", type_name, - sdi->mode == LOGIC ? probe->index : 0, vdev->cur_block); - - if (unzLocateFile(vdev->archive, file_name, 0) != UNZ_OK) - { - sr_err("cant't locate zip inner file:%s", file_name); - send_error_packet(sdi, vdev, &packet); - return FALSE; - } - if (unzOpenCurrentFile(vdev->archive) != UNZ_OK) - { - sr_err("cant't open zip inner file:%s", file_name); - send_error_packet(sdi, vdev, &packet); - return FALSE; - } - vdev->capfile = 1; - } - - if (vdev->capfile) - { - ret = unzReadCurrentFile(vdev->archive, vdev->buf, CHUNKSIZE); - - if (-1 == ret) - { - sr_err("read zip inner file error:%s", file_name); - send_error_packet(sdi, vdev, &packet); - return FALSE; - } - } + packet.type = SR_DF_DSO; + packet.payload = &dso; + dso.num_samples = ret / vdev->num_probes; + dso.data = vdev->buf; + dso.probes = sdi->channels; + dso.mq = SR_MQ_VOLTAGE; + dso.unit = SR_UNIT_VOLT; + dso.mqflags = SR_MQFLAG_AC; } - - if (ret > 0) + else if (sdi->mode == ANALOG) { - if (sdi->mode == DSO) - { - packet.type = SR_DF_DSO; - packet.payload = &dso; - dso.num_samples = ret / vdev->num_probes; - dso.data = vdev->buf; - dso.probes = sdi->channels; - dso.mq = SR_MQ_VOLTAGE; - dso.unit = SR_UNIT_VOLT; - dso.mqflags = SR_MQFLAG_AC; - } - else if (sdi->mode == ANALOG) - { - packet.type = SR_DF_ANALOG; - packet.payload = &analog; - analog.probes = sdi->channels; - analog.num_samples = ret / vdev->num_probes / ((vdev->unit_bits + 7) / 8); - analog.unit_bits = vdev->unit_bits; - analog.mq = SR_MQ_VOLTAGE; - analog.unit = SR_UNIT_VOLT; - analog.mqflags = SR_MQFLAG_AC; - analog.data = vdev->buf; - } - else - { - packet.type = SR_DF_LOGIC; - packet.payload = &logic; - logic.length = ret; - logic.format = (vdev->version == 2) ? LA_SPLIT_DATA : LA_CROSS_DATA; - if (probe) - logic.index = probe->index; - else - logic.index = 0; - logic.order = vdev->cur_channel; - - if (vdev->version == 1) - { - logic.length = ret / 16 * vdev->enabled_probes; - logic.data = vdev->logic_buf; - trans_data(sdi); - } - else if (vdev->version == 2) - { - logic.length = ret; - logic.data = vdev->buf; - } - } - - vdev->bytes_read += ret; - ds_data_forward(sdi, &packet); + packet.type = SR_DF_ANALOG; + packet.payload = &analog; + analog.probes = sdi->channels; + analog.num_samples = ret / vdev->num_probes / ((vdev->unit_bits + 7) / 8); + analog.unit_bits = vdev->unit_bits; + analog.mq = SR_MQ_VOLTAGE; + analog.unit = SR_UNIT_VOLT; + analog.mqflags = SR_MQFLAG_AC; + analog.data = vdev->buf; } else { - /* done with this capture file */ - unzCloseCurrentFile(vdev->archive); - vdev->capfile = 0; - - if (vdev->version == 1) - { - vdev->cur_channel++; + if (vdev->version == 2){ + assert(0); } - else if (vdev->version == 2) + + packet.type = SR_DF_LOGIC; + packet.payload = &logic; + logic.length = ret; + logic.format = LA_CROSS_DATA; + if (probe) + logic.index = probe->index; + else + logic.index = 0; + logic.order = vdev->cur_channel; + + //version == 1 + logic.length = ret / 16 * vdev->enabled_probes; + logic.data = vdev->logic_buf; + trans_data(sdi); + } + + vdev->bytes_read += ret; + ds_data_forward(sdi, &packet); + } + else + { + /* done with this capture file */ + unzCloseCurrentFile(vdev->archive); + vdev->capfile = 0; + + if (vdev->version == 1) + { + vdev->cur_channel++; + } + else if (vdev->version == 2) + { + vdev->cur_block++; + // if read to the last block, move to next channel + if (vdev->cur_block == vdev->num_blocks) { - vdev->cur_block++; - // if read to the last block, move to next channel - if (vdev->cur_block == vdev->num_blocks) - { - vdev->cur_block = 0; - vdev->cur_channel++; - } + vdev->cur_block = 0; + vdev->cur_channel++; } } } - } + } - if (!vdev || vdev->cur_channel >= vdev->num_probes || revents == -1) + if (vdev->cur_channel >= vdev->num_probes || revents == -1) { packet.type = SR_DF_END; ds_data_forward(sdi, &packet); @@ -402,6 +415,222 @@ static int receive_data(int fd, int revents, const struct sr_dev_inst *sdi) return TRUE; } +static int receive_data_logic2(int fd, int revents, const struct sr_dev_inst *sdi) +{ + struct session_vdev *vdev = NULL; + struct sr_datafeed_packet packet; + struct sr_datafeed_logic logic; + struct sr_datafeed_dso dso; + struct sr_datafeed_analog analog; + GSList *l; + int ret; + char file_name[32]; + GSList *pl; + int channel; + int ch_index, ch_index2; + struct session_packet_buffer *pack_buffer; + unz_file_info64 fileInfo; + char szFilePath[15]; + int bToEnd; + int chIndex; + int chan_num; + void *p_wr; + void *p_rd; + + assert(sdi); + assert(sdi->priv); + + (void)fd; + (void)revents; + + sr_detail("Feed chunk."); + + ret = 0; + bToEnd = 0; + packet.status = SR_PKT_OK; + + vdev = sdi->priv; + + assert(vdev->unit_bits > 0); + assert(vdev->archive); + + chan_num = vdev->num_probes; + + if (chan_num < 1){ + sr_err("%s: channel count < 1.", __func__); + return SR_ERR_ARG; + } + + if (vdev->packet_buffer == NULL){ + vdev->cur_block = 0; + + vdev->packet_buffer = g_try_malloc0(sizeof(struct session_packet_buffer)); + if (vdev->packet_buffer == NULL){ + sr_err("%s: vdev->packet_buffer malloc failed", __func__); + return SR_ERR_MALLOC; + } + + for (ch_index = 0; ch_index < SESSION_MAX_CHANNEL_COUNT; ch_index++){ + vdev->packet_buffer->block_bufs[ch_index] = NULL; + vdev->packet_buffer->block_poss[ch_index] = 0; + } + + vdev->packet_buffer->post_buf_len = 8 * chan_num * 1000; + vdev->packet_buffer->post_buf = g_try_malloc0(vdev->packet_buffer->post_buf_len + 1); + if (vdev->packet_buffer->post_buf == NULL){ + sr_err("%s: vdev->packet_buffer->post_buf malloc failed", __func__); + return SR_ERR_MALLOC; + } + + pack_buffer = vdev->packet_buffer; + pack_buffer->post_len; + pack_buffer->block_buf_len = 0; + pack_buffer->block_data_len = 0; + pack_buffer->block_chan_read_pos = 0; + } + pack_buffer = vdev->packet_buffer; + + // Make packet. + chIndex = 0; + + while (pack_buffer->post_len < pack_buffer->post_buf_len) + { + if (pack_buffer->block_chan_read_pos >= pack_buffer->block_data_len) + { + if (vdev->cur_block >= vdev->num_blocks){ + bToEnd = 1; + break; + } + + for (ch_index = 0; ch_index < chan_num; ch_index++) + { + snprintf(file_name, sizeof(file_name)-1, "%s-%d/%d", "L", + ch_index, vdev->cur_block); + + if (unzLocateFile(vdev->archive, file_name, 0) != UNZ_OK) + { + sr_err("cant't locate zip inner file:%s", file_name); + send_error_packet(sdi, vdev, &packet); + return FALSE; + } + + if (unzGetCurrentFileInfo64(vdev->archive, &fileInfo, szFilePath, + sizeof(szFilePath), NULL, 0, NULL, 0) != UNZ_OK) + { + sr_err("%s: unzGetCurrentFileInfo64 error.", __func__); + send_error_packet(sdi, vdev, &packet); + return FALSE; + } + + if (ch_index == 0){ + pack_buffer->block_data_len = fileInfo.uncompressed_size; + + if (pack_buffer->block_data_len > pack_buffer->block_buf_len){ + for (ch_index2 = 0; ch_index2 < chan_num; ch_index2++) + { + // Release the old buffer. + if (pack_buffer->block_bufs[ch_index2] != NULL){ + g_free(pack_buffer->block_bufs[ch_index2]); + pack_buffer->block_bufs[ch_index2] = NULL; + } + + pack_buffer->block_bufs[ch_index2] = g_try_malloc0(pack_buffer->block_data_len + 1); + if (pack_buffer->block_bufs[ch_index2] == NULL){ + sr_err("%s: block buffer malloc failed", __func__); + send_error_packet(sdi, vdev, &packet); + return FALSE; + } + pack_buffer->block_buf_len = pack_buffer->block_data_len; + } + } + } + else + { + if (pack_buffer->block_data_len != fileInfo.uncompressed_size){ + sr_err("The block size is not coincident:%s", file_name); + send_error_packet(sdi, vdev, &packet); + return FALSE; + } + } + + // Read the data to buffer. + if (unzOpenCurrentFile(vdev->archive) != UNZ_OK) + { + sr_err("cant't open zip inner file:%s", file_name); + send_error_packet(sdi, vdev, &packet); + return FALSE; + } + + ret = unzReadCurrentFile(vdev->archive, pack_buffer->block_bufs[ch_index], pack_buffer->block_data_len); + if (-1 == ret) + { + sr_err("read zip inner file error:%s", file_name); + send_error_packet(sdi, vdev, &packet); + return FALSE; + } + unzCloseCurrentFile(vdev->archive); + pack_buffer->block_poss[ch_index] = 0; // Reset the read position. + } + + vdev->cur_block++; + pack_buffer->block_chan_read_pos = 0; + } + + p_wr = (pack_buffer->post_buf + pack_buffer->post_len); + p_rd = (pack_buffer->block_bufs[chIndex] + pack_buffer->block_poss[chIndex]); + *(uint8_t*)p_wr = *(uint8_t*)p_rd; + + pack_buffer->post_len++; + pack_buffer->block_poss[chIndex]++; + + if (pack_buffer->block_poss[chIndex] % 8 == 0 + || pack_buffer->block_poss[chIndex] == pack_buffer->block_data_len) + { + chIndex++; + + if (pack_buffer->block_poss[chIndex] == pack_buffer->block_data_len){ + sr_info("Block read end."); + if (vdev->cur_block < vdev->num_blocks){ + sr_err("%s", "The block data is not align."); + break; + } + } + + if (chIndex == chan_num){ + chIndex = 0; + pack_buffer->block_chan_read_pos += 8; + } + } + } + + if (pack_buffer->post_len >= 8 * chan_num) + { + packet.type = SR_DF_LOGIC; + packet.payload = &logic; + logic.format = LA_CROSS_DATA; + logic.index = 0; + logic.order = 0; + + logic.length = pack_buffer->post_len; + logic.data = pack_buffer->post_buf; + + vdev->bytes_read += ret; + ds_data_forward(sdi, &packet); + pack_buffer->post_len = 0; + } + + if (bToEnd || revents == -1) + { + packet.type = SR_DF_END; + ds_data_forward(sdi, &packet); + sr_session_source_remove(-1); + close_archive(vdev); + vdev->bytes_read = 0; + } + + return TRUE; +} + /* driver callbacks */ static int dev_clear(void); @@ -453,13 +682,7 @@ static int dev_open(struct sr_dev_inst *sdi) } vdev = sdi->priv; - vdev->buf = g_try_malloc(CHUNKSIZE + sizeof(uint64_t)); - if (vdev->buf == NULL) - { - sr_err("%s: vdev->buf malloc failed", __func__); - return SR_ERR_MALLOC; - } - + vdev->buf = NULL; vdev->trig_pos = 0; vdev->trig_time = 0; vdev->cur_block = 0; @@ -474,9 +697,16 @@ static int dev_open(struct sr_dev_inst *sdi) vdev->mstatus.measure_valid = TRUE; vdev->archive = NULL; vdev->capfile = 0; - + vdev->packet_buffer = NULL; + vdev->logic_buf = NULL; sdi->status = SR_ST_ACTIVE; + vdev->buf = g_try_malloc(CHUNKSIZE + sizeof(uint64_t)); + if (vdev->buf == NULL){ + sr_err("%s: vdev->buf malloc failed", __func__); + return SR_ERR_MALLOC; + } + ret = sr_load_virtual_device_session(sdi); if (ret != SR_OK) { @@ -490,10 +720,27 @@ static int dev_open(struct sr_dev_inst *sdi) static int dev_close(struct sr_dev_inst *sdi) { struct session_vdev *vdev; + int i; + struct session_packet_buffer *pack_buf; if (sdi && sdi->priv) { vdev = sdi->priv; + + if (vdev->packet_buffer != NULL){ + pack_buf = vdev->packet_buffer; + + g_safe_free(pack_buf->post_buf); + + for (i = 0; i < SESSION_MAX_CHANNEL_COUNT; i++){ + if (pack_buf->block_bufs[i] != NULL){ + g_free(pack_buf->block_bufs[i]); + pack_buf->block_bufs[i] = NULL; + } + } + } + + g_safe_free(vdev->packet_buffer); g_safe_free(vdev->buf); g_safe_free(vdev->logic_buf); g_safe_free(sdi->priv); @@ -1126,7 +1373,12 @@ static int dev_acquisition_start(struct sr_dev_inst *sdi, void *cb_data) } /* freewheeling source */ - sr_session_source_add(-1, 0, 0, receive_data, sdi); + if (sdi->mode == LOGIC && vdev->version == 2){ + sr_session_source_add(-1, 0, 0, receive_data_logic2, sdi); + } + else{ + sr_session_source_add(-1, 0, 0, receive_data, sdi); + } return SR_OK; }