Commit 4ec9c73474d49c84d293fd0053fccae7b60242b3
0 parents
Initial commit. serial-port-cpp library has basic functions up and running.
Showing
7 changed files
with
696 additions
and
0 deletions
.cproject
0 → 100644
| 1 | +++ a/.cproject | ||
| 1 | +<?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||
| 2 | +<?fileVersion 4.0.0?> | ||
| 3 | + | ||
| 4 | +<cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage"> | ||
| 5 | + <storageModule moduleId="org.eclipse.cdt.core.settings"> | ||
| 6 | + <cconfiguration id="cdt.managedbuild.config.gnu.exe.debug.1434179845"> | ||
| 7 | + <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.debug.1434179845" moduleId="org.eclipse.cdt.core.settings" name="Debug"> | ||
| 8 | + <externalSettings/> | ||
| 9 | + <extensions> | ||
| 10 | + <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/> | ||
| 11 | + <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> | ||
| 12 | + <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/> | ||
| 13 | + <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> | ||
| 14 | + <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> | ||
| 15 | + <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> | ||
| 16 | + </extensions> | ||
| 17 | + </storageModule> | ||
| 18 | + <storageModule moduleId="cdtBuildSystem" version="4.0.0"> | ||
| 19 | + <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.debug.1434179845" name="Debug" parent="cdt.managedbuild.config.gnu.exe.debug"> | ||
| 20 | + <folderInfo id="cdt.managedbuild.config.gnu.exe.debug.1434179845." name="/" resourcePath=""> | ||
| 21 | + <toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.1266764326" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.debug"> | ||
| 22 | + <targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.debug.753834071" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/> | ||
| 23 | + <builder buildPath="${workspace_loc:/serial-port-cpp}/Debug" id="cdt.managedbuild.target.gnu.builder.exe.debug.145411499" managedBuildOn="true" name="Gnu Make Builder.Debug" superClass="cdt.managedbuild.target.gnu.builder.exe.debug"/> | ||
| 24 | + <tool id="cdt.managedbuild.tool.gnu.archiver.base.1266840873" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/> | ||
| 25 | + <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.1606617381" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug"> | ||
| 26 | + <option id="gnu.cpp.compiler.exe.debug.option.optimization.level.1135398162" superClass="gnu.cpp.compiler.exe.debug.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/> | ||
| 27 | + <option id="gnu.cpp.compiler.exe.debug.option.debugging.level.1374695701" superClass="gnu.cpp.compiler.exe.debug.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/> | ||
| 28 | + <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.2071854206" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/> | ||
| 29 | + </tool> | ||
| 30 | + <tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.debug.856044512" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.debug"> | ||
| 31 | + <option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.exe.debug.option.optimization.level.1946954569" superClass="gnu.c.compiler.exe.debug.option.optimization.level" valueType="enumerated"/> | ||
| 32 | + <option id="gnu.c.compiler.exe.debug.option.debugging.level.171918039" superClass="gnu.c.compiler.exe.debug.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/> | ||
| 33 | + <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.578162411" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/> | ||
| 34 | + </tool> | ||
| 35 | + <tool id="cdt.managedbuild.tool.gnu.c.linker.exe.debug.874795535" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.debug"/> | ||
| 36 | + <tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug.1041263527" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug"> | ||
| 37 | + <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.883666878" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input"> | ||
| 38 | + <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/> | ||
| 39 | + <additionalInput kind="additionalinput" paths="$(LIBS)"/> | ||
| 40 | + </inputType> | ||
| 41 | + </tool> | ||
| 42 | + <tool id="cdt.managedbuild.tool.gnu.assembler.exe.debug.339286544" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.debug"> | ||
| 43 | + <inputType id="cdt.managedbuild.tool.gnu.assembler.input.1800711142" superClass="cdt.managedbuild.tool.gnu.assembler.input"/> | ||
| 44 | + </tool> | ||
| 45 | + </toolChain> | ||
| 46 | + </folderInfo> | ||
| 47 | + </configuration> | ||
| 48 | + </storageModule> | ||
| 49 | + <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/> | ||
| 50 | + </cconfiguration> | ||
| 51 | + <cconfiguration id="cdt.managedbuild.config.gnu.exe.release.457871666"> | ||
| 52 | + <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.release.457871666" moduleId="org.eclipse.cdt.core.settings" name="Release"> | ||
| 53 | + <externalSettings/> | ||
| 54 | + <extensions> | ||
| 55 | + <extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/> | ||
| 56 | + <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> | ||
| 57 | + <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/> | ||
| 58 | + <extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> | ||
| 59 | + <extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> | ||
| 60 | + <extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/> | ||
| 61 | + </extensions> | ||
| 62 | + </storageModule> | ||
| 63 | + <storageModule moduleId="cdtBuildSystem" version="4.0.0"> | ||
| 64 | + <configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.release.457871666" name="Release" parent="cdt.managedbuild.config.gnu.exe.release"> | ||
| 65 | + <folderInfo id="cdt.managedbuild.config.gnu.exe.release.457871666." name="/" resourcePath=""> | ||
| 66 | + <toolChain id="cdt.managedbuild.toolchain.gnu.exe.release.409895619" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.release"> | ||
| 67 | + <targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.release.1193567911" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.release"/> | ||
| 68 | + <builder buildPath="${workspace_loc:/serial-port-cpp}/Release" id="cdt.managedbuild.target.gnu.builder.exe.release.1071856767" managedBuildOn="true" name="Gnu Make Builder.Release" superClass="cdt.managedbuild.target.gnu.builder.exe.release"/> | ||
| 69 | + <tool id="cdt.managedbuild.tool.gnu.archiver.base.172329860" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/> | ||
| 70 | + <tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.150242263" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release"> | ||
| 71 | + <option id="gnu.cpp.compiler.exe.release.option.optimization.level.2067054569" superClass="gnu.cpp.compiler.exe.release.option.optimization.level" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/> | ||
| 72 | + <option id="gnu.cpp.compiler.exe.release.option.debugging.level.1786443037" superClass="gnu.cpp.compiler.exe.release.option.debugging.level" value="gnu.cpp.compiler.debugging.level.none" valueType="enumerated"/> | ||
| 73 | + <inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1665355821" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/> | ||
| 74 | + </tool> | ||
| 75 | + <tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.release.1282472662" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.release"> | ||
| 76 | + <option defaultValue="gnu.c.optimization.level.most" id="gnu.c.compiler.exe.release.option.optimization.level.442630623" superClass="gnu.c.compiler.exe.release.option.optimization.level" valueType="enumerated"/> | ||
| 77 | + <option id="gnu.c.compiler.exe.release.option.debugging.level.396767700" superClass="gnu.c.compiler.exe.release.option.debugging.level" value="gnu.c.debugging.level.none" valueType="enumerated"/> | ||
| 78 | + <inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.228423099" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/> | ||
| 79 | + </tool> | ||
| 80 | + <tool id="cdt.managedbuild.tool.gnu.c.linker.exe.release.428566658" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.release"/> | ||
| 81 | + <tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.release.1163261937" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.release"> | ||
| 82 | + <inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.854514091" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input"> | ||
| 83 | + <additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/> | ||
| 84 | + <additionalInput kind="additionalinput" paths="$(LIBS)"/> | ||
| 85 | + </inputType> | ||
| 86 | + </tool> | ||
| 87 | + <tool id="cdt.managedbuild.tool.gnu.assembler.exe.release.752097052" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.release"> | ||
| 88 | + <inputType id="cdt.managedbuild.tool.gnu.assembler.input.935633559" superClass="cdt.managedbuild.tool.gnu.assembler.input"/> | ||
| 89 | + </tool> | ||
| 90 | + </toolChain> | ||
| 91 | + </folderInfo> | ||
| 92 | + </configuration> | ||
| 93 | + </storageModule> | ||
| 94 | + </cconfiguration> | ||
| 95 | + </storageModule> | ||
| 96 | + <storageModule moduleId="cdtBuildSystem" version="4.0.0"> | ||
| 97 | + <project id="serial-port-cpp.cdt.managedbuild.target.gnu.exe.525128155" name="Executable" projectType="cdt.managedbuild.target.gnu.exe"/> | ||
| 98 | + </storageModule> | ||
| 99 | + <storageModule moduleId="scannerConfiguration"> | ||
| 100 | + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> | ||
| 101 | + <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.457871666;cdt.managedbuild.config.gnu.exe.release.457871666.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.150242263;cdt.managedbuild.tool.gnu.cpp.compiler.input.1665355821"> | ||
| 102 | + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> | ||
| 103 | + </scannerConfigBuildInfo> | ||
| 104 | + <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1434179845;cdt.managedbuild.config.gnu.exe.debug.1434179845.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.1606617381;cdt.managedbuild.tool.gnu.cpp.compiler.input.2071854206"> | ||
| 105 | + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> | ||
| 106 | + </scannerConfigBuildInfo> | ||
| 107 | + <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.457871666;cdt.managedbuild.config.gnu.exe.release.457871666.;cdt.managedbuild.tool.gnu.c.compiler.exe.release.1282472662;cdt.managedbuild.tool.gnu.c.compiler.input.228423099"> | ||
| 108 | + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> | ||
| 109 | + </scannerConfigBuildInfo> | ||
| 110 | + <scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1434179845;cdt.managedbuild.config.gnu.exe.debug.1434179845.;cdt.managedbuild.tool.gnu.c.compiler.exe.debug.856044512;cdt.managedbuild.tool.gnu.c.compiler.input.578162411"> | ||
| 111 | + <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/> | ||
| 112 | + </scannerConfigBuildInfo> | ||
| 113 | + </storageModule> | ||
| 114 | + <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/> | ||
| 115 | +</cproject> |
.project
0 → 100644
| 1 | +++ a/.project | ||
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<projectDescription> | ||
| 3 | + <name>serial-port-cpp</name> | ||
| 4 | + <comment></comment> | ||
| 5 | + <projects> | ||
| 6 | + </projects> | ||
| 7 | + <buildSpec> | ||
| 8 | + <buildCommand> | ||
| 9 | + <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name> | ||
| 10 | + <triggers>clean,full,incremental,</triggers> | ||
| 11 | + <arguments> | ||
| 12 | + </arguments> | ||
| 13 | + </buildCommand> | ||
| 14 | + <buildCommand> | ||
| 15 | + <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name> | ||
| 16 | + <triggers>full,incremental,</triggers> | ||
| 17 | + <arguments> | ||
| 18 | + </arguments> | ||
| 19 | + </buildCommand> | ||
| 20 | + </buildSpec> | ||
| 21 | + <natures> | ||
| 22 | + <nature>org.eclipse.cdt.core.cnature</nature> | ||
| 23 | + <nature>org.eclipse.cdt.core.ccnature</nature> | ||
| 24 | + <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature> | ||
| 25 | + <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature> | ||
| 26 | + </natures> | ||
| 27 | +</projectDescription> |
README.rst
0 → 100644
| 1 | +++ a/README.rst | ||
| 1 | +============================================================== | ||
| 2 | +serial-port-cpp | ||
| 3 | +============================================================== | ||
| 4 | + | ||
| 5 | +---------------------------------- | ||
| 6 | +Serial port library written in C++ | ||
| 7 | +---------------------------------- | ||
| 8 | + | ||
| 9 | +.. image:: https://api.travis-ci.org/gbmhunter/serial-port-cpp.png?branch=master | ||
| 10 | + :target: https://travis-ci.org/gbmhunter/serial-port-cpp | ||
| 11 | + | ||
| 12 | +- Author: gbmhunter <gbmhunter@gmail.com> (http://www.cladlab.com) | ||
| 13 | +- Created: 2014/01/07 | ||
| 14 | +- Last Modified: 2014/05/15 | ||
| 15 | +- Version: v1.0.0.0 | ||
| 16 | +- Company: CladLabs | ||
| 17 | +- Project: Free Code Libraries | ||
| 18 | +- Language: C++ | ||
| 19 | +- Compiler: GCC | ||
| 20 | +- uC Model: n/a | ||
| 21 | +- Computer Architecture: n/a | ||
| 22 | +- Operating System: n/a | ||
| 23 | +- Documentation Format: Doxygen | ||
| 24 | +- License: GPLv3 | ||
| 25 | + | ||
| 26 | +.. role:: bash(code) | ||
| 27 | + :language: bash | ||
| 28 | + | ||
| 29 | +Description | ||
| 30 | +=========== | ||
| 31 | + | ||
| 32 | +Library for communicating with COM ports on a Linux system. | ||
| 33 | + | ||
| 34 | +Uses fstream to the file I/O. | ||
| 35 | + | ||
| 36 | +Installation | ||
| 37 | +============ | ||
| 38 | + | ||
| 39 | +1. Clone the git repo onto your local storage. | ||
| 40 | + | ||
| 41 | +2. Run `make all` to compile and run unit tests. Do not worry about error messages being printed when unit tests are run, the unit tests are designed to specifically cause errors to test the response. | ||
| 42 | + | ||
| 43 | +3. To include serial-port-cpp into your embedded (or otherwise) firmware/software project, copy the repo into your project folder (or other suitable place), include the file "/api/SerialPortApi.hpp" from your C++ code, and make sure to compile all the files within "/src/". | ||
| 44 | + | ||
| 45 | + | ||
| 46 | +Dependencies | ||
| 47 | +============ | ||
| 48 | + | ||
| 49 | +The following table lists all of the libraries dependencies. | ||
| 50 | + | ||
| 51 | +====================== ==================== ====================================================================== | ||
| 52 | +Dependency Delivery Usage | ||
| 53 | +====================== ==================== ====================================================================== | ||
| 54 | +<stdio.h> Standard C library snprintf() | ||
| 55 | +====================== ==================== ====================================================================== | ||
| 56 | + | ||
| 57 | +Issues | ||
| 58 | +====== | ||
| 59 | + | ||
| 60 | +See GitHub Issues. | ||
| 61 | + | ||
| 62 | +Usage | ||
| 63 | +===== | ||
| 64 | + | ||
| 65 | +In main.c add... | ||
| 66 | + | ||
| 67 | +:: | ||
| 68 | + | ||
| 69 | + | ||
| 70 | + | ||
| 71 | + | ||
| 72 | + int main() | ||
| 73 | + { | ||
| 74 | + | ||
| 75 | + | ||
| 76 | + } | ||
| 77 | + | ||
| 78 | + | ||
| 79 | + | ||
| 80 | +FAQ | ||
| 81 | +=== | ||
| 82 | + | ||
| 83 | +1. My code stalls when calling functions like :code:`SerialPort::Read()`. This is probably because the library is set up to do a blocking read, and not enough characters have been received to allow :code:`SerialPort::Read()` to return. Use :code:`SerialPort::SetNumCharsToWait()` to determine how many characters to wait for before returning (set to 0 for non-blocking mode). | ||
| 84 | + | ||
| 85 | + | ||
| 86 | +Changelog | ||
| 87 | +========= | ||
| 88 | + | ||
| 89 | +========= ========== =================================================================================================== | ||
| 90 | +Version Date Comment | ||
| 91 | +========= ========== =================================================================================================== | ||
| 92 | +v1.0.0.0 2013/05/15 Initial commit. serial-port-cpp library has basic functions up and running. | ||
| 93 | +========= ========== =================================================================================================== | ||
| 0 | \ No newline at end of file | 94 | \ No newline at end of file |
api/SerialPortApi.hpp
0 → 100644
| 1 | +++ a/api/SerialPortApi.hpp | ||
| 1 | +//! | ||
| 2 | +//! @file SerialPortApi.hpp | ||
| 3 | +//! @author Geoffrey Hunter <gbmhunter@gmail.com> (www.cladlab.com) | ||
| 4 | +//! @created 2014/05/15 | ||
| 5 | +//! @last-modified 2014/05/15 | ||
| 6 | +//! @brief File which contains all the API definitions needed to use the serial-port-cpp library. | ||
| 7 | +//! @details | ||
| 8 | +//! See README.rst in repo root dir for more info. | ||
| 9 | + | ||
| 10 | +// Header guard | ||
| 11 | +#ifndef SERIAL_PORT_SERIAL_PORT_API_H | ||
| 12 | +#define SERIAL_PORT_SERIAL_PORT_API_H | ||
| 13 | + | ||
| 14 | +// User headers | ||
| 15 | +#include "../include/SerialPort.hpp" | ||
| 16 | + | ||
| 17 | +#endif // #ifndef SERIAL_PORT_SERIAL_PORT_API_H |
include/Config.hpp
0 → 100644
| 1 | +++ a/include/Config.hpp | ||
| 1 | +//! | ||
| 2 | +//! @file Config.hpp | ||
| 3 | +//! @author Geoffrey Hunter <gbmhunter@gmail.com> () | ||
| 4 | +//! @created 2014/01/07 | ||
| 5 | +//! @last-modified 2014/01/07 | ||
| 6 | +//! @brief Config file for the ComPort library. | ||
| 7 | +//! @details | ||
| 8 | +//! See README.rst in repo root dir for more info. | ||
| 9 | + | ||
| 10 | + | ||
| 11 | +namespace SerialPort | ||
| 12 | +{ | ||
| 13 | + | ||
| 14 | + | ||
| 15 | +} |
include/SerialPort.hpp
0 → 100644
| 1 | +++ a/include/SerialPort.hpp | ||
| 1 | +//! | ||
| 2 | +//! @file SerialPort.hpp | ||
| 3 | +//! @author Geoffrey Hunter <gbmhunter@gmail.com> () | ||
| 4 | +//! @created 2014/01/07 | ||
| 5 | +//! @last-modified 2014/05/14 | ||
| 6 | +//! @brief The main serial port class. | ||
| 7 | +//! @details | ||
| 8 | +//! See README.rst in repo root dir for more info. | ||
| 9 | + | ||
| 10 | +// Header guard | ||
| 11 | +#ifndef SERIAL_PORT_SERIAL_PORT_H | ||
| 12 | +#define SERIAL_PORT_SERIAL_PORT_H | ||
| 13 | + | ||
| 14 | +// System headers | ||
| 15 | +#include <fstream> // For file I/O (reading/writing to COM port) | ||
| 16 | +#include <sstream> | ||
| 17 | +#include <termios.h> // POSIX terminal control definitions (struct termios) | ||
| 18 | + | ||
| 19 | +// User headers | ||
| 20 | +#include "lib/SmartPrint/include/Sp.hpp" | ||
| 21 | + | ||
| 22 | +namespace SerialPort | ||
| 23 | +{ | ||
| 24 | + | ||
| 25 | + //! @brief Strongly-typed enumeration of baud rates for use with the SerialPort class | ||
| 26 | + enum class BaudRates | ||
| 27 | + { | ||
| 28 | + none, | ||
| 29 | + b9600, | ||
| 30 | + b57600 | ||
| 31 | + }; | ||
| 32 | + | ||
| 33 | + //! @brief SerialPort object is used to perform rx/tx serial communication. | ||
| 34 | + class SerialPort | ||
| 35 | + { | ||
| 36 | + | ||
| 37 | + public: | ||
| 38 | + | ||
| 39 | + //! @brief Constructor | ||
| 40 | + SerialPort(); | ||
| 41 | + | ||
| 42 | + //! @brief Destructor | ||
| 43 | + virtual ~SerialPort(); | ||
| 44 | + | ||
| 45 | + //! @brief Sets the file path to use for communications. The file path must be set before Open() is called, otherwise Open() will return an error. | ||
| 46 | + void SetFilePath(std::string filePath); | ||
| 47 | + | ||
| 48 | + void SetBaudRate(BaudRates baudRate); | ||
| 49 | + | ||
| 50 | + //! @brief Controls what happens when Read() is called. | ||
| 51 | + //! @param numOfCharToWait Minimum number of characters to wait for before returning. Set to 0 for non-blocking mode. | ||
| 52 | + void SetNumCharsToWait(uint32_t numCharsToWait); | ||
| 53 | + | ||
| 54 | + //! @brief Opens the COM port for use. | ||
| 55 | + //! @throws {std::runtime_error} if filename has not been set. | ||
| 56 | + //! {std::system_error} if system open() operation fails. | ||
| 57 | + //! @note Must call this before you can configure the COM port. | ||
| 58 | + void Open(); | ||
| 59 | + | ||
| 60 | + //! @brief Sets all settings for the com port to common defaults. | ||
| 61 | + void SetEverythingToCommonDefaults(); | ||
| 62 | + | ||
| 63 | + //! @brief Closes the COM port. | ||
| 64 | + void Close(); | ||
| 65 | + | ||
| 66 | + //! @brief Sends a message over the com port. | ||
| 67 | + //! @param str Reference to an string containing the characters to write to the COM port. | ||
| 68 | + //! @throws {std::runtime_error} if filename has not been set. | ||
| 69 | + //! {std::system_error} if system write() operation fails. | ||
| 70 | + void Write(std::string* str); | ||
| 71 | + | ||
| 72 | + //! @brief Use to read from the COM port. | ||
| 73 | + //! @param str Reference to a string that the read characters from the COM port will be saved to. | ||
| 74 | + //! @throws {std::runtime_error} if filename has not been set. | ||
| 75 | + //! {std::system_error} if system read() operation fails. | ||
| 76 | + void Read(std::string* str); | ||
| 77 | + | ||
| 78 | + private: | ||
| 79 | + | ||
| 80 | + std::string filePath; | ||
| 81 | + | ||
| 82 | + BaudRates baudRate; | ||
| 83 | + | ||
| 84 | + //! @brief The file descriptor for the open file. This gets written to when Open() is called. | ||
| 85 | + int fileDesc; | ||
| 86 | + | ||
| 87 | + //! @brief Object for printing debug and error messages with | ||
| 88 | + SmartPrint::Sp* sp; | ||
| 89 | + | ||
| 90 | + //! @brief Returns a populated termios structure for the passed in file descriptor. | ||
| 91 | + termios GetTermios(); | ||
| 92 | + | ||
| 93 | + void SetTermios(termios myTermios); | ||
| 94 | + | ||
| 95 | + }; | ||
| 96 | + | ||
| 97 | +} // namespace SerialPort | ||
| 98 | + | ||
| 99 | +#endif // #ifndef SERIAL_PORT_SERIAL_PORT_H |
src/SerialPort.cpp
0 → 100644
| 1 | +++ a/src/SerialPort.cpp | ||
| 1 | +//! | ||
| 2 | +//! @file SerialPort.cpp | ||
| 3 | +//! @author Geoffrey Hunter <gbmhunter@gmail.com> () | ||
| 4 | +//! @created 2014/01/07 | ||
| 5 | +//! @last-modified 2014/05/15 | ||
| 6 | +//! @brief The main serial port class. | ||
| 7 | +//! @details | ||
| 8 | +//! See README.rst in repo root dir for more info. | ||
| 9 | + | ||
| 10 | +#include <iostream> | ||
| 11 | +#include <sstream> | ||
| 12 | +#include <stdio.h> // Standard input/output definitions | ||
| 13 | +#include <string.h> // String function definitions | ||
| 14 | +#include <unistd.h> // UNIX standard function definitions | ||
| 15 | +#include <fcntl.h> // File control definitions | ||
| 16 | +#include <errno.h> // Error number definitions | ||
| 17 | +#include <termios.h> // POSIX terminal control definitions (struct termios) | ||
| 18 | +#include <system_error> // For throwing std::system_error | ||
| 19 | + | ||
| 20 | +#include "../include/Config.hpp" | ||
| 21 | +#include "../include/SerialPort.hpp" | ||
| 22 | +#include "lib/SmartPrint/api/SmartPrint.hpp" | ||
| 23 | + | ||
| 24 | +namespace SerialPort | ||
| 25 | +{ | ||
| 26 | + | ||
| 27 | + SerialPort::SerialPort() : | ||
| 28 | + filePath(std::string()), | ||
| 29 | + baudRate(BaudRates::none), | ||
| 30 | + fileDesc(0), | ||
| 31 | + sp( | ||
| 32 | + new SmartPrint::Sp( | ||
| 33 | + "Port", | ||
| 34 | + &std::cout, | ||
| 35 | + &SmartPrint::Colours::yellow, | ||
| 36 | + &std::cout, | ||
| 37 | + &SmartPrint::Colours::yellow, | ||
| 38 | + &std::cerr, | ||
| 39 | + &SmartPrint::Colours::red)) | ||
| 40 | + { | ||
| 41 | + // Everything setup in initialiser list | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + SerialPort::~SerialPort() | ||
| 45 | + { | ||
| 46 | + | ||
| 47 | + } | ||
| 48 | + | ||
| 49 | + void SerialPort::SetFilePath(std::string filePath) | ||
| 50 | + { | ||
| 51 | + // Save a pointer to the file path | ||
| 52 | + this->filePath = filePath; | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + void SerialPort::SetBaudRate(BaudRates baudRate) | ||
| 56 | + { | ||
| 57 | + | ||
| 58 | + // Get current termios struct | ||
| 59 | + termios myTermios = this->GetTermios(); | ||
| 60 | + | ||
| 61 | + switch(baudRate) | ||
| 62 | + { | ||
| 63 | + case BaudRates::none: | ||
| 64 | + // Error, baud rate has not been set yet | ||
| 65 | + throw std::runtime_error("Baud rate for '" + this->filePath + "' cannot be set to none."); | ||
| 66 | + break; | ||
| 67 | + case BaudRates::b9600: | ||
| 68 | + cfsetispeed(&myTermios, B9600); | ||
| 69 | + cfsetospeed(&myTermios, B9600); | ||
| 70 | + break; | ||
| 71 | + case BaudRates::b57600: | ||
| 72 | + cfsetispeed(&myTermios, B57600); | ||
| 73 | + cfsetospeed(&myTermios, B57600); | ||
| 74 | + break; | ||
| 75 | + } | ||
| 76 | + | ||
| 77 | + // Save back to file | ||
| 78 | + this->SetTermios(myTermios); | ||
| 79 | + | ||
| 80 | + // Setting the baudrate must of been successful, so we can now store this | ||
| 81 | + // new value internally. This must be done last! | ||
| 82 | + this->baudRate = baudRate; | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | + void SerialPort::Open() | ||
| 86 | + { | ||
| 87 | + | ||
| 88 | + this->sp->PrintDebug(SmartPrint::Ss() << "Attempting to open COM port \"" << this->filePath << "\"."); | ||
| 89 | + | ||
| 90 | + if(this->filePath.size() == 0) | ||
| 91 | + { | ||
| 92 | + //this->sp->PrintError(SmartPrint::Ss() << "Attempted to open file when file path has not been assigned to."); | ||
| 93 | + //return false; | ||
| 94 | + | ||
| 95 | + throw std::runtime_error("Attempted to open file when file path has not been assigned to."); | ||
| 96 | + } | ||
| 97 | + | ||
| 98 | + // Attempt to open file | ||
| 99 | + //this->fileDesc = open(this->filePath, O_RDWR | O_NOCTTY | O_NDELAY); | ||
| 100 | + | ||
| 101 | + // O_RDONLY for read-only, O_WRONLY for write only, O_RDWR for both read/write access | ||
| 102 | + // 3rd, optional parameter is mode_t mode | ||
| 103 | + this->fileDesc = open(this->filePath.c_str(), O_RDWR); | ||
| 104 | + | ||
| 105 | + // Check status | ||
| 106 | + if (this->fileDesc == -1) | ||
| 107 | + { | ||
| 108 | + // Could not open COM port | ||
| 109 | + //this->sp->PrintError(SmartPrint::Ss() << "Unable to open " << this->filePath << " - " << strerror(errno)); | ||
| 110 | + //return false; | ||
| 111 | + | ||
| 112 | + throw std::system_error(EFAULT, std::system_category()); | ||
| 113 | + } | ||
| 114 | + | ||
| 115 | + this->sp->PrintDebug(SmartPrint::Ss() << "COM port opened successfully."); | ||
| 116 | + | ||
| 117 | + // If code reaches here, open and config must of been successful | ||
| 118 | + | ||
| 119 | + } | ||
| 120 | + | ||
| 121 | + void SerialPort::SetEverythingToCommonDefaults() | ||
| 122 | + { | ||
| 123 | + this->sp->PrintDebug(SmartPrint::Ss() << "Configuring COM port \"" << this->filePath << "\"."); | ||
| 124 | + | ||
| 125 | + //================== CONFIGURE ==================// | ||
| 126 | + | ||
| 127 | + termios tty = this->GetTermios(); | ||
| 128 | + /*struct termios tty; | ||
| 129 | + memset(&tty, 0, sizeof(tty)); | ||
| 130 | + | ||
| 131 | + // Get current settings (will be stored in termios structure) | ||
| 132 | + if(tcgetattr(this->fileDesc, &tty) != 0) | ||
| 133 | + { | ||
| 134 | + // Error occurred | ||
| 135 | + this->sp->PrintError(SmartPrint::Ss() << "Could not get terminal attributes for \"" << this->filePath << "\" - " << strerror(errno)); | ||
| 136 | + //return false; | ||
| 137 | + return; | ||
| 138 | + }*/ | ||
| 139 | + | ||
| 140 | + //========================= SET UP BAUD RATES =========================// | ||
| 141 | + | ||
| 142 | + this->SetBaudRate(BaudRates::b57600); | ||
| 143 | + | ||
| 144 | + /* | ||
| 145 | + switch(this->baudRate) | ||
| 146 | + { | ||
| 147 | + case BaudRates::none: | ||
| 148 | + // Error, baud rate has not been set yet | ||
| 149 | + this->sp->PrintError(SmartPrint::Ss() << "Baud rate for \"" << this->filePath << "\" has not been set."); | ||
| 150 | + return; | ||
| 151 | + case BaudRates::b9600: | ||
| 152 | + cfsetispeed(&tty, B9600); | ||
| 153 | + cfsetospeed(&tty, B9600); | ||
| 154 | + break; | ||
| 155 | + case BaudRates::b57600: | ||
| 156 | + cfsetispeed(&tty, B57600); | ||
| 157 | + cfsetospeed(&tty, B57600); | ||
| 158 | + break; | ||
| 159 | + }*/ | ||
| 160 | + | ||
| 161 | + //================= (.c_cflag) ===============// | ||
| 162 | + | ||
| 163 | + tty.c_cflag &= ~PARENB; // No parity bit is added to the output characters | ||
| 164 | + tty.c_cflag &= ~CSTOPB; // Only one stop-bit is used | ||
| 165 | + tty.c_cflag &= ~CSIZE; // CSIZE is a mask for the number of bits per character | ||
| 166 | + tty.c_cflag |= CS8; // Set to 8 bits per character | ||
| 167 | + tty.c_cflag &= ~CRTSCTS; // Disable hadrware flow control (RTS/CTS) | ||
| 168 | + tty.c_cflag |= CREAD | CLOCAL; // Turn on READ & ignore ctrl lines (CLOCAL = 1) | ||
| 169 | + | ||
| 170 | + | ||
| 171 | + //===================== (.c_oflag) =================// | ||
| 172 | + | ||
| 173 | + tty.c_oflag = 0; // No remapping, no delays | ||
| 174 | + tty.c_oflag &= ~OPOST; // Make raw | ||
| 175 | + | ||
| 176 | + //================= CONTROL CHARACTERS (.c_cc[]) ==================// | ||
| 177 | + | ||
| 178 | + // c_cc[WMIN] sets the number of characters to block (wait) for when read() is called. | ||
| 179 | + // Set to 0 if you don't want read to block. Only meaningful when port set to non-canonical mode | ||
| 180 | + //tty.c_cc[VMIN] = 1; | ||
| 181 | + this->SetNumCharsToWait(1); | ||
| 182 | + | ||
| 183 | + // c_cc[VTIME] sets the inter-character timer, in units of 0.1s. | ||
| 184 | + // Only meaningful when port is set to non-canonical mode | ||
| 185 | + tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout | ||
| 186 | + | ||
| 187 | + | ||
| 188 | + //======================== (.c_iflag) ====================// | ||
| 189 | + | ||
| 190 | + tty.c_iflag &= ~(IXON | IXOFF | IXANY); // Turn off s/w flow ctrl | ||
| 191 | + tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL); | ||
| 192 | + | ||
| 193 | + //=========================== LOCAL MODES (c_lflag) =======================// | ||
| 194 | + | ||
| 195 | + // Canonical input is when read waits for EOL or EOF characters before returning. In non-canonical mode, the rate at which | ||
| 196 | + // read() returns is instead controlled by c_cc[VMIN] and c_cc[VTIME] | ||
| 197 | + tty.c_lflag &= ~ICANON; // Turn off canonical input, which is suitable for pass-through | ||
| 198 | + tty.c_lflag &= ~ECHO; // Turn off echo | ||
| 199 | + tty.c_lflag &= ~ECHOE; // Turn off echo erase (echo erase only relevant if canonical input is active) | ||
| 200 | + tty.c_lflag &= ~ECHONL; // | ||
| 201 | + tty.c_lflag &= ~ISIG; // Disables recognition of INTR (interrupt), QUIT and SUSP (suspend) characters | ||
| 202 | + | ||
| 203 | + // Try and use raw function call | ||
| 204 | + //cfmakeraw(&tty); | ||
| 205 | + | ||
| 206 | + this->SetTermios(tty); | ||
| 207 | + | ||
| 208 | + /* | ||
| 209 | + // Flush port, then apply attributes | ||
| 210 | + tcflush(this->fileDesc, TCIFLUSH); | ||
| 211 | + | ||
| 212 | + if(tcsetattr(this->fileDesc, TCSANOW, &tty) != 0) | ||
| 213 | + { | ||
| 214 | + // Error occurred | ||
| 215 | + this->sp->PrintError(SmartPrint::Ss() << "Could not apply terminal attributes for \"" << this->filePath << "\" - " << strerror(errno)); | ||
| 216 | + return; | ||
| 217 | + }*/ | ||
| 218 | + } | ||
| 219 | + | ||
| 220 | + void SerialPort::SetNumCharsToWait(uint32_t numCharsToWait) | ||
| 221 | + { | ||
| 222 | + // Get current termios struct | ||
| 223 | + termios myTermios = this->GetTermios(); | ||
| 224 | + | ||
| 225 | + // Save the number of characters to wait for | ||
| 226 | + // to the control register | ||
| 227 | + myTermios.c_cc[VMIN] = numCharsToWait; | ||
| 228 | + | ||
| 229 | + // Save termios back | ||
| 230 | + this->SetTermios(myTermios); | ||
| 231 | + } | ||
| 232 | + | ||
| 233 | + void SerialPort::Write(std::string* str) | ||
| 234 | + { | ||
| 235 | + if(this->fileDesc == 0) | ||
| 236 | + { | ||
| 237 | + //this->sp->PrintError(SmartPrint::Ss() << ); | ||
| 238 | + //return false; | ||
| 239 | + | ||
| 240 | + throw std::runtime_error("SendMsg called but file descriptor (fileDesc) was 0, indicating file has not been opened."); | ||
| 241 | + } | ||
| 242 | + | ||
| 243 | + int writeResult = write(this->fileDesc, str->c_str(), str->size()); | ||
| 244 | + | ||
| 245 | + // Check status | ||
| 246 | + if (writeResult == -1) | ||
| 247 | + { | ||
| 248 | + // Could not open COM port | ||
| 249 | + //this->sp->PrintError(SmartPrint::Ss() << "Unable to write to \"" << this->filePath << "\" - " << strerror(errno)); | ||
| 250 | + //return false; | ||
| 251 | + | ||
| 252 | + throw std::system_error(EFAULT, std::system_category()); | ||
| 253 | + } | ||
| 254 | + | ||
| 255 | + // If code reaches here than write must of been successful | ||
| 256 | + } | ||
| 257 | + | ||
| 258 | + void SerialPort::Read(std::string* str) | ||
| 259 | + { | ||
| 260 | + if(this->fileDesc == 0) | ||
| 261 | + { | ||
| 262 | + //this->sp->PrintError(SmartPrint::Ss() << "Read() was called but file descriptor (fileDesc) was 0, indicating file has not been opened."); | ||
| 263 | + //return false; | ||
| 264 | + throw std::runtime_error("Read() was called but file descriptor (fileDesc) was 0, indicating file has not been opened."); | ||
| 265 | + } | ||
| 266 | + | ||
| 267 | + // Allocate memory for read buffer | ||
| 268 | + char buf [256]; | ||
| 269 | + memset (&buf, '\0', sizeof buf); | ||
| 270 | + | ||
| 271 | + // Read from file | ||
| 272 | + int n = read(this->fileDesc, &buf, sizeof(buf)); | ||
| 273 | + | ||
| 274 | + // Error Handling | ||
| 275 | + if(n < 0) | ||
| 276 | + { | ||
| 277 | + // Could not open COM port | ||
| 278 | + //this->sp->PrintError(SmartPrint::Ss() << "Unable to read from \"" << this->filePath << "\" - " << strerror(errno)); | ||
| 279 | + //return false; | ||
| 280 | + | ||
| 281 | + throw std::system_error(EFAULT, std::system_category()); | ||
| 282 | + } | ||
| 283 | + | ||
| 284 | + if(n > 0) | ||
| 285 | + { | ||
| 286 | + //this->sp->PrintDebug(SmartPrint::Ss() << "\"" << n << "\" characters have been read from \"" << this->filePath << "\""); | ||
| 287 | + // Characters have been read | ||
| 288 | + buf[n] = '\0'; | ||
| 289 | + //printf("%s\r\n", buf); | ||
| 290 | + str->append(buf); | ||
| 291 | + //std::cout << *str << " and size of string =" << str->size() << "\r\n"; | ||
| 292 | + } | ||
| 293 | + | ||
| 294 | + // If code reaches here, read must of been successful | ||
| 295 | + } | ||
| 296 | + | ||
| 297 | + termios SerialPort::GetTermios() | ||
| 298 | + { | ||
| 299 | + struct termios tty; | ||
| 300 | + memset(&tty, 0, sizeof(tty)); | ||
| 301 | + | ||
| 302 | + // Get current settings (will be stored in termios structure) | ||
| 303 | + if(tcgetattr(this->fileDesc, &tty) != 0) | ||
| 304 | + { | ||
| 305 | + // Error occurred | ||
| 306 | + this->sp->PrintError(SmartPrint::Ss() << "Could not get terminal attributes for \"" << this->filePath << "\" - " << strerror(errno)); | ||
| 307 | + throw std::system_error(EFAULT, std::system_category()); | ||
| 308 | + //return false; | ||
| 309 | + } | ||
| 310 | + | ||
| 311 | + return tty; | ||
| 312 | + } | ||
| 313 | + | ||
| 314 | + void SerialPort::SetTermios(termios myTermios) | ||
| 315 | + { | ||
| 316 | + // Flush port, then apply attributes | ||
| 317 | + tcflush(this->fileDesc, TCIFLUSH); | ||
| 318 | + | ||
| 319 | + if(tcsetattr(this->fileDesc, TCSANOW, &myTermios) != 0) | ||
| 320 | + { | ||
| 321 | + // Error occurred | ||
| 322 | + this->sp->PrintError(SmartPrint::Ss() << "Could not apply terminal attributes for \"" << this->filePath << "\" - " << strerror(errno)); | ||
| 323 | + throw std::system_error(EFAULT, std::system_category()); | ||
| 324 | + | ||
| 325 | + } | ||
| 326 | + | ||
| 327 | + // Successful! | ||
| 328 | + } | ||
| 329 | + | ||
| 330 | +} // namespace ComPort |