【嵌入式】Libmodbus源码分析(一)-类型和结构体
生活随笔
收集整理的這篇文章主要介紹了
【嵌入式】Libmodbus源码分析(一)-类型和结构体
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
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_PREPROCESSOR02. 常量聲明
在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;06. 附錄
libmodbus源碼下載:https://github.com/stephane/libmodbus
總結
以上是生活随笔為你收集整理的【嵌入式】Libmodbus源码分析(一)-类型和结构体的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【嵌入式】Libmodbus下载和编译详
- 下一篇: 【嵌入式】Libmodbus源码分析(二