static void set_options(void) { struct sr_dev_inst *sdi; GSList *devices; GHashTable *devargs; if (!opt_config) { g_critical("No setting specified."); return; } if (!(devargs = parse_generic_arg(opt_config, FALSE))) return; if (!(devices = device_scan())) { g_critical("No devices found."); return; } sdi = devices->data; g_slist_free(devices); if (sr_dev_open(sdi) != SR_OK) { g_critical("Failed to open device."); return; } set_dev_options(sdi, devargs); sr_dev_close(sdi); g_hash_table_destroy(devargs); }
int setup_output_format(void) { GHashTable *fmtargs; GHashTableIter iter; gpointer key, value; struct sr_output_format **outputs; int i; char *fmtspec; if (!opt_output_format) { opt_output_format = DEFAULT_OUTPUT_FORMAT; /* we'll need to remember this so when saving to a file * later, sigrok session format will be used. */ default_output_format = TRUE; } fmtargs = parse_generic_arg(opt_output_format); fmtspec = g_hash_table_lookup(fmtargs, "sigrok_key"); if (!fmtspec) { g_critical("Invalid output format."); return 1; } outputs = sr_output_list(); for (i = 0; outputs[i]; i++) { if (strcmp(outputs[i]->id, fmtspec)) continue; g_hash_table_remove(fmtargs, "sigrok_key"); output_format = outputs[i]; g_hash_table_iter_init(&iter, fmtargs); while (g_hash_table_iter_next(&iter, &key, &value)) { /* only supporting one parameter per output module * for now, and only its value */ output_format_param = g_strdup(value); break; } break; } if (!output_format) { g_critical("Invalid output format %s.", opt_output_format); return 1; } g_hash_table_destroy(fmtargs); return 0; }
static void get_option(void) { struct sr_dev_inst *sdi; struct sr_channel_group *cg; const struct sr_config_info *ci; GSList *devices; GVariant *gvar; GHashTable *devargs; int ret; char *s; struct sr_dev_driver *driver; if (!(devices = device_scan())) { g_critical("No devices found."); return; } sdi = devices->data; g_slist_free(devices); driver = sr_dev_inst_driver_get(sdi); if (sr_dev_open(sdi) != SR_OK) { g_critical("Failed to open device."); return; } cg = select_channel_group(sdi); if (!(ci = sr_config_info_name_get(opt_get))) g_critical("Unknown option '%s'", opt_get); if ((devargs = parse_generic_arg(opt_config, FALSE))) set_dev_options(sdi, devargs); else devargs = NULL; if ((ret = maybe_config_get(driver, sdi, cg, ci->key, &gvar)) != SR_OK) g_critical("Failed to get '%s': %s", opt_get, sr_strerror(ret)); s = g_variant_print(gvar, FALSE); printf("%s\n", s); g_free(s); g_variant_unref(gvar); sr_dev_close(sdi); if (devargs) g_hash_table_destroy(devargs); }
struct sr_output *setup_output_format(const struct sr_dev_inst *sdi) { GHashTable *fmtargs; struct sr_output *o; struct sr_output_format **outputs; int i; char *fmtspec; if (opt_output_format && !strcmp(opt_output_format, "sigrok")) { /* Doesn't really exist as an output module - this is * the session save mode. */ g_free(opt_output_format); opt_output_format = NULL; } if (!opt_output_format) { opt_output_format = DEFAULT_OUTPUT_FORMAT; /* we'll need to remember this so when saving to a file * later, sigrok session format will be used. */ default_output_format = TRUE; } fmtargs = parse_generic_arg(opt_output_format, TRUE); fmtspec = g_hash_table_lookup(fmtargs, "sigrok_key"); if (!fmtspec) g_critical("Invalid output format."); outputs = sr_output_list(); for (i = 0; outputs[i]; i++) { if (strcmp(outputs[i]->id, fmtspec)) continue; g_hash_table_remove(fmtargs, "sigrok_key"); output_format = outputs[i]; break; } if (!output_format) g_critical("Invalid output format '%s'.", opt_output_format); o = sr_output_new(output_format, fmtargs, sdi); g_hash_table_destroy(fmtargs); return o; }
GSList *device_scan(void) { struct sr_dev_driver **drivers, *driver; GHashTable *drvargs; GSList *drvopts, *devices, *tmpdevs, *l; int i; char *drvname; if (opt_drv) { drvargs = parse_generic_arg(opt_drv, TRUE); drvname = g_strdup(g_hash_table_lookup(drvargs, "sigrok_key")); g_hash_table_remove(drvargs, "sigrok_key"); driver = NULL; drivers = sr_driver_list(); for (i = 0; drivers[i]; i++) { if (strcmp(drivers[i]->name, drvname)) continue; driver = drivers[i]; } if (!driver) { g_critical("Driver %s not found.", drvname); g_hash_table_destroy(drvargs); g_free(drvname); return NULL; } g_free(drvname); if (sr_driver_init(sr_ctx, driver) != SR_OK) { g_critical("Failed to initialize driver."); g_hash_table_destroy(drvargs); return NULL; } drvopts = NULL; if (g_hash_table_size(drvargs) > 0) { if (!(drvopts = hash_to_hwopt(drvargs))) { /* Unknown options, already logged. */ g_hash_table_destroy(drvargs); return NULL; } } g_hash_table_destroy(drvargs); devices = sr_driver_scan(driver, drvopts); g_slist_free_full(drvopts, (GDestroyNotify)free_drvopts); } else { /* No driver specified, let them all scan on their own. */ devices = NULL; drivers = sr_driver_list(); for (i = 0; drivers[i]; i++) { driver = drivers[i]; if (sr_driver_init(sr_ctx, driver) != SR_OK) { g_critical("Failed to initialize driver."); return NULL; } tmpdevs = sr_driver_scan(driver, NULL); for (l = tmpdevs; l; l = l->next) devices = g_slist_append(devices, l->data); g_slist_free(tmpdevs); } } return devices; }
void run_session(void) { GSList *devices; GHashTable *devargs; GVariant *gvar; struct sr_dev_inst *sdi; uint64_t min_samples, max_samples; devices = device_scan(); if (!devices) { g_critical("No devices found."); return; } if (g_slist_length(devices) > 1) { g_critical("sigrok-cli only supports one device for capturing."); return; } sdi = devices->data; sr_session_new(); sr_session_datafeed_callback_add(datafeed_in, NULL); if (sr_dev_open(sdi) != SR_OK) { g_critical("Failed to open device."); return; } if (sr_session_dev_add(sdi) != SR_OK) { g_critical("Failed to add device to session."); sr_session_destroy(); return; } if (opt_config) { if ((devargs = parse_generic_arg(opt_config, FALSE))) { if (set_dev_options(sdi, devargs) != SR_OK) return; g_hash_table_destroy(devargs); } } if (select_channels(sdi) != SR_OK) { g_critical("Failed to set channels."); sr_session_destroy(); return; } if (opt_triggers) { if (!parse_triggerstring(sdi, opt_triggers)) { sr_session_destroy(); return; } } if (opt_continuous) { if (!sr_dev_has_option(sdi, SR_CONF_CONTINUOUS)) { g_critical("This device does not support continuous sampling."); sr_session_destroy(); return; } } if (opt_time) { if (set_limit_time(sdi) != SR_OK) { sr_session_destroy(); return; } } if (opt_samples) { if ((sr_parse_sizestring(opt_samples, &limit_samples) != SR_OK)) { g_critical("Invalid sample limit '%s'.", opt_samples); sr_session_destroy(); return; } if (sr_config_list(sdi->driver, sdi, NULL, SR_CONF_LIMIT_SAMPLES, &gvar) == SR_OK) { /* The device has no compression, or compression is turned * off, and publishes its sample memory size. */ g_variant_get(gvar, "(tt)", &min_samples, &max_samples); g_variant_unref(gvar); if (limit_samples < min_samples) { g_critical("The device stores at least %"PRIu64 " samples with the current settings.", min_samples); } if (limit_samples > max_samples) { g_critical("The device can store only %"PRIu64 " samples with the current settings.", max_samples); } } gvar = g_variant_new_uint64(limit_samples); if (sr_config_set(sdi, NULL, SR_CONF_LIMIT_SAMPLES, gvar) != SR_OK) { g_critical("Failed to configure sample limit."); sr_session_destroy(); return; } } if (opt_frames) { if ((sr_parse_sizestring(opt_frames, &limit_frames) != SR_OK)) { g_critical("Invalid sample limit '%s'.", opt_samples); sr_session_destroy(); return; } gvar = g_variant_new_uint64(limit_frames); if (sr_config_set(sdi, NULL, SR_CONF_LIMIT_FRAMES, gvar) != SR_OK) { g_critical("Failed to configure frame limit."); sr_session_destroy(); return; } } if (sr_session_start() != SR_OK) { g_critical("Failed to start session."); sr_session_destroy(); return; } if (opt_continuous) add_anykey(); sr_session_run(); if (opt_continuous) clear_anykey(); sr_session_datafeed_callback_remove_all(); sr_session_destroy(); g_slist_free(devices); }
/* Register the given PDs for this session. * Accepts a string of the form: "spi:sck=3:sdata=4,spi:sck=3:sdata=5" * That will instantiate two SPI decoders on the clock but different data * lines. */ static int register_pds(struct sr_dev *dev, const char *pdstring) { GHashTable *pd_opthash; struct srd_decoder_inst *di; int ret; char **pdtokens, **pdtok, *pd_name; /* Avoid compiler warnings. */ (void)dev; ret = 0; pd_ann_visible = g_hash_table_new_full(g_str_hash, g_int_equal, g_free, NULL); pd_name = NULL; pd_opthash = NULL; pdtokens = g_strsplit(pdstring, ",", 0); for (pdtok = pdtokens; *pdtok; pdtok++) { if (!(pd_opthash = parse_generic_arg(*pdtok))) { g_critical("Invalid protocol decoder option '%s'.", *pdtok); goto err_out; } pd_name = g_strdup(g_hash_table_lookup(pd_opthash, "sigrok_key")); g_hash_table_remove(pd_opthash, "sigrok_key"); if (srd_decoder_load(pd_name) != SRD_OK) { g_critical("Failed to load protocol decoder %s.", pd_name); ret = 1; goto err_out; } if (!(di = srd_inst_new(pd_name, pd_opthash))) { g_critical("Failed to instantiate protocol decoder %s.", pd_name); ret = 1; goto err_out; } /* If no annotation list was specified, add them all in now. * This will be pared down later to leave only the last PD * in the stack. */ if (!opt_pd_annotations) g_hash_table_insert(pd_ann_visible, g_strdup(di->inst_id), NULL); /* Any keys left in the options hash are probes, where the key * is the probe name as specified in the decoder class, and the * value is the probe number i.e. the order in which the PD's * incoming samples are arranged. */ if (srd_inst_probe_set_all(di, pd_opthash) != SRD_OK) { ret = 1; goto err_out; } g_hash_table_destroy(pd_opthash); pd_opthash = NULL; } err_out: g_strfreev(pdtokens); if (pd_opthash) g_hash_table_destroy(pd_opthash); if (pd_name) g_free(pd_name); return ret; }
static void run_session(void) { struct sr_dev *dev; GHashTable *devargs; int num_devs, max_probes, i; uint64_t time_msec; char **probelist, *devspec; devargs = NULL; if (opt_dev) { devargs = parse_generic_arg(opt_dev); devspec = g_hash_table_lookup(devargs, "sigrok_key"); dev = parse_devstring(devspec); if (!dev) { g_critical("Device not found."); return; } g_hash_table_remove(devargs, "sigrok_key"); } else { num_devs = num_real_devs(); if (num_devs == 1) { /* No device specified, but there is only one. */ devargs = NULL; dev = parse_devstring("0"); } else if (num_devs == 0) { g_critical("No devices found."); return; } else { g_critical("%d devices found, please select one.", num_devs); return; } } sr_session_new(); sr_session_datafeed_callback_add(datafeed_in); if (sr_session_dev_add(dev) != SR_OK) { g_critical("Failed to use device."); sr_session_destroy(); return; } if (devargs) { if (set_dev_options(dev, devargs) != SR_OK) { sr_session_destroy(); return; } g_hash_table_destroy(devargs); } if (select_probes(dev) != SR_OK) return; if (opt_continuous) { if (!sr_driver_hwcap_exists(dev->driver, SR_HWCAP_CONTINUOUS)) { g_critical("This device does not support continuous sampling."); sr_session_destroy(); return; } } if (opt_triggers) { probelist = sr_parse_triggerstring(dev, opt_triggers); if (!probelist) { sr_session_destroy(); return; } max_probes = g_slist_length(dev->probes); for (i = 0; i < max_probes; i++) { if (probelist[i]) { sr_dev_trigger_set(dev, i + 1, probelist[i]); g_free(probelist[i]); } } g_free(probelist); } if (opt_time) { time_msec = sr_parse_timestring(opt_time); if (time_msec == 0) { g_critical("Invalid time '%s'", opt_time); sr_session_destroy(); return; } if (sr_driver_hwcap_exists(dev->driver, SR_HWCAP_LIMIT_MSEC)) { if (dev->driver->dev_config_set(dev->driver_index, SR_HWCAP_LIMIT_MSEC, &time_msec) != SR_OK) { g_critical("Failed to configure time limit."); sr_session_destroy(); return; } } else { /* time limit set, but device doesn't support this... * convert to samples based on the samplerate. */ limit_samples = 0; if (sr_dev_has_hwcap(dev, SR_HWCAP_SAMPLERATE)) { const uint64_t *samplerate; sr_dev_info_get(dev, SR_DI_CUR_SAMPLERATE, (const void **)&samplerate); limit_samples = (*samplerate) * time_msec / (uint64_t)1000; } if (limit_samples == 0) { g_critical("Not enough time at this samplerate."); sr_session_destroy(); return; } if (dev->driver->dev_config_set(dev->driver_index, SR_HWCAP_LIMIT_SAMPLES, &limit_samples) != SR_OK) { g_critical("Failed to configure time-based sample limit."); sr_session_destroy(); return; } } } if (opt_samples) { if ((sr_parse_sizestring(opt_samples, &limit_samples) != SR_OK) || (dev->driver->dev_config_set(dev->driver_index, SR_HWCAP_LIMIT_SAMPLES, &limit_samples) != SR_OK)) { g_critical("Failed to configure sample limit."); sr_session_destroy(); return; } } if (opt_frames) { if ((sr_parse_sizestring(opt_frames, &limit_frames) != SR_OK) || (dev->driver->dev_config_set(dev->driver_index, SR_HWCAP_LIMIT_FRAMES, &limit_frames) != SR_OK)) { printf("Failed to configure frame limit.\n"); sr_session_destroy(); return; } } if (dev->driver->dev_config_set(dev->driver_index, SR_HWCAP_PROBECONFIG, (char *)dev->probes) != SR_OK) { g_critical("Failed to configure probes."); sr_session_destroy(); return; } if (sr_session_start() != SR_OK) { g_critical("Failed to start session."); sr_session_destroy(); return; } if (opt_continuous) add_anykey(); sr_session_run(); if (opt_continuous) clear_anykey(); if (opt_output_file && default_output_format) { if (sr_session_save(opt_output_file) != SR_OK) g_critical("Failed to save session."); } sr_session_destroy(); }
static void load_input_file_format(void) { GHashTable *fmtargs = NULL; struct stat st; struct sr_input *in; struct sr_input_format *input_format; char *fmtspec = NULL; if (opt_input_format) { fmtargs = parse_generic_arg(opt_input_format); fmtspec = g_hash_table_lookup(fmtargs, "sigrok_key"); } if (!(input_format = determine_input_file_format(opt_input_file, fmtspec))) { /* The exact cause was already logged. */ return; } ; if (fmtargs) g_hash_table_remove(fmtargs, "sigrok_key"); if (stat(opt_input_file, &st) == -1) { g_critical("Failed to load %s: %s", opt_input_file, strerror(errno)); exit(1); } /* Initialize the input module. */ if (!(in = g_try_malloc(sizeof(struct sr_input)))) { g_critical("Failed to allocate input module."); exit(1); } in->format = input_format; in->param = fmtargs; if (in->format->init) { if (in->format->init(in) != SR_OK) { g_critical("Input format init failed."); exit(1); } } if (select_probes(in->vdev) > 0) return; sr_session_new(); sr_session_datafeed_callback_add(datafeed_in); if (sr_session_dev_add(in->vdev) != SR_OK) { g_critical("Failed to use device."); sr_session_destroy(); return; } input_format->loadfile(in, opt_input_file); if (opt_output_file && default_output_format) { if (sr_session_save(opt_output_file) != SR_OK) g_critical("Failed to save session."); } sr_session_destroy(); if (fmtargs) g_hash_table_destroy(fmtargs); }