CSerialPort Tutorial 4.3.x (2) - Introduction to CSerialPort Source Code

CSerialPort Tutorial 4.3.x (2) - Introduction to CSerialPort Source Code

foreword

The CSerialPort project is a lightweight open source cross-platform serial port class library based on C/C++, which can easily realize serial port reading and writing across platforms and multiple operating systems, and also supports C#, Java, Python, Node.js, etc.

The open source protocol of the CSerialPort project has adopted the GNU Lesser General Public License v3.0 since version V3.0.0.171216

In order to allow developers to better use CSerialPort for development, a CSerialPort tutorial series based on version 4.3.x is specially written.

CSerialPort project address:

This article CSerialPort 4.3.0introduces the version source code.

1. CSerialPort source directory structure

CSerialPort # root
+--- .clang-format # code format 代码规范
├── bindings # 第三方语言接口
│   ├── c # c interface c接口
│   ├── csharp # csharp interface c#接口
│   ├── java # java interface java接口
│   ├── javascript # javascript interface javascript接口
│   └── python # python interface python接口
├── CHANGELOG.md # change log 修改日志
├── cmake # cross compile 交叉编译
├── CMakeLists.txt
├── doc # document 文档
├── examples # example 示例程序
│   ├── CommMFC # CSerialPort MFC Demo MFC程序示例
│   ├── CommNoGui # CSerialPort No Gui Demo 无界面程序示例
│   ├── CommQT # CSerialPort QT Demo QT程序示例
│   ├── CommTui # CSerialPort tui Demo 文本界面程序示例
│   ├── CommWXWidgets # CSerialPort wxwidgets Demo wxwidgets界面程序示例
├── include # headers 头文件
│   └── CSerialPort
│       ├── ibuffer.hpp # lightweight cross-platform buffer library 轻量级跨平台缓冲区类
│       ├── ithread.hpp # lightweight cross-platform thread library 轻量级跨平台线程类
│       ├── itimer.hpp # lightweight cross-platform timer library 轻量级跨平台定时器类
│       ├── iutils.hpp # lightweight cross-platform utils library 轻量级跨平台工具类
│       ├── SerialPortBase.h # CSerialPort Base class 串口基类
│       ├── SerialPort_global.h # Global difine of CSerialPort 串口全局定义 
│       ├── SerialPort.h # lightweight cross-platform serial port library 轻量级跨平台串口类库
│       ├── SerialPortInfoBase.h # CSerialPortInfo Base class 串口信息辅助类基类
│       ├── SerialPortInfo.h # CSerialPortInfo class 串口信息辅助类
│       ├── SerialPortInfoUnixBase.h # CSerialPortInfo unix class unix串口信息辅助类基类
│       ├── SerialPortInfoWinBase.h # CSerialPortInfo windows class windows串口信息辅助类基类
│       ├── SerialPortListener.h # CSerialPortListener interface class 串口事件监听接口类
│       ├── SerialPortUnixBase.h # CSerialPort unix Base class unix串口基类
│       ├── SerialPort_version.h # CSerialPort version 版本定义
│       └── SerialPortWinBase.h # CSerialPort Windows Base class windows串口基类
├── lib # lib 库目录
├── LICENSE # LGPL3.0 license
├── pic # picture 图片
├── README.md
├── README_zh_CN.md
├── src # source 源代码
├── test # unit test 单元测试
└── VERSION # version 版本号

2. Common functions of CSerialPort

2.1 Serial port information related functions

2.1.1 Get serial port information list function availablePortInfos

This function obtains a list of serial port information, mainly including:

  • Serial port name (such as COM2)
  • Description information (such as USB-SERIAL CH340)
  • Hardware id (such as USB\VID_1A86&PID_7523&REV_0264)
static vector<SerialPortInfo> itas109::CSerialPortInfo::availablePortInfos()

2.2 Serial port operation related functions

2.2.1 Serial port initialization function init

This function is used for serial port initialization.

void itas109::CSerialPort::init(const char *portName,                                 // 串口名称 Windows:COM1 Linux:/dev/ttyS0
                                int baudRate = itas109::BaudRate9600,                 // 波特率
                                itas109::Parity parity = itas109::ParityNone,         // 校验位
                                itas109::DataBits dataBits = itas109::DataBits8,      // 数据位
                                itas109::StopBits stopbits = itas109::StopOne,        // 停止位
                                itas109::FlowControl flowControl = itas109::FlowNone, // 流控制
                                unsigned int readBufferSize = 4096                    // 读取缓冲区大小
)

Notice:

  • 5 data bits cannot use 2 stop bits
  • 1.5 stop bits cannot use 5 data bits
  • The 8-bit data bit of the POSIX system cannot use 0 parity
  • The range of windows data bits is 4 - 8
  • 1.5 stop bits only valid for windows
  • The stop bit number 1 means StopOneAndHalf, that is, 1.5 stop bits, not 1 stop bit

