mirror of
git://sigrok.org/libserialport
synced 2023-08-10 21:13:24 +03:00
Compare commits
93 Commits
libserialp
...
master
Author | SHA1 | Date | |
---|---|---|---|
6f9b03e597 | |||
1abec20502 | |||
a06a765515 | |||
1b011060df | |||
086a418145 | |||
ffbfc5c76b | |||
0a24247de8 | |||
251890e3b9 | |||
ba49ee82db | |||
2913355f7e | |||
6711e43e9b | |||
75a280a597 | |||
7b0686ed58 | |||
4349b1f6a2 | |||
cd1a7d4361 | |||
d81a4dfdc6 | |||
78c3db9bfb | |||
42b3cf3b98 | |||
fb58f12ee9 | |||
2be41b1265 | |||
f6abee5c78 | |||
6339fa04d6 | |||
28981e0793 | |||
67b55d10b8 | |||
d8c4d388e8 | |||
d6412d2801 | |||
60fc49ceab | |||
41fc921ce4 | |||
528e8c0002 | |||
988ace6c9f | |||
bf40b1cea9 | |||
e47c7dcbff | |||
2149db9e93 | |||
4651adb4f6 | |||
75f468923b | |||
e919e2efaa | |||
a20ed2965b | |||
4720053160 | |||
6dba844779 | |||
9ddf08588d | |||
0838c979cc | |||
f6e32b2dfa | |||
6aaf844863 | |||
fdbb55ae1e | |||
a9900f8b64 | |||
e9d78d82c4 | |||
8488868187 | |||
c79e0ac8ef | |||
060d1d8a73 | |||
8073f87d45 | |||
39acdc47db | |||
bd72614f08 | |||
9d1ca7c855 | |||
3317d678de | |||
08eb25f53a | |||
32dbe2d298 | |||
9a7945af84 | |||
d9cc984fe7 | |||
44df415480 | |||
89c3d63e1a | |||
ee12a01e52 | |||
ad19d60493 | |||
7c8d67efdc | |||
8c1a14e658 | |||
abd31fd9f9 | |||
277f832a6a | |||
9118f753f4 | |||
fa106ef155 | |||
bd0fb6094f | |||
7fb9a7b0a7 | |||
192e77492a | |||
f40ea9d461 | |||
46bdc20c26 | |||
573feabc63 | |||
b457865b8f | |||
39df7833f7 | |||
6bd6a8b520 | |||
55ab7e0b6b | |||
81243567bc | |||
2e0437c28e | |||
38b71192dd | |||
a84ffb5372 | |||
42ad781896 | |||
62ed9f801a | |||
15541ebd78 | |||
95bad38c5b | |||
2a6c24be33 | |||
6c8115820d | |||
d8de88de32 | |||
0b53933127 | |||
5ec2f93bce | |||
df3b70a888 | |||
b2359c5c99 |
6
.gitignore
vendored
6
.gitignore
vendored
@ -12,7 +12,11 @@
|
|||||||
/configure
|
/configure
|
||||||
/configure.lineno
|
/configure.lineno
|
||||||
/libserialport-*.tar.*
|
/libserialport-*.tar.*
|
||||||
/libserialport.h
|
|
||||||
/libserialport.pc
|
/libserialport.pc
|
||||||
/libtool
|
/libtool
|
||||||
stamp-h?
|
stamp-h?
|
||||||
|
.vs/
|
||||||
|
Debug/
|
||||||
|
Release/
|
||||||
|
x64/
|
||||||
|
*.vcxproj.user
|
||||||
|
19
Makefile.am
19
Makefile.am
@ -24,10 +24,13 @@ GNUMAKEFLAGS = --no-print-directory
|
|||||||
|
|
||||||
# Enable more compiler warnings.
|
# Enable more compiler warnings.
|
||||||
AM_CFLAGS = -std=c99 -Wall -Wextra -pedantic -Wmissing-prototypes -Wshadow
|
AM_CFLAGS = -std=c99 -Wall -Wextra -pedantic -Wmissing-prototypes -Wshadow
|
||||||
|
# Set flag used in libserialport.h to indicate we are building the library
|
||||||
|
# using autotools.
|
||||||
|
AM_CFLAGS += -DLIBSERIALPORT_ATBUILD
|
||||||
|
|
||||||
lib_LTLIBRARIES = libserialport.la
|
lib_LTLIBRARIES = libserialport.la
|
||||||
|
|
||||||
libserialport_la_SOURCES = serialport.c libserialport_internal.h
|
libserialport_la_SOURCES = serialport.c timing.c libserialport_internal.h
|
||||||
if LINUX
|
if LINUX
|
||||||
libserialport_la_SOURCES += linux.c linux_termios.c linux_termios.h
|
libserialport_la_SOURCES += linux.c linux_termios.c linux_termios.h
|
||||||
endif
|
endif
|
||||||
@ -53,7 +56,19 @@ nodist_include_HEADERS = libserialport.h
|
|||||||
pkgconfigdir = $(libdir)/pkgconfig
|
pkgconfigdir = $(libdir)/pkgconfig
|
||||||
pkgconfig_DATA = libserialport.pc
|
pkgconfig_DATA = libserialport.pc
|
||||||
|
|
||||||
EXTRA_DIST = Doxyfile
|
TESTS = test_timing
|
||||||
|
check_PROGRAMS = test_timing
|
||||||
|
test_timing_SOURCES = timing.c test_timing.c
|
||||||
|
test_timing_CFLAGS = $(AM_CFLAGS)
|
||||||
|
|
||||||
|
EXTRA_DIST = Doxyfile \
|
||||||
|
examples/Makefile \
|
||||||
|
examples/README \
|
||||||
|
examples/list_ports.c \
|
||||||
|
examples/port_info.c \
|
||||||
|
examples/port_config.c \
|
||||||
|
examples/await_events.c \
|
||||||
|
examples/handle_errors.c
|
||||||
|
|
||||||
MAINTAINERCLEANFILES = ChangeLog
|
MAINTAINERCLEANFILES = ChangeLog
|
||||||
|
|
||||||
|
38
README
38
README
@ -40,18 +40,27 @@ No other libraries are required.
|
|||||||
Building
|
Building
|
||||||
========
|
========
|
||||||
|
|
||||||
The package uses a GNU style build system and requires a Unix style shell.
|
On Windows, libserialport can be built with Visual Studio 2019 or with
|
||||||
|
the standalone MSBuild tool, using the solution and project files provided.
|
||||||
|
|
||||||
Windows builds can be created natively with the MinGW-w64 toolchain and
|
For other environments, the package uses a GNU style build based on autotools.
|
||||||
MSYS2 environment, or cross-compiled using a MinGW-w64 toolchain:
|
|
||||||
|
|
||||||
http://mingw-w64.sourceforge.net/
|
|
||||||
|
|
||||||
The "old" MinGW from http://mingw.org/ is not supported.
|
|
||||||
|
|
||||||
Run "./autogen.sh" to generate the build system, "./configure" to setup, then
|
Run "./autogen.sh" to generate the build system, "./configure" to setup, then
|
||||||
"make" to build the library and "make install" to install it.
|
"make" to build the library and "make install" to install it.
|
||||||
|
|
||||||
|
Windows builds can also be created using the autotools build system, using the
|
||||||
|
MinGW-w64 toolchain from http://mingw-w64.sourceforge.net/ - either natively
|
||||||
|
in Windows with the MSYS2 environment, or cross-compiling from another system.
|
||||||
|
|
||||||
|
To build from MSYS2, the following packages must be installed: autoconf,
|
||||||
|
automake-wrapper, libtool, make, and either mingw-w64-i686-gcc (for 32-bit)
|
||||||
|
or mingw-w64-x86_64-gcc (for 64-bit). Open either the "MSYS2 MinGW 32-bit" or
|
||||||
|
"MSYS2 MinGW 64-bit" command window from the Start menu and use this when
|
||||||
|
configuring and building the package. Using the "MSYS2 MSYS" shell will build
|
||||||
|
against the Cygwin compatibility layer; this works, but port enumeration and
|
||||||
|
metadata will not be available, and binaries will depend on Cygwin. The builds
|
||||||
|
produced by MinGW-w64 are normal Windows DLLs without additional dependencies.
|
||||||
|
|
||||||
API
|
API
|
||||||
===
|
===
|
||||||
|
|
||||||
@ -61,6 +70,21 @@ It can also be viewed online at:
|
|||||||
|
|
||||||
http://sigrok.org/api/libserialport/unstable/
|
http://sigrok.org/api/libserialport/unstable/
|
||||||
|
|
||||||
|
Bug reports
|
||||||
|
===========
|
||||||
|
|
||||||
|
You can report bugs for libserialport at https://sigrok.org/bugzilla.
|
||||||
|
|
||||||
|
Mailing list
|
||||||
|
============
|
||||||
|
|
||||||
|
https://lists.sourceforge.net/lists/listinfo/sigrok-devel
|
||||||
|
|
||||||
|
IRC
|
||||||
|
===
|
||||||
|
|
||||||
|
You can find the developers in the #sigrok IRC channel on Libera.Chat.
|
||||||
|
|
||||||
Website
|
Website
|
||||||
=======
|
=======
|
||||||
|
|
||||||
|
23
common.props
Normal file
23
common.props
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ImportGroup Label="PropertySheets" />
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<_PropertySheetDisplayName>Common</_PropertySheetDisplayName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup>
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<EnableUAC>false</EnableUAC>
|
||||||
|
<AdditionalDependencies>setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup />
|
||||||
|
</Project>
|
54
configure.ac
54
configure.ac
@ -29,7 +29,7 @@ m4_define([sp_package_version], [sp_package_version_major.sp_package_version_min
|
|||||||
|
|
||||||
AC_INIT([libserialport], [sp_package_version], [martin-libserialport@earth.li],
|
AC_INIT([libserialport], [sp_package_version], [martin-libserialport@earth.li],
|
||||||
[libserialport], [http://sigrok.org/wiki/Libserialport])
|
[libserialport], [http://sigrok.org/wiki/Libserialport])
|
||||||
AC_CONFIG_HEADERS([config.h libserialport.h])
|
AC_CONFIG_HEADERS([config.h])
|
||||||
AC_CONFIG_MACRO_DIR([autostuff])
|
AC_CONFIG_MACRO_DIR([autostuff])
|
||||||
AC_CONFIG_AUX_DIR([autostuff])
|
AC_CONFIG_AUX_DIR([autostuff])
|
||||||
|
|
||||||
@ -50,6 +50,19 @@ AC_PROG_CC
|
|||||||
AC_PROG_INSTALL
|
AC_PROG_INSTALL
|
||||||
AC_PROG_LN_S
|
AC_PROG_LN_S
|
||||||
|
|
||||||
|
## SP_PROG_VERSION(program, sh-var)
|
||||||
|
## Obtain the version of <program> and store it in <sh-var>.
|
||||||
|
AC_DEFUN([SP_PROG_VERSION],
|
||||||
|
[dnl
|
||||||
|
m4_assert([$# >= 2])[]dnl
|
||||||
|
sp_prog_ver=`$1 --version 2>&AS_MESSAGE_LOG_FD | sed 1q 2>&AS_MESSAGE_LOG_FD`
|
||||||
|
AS_CASE([[$]?:$sp_prog_ver],
|
||||||
|
[[0:*[0-9].[0-9]*]], [$2=$sp_prog_ver],
|
||||||
|
[$2=unknown])[]dnl
|
||||||
|
])
|
||||||
|
|
||||||
|
SP_PROG_VERSION([$CC], [sp_cc_version])
|
||||||
|
|
||||||
# Initialize libtool.
|
# Initialize libtool.
|
||||||
LT_INIT
|
LT_INIT
|
||||||
|
|
||||||
@ -74,18 +87,21 @@ AC_DEFINE_UNQUOTED([SP_LIB_VERSION_REVISION], [$SP_LIB_VERSION_REVISION], [.])
|
|||||||
AC_DEFINE_UNQUOTED([SP_LIB_VERSION_AGE], [$SP_LIB_VERSION_AGE], [.])
|
AC_DEFINE_UNQUOTED([SP_LIB_VERSION_AGE], [$SP_LIB_VERSION_AGE], [.])
|
||||||
AC_DEFINE_UNQUOTED([SP_LIB_VERSION_STRING], ["$SP_LIB_VERSION"], [.])
|
AC_DEFINE_UNQUOTED([SP_LIB_VERSION_STRING], ["$SP_LIB_VERSION"], [.])
|
||||||
|
|
||||||
AM_CONDITIONAL([LINUX], [test -z "${host_os##linux*}"])
|
AM_CONDITIONAL([LINUX], [test -z "${host_os##linux*}" || test -z "${host_os##uclinux*}"])
|
||||||
AM_CONDITIONAL([WIN32], [test -z "${host_os##mingw*}" || test -z "${host_os##cygwin*}"])
|
AM_CONDITIONAL([WIN32], [test -z "${host_os##mingw*}"])
|
||||||
AM_CONDITIONAL([MACOSX], [test -z "${host_os##darwin*}"])
|
AM_CONDITIONAL([MACOSX], [test -z "${host_os##darwin*}"])
|
||||||
AM_CONDITIONAL([FREEBSD], [test -z "${host_os##freebsd*}"])
|
AM_CONDITIONAL([FREEBSD], [test -z "${host_os##freebsd*}"])
|
||||||
|
|
||||||
AM_COND_IF([WIN32], [SP_LIBS='-lsetupapi'], [SP_LIBS=])
|
AM_COND_IF([WIN32], [SP_LIBS='-lsetupapi'], [SP_LIBS=])
|
||||||
AC_SUBST([SP_LIBS])
|
AC_SUBST([SP_LIBS])
|
||||||
|
|
||||||
|
AM_COND_IF([FREEBSD], [SP_PKGLIBS='libusb-2.0'], [SP_PKGLIBS=])
|
||||||
|
AC_SUBST([SP_PKGLIBS])
|
||||||
|
|
||||||
AM_COND_IF([MACOSX], [AC_CHECK_HEADER([IOKit/IOKitLib.h], [],
|
AM_COND_IF([MACOSX], [AC_CHECK_HEADER([IOKit/IOKitLib.h], [],
|
||||||
[AC_MSG_ERROR([IOKit/IOKitLib.h not found])])])
|
[AC_MSG_ERROR([IOKit/IOKitLib.h not found])])])
|
||||||
|
|
||||||
AS_CASE([$host_os], [linux*|darwin*|mingw*|cygwin*|freebsd*],, [
|
AS_CASE([$host_os], [linux*|darwin*|mingw*|freebsd*],, [
|
||||||
AC_DEFINE([NO_ENUMERATION], [1], [Enumeration is unsupported.])
|
AC_DEFINE([NO_ENUMERATION], [1], [Enumeration is unsupported.])
|
||||||
AC_DEFINE([NO_PORT_METADATA], [1], [Port metadata is unavailable.])
|
AC_DEFINE([NO_PORT_METADATA], [1], [Port metadata is unavailable.])
|
||||||
])
|
])
|
||||||
@ -96,7 +112,7 @@ AC_SYS_LARGEFILE
|
|||||||
AC_TYPE_SIZE_T
|
AC_TYPE_SIZE_T
|
||||||
|
|
||||||
# Check for specific termios structures.
|
# Check for specific termios structures.
|
||||||
AC_CHECK_TYPES([struct termios2, struct termiox],,,
|
AC_CHECK_TYPES([struct termios2],,,
|
||||||
[[#include <linux/termios.h>]])
|
[[#include <linux/termios.h>]])
|
||||||
AC_CHECK_MEMBERS([struct termios.c_ispeed, struct termios.c_ospeed,
|
AC_CHECK_MEMBERS([struct termios.c_ispeed, struct termios.c_ospeed,
|
||||||
struct termios2.c_ispeed, struct termios2.c_ospeed],,,
|
struct termios2.c_ispeed, struct termios2.c_ospeed],,,
|
||||||
@ -110,6 +126,17 @@ AC_CHECK_DECLS([BOTHER],,, [[#include <linux/termios.h>]])
|
|||||||
# Check for serial_struct.
|
# Check for serial_struct.
|
||||||
AC_CHECK_TYPES([struct serial_struct],,, [[#include <linux/serial.h>]])
|
AC_CHECK_TYPES([struct serial_struct],,, [[#include <linux/serial.h>]])
|
||||||
|
|
||||||
|
# Check for realpath().
|
||||||
|
AC_CHECK_FUNC([realpath], [AC_DEFINE(HAVE_REALPATH, 1, [realpath is available.])], [])
|
||||||
|
|
||||||
|
# Check for flock().
|
||||||
|
AC_CHECK_HEADER([sys/file.h], [AC_DEFINE(HAVE_SYS_FILE_H, 1, [sys/file.h is available.])], [])
|
||||||
|
AC_CHECK_FUNC([flock], [AC_DEFINE(HAVE_FLOCK, 1, [flock is available.])], [])
|
||||||
|
|
||||||
|
# Check for clock_gettime().
|
||||||
|
AC_CHECK_FUNC([clock_gettime],
|
||||||
|
[AC_DEFINE(HAVE_CLOCK_GETTIME, 1, [clock_gettime is available.])], [])
|
||||||
|
|
||||||
AC_CACHE_CHECK([for visibility control], [sp_cv_visibility_control], [
|
AC_CACHE_CHECK([for visibility control], [sp_cv_visibility_control], [
|
||||||
sp_saved_CFLAGS=$CFLAGS
|
sp_saved_CFLAGS=$CFLAGS
|
||||||
CFLAGS="$CFLAGS -Werror"
|
CFLAGS="$CFLAGS -Werror"
|
||||||
@ -138,10 +165,17 @@ cat >&AS_MESSAGE_FD <<_EOF
|
|||||||
|
|
||||||
libserialport configuration summary:
|
libserialport configuration summary:
|
||||||
|
|
||||||
- Package version (major.minor.micro): $SP_PACKAGE_VERSION
|
- Package version................. $SP_PACKAGE_VERSION
|
||||||
- Library version (current:revision:age): $SP_LIB_VERSION
|
- Library ABI version............. $SP_LIB_VERSION
|
||||||
- Prefix: $prefix
|
- Prefix.......................... $prefix
|
||||||
- Building on: $build
|
- Building on..................... $build
|
||||||
- Building for: $host
|
- Building for.................... $host
|
||||||
|
- Building shared / static........ $enable_shared / $enable_static
|
||||||
|
|
||||||
|
Compile configuration:
|
||||||
|
- C compiler...................... $CC
|
||||||
|
- C compiler version.............. $sp_cc_version
|
||||||
|
- C compiler flags................ $CFLAGS
|
||||||
|
- Linker flags.................... $LDFLAGS
|
||||||
|
|
||||||
_EOF
|
_EOF
|
||||||
|
17
debug.props
Normal file
17
debug.props
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ImportGroup Label="PropertySheets" />
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<_PropertySheetDisplayName>Debug</_PropertySheetDisplayName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup>
|
||||||
|
<ClCompile>
|
||||||
|
<PreprocessorDefinitions>LIBSERIALPORT_MSBUILD;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup />
|
||||||
|
</Project>
|
6
examples/.gitignore
vendored
Normal file
6
examples/.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
await_events
|
||||||
|
handle_errors
|
||||||
|
list_ports
|
||||||
|
port_info
|
||||||
|
port_config
|
||||||
|
send_receive
|
20
examples/Makefile
Normal file
20
examples/Makefile
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# A simple Makefile to build the examples in this directory.
|
||||||
|
#
|
||||||
|
# This example file is released to the public domain.
|
||||||
|
|
||||||
|
CC = gcc
|
||||||
|
PKG_CONFIG = pkg-config
|
||||||
|
CFLAGS = -g -Wall $(shell $(PKG_CONFIG) --cflags libserialport)
|
||||||
|
LIBS = $(shell $(PKG_CONFIG) --libs libserialport)
|
||||||
|
|
||||||
|
SOURCES = $(wildcard *.c)
|
||||||
|
|
||||||
|
BINARIES = $(SOURCES:.c=)
|
||||||
|
|
||||||
|
%: %.c
|
||||||
|
$(CC) $(CFLAGS) $< $(LIBS) -o $@
|
||||||
|
|
||||||
|
all: $(BINARIES)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm $(BINARIES)
|
33
examples/README
Normal file
33
examples/README
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
This directory contains example programs showing how to use libserialport.
|
||||||
|
|
||||||
|
The examples currently included are:
|
||||||
|
|
||||||
|
list_ports.c - displays a list of ports on the system.
|
||||||
|
port_info.c - displays info about a particular port on the system.
|
||||||
|
port_config.c - sets and displays configuration settings on a port.
|
||||||
|
send_receive.c - loopback test sending & receiving data on 1 or 2 ports.
|
||||||
|
await_events.c - awaits receive events on multiple ports simultaneously.
|
||||||
|
handle_errors.c - demonstrates handling errors returned from the library.
|
||||||
|
|
||||||
|
The programs themselves are completely OS-independent, and require only a
|
||||||
|
C compiler and libserialport.
|
||||||
|
|
||||||
|
The 'examples.sln' file is a solution file for Microsoft Visual Studio 2019
|
||||||
|
which will build libserialport and all of the example programs.
|
||||||
|
|
||||||
|
The Makefile in this directory will attempt to build all the examples,
|
||||||
|
using 'gcc' to compile them and 'pkg-config' to discover the include
|
||||||
|
paths and linker settings needed to build with libserialport. It provides
|
||||||
|
a minimal example of how to write a Makefile to build a program using
|
||||||
|
libserialport.
|
||||||
|
|
||||||
|
If you have make, gcc, pkg-config and libserialport installed correctly
|
||||||
|
then running 'make' should build the example programs in this directory.
|
||||||
|
If this doesn't work, you may need to modify the Makefile or set necessary
|
||||||
|
paths in your environment to suit your system.
|
||||||
|
|
||||||
|
You can also build these examples using any other compiler, IDE or build
|
||||||
|
system. You just need the libserialport.h header available to compile them,
|
||||||
|
and the libserialport library available to link and run them.
|
||||||
|
|
||||||
|
These example files are hereby released into the public domain by the author.
|
101
examples/await_events.c
Normal file
101
examples/await_events.c
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
#include <libserialport.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Example of how to wait for events on multiple ports.
|
||||||
|
*
|
||||||
|
* This example file is released to the public domain. */
|
||||||
|
|
||||||
|
/* Helper function for error handling. */
|
||||||
|
int check(enum sp_return result);
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
/* Get the port names from the command line. */
|
||||||
|
if (argc < 2) {
|
||||||
|
printf("Usage: %s <port name>...\n", argv[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int num_ports = argc - 1;
|
||||||
|
char **port_names = argv + 1;
|
||||||
|
|
||||||
|
/* The ports we will use. */
|
||||||
|
struct sp_port **ports = malloc(num_ports * sizeof(struct sp_port *));
|
||||||
|
if (!ports)
|
||||||
|
abort();
|
||||||
|
|
||||||
|
/* The set of events we will wait for. */
|
||||||
|
struct sp_event_set *event_set;
|
||||||
|
|
||||||
|
/* Allocate the event set. */
|
||||||
|
check(sp_new_event_set(&event_set));
|
||||||
|
|
||||||
|
/* Open and configure each port, and then add its RX event
|
||||||
|
* to the event set. */
|
||||||
|
for (int i = 0; i < num_ports; i++) {
|
||||||
|
printf("Looking for port %s.\n", port_names[i]);
|
||||||
|
check(sp_get_port_by_name(port_names[i], &ports[i]));
|
||||||
|
|
||||||
|
printf("Opening port.\n");
|
||||||
|
check(sp_open(ports[i], SP_MODE_READ));
|
||||||
|
|
||||||
|
printf("Setting port to 9600 8N1, no flow control.\n");
|
||||||
|
check(sp_set_baudrate(ports[i], 9600));
|
||||||
|
check(sp_set_bits(ports[i], 8));
|
||||||
|
check(sp_set_parity(ports[i], SP_PARITY_NONE));
|
||||||
|
check(sp_set_stopbits(ports[i], 1));
|
||||||
|
check(sp_set_flowcontrol(ports[i], SP_FLOWCONTROL_NONE));
|
||||||
|
|
||||||
|
printf("Adding port RX event to event set.\n");
|
||||||
|
check(sp_add_port_events(event_set, ports[i], SP_EVENT_RX_READY));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now we can call sp_wait() to await any event in the set.
|
||||||
|
* It will return when an event occurs, or the timeout elapses. */
|
||||||
|
printf("Waiting up to 5 seconds for RX on any port...\n");
|
||||||
|
check(sp_wait(event_set, 5000));
|
||||||
|
|
||||||
|
/* Iterate over ports to see which have data waiting. */
|
||||||
|
for (int i = 0; i < num_ports; i++) {
|
||||||
|
/* Get number of bytes waiting. */
|
||||||
|
int bytes_waiting = check(sp_input_waiting(ports[i]));
|
||||||
|
printf("Port %s: %d bytes received.\n",
|
||||||
|
sp_get_port_name(ports[i]), bytes_waiting);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close ports and free resources. */
|
||||||
|
sp_free_event_set(event_set);
|
||||||
|
for (int i = 0; i < num_ports; i++) {
|
||||||
|
check(sp_close(ports[i]));
|
||||||
|
sp_free_port(ports[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Helper function for error handling. */
|
||||||
|
int check(enum sp_return result)
|
||||||
|
{
|
||||||
|
/* For this example we'll just exit on any error by calling abort(). */
|
||||||
|
char *error_message;
|
||||||
|
|
||||||
|
switch (result) {
|
||||||
|
case SP_ERR_ARG:
|
||||||
|
printf("Error: Invalid argument.\n");
|
||||||
|
abort();
|
||||||
|
case SP_ERR_FAIL:
|
||||||
|
error_message = sp_last_error_message();
|
||||||
|
printf("Error: Failed: %s\n", error_message);
|
||||||
|
sp_free_error_message(error_message);
|
||||||
|
abort();
|
||||||
|
case SP_ERR_SUPP:
|
||||||
|
printf("Error: Not supported.\n");
|
||||||
|
abort();
|
||||||
|
case SP_ERR_MEM:
|
||||||
|
printf("Error: Couldn't allocate memory.\n");
|
||||||
|
abort();
|
||||||
|
case SP_OK:
|
||||||
|
default:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
91
examples/examples.sln
Normal file
91
examples/examples.sln
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 16
|
||||||
|
VisualStudioVersion = 16.0.29613.14
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "list_ports", "projects\list_ports.vcxproj", "{4447C677-0B59-4E1A-9EFD-50D0BE8A0F64}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "port_info", "projects\port_info.vcxproj", "{4BD48C7E-E097-4580-BC63-B4F586D53B8A}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libserialport", "..\libserialport.vcxproj", "{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "port_config", "projects\port_config.vcxproj", "{6CD526C6-0710-4ECA-BE23-6F85032C95F4}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "await_events", "projects\await_events.vcxproj", "{E757BAB5-C79B-49AD-B9C1-B81276B0A6FA}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "handle_errors", "projects\handle_errors.vcxproj", "{09EC5FFB-4DB0-4FE8-BF1E-050F03EC7ED4}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "send_receive", "projects\send_receive.vcxproj", "{F0B68251-C73A-4B7F-AA62-6778586A72A0}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Debug|x86 = Debug|x86
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
Release|x86 = Release|x86
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{4447C677-0B59-4E1A-9EFD-50D0BE8A0F64}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{4447C677-0B59-4E1A-9EFD-50D0BE8A0F64}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{4447C677-0B59-4E1A-9EFD-50D0BE8A0F64}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{4447C677-0B59-4E1A-9EFD-50D0BE8A0F64}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{4447C677-0B59-4E1A-9EFD-50D0BE8A0F64}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{4447C677-0B59-4E1A-9EFD-50D0BE8A0F64}.Release|x64.Build.0 = Release|x64
|
||||||
|
{4447C677-0B59-4E1A-9EFD-50D0BE8A0F64}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{4447C677-0B59-4E1A-9EFD-50D0BE8A0F64}.Release|x86.Build.0 = Release|Win32
|
||||||
|
{4BD48C7E-E097-4580-BC63-B4F586D53B8A}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{4BD48C7E-E097-4580-BC63-B4F586D53B8A}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{4BD48C7E-E097-4580-BC63-B4F586D53B8A}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{4BD48C7E-E097-4580-BC63-B4F586D53B8A}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{4BD48C7E-E097-4580-BC63-B4F586D53B8A}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{4BD48C7E-E097-4580-BC63-B4F586D53B8A}.Release|x64.Build.0 = Release|x64
|
||||||
|
{4BD48C7E-E097-4580-BC63-B4F586D53B8A}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{4BD48C7E-E097-4580-BC63-B4F586D53B8A}.Release|x86.Build.0 = Release|Win32
|
||||||
|
{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}.Release|x64.Build.0 = Release|x64
|
||||||
|
{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}.Release|x86.Build.0 = Release|Win32
|
||||||
|
{6CD526C6-0710-4ECA-BE23-6F85032C95F4}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{6CD526C6-0710-4ECA-BE23-6F85032C95F4}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{6CD526C6-0710-4ECA-BE23-6F85032C95F4}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{6CD526C6-0710-4ECA-BE23-6F85032C95F4}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{6CD526C6-0710-4ECA-BE23-6F85032C95F4}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{6CD526C6-0710-4ECA-BE23-6F85032C95F4}.Release|x64.Build.0 = Release|x64
|
||||||
|
{6CD526C6-0710-4ECA-BE23-6F85032C95F4}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{6CD526C6-0710-4ECA-BE23-6F85032C95F4}.Release|x86.Build.0 = Release|Win32
|
||||||
|
{E757BAB5-C79B-49AD-B9C1-B81276B0A6FA}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{E757BAB5-C79B-49AD-B9C1-B81276B0A6FA}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{E757BAB5-C79B-49AD-B9C1-B81276B0A6FA}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{E757BAB5-C79B-49AD-B9C1-B81276B0A6FA}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{E757BAB5-C79B-49AD-B9C1-B81276B0A6FA}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{E757BAB5-C79B-49AD-B9C1-B81276B0A6FA}.Release|x64.Build.0 = Release|x64
|
||||||
|
{E757BAB5-C79B-49AD-B9C1-B81276B0A6FA}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{E757BAB5-C79B-49AD-B9C1-B81276B0A6FA}.Release|x86.Build.0 = Release|Win32
|
||||||
|
{09EC5FFB-4DB0-4FE8-BF1E-050F03EC7ED4}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{09EC5FFB-4DB0-4FE8-BF1E-050F03EC7ED4}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{09EC5FFB-4DB0-4FE8-BF1E-050F03EC7ED4}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{09EC5FFB-4DB0-4FE8-BF1E-050F03EC7ED4}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{09EC5FFB-4DB0-4FE8-BF1E-050F03EC7ED4}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{09EC5FFB-4DB0-4FE8-BF1E-050F03EC7ED4}.Release|x64.Build.0 = Release|x64
|
||||||
|
{09EC5FFB-4DB0-4FE8-BF1E-050F03EC7ED4}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{09EC5FFB-4DB0-4FE8-BF1E-050F03EC7ED4}.Release|x86.Build.0 = Release|Win32
|
||||||
|
{F0B68251-C73A-4B7F-AA62-6778586A72A0}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{F0B68251-C73A-4B7F-AA62-6778586A72A0}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{F0B68251-C73A-4B7F-AA62-6778586A72A0}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{F0B68251-C73A-4B7F-AA62-6778586A72A0}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{F0B68251-C73A-4B7F-AA62-6778586A72A0}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{F0B68251-C73A-4B7F-AA62-6778586A72A0}.Release|x64.Build.0 = Release|x64
|
||||||
|
{F0B68251-C73A-4B7F-AA62-6778586A72A0}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{F0B68251-C73A-4B7F-AA62-6778586A72A0}.Release|x86.Build.0 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {EEED7125-B08F-4EB9-8F10-F036CCD5F4CF}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
117
examples/handle_errors.c
Normal file
117
examples/handle_errors.c
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
#include <libserialport.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Example of how to handle errors from libserialport.
|
||||||
|
*
|
||||||
|
* This example file is released to the public domain. */
|
||||||
|
|
||||||
|
/* Pointers used in the program to resources that may need to be freed. */
|
||||||
|
struct sp_port **port_list = NULL;
|
||||||
|
struct sp_port_config *config = NULL;
|
||||||
|
struct sp_port *port = NULL;
|
||||||
|
|
||||||
|
/* Example of a function to clean up and exit the program with a given return code. */
|
||||||
|
void end_program(int return_code)
|
||||||
|
{
|
||||||
|
/* Free any structures we allocated. */
|
||||||
|
if (port_list != NULL)
|
||||||
|
sp_free_port_list(port_list);
|
||||||
|
if (config != NULL)
|
||||||
|
sp_free_config(config);
|
||||||
|
if (port != NULL)
|
||||||
|
sp_free_port(port);
|
||||||
|
|
||||||
|
/* Exit with the given return code. */
|
||||||
|
exit(return_code);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Example of a helper function for error handling. */
|
||||||
|
int check(enum sp_return result)
|
||||||
|
{
|
||||||
|
int error_code;
|
||||||
|
char *error_message;
|
||||||
|
|
||||||
|
switch (result) {
|
||||||
|
|
||||||
|
/* Handle each of the four negative error codes that can be returned.
|
||||||
|
*
|
||||||
|
* In this example, we will end the program on any error, using
|
||||||
|
* a different return code for each possible class of error. */
|
||||||
|
|
||||||
|
case SP_ERR_ARG:
|
||||||
|
/* When SP_ERR_ARG is returned, there was a problem with one
|
||||||
|
* or more of the arguments passed to the function, e.g. a null
|
||||||
|
* pointer or an invalid value. This generally implies a bug in
|
||||||
|
* the calling code. */
|
||||||
|
printf("Error: Invalid argument.\n");
|
||||||
|
end_program(1);
|
||||||
|
|
||||||
|
case SP_ERR_FAIL:
|
||||||
|
/* When SP_ERR_FAIL is returned, there was an error from the OS,
|
||||||
|
* which we can obtain the error code and message for. These
|
||||||
|
* calls must be made in the same thread as the call that
|
||||||
|
* returned SP_ERR_FAIL, and before any other system functions
|
||||||
|
* are called in that thread, or they may not return the
|
||||||
|
* correct results. */
|
||||||
|
error_code = sp_last_error_code();
|
||||||
|
error_message = sp_last_error_message();
|
||||||
|
printf("Error: Failed: OS error code: %d, message: '%s'\n",
|
||||||
|
error_code, error_message);
|
||||||
|
/* The error message should be freed after use. */
|
||||||
|
sp_free_error_message(error_message);
|
||||||
|
end_program(2);
|
||||||
|
|
||||||
|
case SP_ERR_SUPP:
|
||||||
|
/* When SP_ERR_SUPP is returned, the function was asked to do
|
||||||
|
* something that isn't supported by the current OS or device,
|
||||||
|
* or that libserialport doesn't know how to do in the current
|
||||||
|
* version. */
|
||||||
|
printf("Error: Not supported.\n");
|
||||||
|
end_program(3);
|
||||||
|
|
||||||
|
case SP_ERR_MEM:
|
||||||
|
/* When SP_ERR_MEM is returned, libserialport wasn't able to
|
||||||
|
* allocate some memory it needed. Since the library doesn't
|
||||||
|
* normally use any large data structures, this probably means
|
||||||
|
* the system is critically low on memory and recovery will
|
||||||
|
* require very careful handling. The library itself will
|
||||||
|
* always try to handle any allocation failure safely.
|
||||||
|
*
|
||||||
|
* In this example, we'll just try to exit gracefully without
|
||||||
|
* calling printf, which might need to allocate further memory. */
|
||||||
|
end_program(4);
|
||||||
|
|
||||||
|
case SP_OK:
|
||||||
|
default:
|
||||||
|
/* A return value of SP_OK, defined as zero, means that the
|
||||||
|
* operation succeeded. */
|
||||||
|
printf("Operation succeeded.\n");
|
||||||
|
|
||||||
|
/* Some fuctions can also return a value greater than zero to
|
||||||
|
* indicate a numeric result, such as the number of bytes read by
|
||||||
|
* sp_blocking_read(). So when writing an error handling wrapper
|
||||||
|
* function like this one, it's helpful to return the result so
|
||||||
|
* that it can be used. */
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
/* Call some functions that should not result in errors. */
|
||||||
|
|
||||||
|
printf("Getting list of ports.\n");
|
||||||
|
check(sp_list_ports(&port_list));
|
||||||
|
|
||||||
|
printf("Creating a new port configuration.\n");
|
||||||
|
check(sp_new_config(&config));
|
||||||
|
|
||||||
|
/* Now make a function call that will result in an error. */
|
||||||
|
|
||||||
|
printf("Trying to find a port that doesn't exist.\n");
|
||||||
|
check(sp_get_port_by_name("NON-EXISTENT-PORT", &port));
|
||||||
|
|
||||||
|
/* We could now clean up and exit normally if an error hadn't occured. */
|
||||||
|
end_program(0);
|
||||||
|
}
|
50
examples/list_ports.c
Normal file
50
examples/list_ports.c
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#include <libserialport.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/* Example of how to get a list of serial ports on the system.
|
||||||
|
*
|
||||||
|
* This example file is released to the public domain. */
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
/* A pointer to a null-terminated array of pointers to
|
||||||
|
* struct sp_port, which will contain the ports found.*/
|
||||||
|
struct sp_port **port_list;
|
||||||
|
|
||||||
|
printf("Getting port list.\n");
|
||||||
|
|
||||||
|
/* Call sp_list_ports() to get the ports. The port_list
|
||||||
|
* pointer will be updated to refer to the array created. */
|
||||||
|
enum sp_return result = sp_list_ports(&port_list);
|
||||||
|
|
||||||
|
if (result != SP_OK) {
|
||||||
|
printf("sp_list_ports() failed!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Iterate through the ports. When port_list[i] is NULL
|
||||||
|
* this indicates the end of the list. */
|
||||||
|
int i;
|
||||||
|
for (i = 0; port_list[i] != NULL; i++) {
|
||||||
|
struct sp_port *port = port_list[i];
|
||||||
|
|
||||||
|
/* Get the name of the port. */
|
||||||
|
char *port_name = sp_get_port_name(port);
|
||||||
|
|
||||||
|
printf("Found port: %s\n", port_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Found %d ports.\n", i);
|
||||||
|
|
||||||
|
printf("Freeing port list.\n");
|
||||||
|
|
||||||
|
/* Free the array created by sp_list_ports(). */
|
||||||
|
sp_free_port_list(port_list);
|
||||||
|
|
||||||
|
/* Note that this will also free all the sp_port structures
|
||||||
|
* it points to. If you want to keep one of them (e.g. to
|
||||||
|
* use that port in the rest of your program), take a copy
|
||||||
|
* of it first using sp_copy_port(). */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
174
examples/port_config.c
Normal file
174
examples/port_config.c
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
#include <libserialport.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* Example of how to configure a serial port.
|
||||||
|
*
|
||||||
|
* This example file is released to the public domain. */
|
||||||
|
|
||||||
|
/* Helper function for error handling. */
|
||||||
|
int check(enum sp_return result);
|
||||||
|
|
||||||
|
/* Helper function to give a name for each parity mode. */
|
||||||
|
const char *parity_name(enum sp_parity parity);
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
/* Get the port name from the command line. */
|
||||||
|
if (argc != 2) {
|
||||||
|
printf("Usage: %s <port name>\n", argv[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
char *port_name = argv[1];
|
||||||
|
|
||||||
|
/* A pointer to a struct sp_port, which will refer to
|
||||||
|
* the port found. */
|
||||||
|
struct sp_port *port;
|
||||||
|
|
||||||
|
printf("Looking for port %s.\n", port_name);
|
||||||
|
|
||||||
|
/* Call sp_get_port_by_name() to find the port. The port
|
||||||
|
* pointer will be updated to refer to the port found. */
|
||||||
|
check(sp_get_port_by_name(port_name, &port));
|
||||||
|
|
||||||
|
/* Display some basic information about the port. */
|
||||||
|
printf("Port name: %s\n", sp_get_port_name(port));
|
||||||
|
printf("Description: %s\n", sp_get_port_description(port));
|
||||||
|
|
||||||
|
/* The port must be open to access its configuration. */
|
||||||
|
printf("Opening port.\n");
|
||||||
|
check(sp_open(port, SP_MODE_READ_WRITE));
|
||||||
|
|
||||||
|
/* There are two ways to access a port's configuration:
|
||||||
|
*
|
||||||
|
* 1. You can read and write a whole configuration (all settings at
|
||||||
|
* once) using sp_get_config() and sp_set_config(). This is handy
|
||||||
|
* if you want to change between some preset combinations, or save
|
||||||
|
* and restore an existing configuration. It also ensures the
|
||||||
|
* changes are made together, via an efficient set of calls into
|
||||||
|
* the OS - in some cases a single system call can be used.
|
||||||
|
*
|
||||||
|
* Use accessor functions like sp_get_config_baudrate() and
|
||||||
|
* sp_set_config_baudrate() to get and set individual settings
|
||||||
|
* from a configuration.
|
||||||
|
*
|
||||||
|
* Configurations are allocated using sp_new_config() and freed
|
||||||
|
* with sp_free_config(). You need to manage them yourself.
|
||||||
|
*
|
||||||
|
* 2. As a shortcut, you can set individual settings on a port
|
||||||
|
* directly by calling functions like sp_set_baudrate() and
|
||||||
|
* sp_set_parity(). This saves you the work of allocating
|
||||||
|
* a temporary config, setting it up, applying it to a port
|
||||||
|
* and then freeing it.
|
||||||
|
*
|
||||||
|
* In this example we'll do a bit of both: apply some initial settings
|
||||||
|
* to the port, read out that config and display it, then switch to a
|
||||||
|
* different configuration and back using sp_set_config(). */
|
||||||
|
|
||||||
|
/* First let's set some initial settings directly on the port.
|
||||||
|
*
|
||||||
|
* You should always configure all settings before using a port.
|
||||||
|
* There are no "default" settings applied by libserialport.
|
||||||
|
* When you open a port it has the defaults from the OS or driver,
|
||||||
|
* or the settings left over by the last program to use it. */
|
||||||
|
printf("Setting port to 115200 8N1, no flow control.\n");
|
||||||
|
check(sp_set_baudrate(port, 115200));
|
||||||
|
check(sp_set_bits(port, 8));
|
||||||
|
check(sp_set_parity(port, SP_PARITY_NONE));
|
||||||
|
check(sp_set_stopbits(port, 1));
|
||||||
|
check(sp_set_flowcontrol(port, SP_FLOWCONTROL_NONE));
|
||||||
|
|
||||||
|
/* A pointer to a struct sp_port_config, which we'll use for the config
|
||||||
|
* read back from the port. The pointer will be set by sp_new_config(). */
|
||||||
|
struct sp_port_config *initial_config;
|
||||||
|
|
||||||
|
/* Allocate a configuration for us to read the port config into. */
|
||||||
|
check(sp_new_config(&initial_config));
|
||||||
|
|
||||||
|
/* Read the current config from the port into that configuration. */
|
||||||
|
check(sp_get_config(port, initial_config));
|
||||||
|
|
||||||
|
/* Display some of the settings read back from the port. */
|
||||||
|
int baudrate, bits, stopbits;
|
||||||
|
enum sp_parity parity;
|
||||||
|
check(sp_get_config_baudrate(initial_config, &baudrate));
|
||||||
|
check(sp_get_config_bits(initial_config, &bits));
|
||||||
|
check(sp_get_config_stopbits(initial_config, &stopbits));
|
||||||
|
check(sp_get_config_parity(initial_config, &parity));
|
||||||
|
printf("Baudrate: %d, data bits: %d, parity: %s, stop bits: %d\n",
|
||||||
|
baudrate, bits, parity_name(parity), stopbits);
|
||||||
|
|
||||||
|
/* Create a different configuration to have ready for use. */
|
||||||
|
printf("Creating new config for 9600 7E2, XON/XOFF flow control.\n");
|
||||||
|
struct sp_port_config *other_config;
|
||||||
|
check(sp_new_config(&other_config));
|
||||||
|
check(sp_set_config_baudrate(other_config, 9600));
|
||||||
|
check(sp_set_config_bits(other_config, 7));
|
||||||
|
check(sp_set_config_parity(other_config, SP_PARITY_EVEN));
|
||||||
|
check(sp_set_config_stopbits(other_config, 2));
|
||||||
|
check(sp_set_config_flowcontrol(other_config, SP_FLOWCONTROL_XONXOFF));
|
||||||
|
|
||||||
|
/* We can apply the new config to the port in one call. */
|
||||||
|
printf("Applying new configuration.\n");
|
||||||
|
check(sp_set_config(port, other_config));
|
||||||
|
|
||||||
|
/* And now switch back to our original config. */
|
||||||
|
printf("Setting port back to previous config.\n");
|
||||||
|
check(sp_set_config(port, initial_config));
|
||||||
|
|
||||||
|
/* Now clean up by closing the port and freeing structures. */
|
||||||
|
check(sp_close(port));
|
||||||
|
sp_free_port(port);
|
||||||
|
sp_free_config(initial_config);
|
||||||
|
sp_free_config(other_config);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Helper function for error handling. */
|
||||||
|
int check(enum sp_return result)
|
||||||
|
{
|
||||||
|
/* For this example we'll just exit on any error by calling abort(). */
|
||||||
|
char *error_message;
|
||||||
|
|
||||||
|
switch (result) {
|
||||||
|
case SP_ERR_ARG:
|
||||||
|
printf("Error: Invalid argument.\n");
|
||||||
|
abort();
|
||||||
|
case SP_ERR_FAIL:
|
||||||
|
error_message = sp_last_error_message();
|
||||||
|
printf("Error: Failed: %s\n", error_message);
|
||||||
|
sp_free_error_message(error_message);
|
||||||
|
abort();
|
||||||
|
case SP_ERR_SUPP:
|
||||||
|
printf("Error: Not supported.\n");
|
||||||
|
abort();
|
||||||
|
case SP_ERR_MEM:
|
||||||
|
printf("Error: Couldn't allocate memory.\n");
|
||||||
|
abort();
|
||||||
|
case SP_OK:
|
||||||
|
default:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Helper function to give a name for each parity mode. */
|
||||||
|
const char *parity_name(enum sp_parity parity)
|
||||||
|
{
|
||||||
|
switch (parity) {
|
||||||
|
case SP_PARITY_INVALID:
|
||||||
|
return "(Invalid)";
|
||||||
|
case SP_PARITY_NONE:
|
||||||
|
return "None";
|
||||||
|
case SP_PARITY_ODD:
|
||||||
|
return "Odd";
|
||||||
|
case SP_PARITY_EVEN:
|
||||||
|
return "Even";
|
||||||
|
case SP_PARITY_MARK:
|
||||||
|
return "Mark";
|
||||||
|
case SP_PARITY_SPACE:
|
||||||
|
return "Space";
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
80
examples/port_info.c
Normal file
80
examples/port_info.c
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
#include <libserialport.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/* Example of how to get information about a serial port.
|
||||||
|
*
|
||||||
|
* This example file is released to the public domain. */
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
/* Get the port name from the command line. */
|
||||||
|
if (argc != 2) {
|
||||||
|
printf("Usage: %s <port name>\n", argv[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
char *port_name = argv[1];
|
||||||
|
|
||||||
|
/* A pointer to a struct sp_port, which will refer to
|
||||||
|
* the port found. */
|
||||||
|
struct sp_port *port;
|
||||||
|
|
||||||
|
printf("Looking for port %s.\n", port_name);
|
||||||
|
|
||||||
|
/* Call sp_get_port_by_name() to find the port. The port
|
||||||
|
* pointer will be updated to refer to the port found. */
|
||||||
|
enum sp_return result = sp_get_port_by_name(port_name, &port);
|
||||||
|
|
||||||
|
if (result != SP_OK) {
|
||||||
|
printf("sp_get_port_by_name() failed!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Display some basic information about the port. */
|
||||||
|
printf("Port name: %s\n", sp_get_port_name(port));
|
||||||
|
printf("Description: %s\n", sp_get_port_description(port));
|
||||||
|
|
||||||
|
/* Identify the transport which this port is connected through,
|
||||||
|
* e.g. native port, USB or Bluetooth. */
|
||||||
|
enum sp_transport transport = sp_get_port_transport(port);
|
||||||
|
|
||||||
|
if (transport == SP_TRANSPORT_NATIVE) {
|
||||||
|
/* This is a "native" port, usually directly connected
|
||||||
|
* to the system rather than some external interface. */
|
||||||
|
printf("Type: Native\n");
|
||||||
|
} else if (transport == SP_TRANSPORT_USB) {
|
||||||
|
/* This is a USB to serial converter of some kind. */
|
||||||
|
printf("Type: USB\n");
|
||||||
|
|
||||||
|
/* Display string information from the USB descriptors. */
|
||||||
|
printf("Manufacturer: %s\n", sp_get_port_usb_manufacturer(port));
|
||||||
|
printf("Product: %s\n", sp_get_port_usb_product(port));
|
||||||
|
printf("Serial: %s\n", sp_get_port_usb_serial(port));
|
||||||
|
|
||||||
|
/* Display USB vendor and product IDs. */
|
||||||
|
int usb_vid, usb_pid;
|
||||||
|
sp_get_port_usb_vid_pid(port, &usb_vid, &usb_pid);
|
||||||
|
printf("VID: %04X PID: %04X\n", usb_vid, usb_pid);
|
||||||
|
|
||||||
|
/* Display bus and address. */
|
||||||
|
int usb_bus, usb_address;
|
||||||
|
sp_get_port_usb_bus_address(port, &usb_bus, &usb_address);
|
||||||
|
printf("Bus: %d Address: %d\n", usb_bus, usb_address);
|
||||||
|
} else if (transport == SP_TRANSPORT_BLUETOOTH) {
|
||||||
|
/* This is a Bluetooth serial port. */
|
||||||
|
printf("Type: Bluetooth\n");
|
||||||
|
|
||||||
|
/* Display Bluetooth MAC address. */
|
||||||
|
printf("MAC: %s\n", sp_get_port_bluetooth_address(port));
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Freeing port.\n");
|
||||||
|
|
||||||
|
/* Free the port structure created by sp_get_port_by_name(). */
|
||||||
|
sp_free_port(port);
|
||||||
|
|
||||||
|
/* Note that this will also free the port name and other
|
||||||
|
* strings retrieved from the port structure. If you want
|
||||||
|
* to keep these, copy them before freeing the port. */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
167
examples/projects/await_events.vcxproj
Normal file
167
examples/projects/await_events.vcxproj
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\await_events.c" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\libserialport.vcxproj">
|
||||||
|
<Project>{1c8eaaf2-133e-4cee-8981-4a903a8b3935}</Project>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\..\libserialport.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<VCProjectVersion>16.0</VCProjectVersion>
|
||||||
|
<ProjectGuid>{E757BAB5-C79B-49AD-B9C1-B81276B0A6FA}</ProjectGuid>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<RootNamespace>listports</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="Shared">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="common.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="common.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="common.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="common.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
27
examples/projects/await_events.vcxproj.filters
Normal file
27
examples/projects/await_events.vcxproj.filters
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Source Files">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Header Files">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Resource Files">
|
||||||
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\await_events.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\..\libserialport.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
18
examples/projects/common.props
Normal file
18
examples/projects/common.props
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ImportGroup Label="PropertySheets" />
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<_PropertySheetDisplayName>Common</_PropertySheetDisplayName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup>
|
||||||
|
<ClCompile>
|
||||||
|
<AdditionalIncludeDirectories>$(ProjectDir)\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<ProgramDatabaseFile>$(OutDir)$(ProjectName).pdb</ProgramDatabaseFile>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup />
|
||||||
|
</Project>
|
167
examples/projects/handle_errors.vcxproj
Normal file
167
examples/projects/handle_errors.vcxproj
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\handle_errors.c" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\libserialport.vcxproj">
|
||||||
|
<Project>{1c8eaaf2-133e-4cee-8981-4a903a8b3935}</Project>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\..\libserialport.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<VCProjectVersion>16.0</VCProjectVersion>
|
||||||
|
<ProjectGuid>{09EC5FFB-4DB0-4FE8-BF1E-050F03EC7ED4}</ProjectGuid>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<RootNamespace>listports</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="Shared">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="common.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="common.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="common.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="common.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
27
examples/projects/handle_errors.vcxproj.filters
Normal file
27
examples/projects/handle_errors.vcxproj.filters
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Source Files">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Header Files">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Resource Files">
|
||||||
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\handle_errors.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\..\libserialport.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
167
examples/projects/list_ports.vcxproj
Normal file
167
examples/projects/list_ports.vcxproj
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\list_ports.c" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\libserialport.vcxproj">
|
||||||
|
<Project>{1c8eaaf2-133e-4cee-8981-4a903a8b3935}</Project>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\..\libserialport.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<VCProjectVersion>16.0</VCProjectVersion>
|
||||||
|
<ProjectGuid>{4447C677-0B59-4E1A-9EFD-50D0BE8A0F64}</ProjectGuid>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<RootNamespace>listports</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="Shared">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="common.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="common.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="common.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="common.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
27
examples/projects/list_ports.vcxproj.filters
Normal file
27
examples/projects/list_ports.vcxproj.filters
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Source Files">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Header Files">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Resource Files">
|
||||||
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\list_ports.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\..\libserialport.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
167
examples/projects/port_config.vcxproj
Normal file
167
examples/projects/port_config.vcxproj
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\port_config.c" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\libserialport.vcxproj">
|
||||||
|
<Project>{1c8eaaf2-133e-4cee-8981-4a903a8b3935}</Project>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\..\libserialport.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<VCProjectVersion>16.0</VCProjectVersion>
|
||||||
|
<ProjectGuid>{6CD526C6-0710-4ECA-BE23-6F85032C95F4}</ProjectGuid>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<RootNamespace>listports</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="Shared">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="common.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="common.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="common.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="common.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
27
examples/projects/port_config.vcxproj.filters
Normal file
27
examples/projects/port_config.vcxproj.filters
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Source Files">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Header Files">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Resource Files">
|
||||||
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\port_config.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\..\libserialport.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
167
examples/projects/port_info.vcxproj
Normal file
167
examples/projects/port_info.vcxproj
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\port_info.c" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\libserialport.vcxproj">
|
||||||
|
<Project>{1c8eaaf2-133e-4cee-8981-4a903a8b3935}</Project>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\..\libserialport.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<VCProjectVersion>16.0</VCProjectVersion>
|
||||||
|
<ProjectGuid>{4BD48C7E-E097-4580-BC63-B4F586D53B8A}</ProjectGuid>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<RootNamespace>listports</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="Shared">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="common.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="common.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="common.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="common.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
27
examples/projects/port_info.vcxproj.filters
Normal file
27
examples/projects/port_info.vcxproj.filters
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Source Files">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Header Files">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Resource Files">
|
||||||
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\port_info.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\..\libserialport.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
167
examples/projects/send_receive.vcxproj
Normal file
167
examples/projects/send_receive.vcxproj
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\send_receive.c" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\libserialport.vcxproj">
|
||||||
|
<Project>{1c8eaaf2-133e-4cee-8981-4a903a8b3935}</Project>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\..\libserialport.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<VCProjectVersion>16.0</VCProjectVersion>
|
||||||
|
<ProjectGuid>{F0B68251-C73A-4B7F-AA62-6778586A72A0}</ProjectGuid>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<RootNamespace>listports</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="Shared">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="common.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="common.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="common.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="common.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
27
examples/projects/send_receive.vcxproj.filters
Normal file
27
examples/projects/send_receive.vcxproj.filters
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Source Files">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Header Files">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Resource Files">
|
||||||
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\send_receive.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\..\libserialport.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
139
examples/send_receive.c
Normal file
139
examples/send_receive.c
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
#include <libserialport.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* Example of how to send and receive data.
|
||||||
|
*
|
||||||
|
* This example file is released to the public domain. */
|
||||||
|
|
||||||
|
/* Helper function for error handling. */
|
||||||
|
int check(enum sp_return result);
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
/* This example can be used with one or two ports. With one port, it
|
||||||
|
* will send data and try to receive it on the same port. This can be
|
||||||
|
* done by connecting a single wire between the TX and RX pins of the
|
||||||
|
* port.
|
||||||
|
*
|
||||||
|
* Alternatively it can be used with two serial ports connected to each
|
||||||
|
* other, so that data can be sent on one and received on the other.
|
||||||
|
* This can be done with two ports with TX/RX cross-connected, e.g. by
|
||||||
|
* a "null modem" cable, or with a pair of interconnected virtual ports,
|
||||||
|
* such as those created by com0com on Windows or tty0tty on Linux. */
|
||||||
|
|
||||||
|
/* Get the port names from the command line. */
|
||||||
|
if (argc < 2 || argc > 3) {
|
||||||
|
printf("Usage: %s <port 1> [<port 2>]\n", argv[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int num_ports = argc - 1;
|
||||||
|
char **port_names = argv + 1;
|
||||||
|
|
||||||
|
/* The ports we will use. */
|
||||||
|
struct sp_port *ports[2];
|
||||||
|
|
||||||
|
/* Open and configure each port. */
|
||||||
|
for (int i = 0; i < num_ports; i++) {
|
||||||
|
printf("Looking for port %s.\n", port_names[i]);
|
||||||
|
check(sp_get_port_by_name(port_names[i], &ports[i]));
|
||||||
|
|
||||||
|
printf("Opening port.\n");
|
||||||
|
check(sp_open(ports[i], SP_MODE_READ_WRITE));
|
||||||
|
|
||||||
|
printf("Setting port to 9600 8N1, no flow control.\n");
|
||||||
|
check(sp_set_baudrate(ports[i], 9600));
|
||||||
|
check(sp_set_bits(ports[i], 8));
|
||||||
|
check(sp_set_parity(ports[i], SP_PARITY_NONE));
|
||||||
|
check(sp_set_stopbits(ports[i], 1));
|
||||||
|
check(sp_set_flowcontrol(ports[i], SP_FLOWCONTROL_NONE));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now send some data on each port and receive it back. */
|
||||||
|
for (int tx = 0; tx < num_ports; tx++) {
|
||||||
|
/* Get the ports to send and receive on. */
|
||||||
|
int rx = num_ports == 1 ? 0 : ((tx == 0) ? 1 : 0);
|
||||||
|
struct sp_port *tx_port = ports[tx];
|
||||||
|
struct sp_port *rx_port = ports[rx];
|
||||||
|
|
||||||
|
/* The data we will send. */
|
||||||
|
char *data = "Hello!";
|
||||||
|
int size = strlen(data);
|
||||||
|
|
||||||
|
/* We'll allow a 1 second timeout for send and receive. */
|
||||||
|
unsigned int timeout = 1000;
|
||||||
|
|
||||||
|
/* On success, sp_blocking_write() and sp_blocking_read()
|
||||||
|
* return the number of bytes sent/received before the
|
||||||
|
* timeout expired. We'll store that result here. */
|
||||||
|
int result;
|
||||||
|
|
||||||
|
/* Send data. */
|
||||||
|
printf("Sending '%s' (%d bytes) on port %s.\n",
|
||||||
|
data, size, sp_get_port_name(tx_port));
|
||||||
|
result = check(sp_blocking_write(tx_port, data, size, timeout));
|
||||||
|
|
||||||
|
/* Check whether we sent all of the data. */
|
||||||
|
if (result == size)
|
||||||
|
printf("Sent %d bytes successfully.\n", size);
|
||||||
|
else
|
||||||
|
printf("Timed out, %d/%d bytes sent.\n", result, size);
|
||||||
|
|
||||||
|
/* Allocate a buffer to receive data. */
|
||||||
|
char *buf = malloc(size + 1);
|
||||||
|
|
||||||
|
/* Try to receive the data on the other port. */
|
||||||
|
printf("Receiving %d bytes on port %s.\n",
|
||||||
|
size, sp_get_port_name(rx_port));
|
||||||
|
result = check(sp_blocking_read(rx_port, buf, size, timeout));
|
||||||
|
|
||||||
|
/* Check whether we received the number of bytes we wanted. */
|
||||||
|
if (result == size)
|
||||||
|
printf("Received %d bytes successfully.\n", size);
|
||||||
|
else
|
||||||
|
printf("Timed out, %d/%d bytes received.\n", result, size);
|
||||||
|
|
||||||
|
/* Check if we received the same data we sent. */
|
||||||
|
buf[result] = '\0';
|
||||||
|
printf("Received '%s'.\n", buf);
|
||||||
|
|
||||||
|
/* Free receive buffer. */
|
||||||
|
free(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close ports and free resources. */
|
||||||
|
for (int i = 0; i < num_ports; i++) {
|
||||||
|
check(sp_close(ports[i]));
|
||||||
|
sp_free_port(ports[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Helper function for error handling. */
|
||||||
|
int check(enum sp_return result)
|
||||||
|
{
|
||||||
|
/* For this example we'll just exit on any error by calling abort(). */
|
||||||
|
char *error_message;
|
||||||
|
|
||||||
|
switch (result) {
|
||||||
|
case SP_ERR_ARG:
|
||||||
|
printf("Error: Invalid argument.\n");
|
||||||
|
abort();
|
||||||
|
case SP_ERR_FAIL:
|
||||||
|
error_message = sp_last_error_message();
|
||||||
|
printf("Error: Failed: %s\n", error_message);
|
||||||
|
sp_free_error_message(error_message);
|
||||||
|
abort();
|
||||||
|
case SP_ERR_SUPP:
|
||||||
|
printf("Error: Not supported.\n");
|
||||||
|
abort();
|
||||||
|
case SP_ERR_MEM:
|
||||||
|
printf("Error: Couldn't allocate memory.\n");
|
||||||
|
abort();
|
||||||
|
case SP_OK:
|
||||||
|
default:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
21
freebsd.c
21
freebsd.c
@ -325,8 +325,7 @@ SP_PRIV enum sp_return get_port_details(struct sp_port *port)
|
|||||||
SP_PRIV enum sp_return list_ports(struct sp_port ***list)
|
SP_PRIV enum sp_return list_ports(struct sp_port ***list)
|
||||||
{
|
{
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
struct dirent entry;
|
struct dirent *entry;
|
||||||
struct dirent *result;
|
|
||||||
struct termios tios;
|
struct termios tios;
|
||||||
char name[PATH_MAX];
|
char name[PATH_MAX];
|
||||||
int fd, ret;
|
int fd, ret;
|
||||||
@ -336,20 +335,20 @@ SP_PRIV enum sp_return list_ports(struct sp_port ***list)
|
|||||||
RETURN_FAIL("Could not open dir /dev");
|
RETURN_FAIL("Could not open dir /dev");
|
||||||
|
|
||||||
DEBUG("Iterating over results");
|
DEBUG("Iterating over results");
|
||||||
while (!readdir_r(dir, &entry, &result) && result) {
|
while ((entry = readdir(dir))) {
|
||||||
ret = SP_OK;
|
ret = SP_OK;
|
||||||
if (entry.d_type != DT_CHR)
|
if (entry->d_type != DT_CHR)
|
||||||
continue;
|
continue;
|
||||||
if (strncmp(entry.d_name, "cuaU", 4) != 0)
|
if (strncmp(entry->d_name, "cuaU", 4) != 0)
|
||||||
if (strncmp(entry.d_name, "cuau", 4) != 0)
|
if (strncmp(entry->d_name, "cuau", 4) != 0)
|
||||||
if (strncmp(entry.d_name, "cuad", 4) != 0)
|
if (strncmp(entry->d_name, "cuad", 4) != 0)
|
||||||
continue;
|
continue;
|
||||||
if (strend(entry.d_name, ".init"))
|
if (strend(entry->d_name, ".init"))
|
||||||
continue;
|
continue;
|
||||||
if (strend(entry.d_name, ".lock"))
|
if (strend(entry->d_name, ".lock"))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
snprintf(name, sizeof(name), "/dev/%s", entry.d_name);
|
snprintf(name, sizeof(name), "/dev/%s", entry->d_name);
|
||||||
DEBUG_FMT("Found device %s", name);
|
DEBUG_FMT("Found device %s", name);
|
||||||
|
|
||||||
/* Check that we can open tty/cua device in rw mode - we need that. */
|
/* Check that we can open tty/cua device in rw mode - we need that. */
|
||||||
@ -370,7 +369,7 @@ SP_PRIV enum sp_return list_ports(struct sp_port ***list)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
DEBUG_FMT("Found port %s", name);
|
DEBUG_FMT("Found port %s", name);
|
||||||
DBG("%s: %s\n", __func__, entry.d_name);
|
DBG("%s: %s\n", __func__, entry->d_name);
|
||||||
|
|
||||||
*list = list_append(*list, name);
|
*list = list_append(*list, name);
|
||||||
if (!*list) {
|
if (!*list) {
|
||||||
|
@ -59,19 +59,38 @@
|
|||||||
* to restructure things somewhat, or do without some specialised features.
|
* to restructure things somewhat, or do without some specialised features.
|
||||||
* For particular notes on porting existing code, see @ref Porting.
|
* For particular notes on porting existing code, see @ref Porting.
|
||||||
*
|
*
|
||||||
* The following subsections will help explain the principles of the API.
|
* 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.
|
||||||
|
* - @ref port_config.c - Accessing configuration settings of a port.
|
||||||
|
* - @ref send_receive.c - Sending and receiving data.
|
||||||
|
* - @ref await_events.c - Awaiting events on multiple ports.
|
||||||
|
* - @ref handle_errors.c - Handling errors returned from the library.
|
||||||
|
*
|
||||||
|
* 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
|
* Headers
|
||||||
* -------
|
* -------
|
||||||
*
|
*
|
||||||
* To use libserialport functions in your code, you should include the
|
* To use libserialport functions in your code, you should include the
|
||||||
* libserialport.h header, i.e. "#include <libserialport.h>".
|
* libserialport.h header, i.e.
|
||||||
|
* @code
|
||||||
|
* #include <libserialport.h>
|
||||||
|
* @endcode
|
||||||
*
|
*
|
||||||
* Namespace
|
* Namespace
|
||||||
* ---------
|
* ---------
|
||||||
*
|
*
|
||||||
* All identifiers defined by the public libserialport headers use the prefix
|
* All identifiers defined by the public libserialport headers use the prefix
|
||||||
* sp_ (for functions and data types) or SP_ (for macros and constants).
|
* @c sp_ (for functions and data types) or @c SP_ (for macros and constants).
|
||||||
*
|
*
|
||||||
* Functions
|
* Functions
|
||||||
* ---------
|
* ---------
|
||||||
@ -132,12 +151,12 @@
|
|||||||
* numeric result, e.g. sp_blocking_read() or sp_blocking_write().
|
* 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
|
* An error message is only available via sp_last_error_message() in the case
|
||||||
* where SP_ERR_FAIL was returned by the previous function call. The error
|
* 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
|
* message returned is that provided by the OS, using the current language
|
||||||
* settings. It is an error to call sp_last_error_code() or
|
* settings. It is an error to call sp_last_error_code() or
|
||||||
* sp_last_error_message() except after a previous function call returned
|
* sp_last_error_message() except after a previous function call returned
|
||||||
* SP_ERR_FAIL. The library does not define its own error codes or messages
|
* @ref SP_ERR_FAIL. The library does not define its own error codes or
|
||||||
* to accompany other return codes.
|
* messages to accompany other return codes.
|
||||||
*
|
*
|
||||||
* Thread safety
|
* Thread safety
|
||||||
* -------------
|
* -------------
|
||||||
@ -178,7 +197,7 @@
|
|||||||
*
|
*
|
||||||
* The library can output extensive tracing and debugging information. The
|
* The library can output extensive tracing and debugging information. The
|
||||||
* simplest way to use this is to set the environment variable
|
* simplest way to use this is to set the environment variable
|
||||||
* LIBSERIALPORT_DEBUG to any value; messages will then be output to the
|
* @c LIBSERIALPORT_DEBUG to any value; messages will then be output to the
|
||||||
* standard error stream.
|
* standard error stream.
|
||||||
*
|
*
|
||||||
* This behaviour is implemented by a default debug message handling
|
* This behaviour is implemented by a default debug message handling
|
||||||
@ -206,21 +225,21 @@
|
|||||||
* libserialport provides only a raw binary channel with no special handling.
|
* libserialport provides only a raw binary channel with no special handling.
|
||||||
*
|
*
|
||||||
* The second relates to blocking versus non-blocking I/O behaviour. In
|
* The second relates to blocking versus non-blocking I/O behaviour. In
|
||||||
* Unix-like systems this is normally specified by setting the O_NONBLOCK
|
* Unix-like systems this is normally specified by setting the @c O_NONBLOCK
|
||||||
* flag on the file descriptor, affecting the semantics of subsequent read()
|
* flag on the file descriptor, affecting the semantics of subsequent @c read()
|
||||||
* and write() calls.
|
* and @c write() calls.
|
||||||
*
|
*
|
||||||
* In libserialport, blocking and nonblocking operations are both available at
|
* In libserialport, blocking and nonblocking operations are both available at
|
||||||
* any time. If your existing code ѕets O_NONBLOCK, you should use
|
* 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
|
* sp_nonblocking_read() and sp_nonblocking_write() to get the same behaviour
|
||||||
* as your existing read() and write() calls. If it does not, you should use
|
* as your existing @c read() and @c write() calls. If it does not, you should
|
||||||
* sp_blocking_read() and sp_blocking_write() instead. You may also find
|
* 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
|
* sp_blocking_read_next() useful, which reproduces the semantics of a blocking
|
||||||
* read() with VTIME = 0 and VMIN = 1 set in termios.
|
* read() with @c VTIME=0 and @c VMIN=1 set in termios.
|
||||||
*
|
*
|
||||||
* Finally, you should take care if your program uses custom signal handlers.
|
* Finally, you should take care if your program uses custom signal handlers.
|
||||||
* The blocking calls provided by libserialport will restart system calls that
|
* The blocking calls provided by libserialport will restart system calls that
|
||||||
* return with EINTR, so you will need to make your own arrangements if you
|
* 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.
|
* need to interrupt blocking operations when your signal handlers are called.
|
||||||
* This is not an issue if you only use the default handlers.
|
* This is not an issue if you only use the default handlers.
|
||||||
*
|
*
|
||||||
@ -231,23 +250,23 @@
|
|||||||
*
|
*
|
||||||
* If your program does not use overlapped I/O, you can simply use
|
* If your program does not use overlapped I/O, you can simply use
|
||||||
* sp_blocking_read() and sp_blocking_write() as direct equivalents for
|
* sp_blocking_read() and sp_blocking_write() as direct equivalents for
|
||||||
* ReadFile() and WriteFile(). You may also find sp_blocking_read_next()
|
* @c ReadFile() and @c WriteFile(). You may also find sp_blocking_read_next()
|
||||||
* useful, which reproduces the special semantics of ReadFile() with
|
* useful, which reproduces the special semantics of @c ReadFile() with
|
||||||
* ReadIntervalTimeout and ReadTotalTimeoutMultiplier set to MAXDWORD
|
* @c ReadIntervalTimeout and @c ReadTotalTimeoutMultiplier set to @c MAXDWORD
|
||||||
* and 0 < ReadTotalTimeoutConstant < 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
|
* 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
|
* operation is in progress, then you can achieve the same results using
|
||||||
* sp_nonblocking_read() and sp_nonblocking_write().
|
* sp_nonblocking_read() and sp_nonblocking_write().
|
||||||
*
|
*
|
||||||
* Generally, overlapped I/O is combined with either waiting for completion
|
* Generally, overlapped I/O is combined with either waiting for completion
|
||||||
* once there is no more background work to do (using WaitForSingleObject() or
|
* once there is no more background work to do (using @c WaitForSingleObject()
|
||||||
* WaitForMultipleObjects()), or periodically checking for completion with
|
* or @c WaitForMultipleObjects()), or periodically checking for completion
|
||||||
* GetOverlappedResult(). If the aim is to start a new operation for further
|
* with @c GetOverlappedResult(). If the aim is to start a new operation for
|
||||||
* data once the previous one has completed, you can instead simply call the
|
* further data once the previous one has completed, you can instead simply
|
||||||
* nonblocking functions again with the next data. If you need to wait for
|
* call the nonblocking functions again with the next data. If you need to
|
||||||
* completion, use sp_wait() to determine when the port is ready to send or
|
* wait for completion, use sp_wait() to determine when the port is ready to
|
||||||
* receive further data.
|
* send or receive further data.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef LIBSERIALPORT_LIBSERIALPORT_H
|
#ifndef LIBSERIALPORT_LIBSERIALPORT_H
|
||||||
@ -259,6 +278,25 @@ extern "C" {
|
|||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
/** @cond */
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
/* Microsoft Visual C/C++ compiler in use */
|
||||||
|
#ifdef LIBSERIALPORT_MSBUILD
|
||||||
|
/* Building the library - need to export DLL symbols */
|
||||||
|
#define SP_API __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
/* Using the library - need to import DLL symbols */
|
||||||
|
#define SP_API __declspec(dllimport)
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
/* Some other compiler in use */
|
||||||
|
#ifndef LIBSERIALPORT_ATBUILD
|
||||||
|
/* Not building the library itself - don't need any special prefixes. */
|
||||||
|
#define SP_API
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
/** @endcond */
|
||||||
|
|
||||||
/** Return values. */
|
/** Return values. */
|
||||||
enum sp_return {
|
enum sp_return {
|
||||||
/** Operation completed successfully. */
|
/** Operation completed successfully. */
|
||||||
@ -445,6 +483,8 @@ struct sp_event_set {
|
|||||||
*
|
*
|
||||||
* Enumerating the serial ports of a system.
|
* Enumerating the serial ports of a system.
|
||||||
*
|
*
|
||||||
|
* See @ref list_ports.c for a working example of port enumeration.
|
||||||
|
*
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -465,7 +505,7 @@ struct sp_event_set {
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_get_port_by_name(const char *portname, struct sp_port **port_ptr);
|
SP_API enum sp_return sp_get_port_by_name(const char *portname, struct sp_port **port_ptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Free a port structure obtained from sp_get_port_by_name() or sp_copy_port().
|
* Free a port structure obtained from sp_get_port_by_name() or sp_copy_port().
|
||||||
@ -474,7 +514,7 @@ enum sp_return sp_get_port_by_name(const char *portname, struct sp_port **port_p
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
void sp_free_port(struct sp_port *port);
|
SP_API void sp_free_port(struct sp_port *port);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List the serial ports available on the system.
|
* List the serial ports available on the system.
|
||||||
@ -495,7 +535,7 @@ void sp_free_port(struct sp_port *port);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_list_ports(struct sp_port ***list_ptr);
|
SP_API enum sp_return sp_list_ports(struct sp_port ***list_ptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make a new copy of an sp_port structure.
|
* Make a new copy of an sp_port structure.
|
||||||
@ -514,7 +554,7 @@ enum sp_return sp_list_ports(struct sp_port ***list_ptr);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_copy_port(const struct sp_port *port, struct sp_port **copy_ptr);
|
SP_API enum sp_return sp_copy_port(const struct sp_port *port, struct sp_port **copy_ptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Free a port list obtained from sp_list_ports().
|
* Free a port list obtained from sp_list_ports().
|
||||||
@ -526,7 +566,7 @@ enum sp_return sp_copy_port(const struct sp_port *port, struct sp_port **copy_pt
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
void sp_free_port_list(struct sp_port **ports);
|
SP_API void sp_free_port_list(struct sp_port **ports);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
@ -534,6 +574,8 @@ void sp_free_port_list(struct sp_port **ports);
|
|||||||
*
|
*
|
||||||
* Opening, closing and querying ports.
|
* Opening, closing and querying ports.
|
||||||
*
|
*
|
||||||
|
* See @ref port_info.c for a working example of getting port information.
|
||||||
|
*
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -547,7 +589,7 @@ void sp_free_port_list(struct sp_port **ports);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_open(struct sp_port *port, enum sp_mode flags);
|
SP_API enum sp_return sp_open(struct sp_port *port, enum sp_mode flags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close the specified serial port.
|
* Close the specified serial port.
|
||||||
@ -558,7 +600,7 @@ enum sp_return sp_open(struct sp_port *port, enum sp_mode flags);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_close(struct sp_port *port);
|
SP_API enum sp_return sp_close(struct sp_port *port);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the name of a port.
|
* Get the name of a port.
|
||||||
@ -575,7 +617,7 @@ enum sp_return sp_close(struct sp_port *port);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
char *sp_get_port_name(const struct sp_port *port);
|
SP_API char *sp_get_port_name(const struct sp_port *port);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a description for a port, to present to end user.
|
* Get a description for a port, to present to end user.
|
||||||
@ -588,7 +630,7 @@ char *sp_get_port_name(const struct sp_port *port);
|
|||||||
*
|
*
|
||||||
* @since 0.1.1
|
* @since 0.1.1
|
||||||
*/
|
*/
|
||||||
char *sp_get_port_description(const struct sp_port *port);
|
SP_API char *sp_get_port_description(const struct sp_port *port);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the transport type used by a port.
|
* Get the transport type used by a port.
|
||||||
@ -599,7 +641,7 @@ char *sp_get_port_description(const struct sp_port *port);
|
|||||||
*
|
*
|
||||||
* @since 0.1.1
|
* @since 0.1.1
|
||||||
*/
|
*/
|
||||||
enum sp_transport sp_get_port_transport(const struct sp_port *port);
|
SP_API 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.
|
* Get the USB bus number and address on bus of a USB serial adapter port.
|
||||||
@ -614,7 +656,7 @@ enum sp_transport sp_get_port_transport(const struct sp_port *port);
|
|||||||
*
|
*
|
||||||
* @since 0.1.1
|
* @since 0.1.1
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_get_port_usb_bus_address(const struct sp_port *port,
|
SP_API enum sp_return sp_get_port_usb_bus_address(const struct sp_port *port,
|
||||||
int *usb_bus, int *usb_address);
|
int *usb_bus, int *usb_address);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -630,7 +672,7 @@ enum sp_return sp_get_port_usb_bus_address(const struct sp_port *port,
|
|||||||
*
|
*
|
||||||
* @since 0.1.1
|
* @since 0.1.1
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_get_port_usb_vid_pid(const struct sp_port *port, int *usb_vid, int *usb_pid);
|
SP_API enum sp_return sp_get_port_usb_vid_pid(const struct sp_port *port, int *usb_vid, int *usb_pid);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the USB manufacturer string of a USB serial adapter port.
|
* Get the USB manufacturer string of a USB serial adapter port.
|
||||||
@ -643,7 +685,7 @@ enum sp_return sp_get_port_usb_vid_pid(const struct sp_port *port, int *usb_vid,
|
|||||||
*
|
*
|
||||||
* @since 0.1.1
|
* @since 0.1.1
|
||||||
*/
|
*/
|
||||||
char *sp_get_port_usb_manufacturer(const struct sp_port *port);
|
SP_API char *sp_get_port_usb_manufacturer(const struct sp_port *port);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the USB product string of a USB serial adapter port.
|
* Get the USB product string of a USB serial adapter port.
|
||||||
@ -656,7 +698,7 @@ char *sp_get_port_usb_manufacturer(const struct sp_port *port);
|
|||||||
*
|
*
|
||||||
* @since 0.1.1
|
* @since 0.1.1
|
||||||
*/
|
*/
|
||||||
char *sp_get_port_usb_product(const struct sp_port *port);
|
SP_API char *sp_get_port_usb_product(const struct sp_port *port);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the USB serial number string of a USB serial adapter port.
|
* Get the USB serial number string of a USB serial adapter port.
|
||||||
@ -669,7 +711,7 @@ char *sp_get_port_usb_product(const struct sp_port *port);
|
|||||||
*
|
*
|
||||||
* @since 0.1.1
|
* @since 0.1.1
|
||||||
*/
|
*/
|
||||||
char *sp_get_port_usb_serial(const struct sp_port *port);
|
SP_API char *sp_get_port_usb_serial(const struct sp_port *port);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the MAC address of a Bluetooth serial adapter port.
|
* Get the MAC address of a Bluetooth serial adapter port.
|
||||||
@ -682,7 +724,7 @@ char *sp_get_port_usb_serial(const struct sp_port *port);
|
|||||||
*
|
*
|
||||||
* @since 0.1.1
|
* @since 0.1.1
|
||||||
*/
|
*/
|
||||||
char *sp_get_port_bluetooth_address(const struct sp_port *port);
|
SP_API char *sp_get_port_bluetooth_address(const struct sp_port *port);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the operating system handle for a port.
|
* Get the operating system handle for a port.
|
||||||
@ -714,7 +756,7 @@ char *sp_get_port_bluetooth_address(const struct sp_port *port);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_get_port_handle(const struct sp_port *port, void *result_ptr);
|
SP_API enum sp_return sp_get_port_handle(const struct sp_port *port, void *result_ptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
@ -722,6 +764,63 @@ enum sp_return sp_get_port_handle(const struct sp_port *port, void *result_ptr);
|
|||||||
* @defgroup Configuration Configuration
|
* @defgroup Configuration Configuration
|
||||||
*
|
*
|
||||||
* Setting and querying serial port parameters.
|
* Setting and querying serial port parameters.
|
||||||
|
*
|
||||||
|
* See @ref port_config.c for a working example of port configuration.
|
||||||
|
*
|
||||||
|
* You should always configure all settings before using a port.
|
||||||
|
* There are no default settings applied by libserialport.
|
||||||
|
* When you open a port it may have default settings from the OS or
|
||||||
|
* driver, or the settings left over by the last program to use it.
|
||||||
|
*
|
||||||
|
* You should always set baud rate, data bits, parity and stop bits.
|
||||||
|
*
|
||||||
|
* You should normally also set one of the preset @ref sp_flowcontrol
|
||||||
|
* flow control modes, which will set up the RTS, CTS, DTR and DSR pin
|
||||||
|
* behaviours and enable or disable XON/XOFF. If you need an unusual
|
||||||
|
* configuration not covered by the preset flow control modes, you
|
||||||
|
* will need to configure these settings individually, and avoid
|
||||||
|
* calling sp_set_flowcontrol() or sp_set_config_flowcontrol() which
|
||||||
|
* will overwrite these settings.
|
||||||
|
*
|
||||||
|
* A port must be opened before you can change its settings.
|
||||||
|
*
|
||||||
|
* There are two ways of accessing port settings:
|
||||||
|
*
|
||||||
|
* Configuration structures
|
||||||
|
* ------------------------
|
||||||
|
*
|
||||||
|
* You can read and write a whole configuration (all settings at once)
|
||||||
|
* using sp_get_config() and sp_set_config(). This is handy if you want
|
||||||
|
* to change between some preset combinations, or save and restore an
|
||||||
|
* existing configuration. It also ensures the changes are made
|
||||||
|
* together, via an efficient set of calls into the OS - in some cases
|
||||||
|
* a single system call can be used.
|
||||||
|
*
|
||||||
|
* Use accessor functions like sp_get_config_baudrate() and
|
||||||
|
* sp_set_config_baudrate() to get and set individual settings
|
||||||
|
* from a configuration.
|
||||||
|
*
|
||||||
|
* For each setting in a port configuration, a special value of -1 can
|
||||||
|
* be used, which will cause that setting to be left alone when the
|
||||||
|
* configuration is applied by sp_set_config().
|
||||||
|
*
|
||||||
|
* This value is also be used by sp_get_config() for any settings
|
||||||
|
* which are unconfigured at the OS level, or in a state that is
|
||||||
|
* not representable within the libserialport API.
|
||||||
|
*
|
||||||
|
* Configurations are allocated using sp_new_config() and freed
|
||||||
|
* with sp_free_config(). You need to manage them yourself. When
|
||||||
|
* a new configuration is allocated by sp_new_config(), all of
|
||||||
|
* its settings are initially set to the special -1 value.
|
||||||
|
*
|
||||||
|
* Direct functions for changing port settings
|
||||||
|
* -------------------------------------------
|
||||||
|
*
|
||||||
|
* As a shortcut, you can set individual settings on a port directly
|
||||||
|
* by calling functions like sp_set_baudrate() and sp_set_parity().
|
||||||
|
* This saves you the work of allocating a temporary config, setting it
|
||||||
|
* up, applying it to a port and then freeing it.
|
||||||
|
*
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -747,7 +846,7 @@ enum sp_return sp_get_port_handle(const struct sp_port *port, void *result_ptr);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_new_config(struct sp_port_config **config_ptr);
|
SP_API enum sp_return sp_new_config(struct sp_port_config **config_ptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Free a port configuration structure.
|
* Free a port configuration structure.
|
||||||
@ -756,7 +855,7 @@ enum sp_return sp_new_config(struct sp_port_config **config_ptr);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
void sp_free_config(struct sp_port_config *config);
|
SP_API void sp_free_config(struct sp_port_config *config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current configuration of the specified serial port.
|
* Get the current configuration of the specified serial port.
|
||||||
@ -778,7 +877,7 @@ void sp_free_config(struct sp_port_config *config);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_get_config(struct sp_port *port, struct sp_port_config *config);
|
SP_API enum sp_return sp_get_config(struct sp_port *port, struct sp_port_config *config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the configuration for the specified serial port.
|
* Set the configuration for the specified serial port.
|
||||||
@ -797,7 +896,7 @@ enum sp_return sp_get_config(struct sp_port *port, struct sp_port_config *config
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_set_config(struct sp_port *port, const struct sp_port_config *config);
|
SP_API enum sp_return sp_set_config(struct sp_port *port, const struct sp_port_config *config);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the baud rate for the specified serial port.
|
* Set the baud rate for the specified serial port.
|
||||||
@ -809,7 +908,7 @@ enum sp_return sp_set_config(struct sp_port *port, const struct sp_port_config *
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_set_baudrate(struct sp_port *port, int baudrate);
|
SP_API enum sp_return sp_set_baudrate(struct sp_port *port, int baudrate);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the baud rate from a port configuration.
|
* Get the baud rate from a port configuration.
|
||||||
@ -824,7 +923,7 @@ enum sp_return sp_set_baudrate(struct sp_port *port, int baudrate);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_get_config_baudrate(const struct sp_port_config *config, int *baudrate_ptr);
|
SP_API enum sp_return sp_get_config_baudrate(const struct sp_port_config *config, int *baudrate_ptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the baud rate in a port configuration.
|
* Set the baud rate in a port configuration.
|
||||||
@ -836,7 +935,7 @@ enum sp_return sp_get_config_baudrate(const struct sp_port_config *config, int *
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_set_config_baudrate(struct sp_port_config *config, int baudrate);
|
SP_API enum sp_return sp_set_config_baudrate(struct sp_port_config *config, int baudrate);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the data bits for the specified serial port.
|
* Set the data bits for the specified serial port.
|
||||||
@ -848,7 +947,7 @@ enum sp_return sp_set_config_baudrate(struct sp_port_config *config, int baudrat
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_set_bits(struct sp_port *port, int bits);
|
SP_API enum sp_return sp_set_bits(struct sp_port *port, int bits);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the data bits from a port configuration.
|
* Get the data bits from a port configuration.
|
||||||
@ -863,7 +962,7 @@ enum sp_return sp_set_bits(struct sp_port *port, int bits);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_get_config_bits(const struct sp_port_config *config, int *bits_ptr);
|
SP_API enum sp_return sp_get_config_bits(const struct sp_port_config *config, int *bits_ptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the data bits in a port configuration.
|
* Set the data bits in a port configuration.
|
||||||
@ -875,7 +974,7 @@ enum sp_return sp_get_config_bits(const struct sp_port_config *config, int *bits
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_set_config_bits(struct sp_port_config *config, int bits);
|
SP_API enum sp_return sp_set_config_bits(struct sp_port_config *config, int bits);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the parity setting for the specified serial port.
|
* Set the parity setting for the specified serial port.
|
||||||
@ -887,7 +986,7 @@ enum sp_return sp_set_config_bits(struct sp_port_config *config, int bits);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_set_parity(struct sp_port *port, enum sp_parity parity);
|
SP_API enum sp_return sp_set_parity(struct sp_port *port, enum sp_parity parity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the parity setting from a port configuration.
|
* Get the parity setting from a port configuration.
|
||||||
@ -902,7 +1001,7 @@ enum sp_return sp_set_parity(struct sp_port *port, enum sp_parity parity);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_get_config_parity(const struct sp_port_config *config, enum sp_parity *parity_ptr);
|
SP_API enum sp_return sp_get_config_parity(const struct sp_port_config *config, enum sp_parity *parity_ptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the parity setting in a port configuration.
|
* Set the parity setting in a port configuration.
|
||||||
@ -914,7 +1013,7 @@ enum sp_return sp_get_config_parity(const struct sp_port_config *config, enum sp
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_set_config_parity(struct sp_port_config *config, enum sp_parity parity);
|
SP_API enum sp_return sp_set_config_parity(struct sp_port_config *config, enum sp_parity parity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the stop bits for the specified serial port.
|
* Set the stop bits for the specified serial port.
|
||||||
@ -926,7 +1025,7 @@ enum sp_return sp_set_config_parity(struct sp_port_config *config, enum sp_parit
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_set_stopbits(struct sp_port *port, int stopbits);
|
SP_API enum sp_return sp_set_stopbits(struct sp_port *port, int stopbits);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the stop bits from a port configuration.
|
* Get the stop bits from a port configuration.
|
||||||
@ -941,7 +1040,7 @@ enum sp_return sp_set_stopbits(struct sp_port *port, int stopbits);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_get_config_stopbits(const struct sp_port_config *config, int *stopbits_ptr);
|
SP_API enum sp_return sp_get_config_stopbits(const struct sp_port_config *config, int *stopbits_ptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the stop bits in a port configuration.
|
* Set the stop bits in a port configuration.
|
||||||
@ -953,7 +1052,7 @@ enum sp_return sp_get_config_stopbits(const struct sp_port_config *config, int *
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_set_config_stopbits(struct sp_port_config *config, int stopbits);
|
SP_API enum sp_return sp_set_config_stopbits(struct sp_port_config *config, int stopbits);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the RTS pin behaviour for the specified serial port.
|
* Set the RTS pin behaviour for the specified serial port.
|
||||||
@ -965,7 +1064,7 @@ enum sp_return sp_set_config_stopbits(struct sp_port_config *config, int stopbit
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_set_rts(struct sp_port *port, enum sp_rts rts);
|
SP_API enum sp_return sp_set_rts(struct sp_port *port, enum sp_rts rts);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the RTS pin behaviour from a port configuration.
|
* Get the RTS pin behaviour from a port configuration.
|
||||||
@ -980,7 +1079,7 @@ enum sp_return sp_set_rts(struct sp_port *port, enum sp_rts rts);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_get_config_rts(const struct sp_port_config *config, enum sp_rts *rts_ptr);
|
SP_API enum sp_return sp_get_config_rts(const struct sp_port_config *config, enum sp_rts *rts_ptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the RTS pin behaviour in a port configuration.
|
* Set the RTS pin behaviour in a port configuration.
|
||||||
@ -992,7 +1091,7 @@ enum sp_return sp_get_config_rts(const struct sp_port_config *config, enum sp_rt
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_set_config_rts(struct sp_port_config *config, enum sp_rts rts);
|
SP_API enum sp_return sp_set_config_rts(struct sp_port_config *config, enum sp_rts rts);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the CTS pin behaviour for the specified serial port.
|
* Set the CTS pin behaviour for the specified serial port.
|
||||||
@ -1004,7 +1103,7 @@ enum sp_return sp_set_config_rts(struct sp_port_config *config, enum sp_rts rts)
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_set_cts(struct sp_port *port, enum sp_cts cts);
|
SP_API enum sp_return sp_set_cts(struct sp_port *port, enum sp_cts cts);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the CTS pin behaviour from a port configuration.
|
* Get the CTS pin behaviour from a port configuration.
|
||||||
@ -1019,7 +1118,7 @@ enum sp_return sp_set_cts(struct sp_port *port, enum sp_cts cts);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_get_config_cts(const struct sp_port_config *config, enum sp_cts *cts_ptr);
|
SP_API enum sp_return sp_get_config_cts(const struct sp_port_config *config, enum sp_cts *cts_ptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the CTS pin behaviour in a port configuration.
|
* Set the CTS pin behaviour in a port configuration.
|
||||||
@ -1031,7 +1130,7 @@ enum sp_return sp_get_config_cts(const struct sp_port_config *config, enum sp_ct
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_set_config_cts(struct sp_port_config *config, enum sp_cts cts);
|
SP_API enum sp_return sp_set_config_cts(struct sp_port_config *config, enum sp_cts cts);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the DTR pin behaviour for the specified serial port.
|
* Set the DTR pin behaviour for the specified serial port.
|
||||||
@ -1043,7 +1142,7 @@ enum sp_return sp_set_config_cts(struct sp_port_config *config, enum sp_cts cts)
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_set_dtr(struct sp_port *port, enum sp_dtr dtr);
|
SP_API enum sp_return sp_set_dtr(struct sp_port *port, enum sp_dtr dtr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the DTR pin behaviour from a port configuration.
|
* Get the DTR pin behaviour from a port configuration.
|
||||||
@ -1058,7 +1157,7 @@ enum sp_return sp_set_dtr(struct sp_port *port, enum sp_dtr dtr);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_get_config_dtr(const struct sp_port_config *config, enum sp_dtr *dtr_ptr);
|
SP_API enum sp_return sp_get_config_dtr(const struct sp_port_config *config, enum sp_dtr *dtr_ptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the DTR pin behaviour in a port configuration.
|
* Set the DTR pin behaviour in a port configuration.
|
||||||
@ -1070,7 +1169,7 @@ enum sp_return sp_get_config_dtr(const struct sp_port_config *config, enum sp_dt
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_set_config_dtr(struct sp_port_config *config, enum sp_dtr dtr);
|
SP_API enum sp_return sp_set_config_dtr(struct sp_port_config *config, enum sp_dtr dtr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the DSR pin behaviour for the specified serial port.
|
* Set the DSR pin behaviour for the specified serial port.
|
||||||
@ -1082,7 +1181,7 @@ enum sp_return sp_set_config_dtr(struct sp_port_config *config, enum sp_dtr dtr)
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_set_dsr(struct sp_port *port, enum sp_dsr dsr);
|
SP_API enum sp_return sp_set_dsr(struct sp_port *port, enum sp_dsr dsr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the DSR pin behaviour from a port configuration.
|
* Get the DSR pin behaviour from a port configuration.
|
||||||
@ -1097,7 +1196,7 @@ enum sp_return sp_set_dsr(struct sp_port *port, enum sp_dsr dsr);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_get_config_dsr(const struct sp_port_config *config, enum sp_dsr *dsr_ptr);
|
SP_API enum sp_return sp_get_config_dsr(const struct sp_port_config *config, enum sp_dsr *dsr_ptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the DSR pin behaviour in a port configuration.
|
* Set the DSR pin behaviour in a port configuration.
|
||||||
@ -1109,7 +1208,7 @@ enum sp_return sp_get_config_dsr(const struct sp_port_config *config, enum sp_ds
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_set_config_dsr(struct sp_port_config *config, enum sp_dsr dsr);
|
SP_API enum sp_return sp_set_config_dsr(struct sp_port_config *config, enum sp_dsr dsr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the XON/XOFF configuration for the specified serial port.
|
* Set the XON/XOFF configuration for the specified serial port.
|
||||||
@ -1121,7 +1220,7 @@ enum sp_return sp_set_config_dsr(struct sp_port_config *config, enum sp_dsr dsr)
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_set_xon_xoff(struct sp_port *port, enum sp_xonxoff xon_xoff);
|
SP_API enum sp_return sp_set_xon_xoff(struct sp_port *port, enum sp_xonxoff xon_xoff);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the XON/XOFF configuration from a port configuration.
|
* Get the XON/XOFF configuration from a port configuration.
|
||||||
@ -1136,7 +1235,7 @@ enum sp_return sp_set_xon_xoff(struct sp_port *port, enum sp_xonxoff xon_xoff);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_get_config_xon_xoff(const struct sp_port_config *config, enum sp_xonxoff *xon_xoff_ptr);
|
SP_API enum sp_return sp_get_config_xon_xoff(const struct sp_port_config *config, enum sp_xonxoff *xon_xoff_ptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the XON/XOFF configuration in a port configuration.
|
* Set the XON/XOFF configuration in a port configuration.
|
||||||
@ -1148,7 +1247,7 @@ enum sp_return sp_get_config_xon_xoff(const struct sp_port_config *config, enum
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_set_config_xon_xoff(struct sp_port_config *config, enum sp_xonxoff xon_xoff);
|
SP_API enum sp_return sp_set_config_xon_xoff(struct sp_port_config *config, enum sp_xonxoff xon_xoff);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the flow control type in a port configuration.
|
* Set the flow control type in a port configuration.
|
||||||
@ -1165,7 +1264,7 @@ enum sp_return sp_set_config_xon_xoff(struct sp_port_config *config, enum sp_xon
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_set_config_flowcontrol(struct sp_port_config *config, enum sp_flowcontrol flowcontrol);
|
SP_API enum sp_return sp_set_config_flowcontrol(struct sp_port_config *config, enum sp_flowcontrol flowcontrol);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the flow control type for the specified serial port.
|
* Set the flow control type for the specified serial port.
|
||||||
@ -1182,7 +1281,7 @@ enum sp_return sp_set_config_flowcontrol(struct sp_port_config *config, enum sp_
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_set_flowcontrol(struct sp_port *port, enum sp_flowcontrol flowcontrol);
|
SP_API enum sp_return sp_set_flowcontrol(struct sp_port *port, enum sp_flowcontrol flowcontrol);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
@ -1191,6 +1290,8 @@ enum sp_return sp_set_flowcontrol(struct sp_port *port, enum sp_flowcontrol flow
|
|||||||
*
|
*
|
||||||
* Reading, writing, and flushing data.
|
* Reading, writing, and flushing data.
|
||||||
*
|
*
|
||||||
|
* See @ref send_receive.c for an example of sending and receiving data.
|
||||||
|
*
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -1220,7 +1321,7 @@ enum sp_return sp_set_flowcontrol(struct sp_port *port, enum sp_flowcontrol flow
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_blocking_read(struct sp_port *port, void *buf, size_t count, unsigned int timeout_ms);
|
SP_API 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
|
* Read bytes from the specified serial port, returning as soon as any data is
|
||||||
@ -1248,7 +1349,7 @@ enum sp_return sp_blocking_read(struct sp_port *port, void *buf, size_t count, u
|
|||||||
*
|
*
|
||||||
* @since 0.1.1
|
* @since 0.1.1
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_blocking_read_next(struct sp_port *port, void *buf, size_t count, unsigned int timeout_ms);
|
SP_API 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.
|
* Read bytes from the specified serial port, without blocking.
|
||||||
@ -1263,7 +1364,7 @@ enum sp_return sp_blocking_read_next(struct sp_port *port, void *buf, size_t cou
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_nonblocking_read(struct sp_port *port, void *buf, size_t count);
|
SP_API enum sp_return sp_nonblocking_read(struct sp_port *port, void *buf, size_t count);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write bytes to the specified serial port, blocking until complete.
|
* Write bytes to the specified serial port, blocking until complete.
|
||||||
@ -1299,7 +1400,7 @@ enum sp_return sp_nonblocking_read(struct sp_port *port, void *buf, size_t count
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_blocking_write(struct sp_port *port, const void *buf, size_t count, unsigned int timeout_ms);
|
SP_API enum sp_return sp_blocking_write(struct sp_port *port, const void *buf, size_t count, unsigned int timeout_ms);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write bytes to the specified serial port, without blocking.
|
* Write bytes to the specified serial port, without blocking.
|
||||||
@ -1320,7 +1421,7 @@ enum sp_return sp_blocking_write(struct sp_port *port, const void *buf, size_t c
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_nonblocking_write(struct sp_port *port, const void *buf, size_t count);
|
SP_API enum sp_return sp_nonblocking_write(struct sp_port *port, const void *buf, size_t count);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the number of bytes waiting in the input buffer.
|
* Gets the number of bytes waiting in the input buffer.
|
||||||
@ -1331,7 +1432,7 @@ enum sp_return sp_nonblocking_write(struct sp_port *port, const void *buf, size_
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_input_waiting(struct sp_port *port);
|
SP_API enum sp_return sp_input_waiting(struct sp_port *port);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the number of bytes waiting in the output buffer.
|
* Gets the number of bytes waiting in the output buffer.
|
||||||
@ -1342,7 +1443,7 @@ enum sp_return sp_input_waiting(struct sp_port *port);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_output_waiting(struct sp_port *port);
|
SP_API enum sp_return sp_output_waiting(struct sp_port *port);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flush serial port buffers. Data in the selected buffer(s) is discarded.
|
* Flush serial port buffers. Data in the selected buffer(s) is discarded.
|
||||||
@ -1354,7 +1455,7 @@ enum sp_return sp_output_waiting(struct sp_port *port);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_flush(struct sp_port *port, enum sp_buffer buffers);
|
SP_API enum sp_return sp_flush(struct sp_port *port, enum sp_buffer buffers);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wait for buffered data to be transmitted.
|
* Wait for buffered data to be transmitted.
|
||||||
@ -1372,7 +1473,7 @@ enum sp_return sp_flush(struct sp_port *port, enum sp_buffer buffers);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_drain(struct sp_port *port);
|
SP_API enum sp_return sp_drain(struct sp_port *port);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
@ -1381,6 +1482,8 @@ enum sp_return sp_drain(struct sp_port *port);
|
|||||||
*
|
*
|
||||||
* Waiting for events and timeout handling.
|
* Waiting for events and timeout handling.
|
||||||
*
|
*
|
||||||
|
* See @ref await_events.c for an example of awaiting events on multiple ports.
|
||||||
|
*
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -1400,7 +1503,7 @@ enum sp_return sp_drain(struct sp_port *port);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_new_event_set(struct sp_event_set **result_ptr);
|
SP_API enum sp_return sp_new_event_set(struct sp_event_set **result_ptr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add events to a struct sp_event_set for a given port.
|
* Add events to a struct sp_event_set for a given port.
|
||||||
@ -1419,7 +1522,7 @@ enum sp_return sp_new_event_set(struct sp_event_set **result_ptr);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_add_port_events(struct sp_event_set *event_set,
|
SP_API enum sp_return sp_add_port_events(struct sp_event_set *event_set,
|
||||||
const struct sp_port *port, enum sp_event mask);
|
const struct sp_port *port, enum sp_event mask);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1432,7 +1535,7 @@ enum sp_return sp_add_port_events(struct sp_event_set *event_set,
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_wait(struct sp_event_set *event_set, unsigned int timeout_ms);
|
SP_API enum sp_return sp_wait(struct sp_event_set *event_set, unsigned int timeout_ms);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Free a structure allocated by sp_new_event_set().
|
* Free a structure allocated by sp_new_event_set().
|
||||||
@ -1441,7 +1544,7 @@ enum sp_return sp_wait(struct sp_event_set *event_set, unsigned int timeout_ms);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
void sp_free_event_set(struct sp_event_set *event_set);
|
SP_API void sp_free_event_set(struct sp_event_set *event_set);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
@ -1469,7 +1572,7 @@ void sp_free_event_set(struct sp_event_set *event_set);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_get_signals(struct sp_port *port, enum sp_signal *signal_mask);
|
SP_API enum sp_return sp_get_signals(struct sp_port *port, enum sp_signal *signal_mask);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Put the port transmit line into the break state.
|
* Put the port transmit line into the break state.
|
||||||
@ -1480,7 +1583,7 @@ enum sp_return sp_get_signals(struct sp_port *port, enum sp_signal *signal_mask)
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_start_break(struct sp_port *port);
|
SP_API enum sp_return sp_start_break(struct sp_port *port);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Take the port transmit line out of the break state.
|
* Take the port transmit line out of the break state.
|
||||||
@ -1491,7 +1594,7 @@ enum sp_return sp_start_break(struct sp_port *port);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
enum sp_return sp_end_break(struct sp_port *port);
|
SP_API enum sp_return sp_end_break(struct sp_port *port);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
@ -1500,6 +1603,8 @@ enum sp_return sp_end_break(struct sp_port *port);
|
|||||||
*
|
*
|
||||||
* Obtaining error information.
|
* Obtaining error information.
|
||||||
*
|
*
|
||||||
|
* See @ref handle_errors.c for an example of error handling.
|
||||||
|
*
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -1516,7 +1621,7 @@ enum sp_return sp_end_break(struct sp_port *port);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
int sp_last_error_code(void);
|
SP_API int sp_last_error_code(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the error message for a failed operation.
|
* Get the error message for a failed operation.
|
||||||
@ -1532,7 +1637,7 @@ int sp_last_error_code(void);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
char *sp_last_error_message(void);
|
SP_API char *sp_last_error_message(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Free an error message returned by sp_last_error_message().
|
* Free an error message returned by sp_last_error_message().
|
||||||
@ -1541,7 +1646,7 @@ char *sp_last_error_message(void);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
void sp_free_error_message(char *message);
|
SP_API void sp_free_error_message(char *message);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the handler function for library debugging messages.
|
* Set the handler function for library debugging messages.
|
||||||
@ -1560,7 +1665,7 @@ void sp_free_error_message(char *message);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
void sp_set_debug_handler(void (*handler)(const char *format, ...));
|
SP_API void sp_set_debug_handler(void (*handler)(const char *format, ...));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default handler function for library debugging messages.
|
* Default handler function for library debugging messages.
|
||||||
@ -1574,7 +1679,7 @@ void sp_set_debug_handler(void (*handler)(const char *format, ...));
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
void sp_default_debug_handler(const char *format, ...);
|
SP_API void sp_default_debug_handler(const char *format, ...);
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
@ -1603,32 +1708,32 @@ void sp_default_debug_handler(const char *format, ...);
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/** The libserialport package 'major' version number. */
|
/** The libserialport package 'major' version number. */
|
||||||
#undef SP_PACKAGE_VERSION_MAJOR
|
#define SP_PACKAGE_VERSION_MAJOR 0
|
||||||
|
|
||||||
/** The libserialport package 'minor' version number. */
|
/** The libserialport package 'minor' version number. */
|
||||||
#undef SP_PACKAGE_VERSION_MINOR
|
#define SP_PACKAGE_VERSION_MINOR 1
|
||||||
|
|
||||||
/** The libserialport package 'micro' version number. */
|
/** The libserialport package 'micro' version number. */
|
||||||
#undef SP_PACKAGE_VERSION_MICRO
|
#define SP_PACKAGE_VERSION_MICRO 1
|
||||||
|
|
||||||
/** The libserialport package version ("major.minor.micro") as string. */
|
/** The libserialport package version ("major.minor.micro") as string. */
|
||||||
#undef SP_PACKAGE_VERSION_STRING
|
#define SP_PACKAGE_VERSION_STRING "0.1.1"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Library/libtool version macros (can be used for conditional compilation).
|
* Library/libtool version macros (can be used for conditional compilation).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** The libserialport libtool 'current' version number. */
|
/** The libserialport libtool 'current' version number. */
|
||||||
#undef SP_LIB_VERSION_CURRENT
|
#define SP_LIB_VERSION_CURRENT 1
|
||||||
|
|
||||||
/** The libserialport libtool 'revision' version number. */
|
/** The libserialport libtool 'revision' version number. */
|
||||||
#undef SP_LIB_VERSION_REVISION
|
#define SP_LIB_VERSION_REVISION 0
|
||||||
|
|
||||||
/** The libserialport libtool 'age' version number. */
|
/** The libserialport libtool 'age' version number. */
|
||||||
#undef SP_LIB_VERSION_AGE
|
#define SP_LIB_VERSION_AGE 1
|
||||||
|
|
||||||
/** The libserialport libtool version ("current:revision:age") as string. */
|
/** The libserialport libtool version ("current:revision:age") as string. */
|
||||||
#undef SP_LIB_VERSION_STRING
|
#define SP_LIB_VERSION_STRING "1:0:1"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the major libserialport package version number.
|
* Get the major libserialport package version number.
|
||||||
@ -1637,7 +1742,7 @@ void sp_default_debug_handler(const char *format, ...);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
int sp_get_major_package_version(void);
|
SP_API int sp_get_major_package_version(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the minor libserialport package version number.
|
* Get the minor libserialport package version number.
|
||||||
@ -1646,7 +1751,7 @@ int sp_get_major_package_version(void);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
int sp_get_minor_package_version(void);
|
SP_API int sp_get_minor_package_version(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the micro libserialport package version number.
|
* Get the micro libserialport package version number.
|
||||||
@ -1655,7 +1760,7 @@ int sp_get_minor_package_version(void);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
int sp_get_micro_package_version(void);
|
SP_API int sp_get_micro_package_version(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the libserialport package version number as a string.
|
* Get the libserialport package version number as a string.
|
||||||
@ -1665,7 +1770,7 @@ int sp_get_micro_package_version(void);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
const char *sp_get_package_version_string(void);
|
SP_API const char *sp_get_package_version_string(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the "current" part of the libserialport library version number.
|
* Get the "current" part of the libserialport library version number.
|
||||||
@ -1674,7 +1779,7 @@ const char *sp_get_package_version_string(void);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
int sp_get_current_lib_version(void);
|
SP_API int sp_get_current_lib_version(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the "revision" part of the libserialport library version number.
|
* Get the "revision" part of the libserialport library version number.
|
||||||
@ -1683,7 +1788,7 @@ int sp_get_current_lib_version(void);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
int sp_get_revision_lib_version(void);
|
SP_API int sp_get_revision_lib_version(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the "age" part of the libserialport library version number.
|
* Get the "age" part of the libserialport library version number.
|
||||||
@ -1692,7 +1797,7 @@ int sp_get_revision_lib_version(void);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
int sp_get_age_lib_version(void);
|
SP_API int sp_get_age_lib_version(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the libserialport library version number as a string.
|
* Get the libserialport library version number as a string.
|
||||||
@ -1702,10 +1807,19 @@ int sp_get_age_lib_version(void);
|
|||||||
*
|
*
|
||||||
* @since 0.1.0
|
* @since 0.1.0
|
||||||
*/
|
*/
|
||||||
const char *sp_get_lib_version_string(void);
|
SP_API 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.
|
||||||
|
* @example port_config.c Accessing configuration settings of a port.
|
||||||
|
* @example send_receive.c Sending and receiving data.
|
||||||
|
* @example await_events.c Awaiting events on multiple ports.
|
||||||
|
* @example handle_errors.c Handling errors returned from the library.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
@ -6,7 +6,7 @@ includedir=@includedir@
|
|||||||
Name: libserialport
|
Name: libserialport
|
||||||
Description: Cross-platform serial port access library.
|
Description: Cross-platform serial port access library.
|
||||||
URL: http://sigrok.org/wiki/Libserialport
|
URL: http://sigrok.org/wiki/Libserialport
|
||||||
Requires.private:
|
Requires.private: @SP_PKGLIBS@
|
||||||
Version: @SP_PACKAGE_VERSION@
|
Version: @SP_PACKAGE_VERSION@
|
||||||
Libs: -L${libdir} -lserialport
|
Libs: -L${libdir} -lserialport
|
||||||
Libs.private: @SP_LIBS@
|
Libs.private: @SP_LIBS@
|
||||||
|
31
libserialport.sln
Normal file
31
libserialport.sln
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 16
|
||||||
|
VisualStudioVersion = 16.0.29613.14
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libserialport", "libserialport.vcxproj", "{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Debug|x86 = Debug|x86
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
Release|x86 = Release|x86
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}.Release|x64.Build.0 = Release|x64
|
||||||
|
{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}.Release|x86.Build.0 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {C2042526-D57D-45CA-B39F-6D9A782D1A05}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
84
libserialport.vcxproj
Normal file
84
libserialport.vcxproj
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="libserialport.h" />
|
||||||
|
<ClInclude Include="libserialport_internal.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="serialport.c" />
|
||||||
|
<ClCompile Include="timing.c" />
|
||||||
|
<ClCompile Include="windows.c" />
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<VCProjectVersion>16.0</VCProjectVersion>
|
||||||
|
<ProjectGuid>{1C8EAAF2-133E-4CEE-8981-4A903A8B3935}</ProjectGuid>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<RootNamespace>libserialport</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="Shared">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)'=='Debug'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="common.props" />
|
||||||
|
<Import Project="debug.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)'=='Release'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="common.props" />
|
||||||
|
<Import Project="release.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<ItemDefinitionGroup />
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
36
libserialport.vcxproj.filters
Normal file
36
libserialport.vcxproj.filters
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Source Files">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Header Files">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Resource Files">
|
||||||
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="libserialport.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="libserialport_internal.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="serialport.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="windows.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="timing.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
@ -21,23 +21,44 @@
|
|||||||
#ifndef LIBSERIALPORT_LIBSERIALPORT_INTERNAL_H
|
#ifndef LIBSERIALPORT_LIBSERIALPORT_INTERNAL_H
|
||||||
#define LIBSERIALPORT_LIBSERIALPORT_INTERNAL_H
|
#define LIBSERIALPORT_LIBSERIALPORT_INTERNAL_H
|
||||||
|
|
||||||
|
/* These MSVC-specific defines must appear before other headers.*/
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define _CRT_NONSTDC_NO_DEPRECATE
|
||||||
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __linux__
|
/* These feature test macros must appear before other headers.*/
|
||||||
/* For timeradd, timersub, timercmp. */
|
#if defined(__linux__) || defined(__CYGWIN__)
|
||||||
|
/* For timeradd, timersub, timercmp, realpath. */
|
||||||
#define _BSD_SOURCE 1 /* for glibc < 2.19 */
|
#define _BSD_SOURCE 1 /* for glibc < 2.19 */
|
||||||
#define _DEFAULT_SOURCE 1 /* for glibc >= 2.20 */
|
#define _DEFAULT_SOURCE 1 /* for glibc >= 2.20 */
|
||||||
|
/* For clock_gettime and associated types. */
|
||||||
|
#define _POSIX_C_SOURCE 199309L
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef LIBSERIALPORT_ATBUILD
|
||||||
|
/* If building with autoconf, include the generated config.h. */
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LIBSERIALPORT_MSBUILD
|
||||||
|
/* If building with MS tools, define necessary things that
|
||||||
|
would otherwise appear in config.h. */
|
||||||
|
#define SP_PRIV
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "libserialport.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <limits.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
@ -48,13 +69,22 @@
|
|||||||
static const GUID name = { l,w1,w2,{ b1,b2,b3,b4,b5,b6,b7,b8 } }
|
static const GUID name = { l,w1,w2,{ b1,b2,b3,b4,b5,b6,b7,b8 } }
|
||||||
#include <usbioctl.h>
|
#include <usbioctl.h>
|
||||||
#include <usbiodef.h>
|
#include <usbiodef.h>
|
||||||
|
/* The largest size that can be passed to WriteFile() safely
|
||||||
|
* on any architecture. This arises from the expression:
|
||||||
|
* PAGE_SIZE * (65535 - sizeof(MDL)) / sizeof(ULONG_PTR)
|
||||||
|
* and this worst-case value is found on x64. */
|
||||||
|
#define WRITEFILE_MAX_SIZE 33525760
|
||||||
#else
|
#else
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <limits.h>
|
#include <time.h>
|
||||||
#include <poll.h>
|
#include <poll.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#ifdef HAVE_SYS_FILE_H
|
||||||
|
#include <sys/file.h>
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#include <CoreFoundation/CoreFoundation.h>
|
#include <CoreFoundation/CoreFoundation.h>
|
||||||
@ -62,11 +92,13 @@
|
|||||||
#include <IOKit/serial/IOSerialKeys.h>
|
#include <IOKit/serial/IOSerialKeys.h>
|
||||||
#include <IOKit/serial/ioss.h>
|
#include <IOKit/serial/ioss.h>
|
||||||
#include <sys/syslimits.h>
|
#include <sys/syslimits.h>
|
||||||
|
#include <mach/mach_time.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#ifndef __ANDROID__
|
/* Android only has linux/serial.h from platform 21 onwards. */
|
||||||
#include "linux/serial.h"
|
#if !(defined(__ANDROID__) && (__ANDROID_API__ < 21))
|
||||||
|
#include <linux/serial.h>
|
||||||
#endif
|
#endif
|
||||||
#include "linux_termios.h"
|
#include "linux_termios.h"
|
||||||
|
|
||||||
@ -84,8 +116,18 @@
|
|||||||
#define TIOCOUTQ FIONWRITE
|
#define TIOCOUTQ FIONWRITE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* O_CLOEXEC is not available everywhere, fallback to not setting the
|
||||||
|
* flag on those systems.
|
||||||
|
*/
|
||||||
|
#ifndef _WIN32
|
||||||
|
#ifndef O_CLOEXEC
|
||||||
|
#define O_CLOEXEC 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Non-standard baudrates are not available everywhere. */
|
/* Non-standard baudrates are not available everywhere. */
|
||||||
#if (defined(HAVE_TERMIOS_SPEED) || defined(HAVE_TERMIOS2_SPEED)) && defined(HAVE_DECL_BOTHER)
|
#if (defined(HAVE_TERMIOS_SPEED) || defined(HAVE_TERMIOS2_SPEED)) && HAVE_DECL_BOTHER
|
||||||
#define USE_TERMIOS_SPEED
|
#define USE_TERMIOS_SPEED
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -109,7 +151,8 @@ struct sp_port {
|
|||||||
OVERLAPPED read_ovl;
|
OVERLAPPED read_ovl;
|
||||||
OVERLAPPED wait_ovl;
|
OVERLAPPED wait_ovl;
|
||||||
DWORD events;
|
DWORD events;
|
||||||
BYTE pending_byte;
|
BYTE *write_buf;
|
||||||
|
DWORD write_buf_size;
|
||||||
BOOL writing;
|
BOOL writing;
|
||||||
BOOL wait_running;
|
BOOL wait_running;
|
||||||
#else
|
#else
|
||||||
@ -234,4 +277,35 @@ SP_PRIV struct sp_port **list_append(struct sp_port **list, const char *portname
|
|||||||
SP_PRIV enum sp_return get_port_details(struct sp_port *port);
|
SP_PRIV enum sp_return get_port_details(struct sp_port *port);
|
||||||
SP_PRIV enum sp_return list_ports(struct sp_port ***list);
|
SP_PRIV enum sp_return list_ports(struct sp_port ***list);
|
||||||
|
|
||||||
|
/* Timing abstraction */
|
||||||
|
|
||||||
|
struct time {
|
||||||
|
#ifdef _WIN32
|
||||||
|
int64_t ticks;
|
||||||
|
#else
|
||||||
|
struct timeval tv;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
struct timeout {
|
||||||
|
unsigned int ms, limit_ms;
|
||||||
|
struct time start, now, end, delta, delta_max;
|
||||||
|
struct timeval delta_tv;
|
||||||
|
bool calls_started, overflow;
|
||||||
|
};
|
||||||
|
|
||||||
|
SP_PRIV void time_get(struct time *time);
|
||||||
|
SP_PRIV void time_set_ms(struct time *time, unsigned int ms);
|
||||||
|
SP_PRIV void time_add(const struct time *a, const struct time *b, struct time *result);
|
||||||
|
SP_PRIV void time_sub(const struct time *a, const struct time *b, struct time *result);
|
||||||
|
SP_PRIV bool time_greater(const struct time *a, const struct time *b);
|
||||||
|
SP_PRIV void time_as_timeval(const struct time *time, struct timeval *tv);
|
||||||
|
SP_PRIV unsigned int time_as_ms(const struct time *time);
|
||||||
|
SP_PRIV void timeout_start(struct timeout *timeout, unsigned int timeout_ms);
|
||||||
|
SP_PRIV void timeout_limit(struct timeout *timeout, unsigned int limit_ms);
|
||||||
|
SP_PRIV bool timeout_check(struct timeout *timeout);
|
||||||
|
SP_PRIV void timeout_update(struct timeout *timeout);
|
||||||
|
SP_PRIV struct timeval *timeout_timeval(struct timeout *timeout);
|
||||||
|
SP_PRIV unsigned int timeout_remaining_ms(struct timeout *timeout);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
54
linux.c
54
linux.c
@ -22,6 +22,18 @@
|
|||||||
#include "libserialport.h"
|
#include "libserialport.h"
|
||||||
#include "libserialport_internal.h"
|
#include "libserialport_internal.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The 'e' modifier for O_CLOEXEC is glibc >= 2.7 only, hence not
|
||||||
|
* portable, so provide an own wrapper for this functionality.
|
||||||
|
*/
|
||||||
|
static FILE *fopen_cloexec_rdonly(const char *pathname)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
if ((fd = open(pathname, O_RDONLY | O_CLOEXEC)) < 0)
|
||||||
|
return NULL;
|
||||||
|
return fdopen(fd, "r");
|
||||||
|
}
|
||||||
|
|
||||||
SP_PRIV enum sp_return get_port_details(struct sp_port *port)
|
SP_PRIV enum sp_return get_port_details(struct sp_port *port)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -34,7 +46,7 @@ SP_PRIV enum sp_return get_port_details(struct sp_port *port)
|
|||||||
char manufacturer[128], product[128], serial[128];
|
char manufacturer[128], product[128], serial[128];
|
||||||
char baddr[32];
|
char baddr[32];
|
||||||
const char dir_name[] = "/sys/class/tty/%s/device/%s%s";
|
const char dir_name[] = "/sys/class/tty/%s/device/%s%s";
|
||||||
char sub_dir[32] = "", file_name[PATH_MAX];
|
char sub_dir[32] = "", link_name[PATH_MAX], file_name[PATH_MAX];
|
||||||
char *ptr, *dev = port->name + 5;
|
char *ptr, *dev = port->name + 5;
|
||||||
FILE *file;
|
FILE *file;
|
||||||
int i, count;
|
int i, count;
|
||||||
@ -43,12 +55,12 @@ SP_PRIV enum sp_return get_port_details(struct sp_port *port)
|
|||||||
if (strncmp(port->name, "/dev/", 5))
|
if (strncmp(port->name, "/dev/", 5))
|
||||||
RETURN_ERROR(SP_ERR_ARG, "Device name not recognized");
|
RETURN_ERROR(SP_ERR_ARG, "Device name not recognized");
|
||||||
|
|
||||||
snprintf(file_name, sizeof(file_name), "/sys/class/tty/%s", dev);
|
snprintf(link_name, sizeof(link_name), "/sys/class/tty/%s", dev);
|
||||||
if (lstat(file_name, &statbuf) == -1)
|
if (lstat(link_name, &statbuf) == -1)
|
||||||
RETURN_ERROR(SP_ERR_ARG, "Device not found");
|
RETURN_ERROR(SP_ERR_ARG, "Device not found");
|
||||||
if (!S_ISLNK(statbuf.st_mode))
|
if (!S_ISLNK(statbuf.st_mode))
|
||||||
snprintf(file_name, sizeof(file_name), "/sys/class/tty/%s/device", dev);
|
snprintf(link_name, sizeof(link_name), "/sys/class/tty/%s/device", dev);
|
||||||
count = readlink(file_name, file_name, sizeof(file_name));
|
count = readlink(link_name, file_name, sizeof(file_name));
|
||||||
if (count <= 0 || count >= (int)(sizeof(file_name) - 1))
|
if (count <= 0 || count >= (int)(sizeof(file_name) - 1))
|
||||||
RETURN_ERROR(SP_ERR_ARG, "Device not found");
|
RETURN_ERROR(SP_ERR_ARG, "Device not found");
|
||||||
file_name[count] = 0;
|
file_name[count] = 0;
|
||||||
@ -62,7 +74,7 @@ SP_PRIV enum sp_return get_port_details(struct sp_port *port)
|
|||||||
strcat(sub_dir, "../");
|
strcat(sub_dir, "../");
|
||||||
|
|
||||||
snprintf(file_name, sizeof(file_name), dir_name, dev, sub_dir, "busnum");
|
snprintf(file_name, sizeof(file_name), dir_name, dev, sub_dir, "busnum");
|
||||||
if (!(file = fopen(file_name, "r")))
|
if (!(file = fopen_cloexec_rdonly(file_name)))
|
||||||
continue;
|
continue;
|
||||||
count = fscanf(file, "%d", &bus);
|
count = fscanf(file, "%d", &bus);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
@ -70,7 +82,7 @@ SP_PRIV enum sp_return get_port_details(struct sp_port *port)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
snprintf(file_name, sizeof(file_name), dir_name, dev, sub_dir, "devnum");
|
snprintf(file_name, sizeof(file_name), dir_name, dev, sub_dir, "devnum");
|
||||||
if (!(file = fopen(file_name, "r")))
|
if (!(file = fopen_cloexec_rdonly(file_name)))
|
||||||
continue;
|
continue;
|
||||||
count = fscanf(file, "%d", &address);
|
count = fscanf(file, "%d", &address);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
@ -78,7 +90,7 @@ SP_PRIV enum sp_return get_port_details(struct sp_port *port)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
snprintf(file_name, sizeof(file_name), dir_name, dev, sub_dir, "idVendor");
|
snprintf(file_name, sizeof(file_name), dir_name, dev, sub_dir, "idVendor");
|
||||||
if (!(file = fopen(file_name, "r")))
|
if (!(file = fopen_cloexec_rdonly(file_name)))
|
||||||
continue;
|
continue;
|
||||||
count = fscanf(file, "%4x", &vid);
|
count = fscanf(file, "%4x", &vid);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
@ -86,7 +98,7 @@ SP_PRIV enum sp_return get_port_details(struct sp_port *port)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
snprintf(file_name, sizeof(file_name), dir_name, dev, sub_dir, "idProduct");
|
snprintf(file_name, sizeof(file_name), dir_name, dev, sub_dir, "idProduct");
|
||||||
if (!(file = fopen(file_name, "r")))
|
if (!(file = fopen_cloexec_rdonly(file_name)))
|
||||||
continue;
|
continue;
|
||||||
count = fscanf(file, "%4x", &pid);
|
count = fscanf(file, "%4x", &pid);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
@ -99,7 +111,7 @@ SP_PRIV enum sp_return get_port_details(struct sp_port *port)
|
|||||||
port->usb_pid = pid;
|
port->usb_pid = pid;
|
||||||
|
|
||||||
snprintf(file_name, sizeof(file_name), dir_name, dev, sub_dir, "product");
|
snprintf(file_name, sizeof(file_name), dir_name, dev, sub_dir, "product");
|
||||||
if ((file = fopen(file_name, "r"))) {
|
if ((file = fopen_cloexec_rdonly(file_name))) {
|
||||||
if ((ptr = fgets(description, sizeof(description), file))) {
|
if ((ptr = fgets(description, sizeof(description), file))) {
|
||||||
ptr = description + strlen(description) - 1;
|
ptr = description + strlen(description) - 1;
|
||||||
if (ptr >= description && *ptr == '\n')
|
if (ptr >= description && *ptr == '\n')
|
||||||
@ -112,7 +124,7 @@ SP_PRIV enum sp_return get_port_details(struct sp_port *port)
|
|||||||
port->description = strdup(dev);
|
port->description = strdup(dev);
|
||||||
|
|
||||||
snprintf(file_name, sizeof(file_name), dir_name, dev, sub_dir, "manufacturer");
|
snprintf(file_name, sizeof(file_name), dir_name, dev, sub_dir, "manufacturer");
|
||||||
if ((file = fopen(file_name, "r"))) {
|
if ((file = fopen_cloexec_rdonly(file_name))) {
|
||||||
if ((ptr = fgets(manufacturer, sizeof(manufacturer), file))) {
|
if ((ptr = fgets(manufacturer, sizeof(manufacturer), file))) {
|
||||||
ptr = manufacturer + strlen(manufacturer) - 1;
|
ptr = manufacturer + strlen(manufacturer) - 1;
|
||||||
if (ptr >= manufacturer && *ptr == '\n')
|
if (ptr >= manufacturer && *ptr == '\n')
|
||||||
@ -123,7 +135,7 @@ SP_PRIV enum sp_return get_port_details(struct sp_port *port)
|
|||||||
}
|
}
|
||||||
|
|
||||||
snprintf(file_name, sizeof(file_name), dir_name, dev, sub_dir, "product");
|
snprintf(file_name, sizeof(file_name), dir_name, dev, sub_dir, "product");
|
||||||
if ((file = fopen(file_name, "r"))) {
|
if ((file = fopen_cloexec_rdonly(file_name))) {
|
||||||
if ((ptr = fgets(product, sizeof(product), file))) {
|
if ((ptr = fgets(product, sizeof(product), file))) {
|
||||||
ptr = product + strlen(product) - 1;
|
ptr = product + strlen(product) - 1;
|
||||||
if (ptr >= product && *ptr == '\n')
|
if (ptr >= product && *ptr == '\n')
|
||||||
@ -134,7 +146,7 @@ SP_PRIV enum sp_return get_port_details(struct sp_port *port)
|
|||||||
}
|
}
|
||||||
|
|
||||||
snprintf(file_name, sizeof(file_name), dir_name, dev, sub_dir, "serial");
|
snprintf(file_name, sizeof(file_name), dir_name, dev, sub_dir, "serial");
|
||||||
if ((file = fopen(file_name, "r"))) {
|
if ((file = fopen_cloexec_rdonly(file_name))) {
|
||||||
if ((ptr = fgets(serial, sizeof(serial), file))) {
|
if ((ptr = fgets(serial, sizeof(serial), file))) {
|
||||||
ptr = serial + strlen(serial) - 1;
|
ptr = serial + strlen(serial) - 1;
|
||||||
if (ptr >= serial && *ptr == '\n')
|
if (ptr >= serial && *ptr == '\n')
|
||||||
@ -160,7 +172,7 @@ SP_PRIV enum sp_return get_port_details(struct sp_port *port)
|
|||||||
|
|
||||||
if (port->transport == SP_TRANSPORT_BLUETOOTH) {
|
if (port->transport == SP_TRANSPORT_BLUETOOTH) {
|
||||||
snprintf(file_name, sizeof(file_name), dir_name, dev, "", "address");
|
snprintf(file_name, sizeof(file_name), dir_name, dev, "", "address");
|
||||||
if ((file = fopen(file_name, "r"))) {
|
if ((file = fopen_cloexec_rdonly(file_name))) {
|
||||||
if ((ptr = fgets(baddr, sizeof(baddr), file))) {
|
if ((ptr = fgets(baddr, sizeof(baddr), file))) {
|
||||||
ptr = baddr + strlen(baddr) - 1;
|
ptr = baddr + strlen(baddr) - 1;
|
||||||
if (ptr >= baddr && *ptr == '\n')
|
if (ptr >= baddr && *ptr == '\n')
|
||||||
@ -178,12 +190,12 @@ SP_PRIV enum sp_return get_port_details(struct sp_port *port)
|
|||||||
SP_PRIV enum sp_return list_ports(struct sp_port ***list)
|
SP_PRIV enum sp_return list_ports(struct sp_port ***list)
|
||||||
{
|
{
|
||||||
char name[PATH_MAX], target[PATH_MAX];
|
char name[PATH_MAX], target[PATH_MAX];
|
||||||
struct dirent entry, *result;
|
struct dirent *entry;
|
||||||
#ifdef HAVE_STRUCT_SERIAL_STRUCT
|
#ifdef HAVE_STRUCT_SERIAL_STRUCT
|
||||||
struct serial_struct serial_info;
|
struct serial_struct serial_info;
|
||||||
int ioctl_result;
|
int ioctl_result;
|
||||||
#endif
|
#endif
|
||||||
char buf[sizeof(entry.d_name) + 23];
|
char buf[sizeof(entry->d_name) + 23];
|
||||||
int len, fd;
|
int len, fd;
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
int ret = SP_OK;
|
int ret = SP_OK;
|
||||||
@ -194,19 +206,19 @@ SP_PRIV enum sp_return list_ports(struct sp_port ***list)
|
|||||||
RETURN_FAIL("Could not open /sys/class/tty");
|
RETURN_FAIL("Could not open /sys/class/tty");
|
||||||
|
|
||||||
DEBUG("Iterating over results");
|
DEBUG("Iterating over results");
|
||||||
while (!readdir_r(dir, &entry, &result) && result) {
|
while ((entry = readdir(dir))) {
|
||||||
snprintf(buf, sizeof(buf), "/sys/class/tty/%s", entry.d_name);
|
snprintf(buf, sizeof(buf), "/sys/class/tty/%s", entry->d_name);
|
||||||
if (lstat(buf, &statbuf) == -1)
|
if (lstat(buf, &statbuf) == -1)
|
||||||
continue;
|
continue;
|
||||||
if (!S_ISLNK(statbuf.st_mode))
|
if (!S_ISLNK(statbuf.st_mode))
|
||||||
snprintf(buf, sizeof(buf), "/sys/class/tty/%s/device", entry.d_name);
|
snprintf(buf, sizeof(buf), "/sys/class/tty/%s/device", entry->d_name);
|
||||||
len = readlink(buf, target, sizeof(target));
|
len = readlink(buf, target, sizeof(target));
|
||||||
if (len <= 0 || len >= (int)(sizeof(target) - 1))
|
if (len <= 0 || len >= (int)(sizeof(target) - 1))
|
||||||
continue;
|
continue;
|
||||||
target[len] = 0;
|
target[len] = 0;
|
||||||
if (strstr(target, "virtual"))
|
if (strstr(target, "virtual"))
|
||||||
continue;
|
continue;
|
||||||
snprintf(name, sizeof(name), "/dev/%s", entry.d_name);
|
snprintf(name, sizeof(name), "/dev/%s", entry->d_name);
|
||||||
DEBUG_FMT("Found device %s", name);
|
DEBUG_FMT("Found device %s", name);
|
||||||
if (strstr(target, "serial8250")) {
|
if (strstr(target, "serial8250")) {
|
||||||
/*
|
/*
|
||||||
@ -215,7 +227,7 @@ SP_PRIV enum sp_return list_ports(struct sp_port ***list)
|
|||||||
* is to try to open them and make an ioctl call.
|
* is to try to open them and make an ioctl call.
|
||||||
*/
|
*/
|
||||||
DEBUG("serial8250 device, attempting to open");
|
DEBUG("serial8250 device, attempting to open");
|
||||||
if ((fd = open(name, O_RDWR | O_NONBLOCK | O_NOCTTY)) < 0) {
|
if ((fd = open(name, O_RDWR | O_NONBLOCK | O_NOCTTY | O_CLOEXEC)) < 0) {
|
||||||
DEBUG("Open failed, skipping");
|
DEBUG("Open failed, skipping");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ SP_PRIV size_t get_termios_size(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (defined(HAVE_TERMIOS_SPEED) || defined(HAVE_TERMIOS2_SPEED)) && defined(HAVE_DECL_BOTHER)
|
#if (defined(HAVE_TERMIOS_SPEED) || defined(HAVE_TERMIOS2_SPEED)) && HAVE_DECL_BOTHER
|
||||||
SP_PRIV int get_termios_speed(void *data)
|
SP_PRIV int get_termios_speed(void *data)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_STRUCT_TERMIOS2
|
#ifdef HAVE_STRUCT_TERMIOS2
|
||||||
|
20
release.props
Normal file
20
release.props
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ImportGroup Label="PropertySheets" />
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<_PropertySheetDisplayName>Release</_PropertySheetDisplayName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup>
|
||||||
|
<ClCompile>
|
||||||
|
<PreprocessorDefinitions>LIBSERIALPORT_MSBUILD;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup />
|
||||||
|
</Project>
|
493
serialport.c
493
serialport.c
@ -21,8 +21,6 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
#include "libserialport.h"
|
|
||||||
#include "libserialport_internal.h"
|
#include "libserialport_internal.h"
|
||||||
|
|
||||||
static const struct std_baudrate std_baudrates[] = {
|
static const struct std_baudrate std_baudrates[] = {
|
||||||
@ -61,7 +59,7 @@ SP_API enum sp_return sp_get_port_by_name(const char *portname, struct sp_port *
|
|||||||
#ifndef NO_PORT_METADATA
|
#ifndef NO_PORT_METADATA
|
||||||
enum sp_return ret;
|
enum sp_return ret;
|
||||||
#endif
|
#endif
|
||||||
int len;
|
size_t len;
|
||||||
|
|
||||||
TRACE("%s, %p", portname, port_ptr);
|
TRACE("%s, %p", portname, port_ptr);
|
||||||
|
|
||||||
@ -75,6 +73,20 @@ SP_API enum sp_return sp_get_port_by_name(const char *portname, struct sp_port *
|
|||||||
|
|
||||||
DEBUG_FMT("Building structure for port %s", portname);
|
DEBUG_FMT("Building structure for port %s", portname);
|
||||||
|
|
||||||
|
#if !defined(_WIN32) && defined(HAVE_REALPATH)
|
||||||
|
/*
|
||||||
|
* get_port_details() below tries to be too smart and figure out
|
||||||
|
* some transport properties from the port name which breaks with
|
||||||
|
* symlinks. Therefore we canonicalize the portname first.
|
||||||
|
*/
|
||||||
|
char pathbuf[PATH_MAX + 1];
|
||||||
|
char *res = realpath(portname, pathbuf);
|
||||||
|
if (!res)
|
||||||
|
RETURN_ERROR(SP_ERR_ARG, "Could not retrieve realpath behind port name");
|
||||||
|
|
||||||
|
portname = pathbuf;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!(port = malloc(sizeof(struct sp_port))))
|
if (!(port = malloc(sizeof(struct sp_port))))
|
||||||
RETURN_ERROR(SP_ERR_MEM, "Port structure malloc failed");
|
RETURN_ERROR(SP_ERR_MEM, "Port structure malloc failed");
|
||||||
|
|
||||||
@ -90,6 +102,8 @@ SP_API enum sp_return sp_get_port_by_name(const char *portname, struct sp_port *
|
|||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
port->usb_path = NULL;
|
port->usb_path = NULL;
|
||||||
port->hdl = INVALID_HANDLE_VALUE;
|
port->hdl = INVALID_HANDLE_VALUE;
|
||||||
|
port->write_buf = NULL;
|
||||||
|
port->write_buf_size = 0;
|
||||||
#else
|
#else
|
||||||
port->fd = -1;
|
port->fd = -1;
|
||||||
#endif
|
#endif
|
||||||
@ -141,10 +155,7 @@ SP_API enum sp_transport sp_get_port_transport(const struct sp_port *port)
|
|||||||
{
|
{
|
||||||
TRACE("%p", port);
|
TRACE("%p", port);
|
||||||
|
|
||||||
if (!port)
|
RETURN_INT(port ? port->transport : SP_TRANSPORT_NATIVE);
|
||||||
RETURN_ERROR(SP_ERR_ARG, "Null port");
|
|
||||||
|
|
||||||
RETURN_INT(port->transport);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SP_API enum sp_return sp_get_port_usb_bus_address(const struct sp_port *port,
|
SP_API enum sp_return sp_get_port_usb_bus_address(const struct sp_port *port,
|
||||||
@ -296,6 +307,8 @@ SP_API void sp_free_port(struct sp_port *port)
|
|||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (port->usb_path)
|
if (port->usb_path)
|
||||||
free(port->usb_path);
|
free(port->usb_path);
|
||||||
|
if (port->write_buf)
|
||||||
|
free(port->write_buf);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
free(port);
|
free(port);
|
||||||
@ -307,9 +320,10 @@ SP_PRIV struct sp_port **list_append(struct sp_port **list,
|
|||||||
const char *portname)
|
const char *portname)
|
||||||
{
|
{
|
||||||
void *tmp;
|
void *tmp;
|
||||||
unsigned int count;
|
size_t count;
|
||||||
|
|
||||||
for (count = 0; list[count]; count++);
|
for (count = 0; list[count]; count++)
|
||||||
|
;
|
||||||
if (!(tmp = realloc(list, sizeof(struct sp_port *) * (count + 2))))
|
if (!(tmp = realloc(list, sizeof(struct sp_port *) * (count + 2))))
|
||||||
goto fail;
|
goto fail;
|
||||||
list = tmp;
|
list = tmp;
|
||||||
@ -471,7 +485,7 @@ SP_API enum sp_return sp_open(struct sp_port *port, enum sp_mode flags)
|
|||||||
if (flags & SP_MODE_WRITE)
|
if (flags & SP_MODE_WRITE)
|
||||||
desired_access |= GENERIC_WRITE;
|
desired_access |= GENERIC_WRITE;
|
||||||
|
|
||||||
port->hdl = CreateFile(escaped_port_name, desired_access, 0, 0,
|
port->hdl = CreateFileA(escaped_port_name, desired_access, 0, 0,
|
||||||
OPEN_EXISTING, flags_and_attributes, 0);
|
OPEN_EXISTING, flags_and_attributes, 0);
|
||||||
|
|
||||||
free(escaped_port_name);
|
free(escaped_port_name);
|
||||||
@ -522,7 +536,7 @@ SP_API enum sp_return sp_open(struct sp_port *port, enum sp_mode flags)
|
|||||||
RETURN_CODEVAL(ret);
|
RETURN_CODEVAL(ret);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
int flags_local = O_NONBLOCK | O_NOCTTY;
|
int flags_local = O_NONBLOCK | O_NOCTTY | O_CLOEXEC;
|
||||||
|
|
||||||
/* Map 'flags' to the OS-specific settings. */
|
/* Map 'flags' to the OS-specific settings. */
|
||||||
if ((flags & SP_MODE_READ_WRITE) == SP_MODE_READ_WRITE)
|
if ((flags & SP_MODE_READ_WRITE) == SP_MODE_READ_WRITE)
|
||||||
@ -534,6 +548,39 @@ SP_API enum sp_return sp_open(struct sp_port *port, enum sp_mode flags)
|
|||||||
|
|
||||||
if ((port->fd = open(port->name, flags_local)) < 0)
|
if ((port->fd = open(port->name, flags_local)) < 0)
|
||||||
RETURN_FAIL("open() failed");
|
RETURN_FAIL("open() failed");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* On POSIX in the default case the file descriptor of a serial port
|
||||||
|
* is not opened exclusively. Therefore the settings of a port are
|
||||||
|
* overwritten if the serial port is opened a second time. Windows
|
||||||
|
* opens all serial ports exclusively.
|
||||||
|
* So the idea is to open the serial ports alike in the exclusive mode.
|
||||||
|
*
|
||||||
|
* ioctl(*, TIOCEXCL) defines the file descriptor as exclusive. So all
|
||||||
|
* further open calls on the serial port will fail.
|
||||||
|
*
|
||||||
|
* There is a race condition if two processes open the same serial
|
||||||
|
* port. None of the processes will notice the exclusive ownership of
|
||||||
|
* the other process because ioctl() doesn't return an error code if
|
||||||
|
* the file descriptor is already marked as exclusive.
|
||||||
|
* This can be solved with flock(). It returns an error if the file
|
||||||
|
* descriptor is already locked by another process.
|
||||||
|
*/
|
||||||
|
#ifdef HAVE_FLOCK
|
||||||
|
if (flock(port->fd, LOCK_EX | LOCK_NB) < 0)
|
||||||
|
RETURN_FAIL("flock() failed");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TIOCEXCL
|
||||||
|
/*
|
||||||
|
* Before Linux 3.8 ioctl(*, TIOCEXCL) was not implemented and could
|
||||||
|
* lead to EINVAL or ENOTTY.
|
||||||
|
* These errors aren't fatal and can be ignored.
|
||||||
|
*/
|
||||||
|
if (ioctl(port->fd, TIOCEXCL) < 0 && errno != EINVAL && errno != ENOTTY)
|
||||||
|
RETURN_FAIL("ioctl() failed");
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = get_config(port, &data, &config);
|
ret = get_config(port, &data, &config);
|
||||||
@ -543,6 +590,15 @@ SP_API enum sp_return sp_open(struct sp_port *port, enum sp_mode flags)
|
|||||||
RETURN_CODEVAL(ret);
|
RETURN_CODEVAL(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Assume a default baudrate if the OS does not provide one.
|
||||||
|
* Cannot assign -1 here since Windows holds the baudrate in
|
||||||
|
* the DCB and does not configure the rate individually.
|
||||||
|
*/
|
||||||
|
if (config.baudrate == 0) {
|
||||||
|
config.baudrate = 9600;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set sane port settings. */
|
/* Set sane port settings. */
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
data.dcb.fBinary = TRUE;
|
data.dcb.fBinary = TRUE;
|
||||||
@ -586,7 +642,8 @@ SP_API enum sp_return sp_open(struct sp_port *port, enum sp_mode flags)
|
|||||||
data.term.c_cc[VTIME] = 0;
|
data.term.c_cc[VTIME] = 0;
|
||||||
|
|
||||||
/* Ignore modem status lines; enable receiver; leave control lines alone on close. */
|
/* Ignore modem status lines; enable receiver; leave control lines alone on close. */
|
||||||
data.term.c_cflag |= (CLOCAL | CREAD | HUPCL);
|
data.term.c_cflag |= (CLOCAL | CREAD);
|
||||||
|
data.term.c_cflag &= ~(HUPCL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@ -628,6 +685,10 @@ SP_API enum sp_return sp_close(struct sp_port *port)
|
|||||||
CLOSE_OVERLAPPED(write_ovl);
|
CLOSE_OVERLAPPED(write_ovl);
|
||||||
CLOSE_OVERLAPPED(wait_ovl);
|
CLOSE_OVERLAPPED(wait_ovl);
|
||||||
|
|
||||||
|
if (port->write_buf) {
|
||||||
|
free(port->write_buf);
|
||||||
|
port->write_buf = NULL;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
/* Returns 0 upon success, -1 upon failure. */
|
/* Returns 0 upon success, -1 upon failure. */
|
||||||
if (close(port->fd) == -1)
|
if (close(port->fd) == -1)
|
||||||
@ -697,7 +758,9 @@ SP_API enum sp_return sp_drain(struct sp_port *port)
|
|||||||
#else
|
#else
|
||||||
int result;
|
int result;
|
||||||
while (1) {
|
while (1) {
|
||||||
#ifdef __ANDROID__
|
#if defined(__ANDROID__) && (__ANDROID_API__ < 21)
|
||||||
|
/* Android only has tcdrain from platform 21 onwards.
|
||||||
|
* On previous API versions, use the ioctl directly. */
|
||||||
int arg = 1;
|
int arg = 1;
|
||||||
result = ioctl(port->fd, TCSBRK, &arg);
|
result = ioctl(port->fd, TCSBRK, &arg);
|
||||||
#else
|
#else
|
||||||
@ -717,6 +780,27 @@ SP_API enum sp_return sp_drain(struct sp_port *port)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
static enum sp_return await_write_completion(struct sp_port *port)
|
||||||
|
{
|
||||||
|
TRACE("%p", port);
|
||||||
|
DWORD bytes_written;
|
||||||
|
BOOL result;
|
||||||
|
|
||||||
|
/* Wait for previous non-blocking write to complete, if any. */
|
||||||
|
if (port->writing) {
|
||||||
|
DEBUG("Waiting for previous write to complete");
|
||||||
|
result = GetOverlappedResult(port->hdl, &port->write_ovl, &bytes_written, TRUE);
|
||||||
|
port->writing = 0;
|
||||||
|
if (!result)
|
||||||
|
RETURN_FAIL("Previous write failed to complete");
|
||||||
|
DEBUG("Previous write completed");
|
||||||
|
}
|
||||||
|
|
||||||
|
RETURN_OK();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
SP_API enum sp_return sp_blocking_write(struct sp_port *port, const void *buf,
|
SP_API enum sp_return sp_blocking_write(struct sp_port *port, const void *buf,
|
||||||
size_t count, unsigned int timeout_ms)
|
size_t count, unsigned int timeout_ms)
|
||||||
{
|
{
|
||||||
@ -738,82 +822,87 @@ SP_API enum sp_return sp_blocking_write(struct sp_port *port, const void *buf,
|
|||||||
RETURN_INT(0);
|
RETURN_INT(0);
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
DWORD bytes_written = 0;
|
DWORD remaining_ms, write_size, bytes_written;
|
||||||
BOOL result;
|
size_t remaining_bytes, total_bytes_written = 0;
|
||||||
|
const uint8_t *write_ptr = (uint8_t *) buf;
|
||||||
|
bool result;
|
||||||
|
struct timeout timeout;
|
||||||
|
|
||||||
/* Wait for previous non-blocking write to complete, if any. */
|
timeout_start(&timeout, timeout_ms);
|
||||||
if (port->writing) {
|
|
||||||
DEBUG("Waiting for previous write to complete");
|
|
||||||
result = GetOverlappedResult(port->hdl, &port->write_ovl, &bytes_written, TRUE);
|
|
||||||
port->writing = 0;
|
|
||||||
if (!result)
|
|
||||||
RETURN_FAIL("Previous write failed to complete");
|
|
||||||
DEBUG("Previous write completed");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set timeout. */
|
TRY(await_write_completion(port));
|
||||||
if (port->timeouts.WriteTotalTimeoutConstant != timeout_ms) {
|
|
||||||
port->timeouts.WriteTotalTimeoutConstant = timeout_ms;
|
|
||||||
if (SetCommTimeouts(port->hdl, &port->timeouts) == 0)
|
|
||||||
RETURN_FAIL("SetCommTimeouts() failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Start write. */
|
while (total_bytes_written < count) {
|
||||||
if (WriteFile(port->hdl, buf, count, NULL, &port->write_ovl)) {
|
|
||||||
DEBUG("Write completed immediately");
|
if (timeout_check(&timeout))
|
||||||
RETURN_INT(count);
|
break;
|
||||||
} else if (GetLastError() == ERROR_IO_PENDING) {
|
|
||||||
DEBUG("Waiting for write to complete");
|
remaining_ms = timeout_remaining_ms(&timeout);
|
||||||
if (GetOverlappedResult(port->hdl, &port->write_ovl, &bytes_written, TRUE) == 0) {
|
|
||||||
if (GetLastError() == ERROR_SEM_TIMEOUT) {
|
if (port->timeouts.WriteTotalTimeoutConstant != remaining_ms) {
|
||||||
DEBUG("Write timed out");
|
port->timeouts.WriteTotalTimeoutConstant = remaining_ms;
|
||||||
RETURN_INT(0);
|
if (SetCommTimeouts(port->hdl, &port->timeouts) == 0)
|
||||||
} else {
|
RETURN_FAIL("SetCommTimeouts() failed");
|
||||||
RETURN_FAIL("GetOverlappedResult() failed");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
DEBUG_FMT("Write completed, %d/%d bytes written", bytes_written, count);
|
|
||||||
RETURN_INT(bytes_written);
|
/* Reduce write size if it exceeds the WriteFile limit. */
|
||||||
} else {
|
remaining_bytes = count - total_bytes_written;
|
||||||
RETURN_FAIL("WriteFile() failed");
|
if (remaining_bytes > WRITEFILE_MAX_SIZE)
|
||||||
|
write_size = WRITEFILE_MAX_SIZE;
|
||||||
|
else
|
||||||
|
write_size = (DWORD) remaining_bytes;
|
||||||
|
|
||||||
|
/* Start write. */
|
||||||
|
|
||||||
|
result = WriteFile(port->hdl, write_ptr, write_size, NULL, &port->write_ovl);
|
||||||
|
|
||||||
|
timeout_update(&timeout);
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
DEBUG("Write completed immediately");
|
||||||
|
bytes_written = write_size;
|
||||||
|
} else if (GetLastError() == ERROR_IO_PENDING) {
|
||||||
|
DEBUG("Waiting for write to complete");
|
||||||
|
if (GetOverlappedResult(port->hdl, &port->write_ovl, &bytes_written, TRUE) == 0) {
|
||||||
|
if (GetLastError() == ERROR_SEM_TIMEOUT) {
|
||||||
|
DEBUG("Write timed out");
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
RETURN_FAIL("GetOverlappedResult() failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DEBUG_FMT("Write completed, %d/%d bytes written", bytes_written, write_size);
|
||||||
|
} else {
|
||||||
|
RETURN_FAIL("WriteFile() failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
write_ptr += bytes_written;
|
||||||
|
total_bytes_written += bytes_written;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RETURN_INT((int) total_bytes_written);
|
||||||
#else
|
#else
|
||||||
size_t bytes_written = 0;
|
size_t bytes_written = 0;
|
||||||
unsigned char *ptr = (unsigned char *) buf;
|
unsigned char *ptr = (unsigned char *) buf;
|
||||||
struct timeval start, delta, now, end = {0, 0};
|
struct timeout timeout;
|
||||||
int started = 0;
|
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (timeout_ms) {
|
timeout_start(&timeout, timeout_ms);
|
||||||
/* Get time at start of operation. */
|
|
||||||
gettimeofday(&start, NULL);
|
|
||||||
/* Define duration of timeout. */
|
|
||||||
delta.tv_sec = timeout_ms / 1000;
|
|
||||||
delta.tv_usec = (timeout_ms % 1000) * 1000;
|
|
||||||
/* Calculate time at which we should give up. */
|
|
||||||
timeradd(&start, &delta, &end);
|
|
||||||
}
|
|
||||||
|
|
||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
FD_SET(port->fd, &fds);
|
FD_SET(port->fd, &fds);
|
||||||
|
|
||||||
/* Loop until we have written the requested number of bytes. */
|
/* Loop until we have written the requested number of bytes. */
|
||||||
while (bytes_written < count) {
|
while (bytes_written < count) {
|
||||||
/*
|
|
||||||
* Check timeout only if we have run select() at least once,
|
if (timeout_check(&timeout))
|
||||||
* to avoid any issues if a short timeout is reached before
|
break;
|
||||||
* select() is even run.
|
|
||||||
*/
|
result = select(port->fd + 1, NULL, &fds, NULL, timeout_timeval(&timeout));
|
||||||
if (timeout_ms && started) {
|
|
||||||
gettimeofday(&now, NULL);
|
timeout_update(&timeout);
|
||||||
if (timercmp(&now, &end, >))
|
|
||||||
/* Timeout has expired. */
|
|
||||||
break;
|
|
||||||
timersub(&end, &now, &delta);
|
|
||||||
}
|
|
||||||
result = select(port->fd + 1, NULL, &fds, NULL, timeout_ms ? &delta : NULL);
|
|
||||||
started = 1;
|
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
if (errno == EINTR) {
|
if (errno == EINTR) {
|
||||||
DEBUG("select() call was interrupted, repeating");
|
DEBUG("select() call was interrupted, repeating");
|
||||||
@ -865,8 +954,7 @@ SP_API enum sp_return sp_nonblocking_write(struct sp_port *port,
|
|||||||
RETURN_INT(0);
|
RETURN_INT(0);
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
DWORD written = 0;
|
size_t buf_bytes;
|
||||||
BYTE *ptr = (BYTE *) buf;
|
|
||||||
|
|
||||||
/* Check whether previous write is complete. */
|
/* Check whether previous write is complete. */
|
||||||
if (port->writing) {
|
if (port->writing) {
|
||||||
@ -887,48 +975,43 @@ SP_API enum sp_return sp_nonblocking_write(struct sp_port *port,
|
|||||||
RETURN_FAIL("SetCommTimeouts() failed");
|
RETURN_FAIL("SetCommTimeouts() failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Reduce count if it exceeds the WriteFile limit. */
|
||||||
* Keep writing data until the OS has to actually start an async IO
|
if (count > WRITEFILE_MAX_SIZE)
|
||||||
* for it. At that point we know the buffer is full.
|
count = WRITEFILE_MAX_SIZE;
|
||||||
*/
|
|
||||||
while (written < count) {
|
|
||||||
/* Copy first byte of user buffer. */
|
|
||||||
port->pending_byte = *ptr++;
|
|
||||||
|
|
||||||
/* Start asynchronous write. */
|
/* Copy data to our write buffer. */
|
||||||
if (WriteFile(port->hdl, &port->pending_byte, 1, NULL, &port->write_ovl) == 0) {
|
buf_bytes = min(port->write_buf_size, count);
|
||||||
if (GetLastError() == ERROR_IO_PENDING) {
|
memcpy(port->write_buf, buf, buf_bytes);
|
||||||
if (HasOverlappedIoCompleted(&port->write_ovl)) {
|
|
||||||
DEBUG("Asynchronous write completed immediately");
|
/* Start asynchronous write. */
|
||||||
port->writing = 0;
|
if (WriteFile(port->hdl, port->write_buf, (DWORD) buf_bytes, NULL, &port->write_ovl) == 0) {
|
||||||
written++;
|
if (GetLastError() == ERROR_IO_PENDING) {
|
||||||
continue;
|
if ((port->writing = !HasOverlappedIoCompleted(&port->write_ovl)))
|
||||||
} else {
|
DEBUG("Asynchronous write completed immediately");
|
||||||
DEBUG("Asynchronous write running");
|
else
|
||||||
port->writing = 1;
|
DEBUG("Asynchronous write running");
|
||||||
RETURN_INT(++written);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* Actual failure of some kind. */
|
|
||||||
RETURN_FAIL("WriteFile() failed");
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
DEBUG("Single byte written immediately");
|
/* Actual failure of some kind. */
|
||||||
written++;
|
RETURN_FAIL("WriteFile() failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG("All bytes written immediately");
|
DEBUG("All bytes written immediately");
|
||||||
|
|
||||||
RETURN_INT(written);
|
RETURN_INT((int) buf_bytes);
|
||||||
#else
|
#else
|
||||||
/* Returns the number of bytes written, or -1 upon failure. */
|
/* Returns the number of bytes written, or -1 upon failure. */
|
||||||
ssize_t written = write(port->fd, buf, count);
|
ssize_t written = write(port->fd, buf, count);
|
||||||
|
|
||||||
if (written < 0)
|
if (written < 0) {
|
||||||
RETURN_FAIL("write() failed");
|
if (errno == EAGAIN)
|
||||||
else
|
// Buffer is full, no bytes written.
|
||||||
|
RETURN_INT(0);
|
||||||
|
else
|
||||||
|
RETURN_FAIL("write() failed");
|
||||||
|
} else {
|
||||||
RETURN_INT(written);
|
RETURN_INT(written);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -973,7 +1056,7 @@ SP_API enum sp_return sp_blocking_read(struct sp_port *port, void *buf,
|
|||||||
RETURN_INT(0);
|
RETURN_INT(0);
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
DWORD bytes_read = 0;
|
DWORD bytes_read;
|
||||||
|
|
||||||
/* Set timeout. */
|
/* Set timeout. */
|
||||||
if (port->timeouts.ReadIntervalTimeout != 0 ||
|
if (port->timeouts.ReadIntervalTimeout != 0 ||
|
||||||
@ -987,9 +1070,9 @@ SP_API enum sp_return sp_blocking_read(struct sp_port *port, void *buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Start read. */
|
/* Start read. */
|
||||||
if (ReadFile(port->hdl, buf, count, NULL, &port->read_ovl)) {
|
if (ReadFile(port->hdl, buf, (DWORD) count, NULL, &port->read_ovl)) {
|
||||||
DEBUG("Read completed immediately");
|
DEBUG("Read completed immediately");
|
||||||
bytes_read = count;
|
bytes_read = (DWORD) count;
|
||||||
} else if (GetLastError() == ERROR_IO_PENDING) {
|
} else if (GetLastError() == ERROR_IO_PENDING) {
|
||||||
DEBUG("Waiting for read to complete");
|
DEBUG("Waiting for read to complete");
|
||||||
if (GetOverlappedResult(port->hdl, &port->read_ovl, &bytes_read, TRUE) == 0)
|
if (GetOverlappedResult(port->hdl, &port->read_ovl, &bytes_read, TRUE) == 0)
|
||||||
@ -1001,45 +1084,31 @@ SP_API enum sp_return sp_blocking_read(struct sp_port *port, void *buf,
|
|||||||
|
|
||||||
TRY(restart_wait_if_needed(port, bytes_read));
|
TRY(restart_wait_if_needed(port, bytes_read));
|
||||||
|
|
||||||
RETURN_INT(bytes_read);
|
RETURN_INT((int) bytes_read);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
size_t bytes_read = 0;
|
size_t bytes_read = 0;
|
||||||
unsigned char *ptr = (unsigned char *) buf;
|
unsigned char *ptr = (unsigned char *) buf;
|
||||||
struct timeval start, delta, now, end = {0, 0};
|
struct timeout timeout;
|
||||||
int started = 0;
|
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (timeout_ms) {
|
timeout_start(&timeout, timeout_ms);
|
||||||
/* Get time at start of operation. */
|
|
||||||
gettimeofday(&start, NULL);
|
|
||||||
/* Define duration of timeout. */
|
|
||||||
delta.tv_sec = timeout_ms / 1000;
|
|
||||||
delta.tv_usec = (timeout_ms % 1000) * 1000;
|
|
||||||
/* Calculate time at which we should give up. */
|
|
||||||
timeradd(&start, &delta, &end);
|
|
||||||
}
|
|
||||||
|
|
||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
FD_SET(port->fd, &fds);
|
FD_SET(port->fd, &fds);
|
||||||
|
|
||||||
/* Loop until we have the requested number of bytes. */
|
/* Loop until we have the requested number of bytes. */
|
||||||
while (bytes_read < count) {
|
while (bytes_read < count) {
|
||||||
/*
|
|
||||||
* Check timeout only if we have run select() at least once,
|
if (timeout_check(&timeout))
|
||||||
* to avoid any issues if a short timeout is reached before
|
/* Timeout has expired. */
|
||||||
* select() is even run.
|
break;
|
||||||
*/
|
|
||||||
if (timeout_ms && started) {
|
result = select(port->fd + 1, &fds, NULL, NULL, timeout_timeval(&timeout));
|
||||||
gettimeofday(&now, NULL);
|
|
||||||
if (timercmp(&now, &end, >))
|
timeout_update(&timeout);
|
||||||
/* Timeout has expired. */
|
|
||||||
break;
|
|
||||||
timersub(&end, &now, &delta);
|
|
||||||
}
|
|
||||||
result = select(port->fd + 1, &fds, NULL, NULL, timeout_ms ? &delta : NULL);
|
|
||||||
started = 1;
|
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
if (errno == EINTR) {
|
if (errno == EINTR) {
|
||||||
DEBUG("select() call was interrupted, repeating");
|
DEBUG("select() call was interrupted, repeating");
|
||||||
@ -1118,7 +1187,7 @@ SP_API enum sp_return sp_blocking_read_next(struct sp_port *port, void *buf,
|
|||||||
/* Loop until we have at least one byte, or timeout is reached. */
|
/* Loop until we have at least one byte, or timeout is reached. */
|
||||||
while (bytes_read == 0) {
|
while (bytes_read == 0) {
|
||||||
/* Start read. */
|
/* Start read. */
|
||||||
if (ReadFile(port->hdl, buf, count, &bytes_read, &port->read_ovl)) {
|
if (ReadFile(port->hdl, buf, (DWORD) count, &bytes_read, &port->read_ovl)) {
|
||||||
DEBUG("Read completed immediately");
|
DEBUG("Read completed immediately");
|
||||||
} else if (GetLastError() == ERROR_IO_PENDING) {
|
} else if (GetLastError() == ERROR_IO_PENDING) {
|
||||||
DEBUG("Waiting for read to complete");
|
DEBUG("Waiting for read to complete");
|
||||||
@ -1143,40 +1212,26 @@ SP_API enum sp_return sp_blocking_read_next(struct sp_port *port, void *buf,
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
size_t bytes_read = 0;
|
size_t bytes_read = 0;
|
||||||
struct timeval start, delta, now, end = {0, 0};
|
struct timeout timeout;
|
||||||
int started = 0;
|
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (timeout_ms) {
|
timeout_start(&timeout, timeout_ms);
|
||||||
/* Get time at start of operation. */
|
|
||||||
gettimeofday(&start, NULL);
|
|
||||||
/* Define duration of timeout. */
|
|
||||||
delta.tv_sec = timeout_ms / 1000;
|
|
||||||
delta.tv_usec = (timeout_ms % 1000) * 1000;
|
|
||||||
/* Calculate time at which we should give up. */
|
|
||||||
timeradd(&start, &delta, &end);
|
|
||||||
}
|
|
||||||
|
|
||||||
FD_ZERO(&fds);
|
FD_ZERO(&fds);
|
||||||
FD_SET(port->fd, &fds);
|
FD_SET(port->fd, &fds);
|
||||||
|
|
||||||
/* Loop until we have at least one byte, or timeout is reached. */
|
/* Loop until we have at least one byte, or timeout is reached. */
|
||||||
while (bytes_read == 0) {
|
while (bytes_read == 0) {
|
||||||
/*
|
|
||||||
* Check timeout only if we have run select() at least once,
|
if (timeout_check(&timeout))
|
||||||
* to avoid any issues if a short timeout is reached before
|
/* Timeout has expired. */
|
||||||
* select() is even run.
|
break;
|
||||||
*/
|
|
||||||
if (timeout_ms && started) {
|
result = select(port->fd + 1, &fds, NULL, NULL, timeout_timeval(&timeout));
|
||||||
gettimeofday(&now, NULL);
|
|
||||||
if (timercmp(&now, &end, >))
|
timeout_update(&timeout);
|
||||||
/* Timeout has expired. */
|
|
||||||
break;
|
|
||||||
timersub(&end, &now, &delta);
|
|
||||||
}
|
|
||||||
result = select(port->fd + 1, &fds, NULL, NULL, timeout_ms ? &delta : NULL);
|
|
||||||
started = 1;
|
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
if (errno == EINTR) {
|
if (errno == EINTR) {
|
||||||
DEBUG("select() call was interrupted, repeating");
|
DEBUG("select() call was interrupted, repeating");
|
||||||
@ -1238,7 +1293,7 @@ SP_API enum sp_return sp_nonblocking_read(struct sp_port *port, void *buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Do read. */
|
/* Do read. */
|
||||||
if (ReadFile(port->hdl, buf, count, NULL, &port->read_ovl) == 0)
|
if (ReadFile(port->hdl, buf, (DWORD) count, NULL, &port->read_ovl) == 0)
|
||||||
if (GetLastError() != ERROR_IO_PENDING)
|
if (GetLastError() != ERROR_IO_PENDING)
|
||||||
RETURN_FAIL("ReadFile() failed");
|
RETURN_FAIL("ReadFile() failed");
|
||||||
|
|
||||||
@ -1292,6 +1347,11 @@ SP_API enum sp_return sp_output_waiting(struct sp_port *port)
|
|||||||
{
|
{
|
||||||
TRACE("%p", port);
|
TRACE("%p", port);
|
||||||
|
|
||||||
|
#ifdef __CYGWIN__
|
||||||
|
/* TIOCOUTQ is not defined in Cygwin headers */
|
||||||
|
RETURN_ERROR(SP_ERR_SUPP,
|
||||||
|
"Getting output bytes waiting is not supported on Cygwin");
|
||||||
|
#else
|
||||||
CHECK_OPEN_PORT();
|
CHECK_OPEN_PORT();
|
||||||
|
|
||||||
DEBUG_FMT("Checking output bytes waiting on port %s", port->name);
|
DEBUG_FMT("Checking output bytes waiting on port %s", port->name);
|
||||||
@ -1309,6 +1369,7 @@ SP_API enum sp_return sp_output_waiting(struct sp_port *port)
|
|||||||
RETURN_FAIL("TIOCOUTQ ioctl failed");
|
RETURN_FAIL("TIOCOUTQ ioctl failed");
|
||||||
RETURN_INT(bytes_waiting);
|
RETURN_INT(bytes_waiting);
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
SP_API enum sp_return sp_new_event_set(struct sp_event_set **result_ptr)
|
SP_API enum sp_return sp_new_event_set(struct sp_event_set **result_ptr)
|
||||||
@ -1426,11 +1487,9 @@ SP_API enum sp_return sp_wait(struct sp_event_set *event_set,
|
|||||||
|
|
||||||
RETURN_OK();
|
RETURN_OK();
|
||||||
#else
|
#else
|
||||||
struct timeval start, delta, now, end = {0, 0};
|
struct timeout timeout;
|
||||||
const struct timeval max_delta = {
|
int poll_timeout;
|
||||||
(INT_MAX / 1000), (INT_MAX % 1000) * 1000};
|
int result;
|
||||||
int started = 0, timeout_overflow = 0;
|
|
||||||
int result, timeout_remaining_ms;
|
|
||||||
struct pollfd *pollfds;
|
struct pollfd *pollfds;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
@ -1438,7 +1497,7 @@ SP_API enum sp_return sp_wait(struct sp_event_set *event_set,
|
|||||||
RETURN_ERROR(SP_ERR_MEM, "pollfds malloc() failed");
|
RETURN_ERROR(SP_ERR_MEM, "pollfds malloc() failed");
|
||||||
|
|
||||||
for (i = 0; i < event_set->count; i++) {
|
for (i = 0; i < event_set->count; i++) {
|
||||||
pollfds[i].fd = ((int *) event_set->handles)[i];
|
pollfds[i].fd = ((int *)event_set->handles)[i];
|
||||||
pollfds[i].events = 0;
|
pollfds[i].events = 0;
|
||||||
pollfds[i].revents = 0;
|
pollfds[i].revents = 0;
|
||||||
if (event_set->masks[i] & SP_EVENT_RX_READY)
|
if (event_set->masks[i] & SP_EVENT_RX_READY)
|
||||||
@ -1449,42 +1508,24 @@ SP_API enum sp_return sp_wait(struct sp_event_set *event_set,
|
|||||||
pollfds[i].events |= POLLERR;
|
pollfds[i].events |= POLLERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timeout_ms) {
|
timeout_start(&timeout, timeout_ms);
|
||||||
/* Get time at start of operation. */
|
timeout_limit(&timeout, INT_MAX);
|
||||||
gettimeofday(&start, NULL);
|
|
||||||
/* Define duration of timeout. */
|
|
||||||
delta.tv_sec = timeout_ms / 1000;
|
|
||||||
delta.tv_usec = (timeout_ms % 1000) * 1000;
|
|
||||||
/* Calculate time at which we should give up. */
|
|
||||||
timeradd(&start, &delta, &end);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Loop until an event occurs. */
|
/* Loop until an event occurs. */
|
||||||
while (1) {
|
while (1) {
|
||||||
/*
|
|
||||||
* Check timeout only if we have run poll() at least once,
|
if (timeout_check(&timeout)) {
|
||||||
* to avoid any issues if a short timeout is reached before
|
DEBUG("Wait timed out");
|
||||||
* poll() is even run.
|
break;
|
||||||
*/
|
|
||||||
if (!timeout_ms) {
|
|
||||||
timeout_remaining_ms = -1;
|
|
||||||
} else if (!started) {
|
|
||||||
timeout_overflow = (timeout_ms > INT_MAX);
|
|
||||||
timeout_remaining_ms = timeout_overflow ? INT_MAX : timeout_ms;
|
|
||||||
} else {
|
|
||||||
gettimeofday(&now, NULL);
|
|
||||||
if (timercmp(&now, &end, >)) {
|
|
||||||
DEBUG("Wait timed out");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
timersub(&end, &now, &delta);
|
|
||||||
if ((timeout_overflow = timercmp(&delta, &max_delta, >)))
|
|
||||||
delta = max_delta;
|
|
||||||
timeout_remaining_ms = delta.tv_sec * 1000 + delta.tv_usec / 1000;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result = poll(pollfds, event_set->count, timeout_remaining_ms);
|
poll_timeout = (int) timeout_remaining_ms(&timeout);
|
||||||
started = 1;
|
if (poll_timeout == 0)
|
||||||
|
poll_timeout = -1;
|
||||||
|
|
||||||
|
result = poll(pollfds, event_set->count, poll_timeout);
|
||||||
|
|
||||||
|
timeout_update(&timeout);
|
||||||
|
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
if (errno == EINTR) {
|
if (errno == EINTR) {
|
||||||
@ -1496,7 +1537,7 @@ SP_API enum sp_return sp_wait(struct sp_event_set *event_set,
|
|||||||
}
|
}
|
||||||
} else if (result == 0) {
|
} else if (result == 0) {
|
||||||
DEBUG("poll() timed out");
|
DEBUG("poll() timed out");
|
||||||
if (!timeout_overflow)
|
if (!timeout.overflow)
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
DEBUG("poll() completed");
|
DEBUG("poll() completed");
|
||||||
@ -1647,28 +1688,25 @@ static enum sp_return get_config(struct sp_port *port, struct port_data *data,
|
|||||||
|
|
||||||
config->bits = data->dcb.ByteSize;
|
config->bits = data->dcb.ByteSize;
|
||||||
|
|
||||||
if (data->dcb.fParity)
|
switch (data->dcb.Parity) {
|
||||||
switch (data->dcb.Parity) {
|
case NOPARITY:
|
||||||
case NOPARITY:
|
|
||||||
config->parity = SP_PARITY_NONE;
|
|
||||||
break;
|
|
||||||
case ODDPARITY:
|
|
||||||
config->parity = SP_PARITY_ODD;
|
|
||||||
break;
|
|
||||||
case EVENPARITY:
|
|
||||||
config->parity = SP_PARITY_EVEN;
|
|
||||||
break;
|
|
||||||
case MARKPARITY:
|
|
||||||
config->parity = SP_PARITY_MARK;
|
|
||||||
break;
|
|
||||||
case SPACEPARITY:
|
|
||||||
config->parity = SP_PARITY_SPACE;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
config->parity = -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
config->parity = SP_PARITY_NONE;
|
config->parity = SP_PARITY_NONE;
|
||||||
|
break;
|
||||||
|
case ODDPARITY:
|
||||||
|
config->parity = SP_PARITY_ODD;
|
||||||
|
break;
|
||||||
|
case EVENPARITY:
|
||||||
|
config->parity = SP_PARITY_EVEN;
|
||||||
|
break;
|
||||||
|
case MARKPARITY:
|
||||||
|
config->parity = SP_PARITY_MARK;
|
||||||
|
break;
|
||||||
|
case SPACEPARITY:
|
||||||
|
config->parity = SP_PARITY_SPACE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
config->parity = -1;
|
||||||
|
}
|
||||||
|
|
||||||
switch (data->dcb.StopBits) {
|
switch (data->dcb.StopBits) {
|
||||||
case ONESTOPBIT:
|
case ONESTOPBIT:
|
||||||
@ -1848,6 +1886,10 @@ static enum sp_return set_config(struct sp_port *port, struct port_data *data,
|
|||||||
DEBUG_FMT("Setting configuration for port %s", port->name);
|
DEBUG_FMT("Setting configuration for port %s", port->name);
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
BYTE* new_buf;
|
||||||
|
|
||||||
|
TRY(await_write_completion(port));
|
||||||
|
|
||||||
if (config->baudrate >= 0) {
|
if (config->baudrate >= 0) {
|
||||||
for (i = 0; i < NUM_STD_BAUDRATES; i++) {
|
for (i = 0; i < NUM_STD_BAUDRATES; i++) {
|
||||||
if (config->baudrate == std_baudrates[i].value) {
|
if (config->baudrate == std_baudrates[i].value) {
|
||||||
@ -1858,6 +1900,13 @@ static enum sp_return set_config(struct sp_port *port, struct port_data *data,
|
|||||||
|
|
||||||
if (i == NUM_STD_BAUDRATES)
|
if (i == NUM_STD_BAUDRATES)
|
||||||
data->dcb.BaudRate = config->baudrate;
|
data->dcb.BaudRate = config->baudrate;
|
||||||
|
|
||||||
|
/* Allocate write buffer for 50ms of data at baud rate. */
|
||||||
|
port->write_buf_size = max(config->baudrate / (8 * 20), 1);
|
||||||
|
new_buf = realloc(port->write_buf, port->write_buf_size);
|
||||||
|
if (!new_buf)
|
||||||
|
RETURN_ERROR(SP_ERR_MEM, "Allocating write buffer failed");
|
||||||
|
port->write_buf = new_buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config->bits >= 0)
|
if (config->bits >= 0)
|
||||||
@ -2477,17 +2526,17 @@ SP_API char *sp_last_error_message(void)
|
|||||||
TRACE_VOID();
|
TRACE_VOID();
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
TCHAR *message;
|
char *message;
|
||||||
DWORD error = GetLastError();
|
DWORD error = GetLastError();
|
||||||
|
|
||||||
DWORD length = FormatMessage(
|
DWORD length = FormatMessageA(
|
||||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
NULL,
|
NULL,
|
||||||
error,
|
error,
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
(LPTSTR) &message,
|
(LPSTR) &message,
|
||||||
0, NULL );
|
0, NULL );
|
||||||
|
|
||||||
if (length >= 2 && message[length - 2] == '\r')
|
if (length >= 2 && message[length - 2] == '\r')
|
||||||
|
69
test_timing.c
Normal file
69
test_timing.c
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
#include "config.h"
|
||||||
|
#include "libserialport.h"
|
||||||
|
#include "libserialport_internal.h"
|
||||||
|
#include <assert.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
(void) argc;
|
||||||
|
(void) argv;
|
||||||
|
struct time a, b, c;
|
||||||
|
struct timeval tv;
|
||||||
|
struct timeout to;
|
||||||
|
|
||||||
|
printf("Testing arithmetic\n");
|
||||||
|
time_set_ms(&a, 10050);
|
||||||
|
time_set_ms(&b, 100);
|
||||||
|
assert(time_greater(&a, &b));
|
||||||
|
assert(!time_greater(&b, &a));
|
||||||
|
time_add(&a, &b, &c);
|
||||||
|
assert(time_as_ms(&c) == 10150);
|
||||||
|
time_sub(&a, &b, &c);
|
||||||
|
assert(time_as_ms(&c) == 9950);
|
||||||
|
time_as_timeval(&a, &tv);
|
||||||
|
assert(tv.tv_sec == 10);
|
||||||
|
assert(tv.tv_usec == 50000);
|
||||||
|
time_get(&a);
|
||||||
|
printf("Sleeping for 1s\n");
|
||||||
|
sleep(1);
|
||||||
|
time_get(&b);
|
||||||
|
time_sub(&b, &a, &c);
|
||||||
|
printf("Measured: %ums\n", time_as_ms(&c));
|
||||||
|
assert(time_as_ms(&c) >= 950);
|
||||||
|
assert(time_as_ms(&c) <= 1050);
|
||||||
|
printf("Starting 3s timeout\n");
|
||||||
|
timeout_start(&to, 3000);
|
||||||
|
printf("Time to wait: %dms\n", timeout_remaining_ms(&to));
|
||||||
|
printf("Sleeping for 1s\n");
|
||||||
|
sleep(1);
|
||||||
|
timeout_update(&to);
|
||||||
|
assert(!timeout_check(&to));
|
||||||
|
printf("Sleeping for 1s\n");
|
||||||
|
sleep(1);
|
||||||
|
timeout_update(&to);
|
||||||
|
assert(!timeout_check(&to));
|
||||||
|
printf("Remaining: %ums\n", timeout_remaining_ms(&to));
|
||||||
|
printf("Sleeping for 1s\n");
|
||||||
|
sleep(1);
|
||||||
|
timeout_update(&to);
|
||||||
|
assert(timeout_check(&to));
|
||||||
|
printf("Timeout expired\n");
|
||||||
|
printf("Starting 2s timeout\n");
|
||||||
|
timeout_start(&to, 2000);
|
||||||
|
printf("Limiting steps to 1s\n");
|
||||||
|
timeout_limit(&to, 1000);
|
||||||
|
printf("Time to wait: %ums\n", timeout_remaining_ms(&to));
|
||||||
|
printf("Sleeping for 1s\n");
|
||||||
|
sleep(1);
|
||||||
|
timeout_update(&to);
|
||||||
|
assert(!timeout_check(&to));
|
||||||
|
printf("Remaining: %ums\n", timeout_remaining_ms(&to));
|
||||||
|
printf("Sleeping for 1s\n");
|
||||||
|
sleep(1);
|
||||||
|
timeout_update(&to);
|
||||||
|
assert(timeout_check(&to));
|
||||||
|
printf("Timeout expired\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
174
timing.c
Normal file
174
timing.c
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the libserialport project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 Martin Ling <martin-libserialport@earth.li>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libserialport_internal.h"
|
||||||
|
|
||||||
|
SP_PRIV void time_get(struct time *time)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
LARGE_INTEGER count;
|
||||||
|
QueryPerformanceCounter(&count);
|
||||||
|
time->ticks = count.QuadPart;
|
||||||
|
#elif defined(HAVE_CLOCK_GETTIME)
|
||||||
|
struct timespec ts;
|
||||||
|
if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1)
|
||||||
|
clock_gettime(CLOCK_REALTIME, &ts);
|
||||||
|
time->tv.tv_sec = ts.tv_sec;
|
||||||
|
time->tv.tv_usec = ts.tv_nsec / 1000;
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
mach_timebase_info_data_t info;
|
||||||
|
mach_timebase_info(&info);
|
||||||
|
uint64_t ticks = mach_absolute_time();
|
||||||
|
uint64_t ns = (ticks * info.numer) / info.denom;
|
||||||
|
time->tv.tv_sec = ns / 1000000000;
|
||||||
|
time->tv.tv_usec = (ns % 1000000000) / 1000;
|
||||||
|
#else
|
||||||
|
gettimeofday(&time->tv, NULL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
SP_PRIV void time_set_ms(struct time *time, unsigned int ms)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
LARGE_INTEGER frequency;
|
||||||
|
QueryPerformanceFrequency(&frequency);
|
||||||
|
time->ticks = ms * (frequency.QuadPart / 1000);
|
||||||
|
#else
|
||||||
|
time->tv.tv_sec = ms / 1000;
|
||||||
|
time->tv.tv_usec = (ms % 1000) * 1000;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
SP_PRIV void time_add(const struct time *a,
|
||||||
|
const struct time *b, struct time *result)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
result->ticks = a->ticks + b->ticks;
|
||||||
|
#else
|
||||||
|
timeradd(&a->tv, &b->tv, &result->tv);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
SP_PRIV void time_sub(const struct time *a,
|
||||||
|
const struct time *b, struct time *result)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
result->ticks = a->ticks - b->ticks;
|
||||||
|
#else
|
||||||
|
timersub(&a->tv, &b->tv, &result->tv);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
SP_PRIV bool time_greater(const struct time *a, const struct time *b)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
return (a->ticks > b->ticks);
|
||||||
|
#else
|
||||||
|
return timercmp(&a->tv, &b->tv, >);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
SP_PRIV void time_as_timeval(const struct time *time, struct timeval *tv)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
LARGE_INTEGER frequency;
|
||||||
|
QueryPerformanceFrequency(&frequency);
|
||||||
|
tv->tv_sec = (long) (time->ticks / frequency.QuadPart);
|
||||||
|
tv->tv_usec = (long) ((time->ticks % frequency.QuadPart) /
|
||||||
|
(frequency.QuadPart / 1000000));
|
||||||
|
#else
|
||||||
|
*tv = time->tv;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
SP_PRIV unsigned int time_as_ms(const struct time *time)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
LARGE_INTEGER frequency;
|
||||||
|
QueryPerformanceFrequency(&frequency);
|
||||||
|
return (unsigned int) (time->ticks / (frequency.QuadPart / 1000));
|
||||||
|
#else
|
||||||
|
return time->tv.tv_sec * 1000 + time->tv.tv_usec / 1000;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
SP_PRIV void timeout_start(struct timeout *timeout, unsigned int timeout_ms)
|
||||||
|
{
|
||||||
|
timeout->ms = timeout_ms;
|
||||||
|
|
||||||
|
/* Get time at start of operation. */
|
||||||
|
time_get(&timeout->start);
|
||||||
|
/* Define duration of timeout. */
|
||||||
|
time_set_ms(&timeout->delta, timeout_ms);
|
||||||
|
/* Calculate time at which we should give up. */
|
||||||
|
time_add(&timeout->start, &timeout->delta, &timeout->end);
|
||||||
|
/* Disable limit unless timeout_limit() called. */
|
||||||
|
timeout->limit_ms = 0;
|
||||||
|
/* First blocking call has not yet been made. */
|
||||||
|
timeout->calls_started = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SP_PRIV void timeout_limit(struct timeout *timeout, unsigned int limit_ms)
|
||||||
|
{
|
||||||
|
timeout->limit_ms = limit_ms;
|
||||||
|
timeout->overflow = (timeout->ms > timeout->limit_ms);
|
||||||
|
time_set_ms(&timeout->delta_max, timeout->limit_ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
SP_PRIV bool timeout_check(struct timeout *timeout)
|
||||||
|
{
|
||||||
|
if (!timeout->calls_started)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (timeout->ms == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
time_get(&timeout->now);
|
||||||
|
time_sub(&timeout->end, &timeout->now, &timeout->delta);
|
||||||
|
if (timeout->limit_ms)
|
||||||
|
if ((timeout->overflow = time_greater(&timeout->delta, &timeout->delta_max)))
|
||||||
|
timeout->delta = timeout->delta_max;
|
||||||
|
|
||||||
|
return time_greater(&timeout->now, &timeout->end);
|
||||||
|
}
|
||||||
|
|
||||||
|
SP_PRIV void timeout_update(struct timeout *timeout)
|
||||||
|
{
|
||||||
|
timeout->calls_started = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
SP_PRIV struct timeval *timeout_timeval(struct timeout *timeout)
|
||||||
|
{
|
||||||
|
if (timeout->ms == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
time_as_timeval(&timeout->delta, &timeout->delta_tv);
|
||||||
|
|
||||||
|
return &timeout->delta_tv;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
SP_PRIV unsigned int timeout_remaining_ms(struct timeout *timeout)
|
||||||
|
{
|
||||||
|
if (timeout->limit_ms && timeout->overflow)
|
||||||
|
return timeout->limit_ms;
|
||||||
|
else
|
||||||
|
return time_as_ms(&timeout->delta);
|
||||||
|
}
|
74
windows.c
74
windows.c
@ -18,8 +18,6 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
#include "libserialport.h"
|
|
||||||
#include "libserialport_internal.h"
|
#include "libserialport_internal.h"
|
||||||
|
|
||||||
/* USB path is a string of at most 8 decimal numbers < 128 separated by dots. */
|
/* USB path is a string of at most 8 decimal numbers < 128 separated by dots. */
|
||||||
@ -28,31 +26,42 @@
|
|||||||
static void enumerate_hub(struct sp_port *port, const char *hub_name,
|
static void enumerate_hub(struct sp_port *port, const char *hub_name,
|
||||||
const char *parent_path, DEVINST dev_inst);
|
const char *parent_path, DEVINST dev_inst);
|
||||||
|
|
||||||
static char *wc_to_utf8(PWCHAR wc_buffer, ULONG size)
|
static char *wc_to_utf8(PWCHAR wc_buffer, ULONG wc_bytes)
|
||||||
{
|
{
|
||||||
WCHAR wc_str[(size / sizeof(WCHAR)) + 1];
|
ULONG wc_length = wc_bytes / sizeof(WCHAR);
|
||||||
char *utf8_str;
|
ULONG utf8_bytes;
|
||||||
|
WCHAR *wc_str = NULL;
|
||||||
|
char *utf8_str = NULL;
|
||||||
|
|
||||||
|
/* Allocate aligned wide char buffer */
|
||||||
|
if (!(wc_str = malloc((wc_length + 1) * sizeof(WCHAR))))
|
||||||
|
goto wc_to_utf8_end;
|
||||||
|
|
||||||
/* Zero-terminate the wide char string. */
|
/* Zero-terminate the wide char string. */
|
||||||
memcpy(wc_str, wc_buffer, size);
|
memcpy(wc_str, wc_buffer, wc_bytes);
|
||||||
wc_str[sizeof(wc_str) - 1] = 0;
|
wc_str[wc_length] = 0;
|
||||||
|
|
||||||
/* Compute the size of the UTF-8 converted string. */
|
/* Compute the size of the UTF-8 converted string. */
|
||||||
if (!(size = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, wc_str, -1,
|
if (!(utf8_bytes = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, wc_str, -1,
|
||||||
NULL, 0, NULL, NULL)))
|
NULL, 0, NULL, NULL)))
|
||||||
return NULL;
|
goto wc_to_utf8_end;
|
||||||
|
|
||||||
/* Allocate UTF-8 output buffer. */
|
/* Allocate UTF-8 output buffer. */
|
||||||
if (!(utf8_str = malloc(size)))
|
if (!(utf8_str = malloc(utf8_bytes)))
|
||||||
return NULL;
|
goto wc_to_utf8_end;
|
||||||
|
|
||||||
/* Actually converted to UTF-8. */
|
/* Actually converted to UTF-8. */
|
||||||
if (!WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, wc_str, -1,
|
if (!WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, wc_str, -1,
|
||||||
utf8_str, size, NULL, NULL)) {
|
utf8_str, utf8_bytes, NULL, NULL)) {
|
||||||
free(utf8_str);
|
free(utf8_str);
|
||||||
return NULL;
|
utf8_str = NULL;
|
||||||
|
goto wc_to_utf8_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wc_to_utf8_end:
|
||||||
|
if (wc_str)
|
||||||
|
free(wc_str);
|
||||||
|
|
||||||
return utf8_str;
|
return utf8_str;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +90,7 @@ static char *get_root_hub_name(HANDLE host_controller)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Convert the root hub name string to UTF-8. */
|
/* Convert the root hub name string to UTF-8. */
|
||||||
root_hub_name_utf8 = wc_to_utf8(root_hub_name_wc->RootHubName, size);
|
root_hub_name_utf8 = wc_to_utf8(root_hub_name_wc->RootHubName, size - offsetof(USB_ROOT_HUB_NAME, RootHubName));
|
||||||
free(root_hub_name_wc);
|
free(root_hub_name_wc);
|
||||||
return root_hub_name_utf8;
|
return root_hub_name_utf8;
|
||||||
}
|
}
|
||||||
@ -116,7 +125,7 @@ static char *get_external_hub_name(HANDLE hub, ULONG connection_index)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Convert the external hub name string to UTF-8. */
|
/* Convert the external hub name string to UTF-8. */
|
||||||
ext_hub_name_utf8 = wc_to_utf8(ext_hub_name_wc->NodeName, size);
|
ext_hub_name_utf8 = wc_to_utf8(ext_hub_name_wc->NodeName, size - offsetof(USB_NODE_CONNECTION_NAME, NodeName));
|
||||||
free(ext_hub_name_wc);
|
free(ext_hub_name_wc);
|
||||||
return ext_hub_name_utf8;
|
return ext_hub_name_utf8;
|
||||||
}
|
}
|
||||||
@ -134,7 +143,7 @@ static char *get_string_descriptor(HANDLE hub_device, ULONG connection_index,
|
|||||||
desc_req->SetupPacket.wValue = (USB_STRING_DESCRIPTOR_TYPE << 8)
|
desc_req->SetupPacket.wValue = (USB_STRING_DESCRIPTOR_TYPE << 8)
|
||||||
| descriptor_index;
|
| descriptor_index;
|
||||||
desc_req->SetupPacket.wIndex = 0;
|
desc_req->SetupPacket.wIndex = 0;
|
||||||
desc_req->SetupPacket.wLength = size - sizeof(*desc_req);
|
desc_req->SetupPacket.wLength = (USHORT) (size - sizeof(*desc_req));
|
||||||
|
|
||||||
if (!DeviceIoControl(hub_device,
|
if (!DeviceIoControl(hub_device,
|
||||||
IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION,
|
IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION,
|
||||||
@ -145,7 +154,7 @@ static char *get_string_descriptor(HANDLE hub_device, ULONG connection_index,
|
|||||||
|| desc->bLength % 2)
|
|| desc->bLength % 2)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return wc_to_utf8(desc->bString, desc->bLength);
|
return wc_to_utf8(desc->bString, desc->bLength - offsetof(USB_STRING_DESCRIPTOR, bString));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void enumerate_hub_ports(struct sp_port *port, HANDLE hub_device,
|
static void enumerate_hub_ports(struct sp_port *port, HANDLE hub_device,
|
||||||
@ -219,7 +228,7 @@ static void enumerate_hub_ports(struct sp_port *port, HANDLE hub_device,
|
|||||||
port->usb_pid = connection_info_ex->DeviceDescriptor.idProduct;
|
port->usb_pid = connection_info_ex->DeviceDescriptor.idProduct;
|
||||||
|
|
||||||
if (connection_info_ex->DeviceDescriptor.iManufacturer)
|
if (connection_info_ex->DeviceDescriptor.iManufacturer)
|
||||||
port->usb_manufacturer = get_string_descriptor(hub_device,index,
|
port->usb_manufacturer = get_string_descriptor(hub_device, index,
|
||||||
connection_info_ex->DeviceDescriptor.iManufacturer);
|
connection_info_ex->DeviceDescriptor.iManufacturer);
|
||||||
if (connection_info_ex->DeviceDescriptor.iProduct)
|
if (connection_info_ex->DeviceDescriptor.iProduct)
|
||||||
port->usb_product = get_string_descriptor(hub_device, index,
|
port->usb_product = get_string_descriptor(hub_device, index,
|
||||||
@ -256,8 +265,8 @@ static void enumerate_hub(struct sp_port *port, const char *hub_name,
|
|||||||
return;
|
return;
|
||||||
strcpy(device_name, "\\\\.\\");
|
strcpy(device_name, "\\\\.\\");
|
||||||
strcat(device_name, hub_name);
|
strcat(device_name, hub_name);
|
||||||
hub_device = CreateFile(device_name, GENERIC_WRITE, FILE_SHARE_WRITE,
|
hub_device = CreateFileA(device_name, GENERIC_WRITE, FILE_SHARE_WRITE,
|
||||||
NULL, OPEN_EXISTING, 0, NULL);
|
NULL, OPEN_EXISTING, 0, NULL);
|
||||||
free(device_name);
|
free(device_name);
|
||||||
if (hub_device == INVALID_HANDLE_VALUE)
|
if (hub_device == INVALID_HANDLE_VALUE)
|
||||||
return;
|
return;
|
||||||
@ -380,7 +389,7 @@ SP_PRIV enum sp_return get_port_details(struct sp_port *port)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
RegCloseKey(device_key);
|
RegCloseKey(device_key);
|
||||||
value[sizeof(value)-1] = 0;
|
value[sizeof(value) - 1] = 0;
|
||||||
if (strcmp(value, port->name))
|
if (strcmp(value, port->name))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -458,9 +467,9 @@ SP_PRIV enum sp_return get_port_details(struct sp_port *port)
|
|||||||
if (!(escaped_port_name = malloc(strlen(port->name) + 5)))
|
if (!(escaped_port_name = malloc(strlen(port->name) + 5)))
|
||||||
RETURN_ERROR(SP_ERR_MEM, "Escaped port name malloc failed");
|
RETURN_ERROR(SP_ERR_MEM, "Escaped port name malloc failed");
|
||||||
sprintf(escaped_port_name, "\\\\.\\%s", port->name);
|
sprintf(escaped_port_name, "\\\\.\\%s", port->name);
|
||||||
handle = CreateFile(escaped_port_name, GENERIC_READ, 0, 0,
|
handle = CreateFileA(escaped_port_name, GENERIC_READ, 0, 0,
|
||||||
OPEN_EXISTING,
|
OPEN_EXISTING,
|
||||||
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, 0);
|
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, 0);
|
||||||
free(escaped_port_name);
|
free(escaped_port_name);
|
||||||
CloseHandle(handle);
|
CloseHandle(handle);
|
||||||
|
|
||||||
@ -482,19 +491,26 @@ SP_PRIV enum sp_return list_ports(struct sp_port ***list)
|
|||||||
DWORD max_value_len, max_data_size, max_data_len;
|
DWORD max_value_len, max_data_size, max_data_len;
|
||||||
DWORD value_len, data_size, data_len;
|
DWORD value_len, data_size, data_len;
|
||||||
DWORD type, index = 0;
|
DWORD type, index = 0;
|
||||||
|
LSTATUS result;
|
||||||
char *name;
|
char *name;
|
||||||
int name_len;
|
int name_len;
|
||||||
int ret = SP_OK;
|
int ret = SP_OK;
|
||||||
|
|
||||||
DEBUG("Opening registry key");
|
DEBUG("Opening registry key");
|
||||||
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("HARDWARE\\DEVICEMAP\\SERIALCOMM"),
|
if ((result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("HARDWARE\\DEVICEMAP\\SERIALCOMM"),
|
||||||
0, KEY_QUERY_VALUE, &key) != ERROR_SUCCESS) {
|
0, KEY_QUERY_VALUE, &key)) != ERROR_SUCCESS) {
|
||||||
SET_FAIL(ret, "RegOpenKeyEx() failed");
|
/* It's possible for this key to not exist if there are no serial ports
|
||||||
|
* at all. In that case we're done. Return a failure for any other error. */
|
||||||
|
if (result != ERROR_FILE_NOT_FOUND) {
|
||||||
|
SetLastError(result);
|
||||||
|
SET_FAIL(ret, "RegOpenKeyEx() failed");
|
||||||
|
}
|
||||||
goto out_done;
|
goto out_done;
|
||||||
}
|
}
|
||||||
DEBUG("Querying registry key value and data sizes");
|
DEBUG("Querying registry key value and data sizes");
|
||||||
if (RegQueryInfoKey(key, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
if ((result = RegQueryInfoKey(key, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
&max_value_len, &max_data_size, NULL, NULL) != ERROR_SUCCESS) {
|
&max_value_len, &max_data_size, NULL, NULL)) != ERROR_SUCCESS) {
|
||||||
|
SetLastError(result);
|
||||||
SET_FAIL(ret, "RegQueryInfoKey() failed");
|
SET_FAIL(ret, "RegQueryInfoKey() failed");
|
||||||
goto out_close;
|
goto out_close;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user