Qt中的串口編程之三

來源:互聯網
上載者:User

QtSerialPort

今天我們來介紹一下QtSerialPort模組的原始碼,學習一下該可移植的串口編程庫是怎麼實現的。

首先,我們下載好了原始碼之後,使用QtCreator開啟整個工程,可以看到如的原始碼結構:


我們先來看一下serialport-lib.pri這個檔案,serialport.pro工程檔案就是靠這個檔案來控制整個原始碼的編譯的。,具體內容如下:


上面的內容只是最基本的類,大家知道,跨平台的類一般在底層都包含這與作業系統相關的一些實現,這裡也不例外,大家看看下面的圖就明白了,

這裡只以類unix作業系統為例來做說明:


也許看到這個大家不是很明白:


      這與qmake的一些特性相關:CONFIG、DEFINE、PKGCONFIG都是qmake私人的一些變數,而packagesExist()則是qmake私人的函數,

整個這一塊要表達的意思是"如果udev這個庫存在,則編譯器的時候就定義HAVE_LIBUDEV這個宏定義(在我們的代碼中使用了這個宏定義),

並且連結程式的時候,也連結udev這個庫"。至於qmake的一些特性以及使用方法,後續會專門寫幾篇博文詳細介紹。

      至於udev這個庫的介紹,請見:libudev

      我們在代碼中是如下使用udev庫的:


      在serialport原始碼中還是用了另外一個開源庫,那就是lockdev,該庫主要提供的功能就是“Lockdev is a setgid binary,
which provides a reliable way to put an exclusive lock in /var/lock to devices (e.g. ttyS0) using both FSSTND and SVr4 methods,
so regular users don't need write access there.”

      下面,看看我們在代碼中是如何使用lockdev的:


      對於lockdev,我們在下一篇部落格中將詳細介紹它的功能的和實現。

 好了,言歸正傳,我們來看看serialport庫在類unix作業系統上是如何?的:

標頭檔:

與平台無關的公用標頭檔:qserialportglobal.h qserialport.h qserialportinfo.h
與平台無關的私人標頭檔:qserialport_p.h qserialportinfo_p.h
與平台有關的標頭檔:       qttylocker_unix_p.h qserialport_unix_p.h

源檔案:

與平台無關的源檔案:qserialport.cpp qserialportinfo.cpp
與平台有關的源檔案:qttylocker_unix.cpp qserialport_unix.cpp qserialportinfo_unix.cpp

原始碼解析:

1、QSerialPort類源碼解析

(1)QSerialPort類繼承自QIODevice,包含對串口的基本操作:

與該類有關係的類主要是如下幾個:

QIODevice、QSerialPort、QSerialPortPrivate、QSerialPortPrivateData。

它們的關係如下:

QSerialPort繼承自QIODevice,繼承了對裝置檔案基本的操作。

QSerialPortPrivate是QSerialPort對象中表示操作一類的,該部分與作業系統有關。QSerialPortvate繼承自QSerialPortPrivateData。

QSerialPortPrivateData是一個串口裝置的初始化資料,例如傳輸速率等等。

QSerialPortPrivateData更多表示串口裝置的初始資料,QSerialPortPrivate更多表示平台相關的對串口裝置的操作。

(2)QSerialPort類定義:

