00. 目錄
文章目錄
00. 目錄01. 常見類型聲明02. 常量聲明03. _modbus結構體聲明04. modbus_backend_t結構體聲明05. modbus_mapping_t結構體聲明06. 附錄
01. 常見類型聲明
便于了解和跨平台使用。
stdint.h内容如下:
//
// stdint.h
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// The C Standard Library <stdint.h> header.
//
#pragma once
#define _STDINT
#include <vcruntime.h>
#if _VCRT_COMPILER_PREPROCESSOR
#pragma warning(push)
#pragma warning(disable: _VCRUNTIME_DISABLED_WARNINGS)
typedef signed char int8_t;
typedef short int16_t;
typedef int int32_t;
typedef long long int64_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
typedef signed char int_least8_t;
typedef short int_least16_t;
typedef int int_least32_t;
typedef long long int_least64_t;
typedef unsigned char uint_least8_t;
typedef unsigned short uint_least16_t;
typedef unsigned int uint_least32_t;
typedef unsigned long long uint_least64_t;
typedef signed char int_fast8_t;
typedef int int_fast16_t;
typedef int int_fast32_t;
typedef long long int_fast64_t;
typedef unsigned char uint_fast8_t;
typedef unsigned int uint_fast16_t;
typedef unsigned int uint_fast32_t;
typedef unsigned long long uint_fast64_t;
typedef long long intmax_t;
typedef unsigned long long uintmax_t;
// These macros must exactly match those in the Windows SDK's intsafe.h.
#define INT8_MIN (-127i8 - 1)
#define INT16_MIN (-32767i16 - 1)
#define INT32_MIN (-2147483647i32 - 1)
#define INT64_MIN (-9223372036854775807i64 - 1)
#define INT8_MAX 127i8
#define INT16_MAX 32767i16
#define INT32_MAX 2147483647i32
#define INT64_MAX 9223372036854775807i64
#define UINT8_MAX 0xffui8
#define UINT16_MAX 0xffffui16
#define UINT32_MAX 0xffffffffui32
#define UINT64_MAX 0xffffffffffffffffui64
#define INT_LEAST8_MIN INT8_MIN
#define INT_LEAST16_MIN INT16_MIN
#define INT_LEAST32_MIN INT32_MIN
#define INT_LEAST64_MIN INT64_MIN
#define INT_LEAST8_MAX INT8_MAX
#define INT_LEAST16_MAX INT16_MAX
#define INT_LEAST32_MAX INT32_MAX
#define INT_LEAST64_MAX INT64_MAX
#define UINT_LEAST8_MAX UINT8_MAX
#define UINT_LEAST16_MAX UINT16_MAX
#define UINT_LEAST32_MAX UINT32_MAX
#define UINT_LEAST64_MAX UINT64_MAX
#define INT_FAST8_MIN INT8_MIN
#define INT_FAST16_MIN INT32_MIN
#define INT_FAST32_MIN INT32_MIN
#define INT_FAST64_MIN INT64_MIN
#define INT_FAST8_MAX INT8_MAX
#define INT_FAST16_MAX INT32_MAX
#define INT_FAST32_MAX INT32_MAX
#define INT_FAST64_MAX INT64_MAX
#define UINT_FAST8_MAX UINT8_MAX
#define UINT_FAST16_MAX UINT32_MAX
#define UINT_FAST32_MAX UINT32_MAX
#define UINT_FAST64_MAX UINT64_MAX
#ifdef _WIN64
#define INTPTR_MIN INT64_MIN
#define INTPTR_MAX INT64_MAX
#define UINTPTR_MAX UINT64_MAX
#else
#define INTPTR_MIN INT32_MIN
#define INTPTR_MAX INT32_MAX
#define UINTPTR_MAX UINT32_MAX
#endif
#define INTMAX_MIN INT64_MIN
#define INTMAX_MAX INT64_MAX
#define UINTMAX_MAX UINT64_MAX
#define PTRDIFF_MIN INTPTR_MIN
#define PTRDIFF_MAX INTPTR_MAX
#ifndef SIZE_MAX
// SIZE_MAX definition must match exactly with limits.h for modules support.
#ifdef _WIN64
#define SIZE_MAX 0xffffffffffffffffui64
#else
#define SIZE_MAX 0xffffffffui32
#endif
#endif
#define SIG_ATOMIC_MIN INT32_MIN
#define SIG_ATOMIC_MAX INT32_MAX
#define WCHAR_MIN 0x0000
#define WCHAR_MAX 0xffff
#define WINT_MIN 0x0000
#define WINT_MAX 0xffff
#define INT8_C(x) (x)
#define INT16_C(x) (x)
#define INT32_C(x) (x)
#define INT64_C(x) (x ## LL)
#define UINT8_C(x) (x)
#define UINT16_C(x) (x)
#define UINT32_C(x) (x ## U)
#define UINT64_C(x) (x ## ULL)
#define INTMAX_C(x) INT64_C(x)
#define UINTMAX_C(x) UINT64_C(x)
#pragma warning(pop) // _VCRUNTIME_DISABLED_WARNINGS
#endif // _VCRT_COMPILER_PREPROCESSOR
02. 常量聲明
在modbus.h檔案中,通過宏定義libmodbus庫目前支援的所有Modbus功能碼
/* Modbus function codes */
#define MODBUS_FC_READ_COILS 0x01
#define MODBUS_FC_READ_DISCRETE_INPUTS 0x02
#define MODBUS_FC_READ_HOLDING_REGISTERS 0x03
#define MODBUS_FC_READ_INPUT_REGISTERS 0x04
#define MODBUS_FC_WRITE_SINGLE_COIL 0x05
#define MODBUS_FC_WRITE_SINGLE_REGISTER 0x06
#define MODBUS_FC_READ_EXCEPTION_STATUS 0x07
#define MODBUS_FC_WRITE_MULTIPLE_COILS 0x0F
#define MODBUS_FC_WRITE_MULTIPLE_REGISTERS 0x10
#define MODBUS_FC_REPORT_SLAVE_ID 0x11
#define MODBUS_FC_MASK_WRITE_REGISTER 0x16
#define MODBUS_FC_WRITE_AND_READ_REGISTERS 0x17
在modbus.h檔案中定義了最大可讀/可寫線圈數量,最大可讀/可寫寄存器數量。
//廣播位址
#define MODBUS_BROADCAST_ADDRESS 0
/* Modbus_Application_Protocol_V1_1b.pdf (chapter 6 section 1 page 12)
* Quantity of Coils to read (2 bytes): 1 to 2000 (0x7D0)
* (chapter 6 section 11 page 29)
* Quantity of Coils to write (2 bytes): 1 to 1968 (0x7B0)
*/
#define MODBUS_MAX_READ_BITS 2000
#define MODBUS_MAX_WRITE_BITS 1968
/* Modbus_Application_Protocol_V1_1b.pdf (chapter 6 section 3 page 15)
* Quantity of Registers to read (2 bytes): 1 to 125 (0x7D)
* (chapter 6 section 12 page 31)
* Quantity of Registers to write (2 bytes) 1 to 123 (0x7B)
* (chapter 6 section 17 page 38)
* Quantity of Registers to write in R/W registers (2 bytes) 1 to 121 (0x79)
*/
#define MODBUS_MAX_READ_REGISTERS 125
#define MODBUS_MAX_WRITE_REGISTERS 123
#define MODBUS_MAX_WR_WRITE_REGISTERS 121
#define MODBUS_MAX_WR_READ_REGISTERS 125
/* The size of the MODBUS PDU is limited by the size constraint inherited from
* the first MODBUS implementation on Serial Line network (max. RS485 ADU = 256
* bytes). Therefore, MODBUS PDU for serial line communication = 256 - Server
* address (1 byte) - CRC (2 bytes) = 253 bytes.
*/
#define MODBUS_MAX_PDU_LENGTH 253
/* Consequently:
* - RTU MODBUS ADU = 253 bytes + Server address (1 byte) + CRC (2 bytes) = 256
* bytes.
* - TCP MODBUS ADU = 253 bytes + MBAP (7 bytes) = 260 bytes.
* so the maximum of both backend in 260 bytes. This size can used to allocate
* an array of bytes to store responses and it will be compatible with the two
* backends.
*/
#define MODBUS_MAX_ADU_LENGTH 260
/* Random number to avoid errno conflicts */
#define MODBUS_ENOBASE 112345678
錯誤碼常量
/* Random number to avoid errno conflicts */
#define MODBUS_ENOBASE 112345678
/* Protocol exceptions */
enum {
MODBUS_EXCEPTION_ILLEGAL_FUNCTION = 0x01, //非法的功能碼
MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS, //非法的資料位址
MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE, //非法的資料值
MODBUS_EXCEPTION_SLAVE_OR_SERVER_FAILURE, //從站裝置故障
MODBUS_EXCEPTION_ACKNOWLEDGE, //ACK異常
MODBUS_EXCEPTION_SLAVE_OR_SERVER_BUSY, //從站裝置忙
MODBUS_EXCEPTION_NEGATIVE_ACKNOWLEDGE, //否定應答
MODBUS_EXCEPTION_MEMORY_PARITY, //記憶體奇偶校驗錯誤
MODBUS_EXCEPTION_NOT_DEFINED, //未定義
MODBUS_EXCEPTION_GATEWAY_PATH, //網關路徑不可用
MODBUS_EXCEPTION_GATEWAY_TARGET, //目标裝置未能回應
MODBUS_EXCEPTION_MAX
};
#define EMBXILFUN (MODBUS_ENOBASE + MODBUS_EXCEPTION_ILLEGAL_FUNCTION)
#define EMBXILADD (MODBUS_ENOBASE + MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS)
#define EMBXILVAL (MODBUS_ENOBASE + MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE)
#define EMBXSFAIL (MODBUS_ENOBASE + MODBUS_EXCEPTION_SLAVE_OR_SERVER_FAILURE)
#define EMBXACK (MODBUS_ENOBASE + MODBUS_EXCEPTION_ACKNOWLEDGE)
#define EMBXSBUSY (MODBUS_ENOBASE + MODBUS_EXCEPTION_SLAVE_OR_SERVER_BUSY)
#define EMBXNACK (MODBUS_ENOBASE + MODBUS_EXCEPTION_NEGATIVE_ACKNOWLEDGE)
#define EMBXMEMPAR (MODBUS_ENOBASE + MODBUS_EXCEPTION_MEMORY_PARITY)
#define EMBXGPATH (MODBUS_ENOBASE + MODBUS_EXCEPTION_GATEWAY_PATH)
#define EMBXGTAR (MODBUS_ENOBASE + MODBUS_EXCEPTION_GATEWAY_TARGET)
/* Native libmodbus error codes */
#define EMBBADCRC (EMBXGTAR + 1) //無效的CRC
#define EMBBADDATA (EMBXGTAR + 2) //無效的資料
#define EMBBADEXC (EMBXGTAR + 3) //無效的異常碼
#define EMBUNKEXC (EMBXGTAR + 4) //保留 未使用
#define EMBMDATA (EMBXGTAR + 5) //資料過多
#define EMBBADSLAVE (EMBXGTAR + 6) //響應與查詢位址不比對
03. _modbus結構體聲明
在檔案modbus-private.h中定義了_modbus結構體,具體定義如下:
struct _modbus {
/* Slave address */
int slave; //從站裝置位址
/* Socket or file descriptor */
int s; //TCP模式下為套接字 RTU模式下為序列槽句柄
int debug; //是否啟用debug模式
int error_recovery; //錯誤恢複模式
struct timeval response_timeout; //響應逾時設定
struct timeval byte_timeout; //位元組逾時設定
struct timeval indication_timeout;
//包含一系列通用函數指針
const modbus_backend_t *backend;
void *backend_data; //TCP模式下特殊配置資料 RTU模式下特殊配置資料
};
04. modbus_backend_t結構體聲明
modbus_backend_t作為一個重要的結構體,包含了各種處理函數。其定義如下:
typedef struct _modbus_backend {
unsigned int backend_type; //modbus_backend_type_t類型
unsigned int header_length; //HBMP長度
unsigned int checksum_length; //錯誤校驗字段長度
unsigned int max_adu_length; //ADU最大長度
int (*set_slave) (modbus_t *ctx, int slave); //設定從站裝置位址
//構造查詢封包的基本通信幀
int (*build_request_basis) (modbus_t *ctx, int function, int addr,
int nb, uint8_t *req);
//構造響應封包的基本通信幀
int (*build_response_basis) (sft_t *sft, uint8_t *rsp);
//構造響應封包TID參數
int (*prepare_response_tid) (const uint8_t *req, int *req_length);
//發送封包前的預處理
int (*send_msg_pre) (uint8_t *req, int req_length);
//發送封包
ssize_t (*send) (modbus_t *ctx, const uint8_t *req, int req_length);
//接收封包
int (*receive) (modbus_t *ctx, uint8_t *req);
//接收封包 該函數被receive函數調用
ssize_t (*recv) (modbus_t *ctx, uint8_t *rsp, int rsp_length);
//用于資料完整性檢查
int (*check_integrity) (modbus_t *ctx, uint8_t *msg,
const int msg_length);
//确認響應封包的幀頭是否一緻
int (*pre_check_confirmation) (modbus_t *ctx, const uint8_t *req,
const uint8_t *rsp, int rsp_length);
//建立連接配接
int (*connect) (modbus_t *ctx);
//關閉連接配接
void (*close) (modbus_t *ctx);
//清空緩沖區
int (*flush) (modbus_t *ctx);
//用于設定逾時并讀取通信事件,以檢測是否存在待接收資料
int (*select) (modbus_t *ctx, fd_set *rset, struct timeval *tv, int msg_length);
//釋放記憶體
void (*free) (modbus_t *ctx);
} modbus_backend_t;
05. modbus_mapping_t結構體聲明
modbus_mapping_t聲明在modbus.h檔案中,其聲明如下:
typedef struct _modbus modbus_t;
typedef struct _modbus_mapping_t {
int nb_bits; //線圈寄存器的數量
int start_bits; //線圈寄存器的起始位址
int nb_input_bits; //離散輸入寄存器的數量
int start_input_bits; //離散輸入寄存器的起始位址
int nb_input_registers; //輸入寄存器的數量
int start_input_registers; //輸入寄存器的起始位址
int nb_registers; //保持寄存器的數量
int start_registers; //保持寄存器的起始位址
uint8_t *tab_bits; //指向線圈寄存器的值
uint8_t *tab_input_bits; //指向離散輸入寄存器的值
uint16_t *tab_input_registers; //指向輸入寄存器的值
uint16_t *tab_registers; //指向保持寄存器的值
} modbus_mapping_t;