X-Git-Url: http://sigrok.org/gitweb/?a=blobdiff_plain;f=libserialport.h.in;h=67df3d7b9db6e00947909235849021d08184e588;hb=6aaf844863e63b71b5cf6b557bf3cd9257b5cffd;hp=43d7ee7e40ab8a2a6d1c2ca7b0436e0641eccbe0;hpb=1b91c6eadbcbd2356441920c11c9385083b93e91;p=libserialport.git diff --git a/libserialport.h.in b/libserialport.h.in index 43d7ee7..67df3d7 100644 --- a/libserialport.h.in +++ b/libserialport.h.in @@ -1,7 +1,9 @@ /* * This file is part of the libserialport project. * - * Copyright (C) 2013 Martin Ling + * Copyright (C) 2013, 2015 Martin Ling + * Copyright (C) 2014 Uwe Hermann + * Copyright (C) 2014 Aurelien Jacobs * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as @@ -29,27 +31,95 @@ * By writing your serial code to use libserialport, you enable it to work * transparently on any platform supported by the library. * - * The operations that are supported are: + * libserialport is an open source project released under the LGPL3+ license. + * + * The library is maintained by the [sigrok](http://sigrok.org/) project. See + * the [libserialport homepage](http://sigrok.org/wiki/Libserialport) for the + * latest information. + * + * Source code is maintained in git at + * [git://sigrok.org/libserialport](http://sigrok.org/gitweb/?p=libserialport.git). + * + * Bugs are tracked at http://sigrok.org/bugzilla/. + * + * The library was conceived and designed by Martin Ling, is maintained by + * Uwe Hermann, and has received contributions from several other developers. + * See the git history for full credits. + * + * API information + * =============== + * + * The API has been designed from scratch. It does not exactly resemble the + * serial API of any particular operating system. Instead it aims to provide + * a set of functions that can reliably be implemented across all operating + * systems. These form a sufficient basis for higher level behaviour to + * be implemented in a platform independent manner. + * + * If you are porting code written for a particular OS, you may find you need + * to restructure things somewhat, or do without some specialised features. + * For particular notes on porting existing code, see @ref Porting. + * + * Examples + * -------- + * + * Some simple example programs using libserialport are included in the + * @c examples directory in the source package: + * + * - @ref list_ports.c - Getting a list of ports present on the system. + * - @ref port_info.c - Getting information on a particular serial port. + * + * These examples are linked with the API documentation. Each function + * in the API reference includes links to where it is used in an example + * program, and each appearance of a function in the examples links + * to that function's entry in the API reference. + * + * Headers + * ------- + * + * To use libserialport functions in your code, you should include the + * libserialport.h header, i.e. + * @code + * #include + * @endcode + * + * Namespace + * --------- + * + * All identifiers defined by the public libserialport headers use the prefix + * @c sp_ (for functions and data types) or @c SP_ (for macros and constants). + * + * Functions + * --------- + * + * The functions provided by the library are documented in detail in + * the following sections: * * - @ref Enumeration (obtaining a list of serial ports on the system) - * - @ref Ports + * - @ref Ports (opening, closing and getting information about ports) * - @ref Configuration (baud rate, parity, etc.) * - @ref Signals (modem control lines, breaks, etc.) - * - @ref Data - * - @ref Waiting - * - @ref Errors + * - @ref Data (reading and writing data, and buffer management) + * - @ref Waiting (waiting for ports to be ready, integrating with event loops) + * - @ref Errors (getting error and debugging information) * - * libserialport is an open source project released under the LGPL3+ license. + * Data structures + * --------------- * - * API principles - * ============== + * The library defines three data structures: * - * The API is simple, and designed to be a minimal wrapper around the serial - * port support in each OS. + * - @ref sp_port, which represents a serial port. + * See @ref Enumeration. + * - @ref sp_port_config, which represents a port configuration. + * See @ref Configuration. + * - @ref sp_event_set, which represents a set of events. + * See @ref Waiting. * - * Most functions take a pointer to a struct sp_port, which represents a serial - * port. These structures are always allocated and freed by the library, using - * the functions in the @ref Enumeration "Enumeration" section. + * All these structures are allocated and freed by library functions. It is + * the caller's responsibility to ensure that the correct calls are made to + * free allocated structures after use. + * + * Return codes and error handling + * ------------------------------- * * Most functions have return type @ref sp_return and can return only four * possible error values: @@ -75,6 +145,124 @@ * Calls that succeed return @ref SP_OK, which is equal to zero. Some functions * declared @ref sp_return can also return a positive value for a successful * numeric result, e.g. sp_blocking_read() or sp_blocking_write(). + * + * An error message is only available via sp_last_error_message() in the case + * where @ref SP_ERR_FAIL was returned by the previous function call. The error + * message returned is that provided by the OS, using the current language + * settings. It is an error to call sp_last_error_code() or + * sp_last_error_message() except after a previous function call returned + * @ref SP_ERR_FAIL. The library does not define its own error codes or + * messages to accompany other return codes. + * + * Thread safety + * ------------- + * + * Certain combinations of calls can be made concurrently, as follows. + * + * - Calls using different ports may always be made concurrently, i.e. + * it is safe for separate threads to handle their own ports. + * + * - Calls using the same port may be made concurrently when one call + * is a read operation and one call is a write operation, i.e. it is safe + * to use separate "reader" and "writer" threads for the same port. See + * below for which operations meet these definitions. + * + * Read operations: + * + * - sp_blocking_read() + * - sp_blocking_read_next() + * - sp_nonblocking_read() + * - sp_input_waiting() + * - sp_flush() with @ref SP_BUF_INPUT only. + * - sp_wait() with @ref SP_EVENT_RX_READY only. + * + * Write operations: + * + * - sp_blocking_write() + * - sp_nonblocking_write() + * - sp_output_waiting() + * - sp_drain() + * - sp_flush() with @ref SP_BUF_OUTPUT only. + * - sp_wait() with @ref SP_EVENT_TX_READY only. + * + * If two calls, on the same port, do not fit into one of these categories + * each, then they may not be made concurrently. + * + * Debugging + * --------- + * + * The library can output extensive tracing and debugging information. The + * simplest way to use this is to set the environment variable + * @c LIBSERIALPORT_DEBUG to any value; messages will then be output to the + * standard error stream. + * + * This behaviour is implemented by a default debug message handling + * callback. An alternative callback can be set using sp_set_debug_handler(), + * in order to e.g. redirect the output elsewhere or filter it. + * + * No guarantees are made about the content of the debug output; it is chosen + * to suit the needs of the developers and may change between releases. + * + * @anchor Porting + * Porting + * ------- + * + * The following guidelines may help when porting existing OS-specific code + * to use libserialport. + * + * ### Porting from Unix-like systems ### + * + * There are two main differences to note when porting code written for Unix. + * + * The first is that Unix traditionally provides a wide range of functionality + * for dealing with serial devices at the OS level; this is exposed through the + * termios API and dates to the days when serial terminals were common. If your + * code relies on many of these facilities you will need to adapt it, because + * libserialport provides only a raw binary channel with no special handling. + * + * The second relates to blocking versus non-blocking I/O behaviour. In + * Unix-like systems this is normally specified by setting the @c O_NONBLOCK + * flag on the file descriptor, affecting the semantics of subsequent @c read() + * and @c write() calls. + * + * In libserialport, blocking and nonblocking operations are both available at + * any time. If your existing code ѕets @c O_NONBLOCK, you should use + * sp_nonblocking_read() and sp_nonblocking_write() to get the same behaviour + * as your existing @c read() and @c write() calls. If it does not, you should + * use sp_blocking_read() and sp_blocking_write() instead. You may also find + * sp_blocking_read_next() useful, which reproduces the semantics of a blocking + * read() with @c VTIME=0 and @c VMIN=1 set in termios. + * + * Finally, you should take care if your program uses custom signal handlers. + * The blocking calls provided by libserialport will restart system calls that + * return with @c EINTR, so you will need to make your own arrangements if you + * need to interrupt blocking operations when your signal handlers are called. + * This is not an issue if you only use the default handlers. + * + * ### Porting from Windows ### + * + * The main consideration when porting from Windows is that there is no + * direct equivalent for overlapped I/O operations. + * + * If your program does not use overlapped I/O, you can simply use + * sp_blocking_read() and sp_blocking_write() as direct equivalents for + * @c ReadFile() and @c WriteFile(). You may also find sp_blocking_read_next() + * useful, which reproduces the special semantics of @c ReadFile() with + * @c ReadIntervalTimeout and @c ReadTotalTimeoutMultiplier set to @c MAXDWORD + * and @c ReadTotalTimeoutConstant set to between @c 1 and @c MAXDWORD-1 . + * + * If your program makes use of overlapped I/O to continue work while a serial + * operation is in progress, then you can achieve the same results using + * sp_nonblocking_read() and sp_nonblocking_write(). + * + * Generally, overlapped I/O is combined with either waiting for completion + * once there is no more background work to do (using @c WaitForSingleObject() + * or @c WaitForMultipleObjects()), or periodically checking for completion + * with @c GetOverlappedResult(). If the aim is to start a new operation for + * further data once the previous one has completed, you can instead simply + * call the nonblocking functions again with the next data. If you need to + * wait for completion, use sp_wait() to determine when the port is ready to + * send or receive further data. */ #ifndef LIBSERIALPORT_LIBSERIALPORT_H @@ -272,6 +460,8 @@ struct sp_event_set { * * Enumerating the serial ports of a system. * + * See @ref list_ports.c for a working example of port enumeration. + * * @{ */ @@ -361,6 +551,8 @@ void sp_free_port_list(struct sp_port **ports); * * Opening, closing and querying ports. * + * See @ref port_info.c for a working example of getting port information. + * * @{ */ @@ -432,8 +624,10 @@ enum sp_transport sp_get_port_transport(const struct sp_port *port); * Get the USB bus number and address on bus of a USB serial adapter port. * * @param[in] port Pointer to a port structure. Must not be NULL. - * @param[out] usb_bus Pointer to a variable to store the USB bus. Must not be NULL. - * @param[out] usb_address Pointer to a variable to store the USB address. Must not be NULL. + * @param[out] usb_bus Pointer to a variable to store the USB bus. + * Can be NULL (in that case it will be ignored). + * @param[out] usb_address Pointer to a variable to store the USB address. + * Can be NULL (in that case it will be ignored). * * @return SP_OK upon success, a negative error code otherwise. * @@ -446,8 +640,10 @@ enum sp_return sp_get_port_usb_bus_address(const struct sp_port *port, * Get the USB Vendor ID and Product ID of a USB serial adapter port. * * @param[in] port Pointer to a port structure. Must not be NULL. - * @param[out] usb_vid Pointer to a variable to store the USB VID. Must not be NULL. - * @param[out] usb_pid Pointer to a variable to store the USB PID. Must not be NULL. + * @param[out] usb_vid Pointer to a variable to store the USB VID. + * Can be NULL (in that case it will be ignored). + * @param[out] usb_pid Pointer to a variable to store the USB PID. + * Can be NULL (in that case it will be ignored). * * @return SP_OK upon success, a negative error code otherwise. * @@ -529,8 +725,9 @@ char *sp_get_port_bluetooth_address(const struct sp_port *port); * * @param[in] port Pointer to a port structure. Must not be NULL. * @param[out] result_ptr If any error is returned, the variable pointed to by - * result_ptr will be set to NULL. Otherwise, it will - * be set to point to the OS handle. Must not be NULL. + * result_ptr will have unknown contents and should not + * be used. Otherwise, it will be set to point to the + * OS handle. Must not be NULL. * * @return SP_OK upon success, a negative error code otherwise. * @@ -550,17 +747,19 @@ enum sp_return sp_get_port_handle(const struct sp_port *port, void *result_ptr); /** * Allocate a port configuration structure. * - * The user should allocate a variable of type "struct sp_config *" and pass a - * pointer to this to receive the result. The variable will be updated to - * point to the new configuration structure. The structure is opaque and must - * be accessed via the functions provided. + * The user should allocate a variable of type "struct sp_port_config *" and + * pass a pointer to this to receive the result. The variable will be updated + * to point to the new configuration structure. The structure is opaque and + * must be accessed via the functions provided. * * All parameters in the structure will be initialised to special values which * are ignored by sp_set_config(). * * The structure should be freed after use by calling sp_free_config(). * - * @param[out] config_ptr Pointer to a variable to receive the result. + * @param[out] config_ptr If any error is returned, the variable pointed to by + * config_ptr will be set to NULL. Otherwise, it will + * be set to point to the allocated config structure. * Must not be NULL. * * @return SP_OK upon success, a negative error code otherwise. @@ -591,7 +790,8 @@ void sp_free_config(struct sp_port_config *config); * * @param[in] port Pointer to a port structure. Must not be NULL. * @param[out] config Pointer to a configuration structure that will hold - * the result. Must not be NULL. + * the result. Upon errors the contents of the config + * struct will not be changed. Must not be NULL. * * @return SP_OK upon success, a negative error code otherwise. * @@ -606,6 +806,9 @@ enum sp_return sp_get_config(struct sp_port *port, struct sp_port_config *config * -1, but see the documentation for each field). These values will be ignored * and the corresponding setting left unchanged on the port. * + * Upon errors, the configuration of the serial port is unknown since + * partial/incomplete config updates may have happened. + * * @param[in] port Pointer to a port structure. Must not be NULL. * @param[in] config Pointer to a configuration structure. Must not be NULL. * @@ -1038,6 +1241,34 @@ enum sp_return sp_set_flowcontrol(struct sp_port *port, enum sp_flowcontrol flow */ enum sp_return sp_blocking_read(struct sp_port *port, void *buf, size_t count, unsigned int timeout_ms); +/** + * Read bytes from the specified serial port, returning as soon as any data is + * available. + * + * @warning If your program runs on Unix, defines its own signal handlers, and + * needs to abort blocking reads when these are called, then you + * should not use this function. It repeats system calls that return + * with EINTR. To be able to abort a read from a signal handler, you + * should implement your own blocking read using sp_nonblocking_read() + * together with a blocking method that makes sense for your program. + * E.g. you can obtain the file descriptor for an open port using + * sp_get_port_handle() and use this to call select() or pselect(), + * with appropriate arrangements to return if a signal is received. + * + * @param[in] port Pointer to a port structure. Must not be NULL. + * @param[out] buf Buffer in which to store the bytes read. Must not be NULL. + * @param[in] count Maximum number of bytes to read. Must not be zero. + * @param[in] timeout_ms Timeout in milliseconds, or zero to wait indefinitely. + * + * @return The number of bytes read on success, or a negative error code. If + * the result is zero, the timeout was reached before any bytes were + * available. If timeout_ms is zero, the function will always return + * either at least one byte, or a negative error code. + * + * @since 0.1.1 + */ +enum sp_return sp_blocking_read_next(struct sp_port *port, void *buf, size_t count, unsigned int timeout_ms); + /** * Read bytes from the specified serial port, without blocking. * @@ -1296,6 +1527,8 @@ enum sp_return sp_end_break(struct sp_port *port); * * In order to obtain the correct result, this function should be called * straight after the failure, before executing any other system operations. + * The result is thread-specific, and only valid when called immediately + * after a previous call returning SP_ERR_FAIL. * * @return The system's numeric code for the error that caused the last * operation to fail. @@ -1309,6 +1542,8 @@ int sp_last_error_code(void); * * In order to obtain the correct result, this function should be called * straight after the failure, before executing other system operations. + * The result is thread-specific, and only valid when called immediately + * after a previous call returning SP_ERR_FAIL. * * @return The system's message for the error that caused the last * operation to fail. This string may be allocated by the function, @@ -1387,32 +1622,32 @@ void sp_default_debug_handler(const char *format, ...); */ /** The libserialport package 'major' version number. */ -#define SP_PACKAGE_VERSION_MAJOR @SP_PACKAGE_VERSION_MAJOR@ +#undef SP_PACKAGE_VERSION_MAJOR /** The libserialport package 'minor' version number. */ -#define SP_PACKAGE_VERSION_MINOR @SP_PACKAGE_VERSION_MINOR@ +#undef SP_PACKAGE_VERSION_MINOR /** The libserialport package 'micro' version number. */ -#define SP_PACKAGE_VERSION_MICRO @SP_PACKAGE_VERSION_MICRO@ +#undef SP_PACKAGE_VERSION_MICRO /** The libserialport package version ("major.minor.micro") as string. */ -#define SP_PACKAGE_VERSION_STRING "@SP_PACKAGE_VERSION@" +#undef SP_PACKAGE_VERSION_STRING /* * Library/libtool version macros (can be used for conditional compilation). */ /** The libserialport libtool 'current' version number. */ -#define SP_LIB_VERSION_CURRENT @SP_LIB_VERSION_CURRENT@ +#undef SP_LIB_VERSION_CURRENT /** The libserialport libtool 'revision' version number. */ -#define SP_LIB_VERSION_REVISION @SP_LIB_VERSION_REVISION@ +#undef SP_LIB_VERSION_REVISION /** The libserialport libtool 'age' version number. */ -#define SP_LIB_VERSION_AGE @SP_LIB_VERSION_AGE@ +#undef SP_LIB_VERSION_AGE /** The libserialport libtool version ("current:revision:age") as string. */ -#define SP_LIB_VERSION_STRING "@SP_LIB_VERSION@" +#undef SP_LIB_VERSION_STRING /** * Get the major libserialport package version number. @@ -1490,6 +1725,11 @@ const char *sp_get_lib_version_string(void); /** @} */ +/** + * @example list_ports.c Getting a list of ports present on the system. + * @example port_info.c Getting information on a particular serial port. +*/ + #ifdef __cplusplus } #endif