Skip to content

Commit

Permalink
session: Always save in chunks, including in continuous mode.
Browse files Browse the repository at this point in the history
  • Loading branch information
biot committed Mar 12, 2014
1 parent 1afa97c commit 6ea663a
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 32 deletions.
101 changes: 69 additions & 32 deletions session.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
static struct sr_output_format *output_format = NULL;
static int default_output_format = FALSE;
static char *output_format_param = NULL;
static GByteArray *savebuf;
static uint64_t limit_samples = 0;
static uint64_t limit_frames = 0;

Expand Down Expand Up @@ -146,16 +145,20 @@ void datafeed_in(const struct sr_dev_inst *sdi,
const struct sr_datafeed_logic *logic;
const struct sr_datafeed_analog *analog;
struct sr_config *src;
struct sr_probe *probe;
static struct sr_output *o = NULL;
static uint64_t received_samples = 0;
static uint64_t rcvd_samples_logic = 0;
static uint64_t rcvd_samples_analog = 0;
static uint64_t samplerate = 0;
static int triggered = 0;
static FILE *outfile = NULL;
GSList *l;
GString *out;
uint64_t samplerate;
uint64_t end_sample;
uint64_t output_len, input_len;
uint8_t *output_buf;
int i;
char **probes;

(void) cb_data;

Expand Down Expand Up @@ -185,18 +188,14 @@ void datafeed_in(const struct sr_dev_inst *sdi,
outfile = stdout;
if (opt_output_file) {
if (default_output_format) {
/* output file is in session format, so we'll
* keep a copy of everything as it comes in
* and save from there after the session. */
outfile = NULL;
savebuf = g_byte_array_new();
} else {
/* saving to a file in whatever format was set
* with --format, so all we need is a filehandle */
outfile = g_fopen(opt_output_file, "wb");
}
}
received_samples = 0;
rcvd_samples_logic = rcvd_samples_analog = 0;

#ifdef HAVE_SRD
if (opt_pds) {
Expand Down Expand Up @@ -266,22 +265,35 @@ void datafeed_in(const struct sr_dev_inst *sdi,
if (opt_wait_trigger && !triggered)
break;

if (limit_samples && received_samples >= limit_samples)
if (limit_samples && rcvd_samples_logic >= limit_samples)
break;

end_sample = received_samples + logic->length / logic->unitsize;
end_sample = rcvd_samples_logic + logic->length / logic->unitsize;
/* Cut off last packet according to the sample limit. */
if (limit_samples && end_sample > limit_samples)
end_sample = limit_samples;
input_len = (end_sample - received_samples) * logic->unitsize;
input_len = (end_sample - rcvd_samples_logic) * logic->unitsize;

if (opt_output_file && default_output_format) {
/* Saving to a session file. */
g_byte_array_append(savebuf, logic->data, input_len);
if (rcvd_samples_logic == 0) {
/* First packet with logic data, init session file. */
probes = g_malloc(sizeof(char *) * g_slist_length(sdi->probes));
for (i = 0, l = sdi->probes; l; l = l->next) {
probe = l->data;
if (probe->enabled && probe->type == SR_PROBE_LOGIC)
probes[i++] = probe->name;
}
probes[i] = NULL;
sr_session_save_init(opt_output_file, samplerate,
probes);
g_free(probes);
}
save_chunk_logic(logic->data, input_len, logic->unitsize);
} else {
if (opt_pds) {
#ifdef HAVE_SRD
if (srd_session_send(srd_sess, received_samples, end_sample,
if (srd_session_send(srd_sess, rcvd_samples_logic, end_sample,
logic->data, input_len) != SRD_OK)
sr_session_stop();
#endif
Expand All @@ -298,7 +310,7 @@ void datafeed_in(const struct sr_dev_inst *sdi,
}
}

received_samples = end_sample;
rcvd_samples_logic = end_sample;
break;

case SR_DF_ANALOG:
Expand All @@ -307,7 +319,7 @@ void datafeed_in(const struct sr_dev_inst *sdi,
if (analog->num_samples == 0)
break;

if (limit_samples && received_samples >= limit_samples)
if (limit_samples && rcvd_samples_analog >= limit_samples)
break;

if (o->format->data && packet->type == o->format->df_type) {
Expand All @@ -321,7 +333,7 @@ void datafeed_in(const struct sr_dev_inst *sdi,
}
}

received_samples += analog->num_samples;
rcvd_samples_analog += analog->num_samples;
break;

case SR_DF_FRAME_BEGIN:
Expand Down Expand Up @@ -363,7 +375,7 @@ void datafeed_in(const struct sr_dev_inst *sdi,
}

/* SR_DF_END needs to be handled after the output module's receive()
* is called, so it can properly clean up that module etc. */
* is called, so it can properly clean up that module. */
if (packet->type == SR_DF_END) {
g_debug("cli: Received SR_DF_END");

Expand All @@ -377,14 +389,6 @@ void datafeed_in(const struct sr_dev_inst *sdi,
}
}

if (limit_samples && received_samples < limit_samples)
g_warning("Device only sent %" PRIu64 " samples.",
received_samples);

if (opt_continuous)
g_warning("Device stopped after %" PRIu64 " samples.",
received_samples);

if (o->format->cleanup)
o->format->cleanup(o);
g_free(o);
Expand All @@ -393,13 +397,17 @@ void datafeed_in(const struct sr_dev_inst *sdi,
if (outfile && outfile != stdout)
fclose(outfile);

if (opt_output_file && default_output_format && savebuf->len
&& received_samples > 0) {
if (sr_session_save(opt_output_file, sdi, savebuf->data,
savebuf->len / received_samples,
received_samples) != SR_OK)
g_critical("Failed to save session.");
g_byte_array_free(savebuf, TRUE);
if (opt_output_file && default_output_format)
/* Flush whatever is left out to the session file. */
save_chunk_logic(NULL, 0, 0);

if (limit_samples) {
if (rcvd_samples_logic > 0 && rcvd_samples_logic < limit_samples)
g_warning("Device only sent %" PRIu64 " samples.",
rcvd_samples_logic);
else if (rcvd_samples_analog > 0 && rcvd_samples_analog < limit_samples)
g_warning("Device only sent %" PRIu64 " samples.",
rcvd_samples_analog);
}
}

Expand Down Expand Up @@ -650,3 +658,32 @@ void run_session(void)

}

void save_chunk_logic(uint8_t *data, uint64_t data_len, int unitsize)
{
static uint8_t *buf = NULL;
static int buf_len = 0;
static int last_unitsize = 0;
int max;

if (!buf)
buf = g_malloc(SAVE_CHUNK_SIZE);

if (buf_len + data_len > SAVE_CHUNK_SIZE) {
max = (SAVE_CHUNK_SIZE - buf_len) / unitsize * unitsize;
memcpy(buf + buf_len, data, max);
sr_session_append(opt_output_file, buf, unitsize,
(buf_len + max) / unitsize);
memcpy(buf, data + max, data_len - max);
buf_len = data_len - max;
} else if (data_len == 0) {
/* End of data, flush the buffer out. */
sr_session_append(opt_output_file, buf, last_unitsize,
buf_len / last_unitsize);
} else {
/* Buffer chunk. */
memcpy(buf + buf_len, data, data_len);
buf_len += data_len;
}
last_unitsize = unitsize;

}
2 changes: 2 additions & 0 deletions sigrok-cli.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <libsigrok/libsigrok.h>

#define DEFAULT_OUTPUT_FORMAT "bits:width=64"
#define SAVE_CHUNK_SIZE 524288

/* main.c */
int select_probes(struct sr_dev_inst *sdi);
Expand All @@ -49,6 +50,7 @@ void datafeed_in(const struct sr_dev_inst *sdi,
int opt_to_gvar(char *key, char *value, struct sr_config *src);
int set_dev_options(struct sr_dev_inst *sdi, GHashTable *args);
void run_session(void);
void save_chunk_logic(uint8_t *data, uint64_t data_len, int unitsize);

/* input.c */
void load_input_file(void);
Expand Down

0 comments on commit 6ea663a

Please sign in to comment.