2.2.2 Open serial port function open

This function is used to open the serial port.

bool itas109::CSerialPort::open()

true indicates that the opening is successful, and false indicates that the opening fails.

Open failure can be used itas109::CSerialPort::getLastError()to obtain the error code

2.2.3 Close the serial port function close

This function is used to close the serial port.

void itas109::CSerialPort::close()

2.2.4 Whether to open the serial port success function isOpen

This function is used to get whether the serial port is opened successfully.

bool itas109::CSerialPort::isOpen()

true indicates that the serial port is successfully opened, and false indicates that the serial port fails to be opened.

2.2.5 Write data function writeData to the serial port

This function is used to write data to the serial port.

int itas109::CSerialPort::writeData(const void *data, // 待写入数据
                                    int maxSize       // 写入长度
)

Returns the number of bytes written on success, and -1 on failure.

If writing fails, you can itas109::CSerialPort::getLastError()get the error code.

2.2.6 Read the specified length data function readData from the serial port

This function is used to read specified length data from the serial port.

int readData(void *data,  // 读取结果
             int size     // 读取长度
)

If it is normal, it will return the number of bytes read, and if it fails, it will return -1.

The error code can itas109::CSerialPort::getLastError()be obtained if the reading fails.

Note:
In the asynchronous operation mode of CSerialPort, it needs to connectReadEventbe used with the function. See the code example in Section 3 for details.

2.2.7 Read all data function readAllData from the serial port

This function is used to read all data from the serial port.

int itas109::CSerialPort::readAllData(void *data // 读取结果
)

If it is normal, it will return the number of bytes read, and if it fails, it will return -1.

The error code can itas109::CSerialPort::getLastError()be obtained if the reading fails.

Note:
In the asynchronous operation mode of CSerialPort, it needs to connectReadEventbe used with the function. See the code example in Section 3 for details.

2.2.8 Binding read event function connectReadEvent

This function is used in asynchronous mode (default) to bind the result of reading the response.

Need to inherit CSerialPortListener and implement the onReadEvent virtual function. See the code example in Section 3 for details.

class MyListener : public CSerialPortListener
{
public:
    void onReadEvent(const char *portName, unsigned int readBufferLen)
    {
    }
}

2.2.9 Get CSerialPort version information function getVersion

This function is used to get CSerialPort version information.

std::string itas109::CSerialPort::getVersion()

Return CSerialPort version information, such ashttps://github.com/itas109/CSerialPort - V4.3.0.230215

2.2.10 Error code SerialPortError

error code value Error code macro definition Error Code Description
-1 ErrorUnknown unknown error unknown error
0 Error OK ok success
1 ErrorFail general error general error
2 ErrorNotImplemented not implemented not implemented
3 ErrorInner inner error Internal error (such as memory access exception, etc.)
4 ErrorNullPointer null pointer error null pointer error
5 ErrorInvalidParam invalid parameter error invalid parameter
6 ErrorAccessDenied access denied error permission error
7 ErrorOutOfMemory out of memory insufficient memory
8 ErrorTimeout time out error time out
9 ErrorNotInit not init not initialized
10 ErrorInitFailed init failed initialization failed
11 ErrorAlreadyExist already exist already exists
12 ErrorNotExist not exist does not exist
13 ErrorAlreadyOpen already open already open
14 ErrorNotOpen not open not open
15 ErrorOpenFailed open failed open failed
16 ErrorCloseFailed close failed close failed
17 ErrorWriteFailed write failed write failed
18 ErrorReadFailed read failed read failed

3. CSerialPort simple code example

  • Steps
$ mkdir CSerialPortDemo
$ cd CSerialPortDemo
$ git clone https://github.com/itas109/CSerialPort
$ touch CSerialPortDemo.cpp
$ touch CMakeLists.txt
$ mkdir bin 
$ cd bin
$ cmake ..
$ cmake --build .
  • Directory Structure
$ tree
.
+--- CMakeLists.txt
+--- CSerialPort
|   +--- include
|   +--- src
|   +--- ...
+--- CSerialPortDemo.cpp
  • CSerialPortDemo.cpp

Note: The receiving function needs to inherit CSerialPortListener

#include <iostream>

#include "CSerialPort/SerialPort.h"
#include "CSerialPort/SerialPortInfo.h"

#include <vector>
using namespace itas109;
using namespace std;

class MyListener : public CSerialPortListener
{
public:
    MyListener(CSerialPort *sp)
        : p_sp(sp){};