class QSerialPortInfo;class QSerialPortPrivate;class Q_SERIALPORT_EXPORT QSerialPort : public QIODevice{    Q_OBJECT    Q_PROPERTY(qint32 baudRate READ baudRate WRITE setBaudRate NOTIFY baudRateChanged)    Q_PROPERTY(DataBits dataBits READ dataBits WRITE setDataBits NOTIFY dataBitsChanged)    Q_PROPERTY(Parity parity READ parity WRITE setParity NOTIFY parityChanged)    Q_PROPERTY(StopBits stopBits READ stopBits WRITE setStopBits NOTIFY stopBitsChanged)    Q_PROPERTY(FlowControl flowControl READ flowControl WRITE setFlowControl NOTIFY flowControlChanged)    Q_PROPERTY(DataErrorPolicy dataErrorPolicy READ dataErrorPolicy WRITE setDataErrorPolicy NOTIFY dataErrorPolicyChanged)    Q_PROPERTY(bool dataTerminalReady READ isDataTerminalReady WRITE setDataTerminalReady NOTIFY dataTerminalReadyChanged)    Q_PROPERTY(bool requestToSend READ isRequestToSend WRITE setRequestToSend NOTIFY requestToSendChanged)    Q_PROPERTY(SerialPortError error READ error RESET clearError NOTIFY error)    Q_PROPERTY(bool settingsRestoredOnClose READ settingsRestoredOnClose WRITE setSettingsRestoredOnClose NOTIFY settingsRestoredOnCloseChanged)    Q_ENUMS( Directions Rate DataBits Parity StopBits FlowControl PinoutSignals DataErrorPolicy SerialPortError )public:    enum Direction  {        Input = 1,        Output = 2,        AllDirections = Input | Output    };    Q_DECLARE_FLAGS(Directions, Direction)    enum BaudRate {        Baud1200 = 1200,        Baud2400 = 2400,        Baud4800 = 4800,        Baud9600 = 9600,        Baud19200 = 19200,        Baud38400 = 38400,        Baud57600 = 57600,        Baud115200 = 115200,        UnknownBaud = -1    };    enum DataBits {        Data5 = 5,        Data6 = 6,        Data7 = 7,        Data8 = 8,        UnknownDataBits = -1    };    enum Parity {        NoParity = 0,        EvenParity = 2,        OddParity = 3,        SpaceParity = 4,        MarkParity = 5,        UnknownParity = -1    };    enum StopBits {        OneStop = 1,        OneAndHalfStop = 3,        TwoStop = 2,        UnknownStopBits = -1    };    enum FlowControl {        NoFlowControl,        HardwareControl,        SoftwareControl,        UnknownFlowControl = -1    };    enum PinoutSignal {        NoSignal = 0x00,        TransmittedDataSignal = 0x01,        ReceivedDataSignal = 0x02,        DataTerminalReadySignal = 0x04,        DataCarrierDetectSignal = 0x08,        DataSetReadySignal = 0x10,        RingIndicatorSignal = 0x20,        RequestToSendSignal = 0x40,        ClearToSendSignal = 0x80,        SecondaryTransmittedDataSignal = 0x100,        SecondaryReceivedDataSignal = 0x200    };    Q_DECLARE_FLAGS(PinoutSignals, PinoutSignal)    enum DataErrorPolicy {        SkipPolicy,        PassZeroPolicy,        IgnorePolicy,        StopReceivingPolicy,        UnknownPolicy = -1    };    enum SerialPortError {        NoError,        DeviceNotFoundError,        PermissionError,        OpenError,        ParityError,        FramingError,        BreakConditionError,        WriteError,        ReadError,        ResourceError,        UnsupportedOperationError,        UnknownError    };    explicit QSerialPort(QObject *parent = 0);    explicit QSerialPort(const QString &name, QObject *parent = 0);    explicit QSerialPort(const QSerialPortInfo &info, QObject *parent = 0);    virtual ~QSerialPort();    void setPortName(const QString &name);    QString portName() const;    void setPort(const QSerialPortInfo &info);    bool open(OpenMode mode) Q_DECL_OVERRIDE;    void close() Q_DECL_OVERRIDE;    void setSettingsRestoredOnClose(bool restore);    bool settingsRestoredOnClose() const;    bool setBaudRate(qint32 baudRate, Directions dir = AllDirections);    qint32 baudRate(Directions dir = AllDirections) const;    bool setDataBits(DataBits dataBits);    DataBits dataBits() const;    bool setParity(Parity parity);    Parity parity() const;    bool setStopBits(StopBits stopBits);    StopBits stopBits() const;    bool setFlowControl(FlowControl flow);    FlowControl flowControl() const;    bool setDataTerminalReady(bool set);    bool isDataTerminalReady();    bool setRequestToSend(bool set);    bool isRequestToSend();    PinoutSignals pinoutSignals();    bool flush();    bool clear(Directions dir = AllDirections);    bool atEnd() const Q_DECL_OVERRIDE;    bool setDataErrorPolicy(DataErrorPolicy policy = IgnorePolicy);    DataErrorPolicy dataErrorPolicy() const;    SerialPortError error() const;    void clearError();    qint64 readBufferSize() const;    void setReadBufferSize(qint64 size);    bool isSequential() const Q_DECL_OVERRIDE;    qint64 bytesAvailable() const Q_DECL_OVERRIDE;    qint64 bytesToWrite() const Q_DECL_OVERRIDE;    bool canReadLine() const Q_DECL_OVERRIDE;    bool waitForReadyRead(int msecs) Q_DECL_OVERRIDE;    bool waitForBytesWritten(int msecs) Q_DECL_OVERRIDE;    bool sendBreak(int duration = 0);    bool setBreakEnabled(bool set = true);Q_SIGNALS:    void baudRateChanged(qint32 baudRate, QSerialPort::Directions dir);    void dataBitsChanged(QSerialPort::DataBits dataBits);    void parityChanged(QSerialPort::Parity parity);    void stopBitsChanged(QSerialPort::StopBits stopBits);    void flowControlChanged(QSerialPort::FlowControl flow);    void dataErrorPolicyChanged(QSerialPort::DataErrorPolicy policy);    void dataTerminalReadyChanged(bool set);    void requestToSendChanged(bool set);    void error(QSerialPort::SerialPortError serialPortError);    void settingsRestoredOnCloseChanged(bool restore);protected:    qint64 readData(char *data, qint64 maxSize) Q_DECL_OVERRIDE;    qint64 readLineData(char *data, qint64 maxSize) Q_DECL_OVERRIDE;    qint64 writeData(const char *data, qint64 maxSize) Q_DECL_OVERRIDE;private:    void setError(QSerialPort::SerialPortError error, const QString &errorString = QString());    QSerialPortPrivate * const d_ptr;    Q_DECLARE_PRIVATE(QSerialPort)    Q_DISABLE_COPY(QSerialPort)};Q_DECLARE_OPERATORS_FOR_FLAGS(QSerialPort::Directions)Q_DECLARE_OPERATORS_FOR_FLAGS(QSerialPort::PinoutSignals)

