X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;f=hardware%2Fdemo%2Fdemo.c;h=73fe092727f604423c21afdbd520023cd7eab799;hb=d2e0b1fa71b90faf1f7e77b72627868baf5e9135;hp=0da3fd58b4659f75aeaa2216a105222f288af6b6;hpb=bbd7ef0f18df94232bafe6606c6d37eaad9ffd80;p=libsigrok.git diff --git a/hardware/demo/demo.c b/hardware/demo/demo.c index 0da3fd58..73fe0927 100644 --- a/hardware/demo/demo.c +++ b/hardware/demo/demo.c @@ -81,8 +81,12 @@ enum { /* Private, per-device-instance driver context. */ struct dev_context { + struct sr_dev_inst *sdi; int pipe_fds[2]; - GIOChannel *channels[2]; + GIOChannel *channel; + uint64_t cur_samplerate; + uint64_t limit_samples; + uint64_t limit_msec; uint8_t sample_generator; uint64_t samples_counter; void *cb_data; @@ -136,10 +140,6 @@ static uint8_t pattern_sigrok[] = { /* List of struct sr_dev_inst, maintained by dev_open()/dev_close(). */ SR_PRIV struct sr_dev_driver demo_driver_info; static struct sr_dev_driver *di = &demo_driver_info; -static uint64_t cur_samplerate = SR_KHZ(200); -static uint64_t limit_samples = 0; -static uint64_t limit_msec = 0; -static int default_pattern = PATTERN_SIGROK; static int hw_dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data); @@ -160,6 +160,7 @@ static GSList *hw_scan(GSList *options) struct sr_dev_inst *sdi; struct sr_probe *probe; struct drv_context *drvc; + struct dev_context *devc; GSList *devices; int i; @@ -171,8 +172,8 @@ static GSList *hw_scan(GSList *options) sdi = sr_dev_inst_new(0, SR_ST_ACTIVE, DEMONAME, NULL, NULL); if (!sdi) { - sr_err("%s: sr_dev_inst_new failed", __func__); - return 0; + sr_err("Device instance creation failed."); + return NULL; } sdi->driver = di; @@ -186,6 +187,19 @@ static GSList *hw_scan(GSList *options) devices = g_slist_append(devices, sdi); drvc->instances = g_slist_append(drvc->instances, sdi); + if (!(devc = g_try_malloc(sizeof(struct dev_context)))) { + sr_err("Device context malloc failed."); + return NULL; + } + + devc->sdi = sdi; + devc->cur_samplerate = SR_KHZ(200); + devc->limit_samples = 0; + devc->limit_msec = 0; + devc->sample_generator = PATTERN_SIGROK; + + sdi->priv = devc; + return devices; } @@ -214,26 +228,46 @@ static int hw_dev_close(struct sr_dev_inst *sdi) static int hw_cleanup(void) { - /* Nothing needed so far. */ - return SR_OK; + GSList *l; + struct sr_dev_inst *sdi; + struct drv_context *drvc; + int ret = SR_OK; + + if (!(drvc = di->priv)) + return SR_OK; + + /* Properly close and free all devices. */ + for (l = drvc->instances; l; l = l->next) { + if (!(sdi = l->data)) { + /* Log error, but continue cleaning up the rest. */ + sr_err("%s: sdi was NULL, continuing", __func__); + ret = SR_ERR_BUG; + continue; + } + sr_dev_inst_free(sdi); + } + g_slist_free(drvc->instances); + drvc->instances = NULL; + + return ret; } static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi) { - (void)sdi; + struct dev_context *const devc = sdi->priv; switch (id) { case SR_CONF_SAMPLERATE: - *data = g_variant_new_uint64(cur_samplerate); + *data = g_variant_new_uint64(devc->cur_samplerate); break; case SR_CONF_LIMIT_SAMPLES: - *data = g_variant_new_uint64(limit_samples); + *data = g_variant_new_uint64(devc->limit_samples); break; case SR_CONF_LIMIT_MSEC: - *data = g_variant_new_uint64(limit_msec); + *data = g_variant_new_uint64(devc->limit_msec); break; case SR_CONF_PATTERN_MODE: - switch (default_pattern) { + switch (devc->sample_generator) { case PATTERN_SIGROK: *data = g_variant_new_string(STR_PATTERN_SIGROK); break; @@ -252,7 +286,7 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi) } break; default: - return SR_ERR_ARG; + return SR_ERR_NA; } return SR_OK; @@ -263,44 +297,45 @@ static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi) int ret; const char *stropt; - (void)sdi; + struct dev_context *const devc = sdi->priv; if (id == SR_CONF_SAMPLERATE) { - cur_samplerate = g_variant_get_uint64(data); + devc->cur_samplerate = g_variant_get_uint64(data); sr_dbg("%s: setting samplerate to %" PRIu64, __func__, - cur_samplerate); + devc->cur_samplerate); ret = SR_OK; } else if (id == SR_CONF_LIMIT_SAMPLES) { - limit_msec = 0; - limit_samples = g_variant_get_uint64(data); + devc->limit_msec = 0; + devc->limit_samples = g_variant_get_uint64(data); sr_dbg("%s: setting limit_samples to %" PRIu64, __func__, - limit_samples); + devc->limit_samples); ret = SR_OK; } else if (id == SR_CONF_LIMIT_MSEC) { - limit_msec = g_variant_get_uint64(data); - limit_samples = 0; + devc->limit_msec = g_variant_get_uint64(data); + devc->limit_samples = 0; sr_dbg("%s: setting limit_msec to %" PRIu64, __func__, - limit_msec); + devc->limit_msec); ret = SR_OK; } else if (id == SR_CONF_PATTERN_MODE) { stropt = g_variant_get_string(data, NULL); ret = SR_OK; if (!strcmp(stropt, STR_PATTERN_SIGROK)) { - default_pattern = PATTERN_SIGROK; + devc->sample_generator = PATTERN_SIGROK; } else if (!strcmp(stropt, STR_PATTERN_RANDOM)) { - default_pattern = PATTERN_RANDOM; + devc->sample_generator = PATTERN_RANDOM; } else if (!strcmp(stropt, STR_PATTERN_INC)) { - default_pattern = PATTERN_INC; + devc->sample_generator = PATTERN_INC; } else if (!strcmp(stropt, STR_PATTERN_ALL_LOW)) { - default_pattern = PATTERN_ALL_LOW; + devc->sample_generator = PATTERN_ALL_LOW; } else if (!strcmp(stropt, STR_PATTERN_ALL_HIGH)) { - default_pattern = PATTERN_ALL_HIGH; + devc->sample_generator = PATTERN_ALL_HIGH; } else { ret = SR_ERR; } - sr_dbg("%s: setting pattern to %d", __func__, default_pattern); + sr_dbg("%s: setting pattern to %d", + __func__, devc->sample_generator); } else { - ret = SR_ERR; + ret = SR_ERR_NA; } return ret; @@ -329,7 +364,7 @@ static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi) *data = g_variant_new_strv(pattern_strings, ARRAY_SIZE(pattern_strings)); break; default: - return SR_ERR_ARG; + return SR_ERR_NA; } return SR_OK; @@ -387,13 +422,13 @@ static int receive_data(int fd, int revents, void *cb_data) /* How many "virtual" samples should we have collected by now? */ time = g_get_monotonic_time(); elapsed = time - devc->starttime; - expected_samplenum = elapsed * cur_samplerate / 1000000; + expected_samplenum = elapsed * devc->cur_samplerate / 1000000; /* Of those, how many do we still have to send? */ samples_to_send = expected_samplenum - devc->samples_counter; - if (limit_samples) { + if (devc->limit_samples) { samples_to_send = MIN(samples_to_send, - limit_samples - devc->samples_counter); + devc->limit_samples - devc->samples_counter); } while (samples_to_send > 0) { @@ -410,9 +445,10 @@ static int receive_data(int fd, int revents, void *cb_data) devc->samples_counter += sending_now; } - if (limit_samples && devc->samples_counter >= limit_samples) { + if (devc->limit_samples && + devc->samples_counter >= devc->limit_samples) { sr_info("Requested number of samples reached."); - hw_dev_acquisition_stop(NULL, cb_data); + hw_dev_acquisition_stop(devc->sdi, cb_data); return TRUE; } @@ -422,17 +458,8 @@ static int receive_data(int fd, int revents, void *cb_data) static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data) { - struct dev_context *devc; - - (void)sdi; + struct dev_context *const devc = sdi->priv; - /* TODO: 'devc' is never g_free()'d? */ - if (!(devc = g_try_malloc(sizeof(struct dev_context)))) { - sr_err("%s: devc malloc failed", __func__); - return SR_ERR_MALLOC; - } - - devc->sample_generator = default_pattern; devc->cb_data = cb_data; devc->samples_counter = 0; @@ -449,20 +476,17 @@ static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi, return SR_ERR; } - devc->channels[0] = g_io_channel_unix_new(devc->pipe_fds[0]); - devc->channels[1] = g_io_channel_unix_new(devc->pipe_fds[1]); + devc->channel = g_io_channel_unix_new(devc->pipe_fds[0]); - g_io_channel_set_flags(devc->channels[0], G_IO_FLAG_NONBLOCK, NULL); + g_io_channel_set_flags(devc->channel, G_IO_FLAG_NONBLOCK, NULL); /* Set channel encoding to binary (default is UTF-8). */ - g_io_channel_set_encoding(devc->channels[0], NULL, NULL); - g_io_channel_set_encoding(devc->channels[1], NULL, NULL); + g_io_channel_set_encoding(devc->channel, NULL, NULL); /* Make channels to unbuffered. */ - g_io_channel_set_buffered(devc->channels[0], FALSE); - g_io_channel_set_buffered(devc->channels[1], FALSE); + g_io_channel_set_buffered(devc->channel, FALSE); - sr_session_source_add_channel(devc->channels[0], G_IO_IN | G_IO_ERR, + sr_session_source_add_channel(devc->channel, G_IO_IN | G_IO_ERR, 40, receive_data, devc); /* Send header packet to the session bus. */ @@ -476,17 +500,17 @@ static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi, static int hw_dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data) { - struct dev_context *devc; + struct dev_context *const devc = sdi->priv; struct sr_datafeed_packet packet; - (void)sdi; - - devc = cb_data; + (void)cb_data; sr_dbg("Stopping aquisition."); - sr_session_source_remove_channel(devc->channels[0]); - g_io_channel_shutdown(devc->channels[0], FALSE, NULL); + sr_session_source_remove_channel(devc->channel); + g_io_channel_shutdown(devc->channel, FALSE, NULL); + g_io_channel_unref(devc->channel); + devc->channel = NULL; /* Send last packet. */ packet.type = SR_DF_END;