From 3df03cc2b16dad892b5a9a5026311f23a1d02caa Mon Sep 17 00:00:00 2001 From: Uwe Hermann Date: Thu, 25 Oct 2018 22:00:44 +0200 Subject: [PATCH] Backport recent changes from mainline. This includes all changes from f5735c5ee3e8fb0f1888f0ce22bfb46a99c099df doc: minor update to -O and -g options in the manpage up to f0de24ffe36fb3e983e347e607c522f32a963e25 Force backup analog traces only if needed --- HACKING | 11 +- Makefile.am | 11 +- contrib/org.sigrok.sigrok-cli.desktop | 12 ++ contrib/sigrok-cli.svg | 234 ++++++++++++++++++++++++++ decode.c | 75 ++++++--- doc/sigrok-cli.1 | 154 ++++++++++++----- input.c | 23 +-- main.c | 3 +- options.c | 5 +- session.c | 42 +++-- sigrok-cli.h | 7 +- 11 files changed, 465 insertions(+), 112 deletions(-) create mode 100644 contrib/org.sigrok.sigrok-cli.desktop create mode 100644 contrib/sigrok-cli.svg diff --git a/HACKING b/HACKING index 94064f8..c9b876b 100644 --- a/HACKING +++ b/HACKING @@ -15,15 +15,16 @@ Please use the same style for any code contributions, thanks! Contributions ------------- - - Patches should be sent to the development mailinglist at + - In order to contribute you should ideally clone the git repository and + let us know (preferably via IRC, or via the mailing list) from where to + pull/review your changes. You can use github.com, or any other public git + hosting site. + + - Alternatively, patches can be sent to the development mailinglist at sigrok-devel@lists.sourceforge.net (please subscribe to the list first). https://lists.sourceforge.net/lists/listinfo/sigrok-devel - - Alternatively, you can also clone the git repository and let us know - from where to pull/review your changes. You can use gitorious.org, - github.com, or any other public git hosting site. - Random notes ------------ diff --git a/Makefile.am b/Makefile.am index c6d6c8a..84f94b4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -40,7 +40,16 @@ sigrok_cli_LDADD = $(SIGROK_CLI_LIBS) dist_man_MANS = doc/sigrok-cli.1 -EXTRA_DIST = contrib/sigrok-logo-notext.ico +desktopdir = @datadir@/applications +desktop_DATA = contrib/org.sigrok.sigrok-cli.desktop + +hicolor_icondir = @datadir@/icons/hicolor/scalable/apps +hicolor_icon_DATA = contrib/sigrok-cli.svg + +EXTRA_DIST = \ + contrib/sigrok-logo-notext.ico \ + contrib/org.sigrok.sigrok-cli.desktop \ + contrib/sigrok-cli.svg MAINTAINERCLEANFILES = ChangeLog diff --git a/contrib/org.sigrok.sigrok-cli.desktop b/contrib/org.sigrok.sigrok-cli.desktop new file mode 100644 index 0000000..333a933 --- /dev/null +++ b/contrib/org.sigrok.sigrok-cli.desktop @@ -0,0 +1,12 @@ +[Desktop Entry] +# Creative Commons CC0 1.0 Universal (CC0-1.0, Public Domain Dedication). +Name=sigrok-cli +GenericName=Logic analyzer, oscilloscope and MSO command-line tool +Categories=Development;Electronics; +Comment=Control your logic analyzer, oscilloscope, or MSO +Exec=sigrok-cli +Icon=sigrok-cli +Terminal=true +NoDisplay=true +Type=Application +MimeType=application/vnd.sigrok.session; diff --git a/contrib/sigrok-cli.svg b/contrib/sigrok-cli.svg new file mode 100644 index 0000000..620028d --- /dev/null +++ b/contrib/sigrok-cli.svg @@ -0,0 +1,234 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/decode.c b/decode.c index 2bcc0ae..2b95f23 100644 --- a/decode.c +++ b/decode.c @@ -423,7 +423,8 @@ void show_pd_annotations(struct srd_proto_data *pdata, void *cb_data) GSList *ann_list, *l; int i; char **ann_descr; - gboolean show; + gboolean show_ann, show_snum, show_class, show_quotes, show_abbrev; + const char *quote; (void)cb_data; @@ -438,33 +439,59 @@ void show_pd_annotations(struct srd_proto_data *pdata, void *cb_data) dec = pdata->pdo->di->decoder; pda = pdata->data; - show = FALSE; + show_ann = FALSE; for (l = ann_list; l; l = l->next) { if (GPOINTER_TO_INT(l->data) == -1 || GPOINTER_TO_INT(l->data) == pda->ann_class) { - show = TRUE; + show_ann = TRUE; break; } } - if (!show) + if (!show_ann) return; - if (opt_loglevel <= SR_LOG_WARN) { - /* Show only the longest annotation. */ - printf("%s: %s", pdata->pdo->proto_id, pda->ann_text[0]); - } else if (opt_loglevel >= SR_LOG_INFO) { - /* Sample numbers and quotes around the longest annotation. */ - printf("%"PRIu64"-%"PRIu64"", pdata->start_sample, pdata->end_sample); - if (opt_loglevel == SR_LOG_INFO) { - printf(" %s \"%s\"", pdata->pdo->proto_id, pda->ann_text[0]); - } else { - /* Protocol decoder id, annotation class, - * all annotation strings. */ - ann_descr = g_slist_nth_data(dec->annotations, pda->ann_class); - printf(" %s: %s:", pdata->pdo->proto_id, ann_descr[0]); - for (i = 0; pda->ann_text[i]; i++) - printf(" \"%s\"", pda->ann_text[i]); - } + /* + * Determine which fields of the annotation to display. Inspect + * user specified options as well as the verbosity of the log level: + * - Optionally show the sample numbers for the annotation's span. + * - Always show the protocol decoder ID. + * - Optionally show the annotation's class description. + * - Always show the longest annotation text. + * - Optionally show alternative annotation text (abbreviations + * for different zoom levels). + * - Optionally put quote marks around annotation text, when + * recipients might have to deal with a set of text variants. + */ + show_snum = show_class = show_quotes = show_abbrev = FALSE; + if (opt_pd_samplenum || opt_loglevel > SR_LOG_WARN) { + show_snum = TRUE; + } + if (opt_loglevel > SR_LOG_WARN) { + show_quotes = TRUE; + } + if (opt_loglevel > SR_LOG_INFO) { + show_class = TRUE; + show_abbrev = TRUE; + } + + /* + * Display the annotation's fields after the layout was + * determined above. + */ + if (show_snum) { + printf("%" PRIu64 "-%" PRIu64 " ", + pdata->start_sample, pdata->end_sample); + } + printf("%s: ", pdata->pdo->proto_id); + if (show_class) { + ann_descr = g_slist_nth_data(dec->annotations, pda->ann_class); + printf("%s: ", ann_descr[0]); + } + quote = show_quotes ? "\"" : ""; + printf("%s%s%s", quote, pda->ann_text[0], quote); + if (show_abbrev) { + for (i = 1; pda->ann_text[i]; i++) + printf(" %s%s%s", quote, pda->ann_text[i], quote); } printf("\n"); fflush(stdout); @@ -479,7 +506,7 @@ void show_pd_meta(struct srd_proto_data *pdata, void *cb_data) /* Not in the list of PDs whose meta output we're showing. */ return; - if (opt_loglevel > SR_LOG_WARN) + if (opt_pd_samplenum || opt_loglevel > SR_LOG_WARN) printf("%"PRIu64"-%"PRIu64" ", pdata->start_sample, pdata->end_sample); printf("%s: ", pdata->pdo->proto_id); printf("%s: %s", pdata->pdo->meta_name, g_variant_print(pdata->data, FALSE)); @@ -491,7 +518,7 @@ void show_pd_binary(struct srd_proto_data *pdata, void *cb_data) { struct srd_proto_data_binary *pdb; gpointer classp; - int class; + int classi; (void)cb_data; @@ -500,9 +527,9 @@ void show_pd_binary(struct srd_proto_data *pdata, void *cb_data) /* Not in the list of PDs whose meta output we're showing. */ return; - class = GPOINTER_TO_INT(classp); + classi = GPOINTER_TO_INT(classp); pdb = pdata->data; - if (class != -1 && class != pdb->bin_class) + if (classi != -1 && classi != pdb->bin_class) /* Not showing this binary class. */ return; diff --git a/doc/sigrok-cli.1 b/doc/sigrok-cli.1 index 1666f89..c87d383 100644 --- a/doc/sigrok-cli.1 +++ b/doc/sigrok-cli.1 @@ -1,4 +1,4 @@ -.TH SIGROK\-CLI 1 "May 04, 2014" +.TH SIGROK\-CLI 1 "October 22, 2018" .SH "NAME" sigrok\-cli \- Command-line client for the sigrok software .SH "SYNOPSIS" @@ -21,16 +21,17 @@ Show a help text and exit. .TP .B "\-V, \-\-version" Show -.B sigrok-cli +.B sigrok\-cli version and the versions of libraries used. .TP -.B "\-L, \-\-list-supported" +.B "\-L, \-\-list\-supported" Show information about supported hardware drivers, input file formats, output file formats, and protocol decoders. .TP \fB\-d, \-\-driver\fP A driver must always be selected (unless doing a global scan). Use the -\fB-V\fP option to get a list of available drivers. +.BR "\-L " ( "\-\-list-supported" ")" +option to get a list of available drivers. .sp Drivers can take options, in the form \fBkey=value\fP separated by colons. @@ -39,49 +40,74 @@ Drivers communicating with hardware via a serial port always need the port specified as the \fBconn\fP option. For example, to use the Openbench Logic Sniffer: .sp -.RB " $ " "sigrok\-cli \-\-driver=ols:conn=/dev/ttyACM0" +.RB " $ " "sigrok\-cli \-\-driver=ols:conn=/dev/ttyACM0" " [...]" .sp Some USB devices don't use a unique VendorID/ProductID combination, and thus need that specified as well. This also uses the \fBconn\fP option, using either \fBVendorID.ProductID\fP or \fBbus.address\fP: .sp -.RB " $ " "sigrok\-cli \-\-driver=uni-t-ut61e:conn=1a86.e008" +USB \fBVendorID.ProductID\fP example: +.sp +.RB " $ " "sigrok\-cli \-\-driver=uni\-t\-ut61e:conn=1a86.e008" " [...]" +.sp +USB \fBbus.address\fP example: +.sp +.RB " $ " "sigrok\-cli \-\-driver=uni\-t\-ut61e:conn=4.6" " [...]" .TP -.BR "\-c, \-\-config " +.BR "\-c, \-\-config " A colon-separated list of device options, where each option takes the form .BR key=value . For example, to set the samplerate to 1MHz on a device supported by the fx2lafw driver, you might specify .sp -.RB " $ " "sigrok\-cli \-\-driver=fx2lafw \-\-config samplerate=1m" +.RB " $ " "sigrok\-cli \-d fx2lafw \-\-config samplerate=1m" " [...]" .sp Samplerate is an option common to most logic analyzers. The argument specifies the samplerate in Hz. You can also specify the samplerate in kHz, MHz or GHz. The following are all equivalent: .sp -.RB " $ " "sigrok\-cli \-\-driver fx2lafw \-\-config samplerate=1000000" +.RB " $ " "sigrok\-cli \-d fx2lafw \-\-config samplerate=1000000" " [...]" .sp -.RB " $ " "sigrok\-cli \-\-driver fx2lafw \-\-config samplerate=1m" +.RB " $ " "sigrok\-cli \-d fx2lafw \-\-config samplerate=1m" " [...]" .sp -.RB " $ " "sigrok\-cli \-\-driver fx2lafw \-\-config \(dqsamplerate=1 MHz\(dq" +.RB " $ " "sigrok\-cli \-d fx2lafw \-\-config \(dqsamplerate=1 MHz\(dq" " [...]" .TP .BR "\-i, \-\-input\-file " -Load input from a file instead of a hardware device. If the +Load input from a file instead of a hardware device. You can specify +"-" to use stdin as input. If the .B \-\-input\-format -option is not supplied, sigrok-cli attempts to autodetect the file format of +option is not supplied, sigrok\-cli attempts to autodetect the file format of the input file. +.sp +Example for loading a sigrok session file: +.sp +.RB " $ " "sigrok\-cli \-i example.sr" " [...]" +.sp +Example for loading a WAV file (autodetection of input format): +.sp +.RB " $ " "sigrok\-cli \-i example.wav" " [...] +.sp +Example for loading a VCD file from stdin (autodetection of input format): +.sp +.RB " $ " "cat example.vcd | sigrok\-cli \-i \-" " [...] .TP .BR "\-I, \-\-input\-format " When loading an input file, assume it's in the specified format. If this option is not supplied (in addition to .BR \-\-input\-file ), sigrok-cli attempts to autodetect the file format of the input file. Use the -.B \-V +.BR "\-L " ( "\-\-list\-supported" ")" option to see a list of available input formats. .sp The format name may optionally be followed by a colon-separated list of options, where each option takes the form .BR "key=value" . +.sp +Example for loading a binary file with options: +.sp +.RB " $ " "sigrok\-cli \-i example.bin" +.br +.BR " \-I binary:numchannels=4:samplerate=1mhz" " [...]" .TP .BR "\-o, \-\-output\-file " Save output to a file instead of writing it to stdout. The default format @@ -89,34 +115,26 @@ used when saving is the sigrok session file format. This can be changed with the .B \-\-output\-format option. +.sp +Example for saving data in the sigrok session format: +.sp +.RB " $ " "sigrok\-cli " "[...] " "\-o example.sr" .TP -.BR "\-O, \-\-output\-format " +.BR "\-O, \-\-output\-format " Set the output format to use. Use the -.B \-V +.BR "\-L " ( "\-\-list\-supported" ")" option to see a list of available output formats. .sp The format name may optionally be followed by a colon-separated list of options, where each option takes the form .BR "key=value" . .sp -Supported formats currently include -.BR bits , -.BR hex , -.BR ascii , -.BR binary , -.BR vcd , -.BR ols , -.BR gnuplot , -.BR chronovu-la8 , -.BR csv ", and" -.BR analog . -.sp -The +For example, the .B bits or .B hex formats, for an ASCII bit or ASCII hexadecimal display, can take a "width" option, specifying the number of samples (in bits) to display per line. Thus -.B hex:width=128 +.B "\-O hex:width=128" will display 128 bits per line, in hexadecimal: .sp 0:ffff ffff ffff ffff ffff ffff ffff ffff @@ -128,12 +146,18 @@ like this: .sp 0:11111111 11111111 11111111 11111111 [...] 1:11111111 00000000 11111111 00000000 [...] +.sp +Example for saving data in the CSV format with options: +.sp +.RB " $ " "sigrok\-cli " "[...] " "\-o example.csv \-O csv:dedup:header=false" +.sp +Notice that boolean options are \fBtrue\fP when no value gets specified. .TP .BR "\-C, \-\-channels " A comma-separated list of channels to be used in the session. .sp Note that sigrok always names the channels according to how they're shown on -the enclosure of the hardware. If your logic analyzer numbers the channels 0-15, +the enclosure of the hardware. If your logic analyzer numbers the channels 0\-15, that's how you must specify them with this option. An oscilloscope's channels would generally be referred to as "CH1", "CH2", and so on. Use the \fB\-\-show\fP option to see a list of channel names for your device. @@ -163,11 +187,15 @@ will set the name of channel 1 to .BR "MISO" . .TP .BR "\-g, \-\-channel\-group " -Specify the channel group to operate on. - -Some devices organize channels into groups, the settings of which can -only be changed as a group. The list of channel groups, if any, is displayed -with the \fB\-\-show\fP command. +Specify the channel group to operate on. Some devices organize channels into +groups, the settings of which can only be changed as a group. The list of +channel groups, if any, is displayed with the \fB\-\-show\fP command. +.sp +Examples: +.sp +.RB " $ " "sigrok\-cli \-g CH1" " [...]" +.sp +.RB " $ " "sigrok\-cli \-d demo \-g Logic \-c pattern=graycode" " [...]" .TP .BR "\-t, \-\-triggers " A comma-separated list of triggers to use, of the form @@ -190,7 +218,7 @@ Any kind of change on a pin (either a rising or a falling edge). Not every device supports all of these trigger types. Use the \fB\-\-show\fP command to see which triggers your device supports. .TP -.BR "\-w, \-\-wait-trigger" +.BR "\-w, \-\-wait\-trigger" Don't output any sample data (even if it's actually received from the hardware) before the trigger condition is met. In other words, do not output any pre-trigger data. This option is useful if you don't care about the data @@ -201,7 +229,7 @@ nonetheless). This option allows the user to specify a comma-separated list of protocol decoders to be used in this session. The decoders are specified by their ID, as shown in the -.B \-\-version +.BR "\-L " ( "\-\-list\-supported" ")" output. .sp Example: @@ -240,6 +268,36 @@ is an option supported by the protocol decoder. Additionally, the user tells sigrok to decode the SPI protocol using channel 1 as MISO signal for SPI, channel 5 as MOSI, channel 3 as CLK, and channel 0 as CS# signal. +.sp +Notice that the +.B sigrok\-cli +application does not support "name matching". Instead it's assumed that the +traces in the input stream match the order of the decoder's input signals, +or that users explicitly specify the input channel to decoder signal mapping. +.br +.sp +When multiple decoders are specified in the same +.BR -P +option, they will be stacked on top of each other in the specified order. +.sp +Example: +.sp + $ +.B "sigrok\-cli \-i \-P i2c,eeprom24xx" +.br + $ +.B "sigrok\-cli \-i \-P uart:baudrate=31250,midi" +.sp +When multiple +.BR -P +options are specified, each of them creates one decoder stack, which +executes in parallel to other decoder stacks. +.sp +Example: +.sp + $ +.B "sigrok\-cli \-i \-P uart:tx=D0:rx=D1 \-P timing:data=D2" +.sp .TP .BR "\-A, \-\-protocol\-decoder\-annotations " By default, only the stack's topmost protocol decoder's annotation output is @@ -247,7 +305,7 @@ shown. With this option another decoder's annotation can be selected for display, by specifying its ID: .sp $ -.B "sigrok\-cli \-i \-P i2c,i2cfilter,edid -A i2c" +.B "sigrok\-cli \-i \-P i2c,i2cfilter,edid \-A i2c" .sp If a protocol decoder has multiple annotations, you can also specify which one of them to show by specifying its short description like this: @@ -255,14 +313,14 @@ which one of them to show by specifying its short description like this: $ .B "sigrok\-cli \-i \-P i2c,i2cfilter,edid" .br -.B " \-A i2c=data-read" +.B " \-A i2c=data\-read" .sp Select multiple annotations by separating them with a colon: .sp $ .B "sigrok\-cli \-i \-P i2c,i2cfilter,edid" .br -.B " \-A i2c=data-read:data-write" +.B " \-A i2c=data\-read:data\-write" .sp You can also select multiple protocol decoders, with an optional selected annotation each, by separating them with commas: @@ -270,7 +328,7 @@ annotation each, by separating them with commas: $ .B "sigrok\-cli \-i \-P i2c,i2cfilter,edid" .br -.B " \-A i2c=data-read:data-write,edid" +.B " \-A i2c=data\-read:data\-write,edid" .TP .BR "\-M, \-\-protocol\-decoder\-meta " When given, show protocol decoder meta output instead of annotations. @@ -309,8 +367,12 @@ binary class you're interested in) .sp Not every decoder generates binary output. .TP +.BR "\-\-protocol\-decoder\-samplenum +When given, decoder annotations will include sample numbers, too. +This allows consumers to receive machine readable timing information. +.TP .BR "\-l, \-\-loglevel " -Set the libsigrok and libsigrokdecode loglevel. At the moment \fBsigrok-cli\fP +Set the libsigrok and libsigrokdecode loglevel. At the moment \fBsigrok\-cli\fP doesn't support setting the two loglevels independently. The higher the number, the more debug output will be printed. Valid loglevels are: .sp @@ -359,15 +421,15 @@ Example: .br The following devices were found: .br - demo - Demo device with 12 channels: D0 D1 D2 D3 D4 D5 D6 D7 A0 A1 A2 A3 + demo \- Demo device with 12 channels: D0 D1 D2 D3 D4 D5 D6 D7 A0 A1 A2 A3 .br - fx2lafw:conn=3.26 - CWAV USBee SX with 8 channels: 0 1 2 3 4 5 6 7 + fx2lafw:conn=3.26 \- CWAV USBee SX with 8 channels: 0 1 2 3 4 5 6 7 .sp However, not all devices are auto-detectable (e.g. serial port based ones). For those you'll have to provide a \fBconn\fP option, see above. .sp $ -.B "sigrok\-cli \-\-driver digitek-dt4000zc:conn=/dev/ttyUSB0 \-\-scan +.B "sigrok\-cli \-\-driver digitek\-dt4000zc:conn=/dev/ttyUSB0 \-\-scan .br The following devices were found: .br diff --git a/input.c b/input.c index 21c28cd..8eeb94c 100644 --- a/input.c +++ b/input.c @@ -28,7 +28,7 @@ #include #include "sigrok-cli.h" -#define BUFSIZE (16 * 1024) +#define CHUNK_SIZE (4 * 1024 * 1024) static void load_input_file_module(void) { @@ -43,6 +43,7 @@ static void load_input_file_module(void) int fd; ssize_t len; char *mod_id; + gboolean is_stdin; if (!sr_input_list()) g_critical("No supported input formats available."); @@ -54,8 +55,9 @@ static void load_input_file_module(void) mod_id = g_hash_table_lookup(mod_args, "sigrok_key"); } + is_stdin = strcmp(opt_input_file, "-") == 0; fd = 0; - buf = g_string_sized_new(BUFSIZE); + buf = g_string_sized_new(CHUNK_SIZE); if (mod_id) { /* User specified an input module to use. */ if (!(imod = sr_input_find(mod_id))) @@ -72,11 +74,11 @@ static void load_input_file_module(void) g_hash_table_destroy(mod_opts); if (mod_args) g_hash_table_destroy(mod_args); - if ((fd = open(opt_input_file, O_RDONLY)) == -1) + if (!is_stdin && (fd = open(opt_input_file, O_RDONLY)) < 0) g_critical("Failed to load %s: %s.", opt_input_file, g_strerror(errno)); } else { - if (strcmp(opt_input_file, "-")) { + if (!is_stdin) { /* * An actual filename: let the input modules try to * identify the file. @@ -90,15 +92,16 @@ static void load_input_file_module(void) * Taking input from a pipe: let the input modules try * to identify the stream content. */ - if (!strcmp(opt_input_file, "-")) { + if (is_stdin) { /* stdin */ fd = 0; } else { - if ((fd = open(opt_input_file, O_RDONLY)) == -1) + fd = open(opt_input_file, O_RDONLY); + if (fd == -1) g_critical("Failed to load %s: %s.", opt_input_file, g_strerror(errno)); } - if ((len = read(fd, buf->str, BUFSIZE)) < 1) + if ((len = read(fd, buf->str, CHUNK_SIZE)) < 1) g_critical("Failed to read %s: %s.", opt_input_file, g_strerror(errno)); buf->len = len; @@ -108,12 +111,12 @@ static void load_input_file_module(void) g_critical("Error: no input module found for this file."); } sr_session_new(sr_ctx, &session); - sr_session_datafeed_callback_add(session, &datafeed_in, NULL); + sr_session_datafeed_callback_add(session, &datafeed_in, session); got_sdi = FALSE; while (TRUE) { g_string_truncate(buf, 0); - len = read(fd, buf->str, BUFSIZE); + len = read(fd, buf->str, CHUNK_SIZE); if (len < 0) g_critical("Read failed: %s", g_strerror(errno)); if (len == 0) @@ -174,7 +177,7 @@ void load_input_file(void) } main_loop = g_main_loop_new(NULL, FALSE); - sr_session_datafeed_callback_add(session, datafeed_in, NULL); + sr_session_datafeed_callback_add(session, datafeed_in, session); sr_session_stopped_callback_set(session, (sr_session_stopped_callback)g_main_loop_quit, main_loop); diff --git a/main.c b/main.c index e4d321b..689c2d5 100644 --- a/main.c +++ b/main.c @@ -138,7 +138,8 @@ static void get_option(void) if ((devargs = parse_generic_arg(opt_config, FALSE))) set_dev_options(sdi, devargs); - else devargs = NULL; + 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)); diff --git a/options.c b/options.c index ca16e4c..b9e1494 100644 --- a/options.c +++ b/options.c @@ -38,6 +38,7 @@ gchar **opt_pds = NULL; gchar *opt_pd_annotations = NULL; gchar *opt_pd_meta = NULL; gchar *opt_pd_binary = NULL; +gboolean opt_pd_samplenum = FALSE; #endif gchar *opt_input_format = NULL; gchar *opt_output_format = NULL; @@ -134,6 +135,8 @@ static const GOptionEntry optargs[] = { "Protocol decoder meta output to show", NULL}, {"protocol-decoder-binary", 'B', 0, G_OPTION_ARG_CALLBACK, &check_opt_pd_binary, "Protocol decoder binary output to show", NULL}, + {"protocol-decoder-samplenum", 0, 0, G_OPTION_ARG_NONE, &opt_pd_samplenum, + "Show sample numbers in decoder output", NULL}, #endif {"scan", 0, 0, G_OPTION_ARG_NONE, &opt_scan_devs, "Scan for devices", NULL}, @@ -147,7 +150,7 @@ static const GOptionEntry optargs[] = { "Number of frames to acquire", NULL}, {"continuous", 0, 0, G_OPTION_ARG_NONE, &opt_continuous, "Sample continuously", NULL}, - {"get", 0, 0, G_OPTION_ARG_CALLBACK, &check_opt_get, "Get device option only", NULL}, + {"get", 0, 0, G_OPTION_ARG_CALLBACK, &check_opt_get, "Get device options only", NULL}, {"set", 0, 0, G_OPTION_ARG_NONE, &opt_set, "Set device options only", NULL}, {NULL, 0, 0, 0, NULL, NULL, NULL} }; diff --git a/session.c b/session.c index 4b55544..152f979 100644 --- a/session.c +++ b/session.c @@ -130,9 +130,6 @@ const struct sr_transform *setup_transform_module(const struct sr_dev_inst *sdi) GHashTable *fmtargs, *fmtopts; char *fmtspec; - if (!opt_transform_module) - opt_transform_module = "nop"; - fmtargs = parse_generic_arg(opt_transform_module, TRUE); fmtspec = g_hash_table_lookup(fmtargs, "sigrok_key"); if (!fmtspec) @@ -193,7 +190,9 @@ void datafeed_in(const struct sr_dev_inst *sdi, g_critical("Failed to initialize output module."); /* Set up backup analog output module. */ - oa = sr_output_new(sr_output_find("analog"), NULL, sdi, NULL); + if (outfile) + oa = sr_output_new(sr_output_find("analog"), NULL, + sdi, NULL); rcvd_samples_logic = rcvd_samples_analog = 0; @@ -311,9 +310,7 @@ void datafeed_in(const struct sr_dev_inst *sdi, if (o && !opt_pds) { if (sr_output_send(o, packet, &out) == SR_OK) { - if (!out || (out->len == 0 - && !opt_output_format - && packet->type == SR_DF_ANALOG)) { + if (oa && !out) { /* * The user didn't specify an output module, * but needs to see this analog data. @@ -340,7 +337,8 @@ void datafeed_in(const struct sr_dev_inst *sdi, sr_output_free(o); o = NULL; - sr_output_free(oa); + if (oa) + sr_output_free(oa); oa = NULL; if (outfile && outfile != stdout) @@ -531,7 +529,7 @@ void run_session(void) struct sr_trigger *trigger; struct sr_dev_inst *sdi; uint64_t min_samples, max_samples; - GArray *dev_opts; + GArray *drv_opts; guint i; int is_demo_dev; struct sr_dev_driver *driver; @@ -550,18 +548,18 @@ void run_session(void) driver = sr_dev_inst_driver_get(sdi); - if (!(dev_opts = sr_dev_options(driver, sdi, NULL))) { - g_critical("Failed to query list device options."); + if (!(drv_opts = sr_dev_options(driver, NULL, NULL))) { + g_critical("Failed to query list of driver options."); return; } is_demo_dev = 0; - for (i = 0; i < dev_opts->len; i++) { - if (g_array_index(dev_opts, uint32_t, i) == SR_CONF_DEMO_DEV) + for (i = 0; i < drv_opts->len; i++) { + if (g_array_index(drv_opts, uint32_t, i) == SR_CONF_DEMO_DEV) is_demo_dev = 1; } - g_array_free(dev_opts, TRUE); + g_array_free(drv_opts, TRUE); if (!is_demo_dev) real_devices = g_slist_append(real_devices, sdi); @@ -579,12 +577,18 @@ void run_session(void) } } + /* This is unlikely to happen but it makes static analyzers stop complaining. */ + if (!devices) { + g_critical("No real devices found."); + return; + } + sdi = devices->data; g_slist_free(devices); g_slist_free(real_devices); sr_session_new(sr_ctx, &session); - sr_session_datafeed_callback_add(session, datafeed_in, NULL); + sr_session_datafeed_callback_add(session, datafeed_in, session); if (sr_dev_open(sdi) != SR_OK) { g_critical("Failed to open device."); @@ -671,7 +675,7 @@ void run_session(void) if (opt_frames) { if ((sr_parse_sizestring(opt_frames, &limit_frames) != SR_OK)) { - g_critical("Invalid sample limit '%s'.", opt_samples); + g_critical("Invalid frame limit '%s'.", opt_frames); sr_session_destroy(session); return; } @@ -683,8 +687,10 @@ void run_session(void) } } - if (!(t = setup_transform_module(sdi))) - g_critical("Failed to initialize transform module."); + if (opt_transform_module) { + if (!(t = setup_transform_module(sdi))) + g_critical("Failed to initialize transform module."); + } main_loop = g_main_loop_new(NULL, FALSE); diff --git a/sigrok-cli.h b/sigrok-cli.h index 96d8128..f564448 100644 --- a/sigrok-cli.h +++ b/sigrok-cli.h @@ -28,14 +28,10 @@ #define DEFAULT_OUTPUT_FORMAT_FILE "srzip" #define DEFAULT_OUTPUT_FORMAT_NOFILE "bits:width=64" -#define SAVE_CHUNK_SIZE (512 * 1024) /* main.c */ extern struct sr_context *sr_ctx; int select_channels(struct sr_dev_inst *sdi); -gboolean config_key_has_cap(struct sr_dev_driver *driver, - const struct sr_dev_inst *sdi, struct sr_channel_group *cg, - uint32_t key, uint32_t capability); int maybe_config_get(struct sr_dev_driver *driver, const struct sr_dev_inst *sdi, struct sr_channel_group *cg, uint32_t key, GVariant **gvar); @@ -66,8 +62,6 @@ 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(struct sr_session *session, uint8_t *data, - uint64_t data_len, int unitsize); /* input.c */ void load_input_file(void); @@ -116,6 +110,7 @@ extern gchar **opt_pds; extern gchar *opt_pd_annotations; extern gchar *opt_pd_meta; extern gchar *opt_pd_binary; +extern gboolean opt_pd_samplenum; #endif extern gchar *opt_input_format; extern gchar *opt_output_format; -- 2.30.2