2、QserialPortInfo類源碼解析

(1)QserialPortInfo主要是枚舉系統上可用串口裝置的資訊:

與該類的類主要是如下幾個:

QSerialPort、QSerialPortInfo、QSerialPortInfoPrivate、QSerialPortInfoPrivateDeleter。

QSerialPortInfo的建構函式中使用到了QSerialPort。

QSerialPortInfoPrivate則代表QSerialPortInfo的私人資料。

(2)QserialPortInfo類定義:

class QSerialPort;class QSerialPortInfoPrivate;class QSerialPortInfoPrivateDeleter;class Q_SERIALPORT_EXPORT QSerialPortInfo{    Q_DECLARE_PRIVATE(QSerialPortInfo)public:    QSerialPortInfo();    explicit QSerialPortInfo(const QSerialPort &port);    explicit QSerialPortInfo(const QString &name);    QSerialPortInfo(const QSerialPortInfo &other);    ~QSerialPortInfo();    QSerialPortInfo& operator=(const QSerialPortInfo &other);    void swap(QSerialPortInfo &other);    QString portName() const;    QString systemLocation() const;    QString description() const;    QString manufacturer() const;    quint16 vendorIdentifier() const;    quint16 productIdentifier() const;    bool hasVendorIdentifier() const;    bool hasProductIdentifier() const;    bool isNull() const;    bool isBusy() const;    bool isValid() const;    static QList<qint32> standardBaudRates();    static QList<QSerialPortInfo> availablePorts();private:    QScopedPointer<QSerialPortInfoPrivate, QSerialPortInfoPrivateDeleter> d_ptr;};inline bool QSerialPortInfo::isNull() const{ return !d_ptr; }

附錄:

1、qtserialport原始碼中使用了D指標,Q指標,這方面的介紹請見Qt之美(一):d指標/p指標詳解

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.