![]() |
libsigrok
0.3.0
sigrok hardware access and backend library
|
00001 /* 00002 * This file is part of the libsigrok project. 00003 * 00004 * Copyright (C) 2010-2012 Bert Vermeulen <bert@biot.com> 00005 * Copyright (C) 2012 Peter Stuge <peter@stuge.se> 00006 * 00007 * This program is free software: you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation, either version 3 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * This program is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00019 */ 00020 00021 #include <glib.h> 00022 #include "config.h" /* Needed for HAVE_LIBUSB_1_0 and others. */ 00023 #include "libsigrok.h" 00024 #include "libsigrok-internal.h" 00025 00026 /** @cond PRIVATE */ 00027 #define LOG_PREFIX "backend" 00028 /** @endcond */ 00029 00030 extern struct sr_session *session; 00031 00032 /** 00033 * @mainpage libsigrok API 00034 * 00035 * @section sec_intro Introduction 00036 * 00037 * The <a href="http://sigrok.org">sigrok</a> project aims at creating a 00038 * portable, cross-platform, Free/Libre/Open-Source signal analysis software 00039 * suite that supports various device types (such as logic analyzers, 00040 * oscilloscopes, multimeters, and more). 00041 * 00042 * <a href="http://sigrok.org/wiki/Libsigrok">libsigrok</a> is a shared 00043 * library written in C which provides the basic API for talking to 00044 * <a href="http://sigrok.org/wiki/Supported_hardware">supported hardware</a> 00045 * and reading/writing the acquired data into various 00046 * <a href="http://sigrok.org/wiki/Input_output_formats">input/output 00047 * file formats</a>. 00048 * 00049 * @section sec_api API reference 00050 * 00051 * See the "Modules" page for an introduction to various libsigrok 00052 * related topics and the detailed API documentation of the respective 00053 * functions. 00054 * 00055 * You can also browse the API documentation by file, or review all 00056 * data structures. 00057 * 00058 * @section sec_mailinglists Mailing lists 00059 * 00060 * There are two mailing lists for sigrok/libsigrok: <a href="https://lists.sourceforge.net/lists/listinfo/sigrok-devel">sigrok-devel</a> and <a href="https://lists.sourceforge.net/lists/listinfo/sigrok-commits">sigrok-commits</a>. 00061 * 00062 * @section sec_irc IRC 00063 * 00064 * You can find the sigrok developers in the 00065 * <a href="irc://chat.freenode.net/sigrok">\#sigrok</a> 00066 * IRC channel on Freenode. 00067 * 00068 * @section sec_website Website 00069 * 00070 * <a href="http://sigrok.org/wiki/Libsigrok">sigrok.org/wiki/Libsigrok</a> 00071 */ 00072 00073 /** 00074 * @file 00075 * 00076 * Initializing and shutting down libsigrok. 00077 */ 00078 00079 /** 00080 * @defgroup grp_init Initialization 00081 * 00082 * Initializing and shutting down libsigrok. 00083 * 00084 * Before using any of the libsigrok functionality, sr_init() must 00085 * be called to initialize the library, which will return a struct sr_context 00086 * when the initialization was successful. 00087 * 00088 * When libsigrok functionality is no longer needed, sr_exit() should be 00089 * called, which will (among other things) free the struct sr_context. 00090 * 00091 * Example for a minimal program using libsigrok: 00092 * 00093 * @code{.c} 00094 * #include <stdio.h> 00095 * #include <libsigrok/libsigrok.h> 00096 * 00097 * int main(int argc, char **argv) 00098 * { 00099 * int ret; 00100 * struct sr_context *sr_ctx; 00101 * 00102 * if ((ret = sr_init(&sr_ctx)) != SR_OK) { 00103 * printf("Error initializing libsigrok (%s): %s.\n", 00104 * sr_strerror_name(ret), sr_strerror(ret)); 00105 * return 1; 00106 * } 00107 * 00108 * // Use libsigrok functions here... 00109 * 00110 * if ((ret = sr_exit(sr_ctx)) != SR_OK) { 00111 * printf("Error shutting down libsigrok (%s): %s.\n", 00112 * sr_strerror_name(ret), sr_strerror(ret)); 00113 * return 1; 00114 * } 00115 * 00116 * return 0; 00117 * } 00118 * @endcode 00119 * 00120 * @{ 00121 */ 00122 00123 /** 00124 * Sanity-check all libsigrok drivers. 00125 * 00126 * @retval SR_OK All drivers are OK 00127 * @retval SR_ERR One or more drivers have issues. 00128 */ 00129 static int sanity_check_all_drivers(void) 00130 { 00131 int i, errors, ret = SR_OK; 00132 struct sr_dev_driver **drivers; 00133 const char *d; 00134 00135 sr_spew("Sanity-checking all drivers."); 00136 00137 drivers = sr_driver_list(); 00138 for (i = 0; drivers[i]; i++) { 00139 errors = 0; 00140 00141 d = (drivers[i]->name) ? drivers[i]->name : "NULL"; 00142 00143 if (!drivers[i]->name) { 00144 sr_err("No name in driver %d ('%s').", i, d); 00145 errors++; 00146 } 00147 if (!drivers[i]->longname) { 00148 sr_err("No longname in driver %d ('%s').", i, d); 00149 errors++; 00150 } 00151 if (drivers[i]->api_version < 1) { 00152 sr_err("API version in driver %d ('%s') < 1.", i, d); 00153 errors++; 00154 } 00155 if (!drivers[i]->init) { 00156 sr_err("No init in driver %d ('%s').", i, d); 00157 errors++; 00158 } 00159 if (!drivers[i]->cleanup) { 00160 sr_err("No cleanup in driver %d ('%s').", i, d); 00161 errors++; 00162 } 00163 if (!drivers[i]->scan) { 00164 sr_err("No scan in driver %d ('%s').", i, d); 00165 errors++; 00166 } 00167 if (!drivers[i]->dev_list) { 00168 sr_err("No dev_list in driver %d ('%s').", i, d); 00169 errors++; 00170 } 00171 /* Note: config_get() is optional. */ 00172 if (!drivers[i]->config_set) { 00173 sr_err("No config_set in driver %d ('%s').", i, d); 00174 errors++; 00175 } 00176 if (!drivers[i]->config_list) { 00177 sr_err("No config_list in driver %d ('%s').", i, d); 00178 errors++; 00179 } 00180 if (!drivers[i]->dev_open) { 00181 sr_err("No dev_open in driver %d ('%s').", i, d); 00182 errors++; 00183 } 00184 if (!drivers[i]->dev_close) { 00185 sr_err("No dev_close in driver %d ('%s').", i, d); 00186 errors++; 00187 } 00188 if (!drivers[i]->dev_acquisition_start) { 00189 sr_err("No dev_acquisition_start in driver %d ('%s').", 00190 i, d); 00191 errors++; 00192 } 00193 if (!drivers[i]->dev_acquisition_stop) { 00194 sr_err("No dev_acquisition_stop in driver %d ('%s').", 00195 i, d); 00196 errors++; 00197 } 00198 00199 /* Note: 'priv' is allowed to be NULL. */ 00200 00201 if (errors == 0) 00202 continue; 00203 00204 ret = SR_ERR; 00205 } 00206 00207 return ret; 00208 } 00209 00210 /** 00211 * Sanity-check all libsigrok input modules. 00212 * 00213 * @retval SR_OK All modules are OK 00214 * @retval SR_ERR One or more modules have issues. 00215 */ 00216 static int sanity_check_all_input_modules(void) 00217 { 00218 int i, errors, ret = SR_OK; 00219 struct sr_input_format **inputs; 00220 const char *d; 00221 00222 sr_spew("Sanity-checking all input modules."); 00223 00224 inputs = sr_input_list(); 00225 for (i = 0; inputs[i]; i++) { 00226 errors = 0; 00227 00228 d = (inputs[i]->id) ? inputs[i]->id : "NULL"; 00229 00230 if (!inputs[i]->id) { 00231 sr_err("No ID in module %d ('%s').", i, d); 00232 errors++; 00233 } 00234 if (!inputs[i]->description) { 00235 sr_err("No description in module %d ('%s').", i, d); 00236 errors++; 00237 } 00238 if (!inputs[i]->format_match) { 00239 sr_err("No format_match in module %d ('%s').", i, d); 00240 errors++; 00241 } 00242 if (!inputs[i]->init) { 00243 sr_err("No init in module %d ('%s').", i, d); 00244 errors++; 00245 } 00246 if (!inputs[i]->loadfile) { 00247 sr_err("No loadfile in module %d ('%s').", i, d); 00248 errors++; 00249 } 00250 00251 if (errors == 0) 00252 continue; 00253 00254 ret = SR_ERR; 00255 } 00256 00257 return ret; 00258 } 00259 00260 /** 00261 * Sanity-check all libsigrok output modules. 00262 * 00263 * @retval SR_OK All modules are OK 00264 * @retval SR_ERR One or more modules have issues. 00265 */ 00266 static int sanity_check_all_output_modules(void) 00267 { 00268 int i, errors, ret = SR_OK; 00269 struct sr_output_format **outputs; 00270 const char *d; 00271 00272 sr_spew("Sanity-checking all output modules."); 00273 00274 outputs = sr_output_list(); 00275 for (i = 0; outputs[i]; i++) { 00276 errors = 0; 00277 00278 d = (outputs[i]->id) ? outputs[i]->id : "NULL"; 00279 00280 if (!outputs[i]->id) { 00281 sr_err("No ID in module %d ('%s').", i, d); 00282 errors++; 00283 } 00284 if (!outputs[i]->description) { 00285 sr_err("No description in module '%s'.", d); 00286 errors++; 00287 } 00288 if (!outputs[i]->receive) { 00289 sr_err("No receive in module '%s'.", d); 00290 errors++; 00291 } 00292 00293 if (errors == 0) 00294 continue; 00295 00296 ret = SR_ERR; 00297 } 00298 00299 return ret; 00300 } 00301 00302 /** 00303 * Initialize libsigrok. 00304 * 00305 * This function must be called before any other libsigrok function. 00306 * 00307 * @param ctx Pointer to a libsigrok context struct pointer. Must not be NULL. 00308 * This will be a pointer to a newly allocated libsigrok context 00309 * object upon success, and is undefined upon errors. 00310 * 00311 * @return SR_OK upon success, a (negative) error code otherwise. Upon errors 00312 * the 'ctx' pointer is undefined and should not be used. Upon success, 00313 * the context will be free'd by sr_exit() as part of the libsigrok 00314 * shutdown. 00315 * 00316 * @since 0.2.0 00317 */ 00318 SR_API int sr_init(struct sr_context **ctx) 00319 { 00320 int ret = SR_ERR; 00321 struct sr_context *context; 00322 00323 if (!ctx) { 00324 sr_err("%s(): libsigrok context was NULL.", __func__); 00325 return SR_ERR; 00326 } 00327 00328 if (sanity_check_all_drivers() < 0) { 00329 sr_err("Internal driver error(s), aborting."); 00330 return ret; 00331 } 00332 00333 if (sanity_check_all_input_modules() < 0) { 00334 sr_err("Internal input module error(s), aborting."); 00335 return ret; 00336 } 00337 00338 if (sanity_check_all_output_modules() < 0) { 00339 sr_err("Internal output module error(s), aborting."); 00340 return ret; 00341 } 00342 00343 /* + 1 to handle when struct sr_context has no members. */ 00344 context = g_try_malloc0(sizeof(struct sr_context) + 1); 00345 00346 if (!context) { 00347 ret = SR_ERR_MALLOC; 00348 goto done; 00349 } 00350 00351 #ifdef HAVE_LIBUSB_1_0 00352 ret = libusb_init(&context->libusb_ctx); 00353 if (LIBUSB_SUCCESS != ret) { 00354 sr_err("libusb_init() returned %s.", libusb_error_name(ret)); 00355 ret = SR_ERR; 00356 goto done; 00357 } 00358 #endif 00359 00360 *ctx = context; 00361 context = NULL; 00362 session = NULL; 00363 ret = SR_OK; 00364 00365 done: 00366 if (context) 00367 g_free(context); 00368 return ret; 00369 } 00370 00371 /** 00372 * Shutdown libsigrok. 00373 * 00374 * @param ctx Pointer to a libsigrok context struct. Must not be NULL. 00375 * 00376 * @retval SR_OK Success 00377 * @retval other Error code SR_ERR, ... 00378 * 00379 * @since 0.2.0 00380 */ 00381 SR_API int sr_exit(struct sr_context *ctx) 00382 { 00383 if (!ctx) { 00384 sr_err("%s(): libsigrok context was NULL.", __func__); 00385 return SR_ERR; 00386 } 00387 00388 sr_hw_cleanup_all(); 00389 00390 #ifdef HAVE_LIBUSB_1_0 00391 libusb_exit(ctx->libusb_ctx); 00392 #endif 00393 00394 g_free(ctx); 00395 00396 return SR_OK; 00397 } 00398 00399 /** @} */
1.7.6.1