    void onReadEvent(const char *portName, unsigned int readBufferLen)
    {
        if (readBufferLen > 0)
        {
            char *data = new char[readBufferLen + 1]; // '\0'

            if (data)
            {
                // read
                int recLen = p_sp->readData(data, readBufferLen);

                if (recLen > 0)
                {
                    data[recLen] = '\0';
                    std::cout << portName << ", Length: " << recLen << ", Str: " << data << std::endl;
                }

                delete[] data;
                data = NULL;
            }
        }
    };

private:
    CSerialPort *p_sp;
};

int main()
{
    CSerialPort sp;
    MyListener listener(&sp);

    std::cout << "Version : " << sp.getVersion() << std::endl << std::endl;

    vector<SerialPortInfo> m_availablePortsList = CSerialPortInfo::availablePortInfos();

    std::cout << "availableFriendlyPorts: " << std::endl;

    for (size_t i = 1; i <= m_availablePortsList.size(); ++i)
    {
        SerialPortInfo serialPortInfo = m_availablePortsList[i - 1];
        std::cout << i << " - " << serialPortInfo.portName << " " << serialPortInfo.description << " " << serialPortInfo.hardwareId << std::endl;
    }

    if (m_availablePortsList.size() == 0)
    {
        std::cout << "No valid port" << std::endl;
    }
    else
    {
        std::cout << std::endl;

        int input = -1;
        do
        {
            std::cout << "Please Input The Index Of Port(1 - " << m_availablePortsList.size() << ")" << std::endl;

            std::cin >> input;

            if (input >= 1 && input <= m_availablePortsList.size())
            {
                break;
            }
        } while (true);

        const char *portName = m_availablePortsList[input - 1].portName;
        std::cout << "Port Name: " << portName << std::endl;

        sp.init(portName,              // windows:COM1 Linux:/dev/ttyS0
                itas109::BaudRate9600, // baudrate
                itas109::ParityNone,   // parity
                itas109::DataBits8,    // data bit
                itas109::StopOne,      // stop bit
                itas109::FlowNone,     // flow
                4096                   // read buffer size
        );
        sp.setReadIntervalTimeout(0); // read interval timeout 0ms
        // sp.setOperateMode(itas109::SynchronousOperate);

        sp.open();
        std::cout << "Open " << portName << (sp.isOpen() ? " Success. " : " Failed. ");
        std::cout << "Code: " << sp.getLastError() << ", Message: " << sp.getLastErrorMsg() << std::endl;

        // 绑定读取函数
        sp.connectReadEvent(&listener);

        // 写入数据
        sp.writeData("itas109", 7);

        for (;;)
        {
        }
    }
    return 0;
}
  • CMakeLists.txt
cmake_minimum_required(VERSION 2.8.12)

project(CSerialPortDemo)

if(APPLE)
    find_library(IOKIT_LIBRARY IOKit)
    find_library(FOUNDATION_LIBRARY Foundation)
endif()

include_directories(CSerialPort/include)
file(GLOB_RECURSE COMMON_SOURCES CSerialPort/src/SerialPort.cpp CSerialPort/src/SerialPortBase.cpp CSerialPort/src/SerialPortInfo.cpp CSerialPort/src/SerialPortInfoBase.cpp)
if (CMAKE_HOST_WIN32)
    file(GLOB_RECURSE OS_ABOUT_SOURCES CSerialPort/src/SerialPortInfoWinBase.cpp CSerialPort/src/SerialPortWinBase.cpp)
elseif (CMAKE_HOST_UNIX)
    file(GLOB_RECURSE OS_ABOUT_SOURCES CSerialPort/src/SerialPortInfoUnixBase.cpp CSerialPort/src/SerialPortUnixBase.cpp)
endif ()	

add_executable( ${PROJECT_NAME} CSerialPortDemo.cpp ${COMMON_SOURCES} ${OS_ABOUT_SOURCES})

if (WIN32)
	target_link_libraries( ${PROJECT_NAME} setupapi )
elseif (APPLE)
    target_link_libraries( ${PROJECT_NAME} ${FOUNDATION_LIBRARY} ${IOKIT_LIBRARY})
elseif (UNIX)
	target_link_libraries( ${PROJECT_NAME} pthread )
endif ()
  • Running result (loopback test under windows)
Version : https://github.com/itas109/CSerialPort - V4.3.0.230215

availableFriendlyPorts:
1 - COM1 USB-SERIAL CH340  USB\VID_1A86&PID_7523&REV_0264

Please Input The Index Of Port(1 - 1)
1
Port Name: COM1
Open COM1 Success. Code: 0, Message: success
COM1, Length: 7, Str: itas109

License

License under CC BY-NC-ND 4.0: Attribution-Noncommercial Use-No Derivatives


Reference:

  1. https://github.com/itas109/CSerialPort
  2. https://gitee.com/itas109/CSerialPort
  3. https://blog.csdn.net/itas109

Guess you like

Origin blog.csdn.net/itas109/article/details/132389523