libmodbus官方手冊中文翻譯


libmodbus官方手冊中文翻譯

最近做libmodbus相關內容,因為中文沒有libmodbus各個函數的詳細解釋,所以在此把要用的libmodbus的官方手冊包括所有的函數都翻譯整理一下,給自己和大家們學習,歡迎大家交流指正。手冊原文http://libmodbus.org/docs/v3.0.6/,   http://libmodbus.org/docs/v3.1.4/

注:可以通過Ctrl+F 快速查詢,常用的modbus指令主要有如下幾條,並基本基於此順序執行:

1、初始化RTU指針

2、建立連接

3、設置從站ID

4、讀取保持寄存器/讀取輸入寄存器/讀取位

5、寫單寄存器/寫多寄存器/寫多位數據

6、關閉連接


 

目錄

libmodbus

特點

概要

描述

環境(contexts)

RTU環境

創建modbus RTU 環境

初試化RTU環境指針 modbus_t *modbus_new_rtu(const char *device, int baud, char parity, int data_bit, int stop_bit)

設置串口模式

獲取當前串口模式 int modbus_rtu_get_serial_mode(modbus_t *ctx);

設置串口模式 int modbus_rtu_set_serial_mode(modbus_t *ctx, int mode);

在 RTU環境下 中獲取當前RTS模式 int modbus_rtu_get_rts(modbus_t *ctx)(3.1.4版本補充)

在RTU環境下獲取設置RTS模式 int modbus_rtu_set_rts(modbus_t *ctx, int mode)(3.1.4版本補充)

自定義RTS實現 int modbus_rtu_set_custom_rts(modbus_t *ctx, void (set_rts) (modbus_t ctx, int on))(3.1.4版本補充)

獲取RTU中當前RTS延遲 int modbus_rtu_get_rts_delay(modbus_t *ctx);(3.1.4版本補充)

設置RTU中的RTS延遲   int modbus_rtu_set_rts_delay(modbus_t *ctx, int us);(3.1.4版本補充)

TCP(IPv4)環境

創建Modbus TCP環境 modbus_t *modbus_new_tcp(const char *ip, int port);

TCP PI(IPv4和IPv6)環境

創建Modbus TCP PI環境modbus_t *modbus_new_tcp_pi(const char *node, const char *service);

通用函數:

釋放modbus環境void modbus_free(modbus_t *ctx);

設置從站ID int modbus_set_slave(modbus_t *ctx, int slave);(3.1.4版本補充)

啟用調試模式 int modbus_set_debug(modbus_t *ctx, int flag);(3.1.4版本補充)

超時設置: 

獲取字節之間的超時 int modbus_get_byte_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec);

設置字節之間超時間隔 void modbus_set_byte_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec);

獲取響應超時時間void modbus_get_response_timeout(modbus_t *ctx, struct timeval *timeout);

設置超時響應時間 void modbus_set_response_timeout(modbus_t *ctx, struct timeval *timeout);

設置錯誤恢復模式 int modbus_set_error_recovery(modbus_t *ctx, modbus_error_recovery_mode error_recovery);(3.1.4版本補充)

設置環境套接字(socket )int modbus_set_socket(modbus_t *ctx, int s);

獲取環境套接字(socket) int modbus_get_socket(modbus_t *ctx);

檢索當前標頭長度 int modbus_get_header_length(modbus_t *ctx);

用於數據操作的宏

用於操作位和字節的函數(3.1.4版本修改)

從單個字節值設置多個位void modbus_set_bits_from_byte(uint8_t *dest, int index, const uint8_t value);

從字節數組設置多個位void modbus_set_bits_from_bytes(uint8_t *dest, int index, unsigned int nb_bits, const uint8_t *tab_byte);

從多個位獲取數值uint8_t modbus_get_byte_from_bits(const uint8_t *src, int index, unsigned int nb_bits);

設置或獲取浮點數

ABCD順序獲取浮點值float modbus_get_float_abcd(const uint16_t *src);

ABCD順序存儲浮點值void modbus_set_float_abcd(float f, uint16_t *dest);

BADC順序獲取浮點值float modbus_get_float_badc(const uint16_t *src);

BADC順序存儲浮點值void modbus_set_float_badc(float f, uint16_t *dest);

CDAB順序獲取浮點值float modbus_get_float_cdab(const uint16_t *src);

CDAB順序存儲浮點值void modbus_set_float_cdab(float f, uint16_t *dest);

DCBA順序獲取浮點值float modbus_get_float_dcba(const uint16_t *src);

DCBA順序存儲浮點值void modbus_set_float_dcba(float f, uint16_t *dest);

連接

建立連接 int modbus_connect(modbus_t *ctx);

關閉連接 void modbus_close(modbus_t *ctx);

沖洗未連接數據int modbus_flush(modbus_t *ctx);

主機(客戶端Client)

讀取數據

讀取位(讀取線圈狀態) int modbus_read_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest);

讀取輸入位(讀取輸入狀態) int modbus_read_input_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest);

讀取保持寄存器 int modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest);

讀取輸入寄存器int modbus_read_input_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest);

讀取控制器(controller)描述  int modbus_report_slave_id(modbus_t *ctx, int max_dest, uint8_t *dest);

寫數據

寫一位數據(強置單線圈)int modbus_write_bit(modbus_t *ctx, int addr, int status);

寫單寄存器(預置單寄存器)int modbus_write_register(modbus_t *ctx, int addr, int value);

寫多位數據(強置多線圈)int modbus_write_bits(modbus_t *ctx, int addr, int nb, const uint8_t *src);

寫多寄存器(預置多寄存器)int modbus_write_registers(modbus_t *ctx, int addr, int nb, const uint16_t *src);

寫和讀數據

在單個處理中寫入和讀取多個寄存器int modbus_write_and_read_registers(modbus_t *ctx, int write_addr, int write_nb, const uint16_t *src, int read_addr, int read_nb, const uint16_t *dest);

原始請求

發送原始請求 int modbus_send_raw_request (modbus_t *ctx, uint8_t *raw_req, int raw_req_length);

收到確認請求 int modbus_receive_confirmation(modbus_t *ctx, uint8_t *rsp);

回復異常

發送一個異常響應*int modbus_reply_exception(modbus_t *ctx, const uint8_t *req, unsigned int exception_code);

從機(服務器server)

數據映射

分配位(線圈)和寄存器的數組modbus_mapping_t modbus_mapping_new (int nb_bits, int nb_input_bits, int nb_registers, intnb_input_registers);

釋放modbus_mapping_t 結構void modbus_mapping_free(modbus_mapping_t *mb_mapping);

接收

收到指示請求 int modbus_receive(modbus_t *ctx, uint8_t *req);

回復

響應收到的請求int modbus_reply(modbus_t *ctx, const uint8_t *req, int req_length, modbus_mapping_t *mb_mapping);

發送異常響應int modbus_reply_exception(modbus_t *ctx, const uint8_t *req, unsigned int exception_code);

錯誤處理

返回錯誤信息const char *modbus_strerror(int errnum);

雜項

版權協議


 

libmodbus

版本號:V3.0.6(已加入3.1.4版本補充)

特點

     libmodbus是一個快速、跨平台的Modbus庫。

概要

#include <modbus.h>

cc `pkg-config --cflags --libs libmodbus` files

描述

libmodbus是一個與使用Modbus協議的設備進行數據發送/接收的庫。該庫包含各種后端(backends)通過不同網絡進行通信(例如,RTU模式下的串口或TCP / IPv6中的以太網)。

 http://www.modbus.org網站提供了協議規范文檔http://www.modbus.org/specs.php

libmodbus提供了較低通信層的抽象,並在所有支持的平台上提供相同的API。

本文檔介紹了了libmodbus概念,介紹了libmodbus如何從在不同的硬件和平台中實現Modbus通信,並為libmodbus庫提供的函數提供了參考手冊。

環境(contexts)

Modbus協議包含許多變體(例如串行RTU或Ehternet TCP),為了簡化變體的實現,該庫被設計成為每個變體使用后端(backends)。后端也是滿足其他要求(例如實時操作)的便捷方法。每個后端都提供了一個特定的函數來創建一個新的modbus_t環境。 modbus_t環境是一個不透明的結構,包含根據所選變體與其他Modbus設備建立連接的所有必要信息。


RTU環境

RTU后端(遠程終端單元)用於串口通信,並使用用於協議通信的數據的緊湊的二進制表示形式。RTU格式遵循命令/數據,和CRC(cyclic redundancy check循環冗余校驗)作為錯誤檢查機制,以確保數據的可靠性。Modbus RTU是可用於Modbus的最常用的實現方式。Modbus RTU消息必須連續發送,不能有字符間隔(摘自Wikipedia,Modbus, http://en.wikipedia.org/wiki/Modbus  截至2011年3月13日,格林尼治時間20:51)。

Modbus RTU框架調用一個從站,一個處理Modbus請求的設備/服務器,以及一個發送請求的客戶端(主站)。通信始終由主站服務端發起。

許多Modbus設備可以在同一個的物理鏈路上連接在一起(總線結構),因此在發送消息之前,必須使用modbus_set_slave設置從站(接收設備 )ID。如果您正在運行一個從站,則其從站號將用於過濾接收的消息。

 

創建modbus RTU 環境

初試化RTU環境指針 modbus_t *modbus_new_rtu(const char *device, int baud, char parity, int data_bit, int stop_bit)

  1.  
    modbus_t *modbus_new_rtu(const char *device, int baud, char parity, int data_bit, int stop_bit);
  2.  
     
  3.  
     
  4.  
    //參考代碼:
  5.  
    modbus_t *ctx;
  6.  
     
  7.  
    ctx = modbus_new_rtu( "/dev/ttyUSB0", 115200, 'N', 8, 1);
  8.  
    if (ctx == NULL) {
  9.  
    fprintf(stderr, "Unable to create the libmodbus context\n");
  10.  
    return -1;
  11.  
    }

這個 modbus_new_rtu()函數會生成並初始化一個modbus的結構體來在串行線路中使用RTU模式進行通訊。

device 指定OS處理的串行端口的名稱,比如 /dev/ttyS0 or /dev/ttyUSB0,在windows系統上,如果COM編號大於9,必須要在COM前加上\\.\ ,比如 \\\\.\\COM10.,參照http://msdn.microsoft.com/en-us/library/aa365247(v=vs.85).aspx

 baud :指定連接的波特率,比如9600, 19200, 57600, 115200等。

parity :代表奇偶檢驗位,有如下值:

N   無奇偶校驗

E  偶數校驗

O  奇數校驗

data_bit :指定數據的位數,允許值有: 5, 6, 7 ,8.

stop_bit :指定停止位位數,允許值有1和2.

返回:如果建立成功,modbus_new_rtu()函數將返回指向modbus_t結構的指針。 否則它將返回NULL並將errno設置為An invalid argument was given.。

設置串口模式

獲取當前串口模式 int modbus_rtu_get_serial_mode(modbus_t *ctx);

int modbus_rtu_get_serial_mode (modbus_t *ctx); 

返回:如果成功, 函數應返回 MODBUS_RTU_RS232 或 MODBUS_RTU_RS485 。否則, 它將返回-1並將errno設為The current libmodbus backend is not RTU.

只用於RTU環境。

設置串口模式 int modbus_rtu_set_serial_mode(modbus_t *ctx, int mode);

int modbus_rtu_set_serial_mode(modbus_t *ctx, int mode);

mode: 填入 MODBUS_RTU_RS232 或 MODBUS_RTU_RS485

返回值:如果成功, 函數應返回0。否則, 它將返回-1 並將 errno 設置為下面定義的值之一。

EINVAL The current libmodbus backend is not RTU.

ENOTSUP The function is not supported on your platform.。

如果對 ioctl () 的調用失敗, 將返回 ioctl 的錯誤代碼。

在 RTU環境下 中獲取當前RTS模式 int modbus_rtu_get_rts(modbus_t *ctx)(3.1.4版本補充)

int modbus_rtu_get_rts (modbus_t *ctx);

可以獲得在當前ctx環境下發送請求的的模式。

返回值:

       MODBUS_RTU_RTS_NONE

       MODBUS_RTU_RTS_UP

       MODBUS_RTU_RTS_DOWN

       -1,即調用失敗,並設置EINVAL為The libmodbus backend is not RTU.

 

在RTU環境下獲取設置RTS模式 int modbus_rtu_set_rts(modbus_t *ctx, int mode)(3.1.4版本補充)

  1.  
    int modbus_rtu_set_rts(modbus_t *ctx, int mode);
  2.  
     
  3.  
    //例子:啟動有正極性的RTS模式
  4.  
    modbus_t *ctx;
  5.  
    uint16_t tab_reg[10];
  6.  
     
  7.  
    ctx = modbus_new_rtu( "/dev/ttyS0", 115200, 'N', 8, 1);
  8.  
    modbus_set_slave(ctx, 1);
  9.  
    modbus_rtu_set_serial_mode(ctx, MODBUS_RTU_RS485);
  10.  
    modbus_rtu_set_rts(ctx, MODBUS_RTU_RTS_UP);
  11.  
     
  12.  
    if (modbus_connect(ctx) == -1) {
  13.  
    fprintf(stderr, "Connexion failed: %s\n", modbus_strerror(errno));
  14.  
    modbus_free(ctx);
  15.  
    return -1;
  16.  
    }
  17.  
     
  18.  
    rc = modbus_read_registers(ctx, 0, 7, tab_reg);
  19.  
    if (rc == -1) {
  20.  
    fprintf(stderr, "%s\n", modbus_strerror(errno));
  21.  
    return -1;
  22.  
    }
  23.  
     
  24.  
    modbus_close(ctx);
  25.  
    modbus_free(ctx);

設置發送請求模式用於在RS485串行總線上進行通訊,默認模式為MODBUS_RTU_RTS_NONE,在把數據寫入線路之前不會有信號發出。

要啟用RTS 模式, 必須使用 MODBUS_RTU_RTS_UP或MODBUS_RTU_RTS_DOWN, 這些模式啟用 RTS 模式並同時設置極性。使用MODBUS_RTU_RTS_UP時, 將RTS 標志位置為使能並進行 ioctl 調用, 然后在1毫秒的延遲后在總線上寫入數據, 然后將 RTS 標志位置為非使能進行另一個 ioctl 調用, 並再次延遲1毫秒。MODBUS_RTU_RTS_DOWN模式與之類似, 但使用相反的 RTS 標志位。

如果成功, 函數應返回0。否則, 它將返回-1 並將 errno 設置為The libmodbus backend isn’t RTU or the mode given in argument is invalid.。

 

自定義RTS實現 int modbus_rtu_set_custom_rts(modbus_t *ctx, void (set_rts) (modbus_t ctx, int on))(3.1.4版本補充)

int modbus_rtu_set_custom_rts(modbus_t *ctx, void (set_rts) (modbus_t ctx, int on)); 

設置傳輸前后設置RST PIN要調用的自定義函數,默認情況下,默認情況下,設置為使用IOCTL調用切換RTS PIN的內部函數。

注意,該函數遵循RTS模式,必須使用值MODBUS_RTU_RTS_UPMODBUS_RTU_RTS_DOWN來調用該函數。

返回:如果成功, modbus_rtu_set_custom_rts ()函數應返回0。否則, 它將返回-1 並將 errno 設置為The libmodbus backend is not RTU.

 

獲取RTU中當前RTS延遲 int modbus_rtu_get_rts_delay(modbus_t *ctx);(3.1.4版本補充)

int modbus_rtu_get_rts_delay(modbus_t *ctx); 

返回:成功則以微秒為單位返回當前RTS延遲。否則它將返回-1並設置errno為The libmodbus backend is not RTU.。

 

設置RTU中的RTS延遲   int modbus_rtu_set_rts_delay(modbus_t *ctx, int us);(3.1.4版本補充)

int modbus_rtu_set_rts_delay(modbus_t *ctx, int us);

設置請求發送延遲。

返回:成功,返回0。否則它將返回-1並設置errno:The libmodbus backend is not RTU or a negative delay was specified.


TCP(IPv4)環境

TCP后端實現了用於通過TCP / IPv4網絡進行通信的Modbus變體。它不需要校驗和計算,因為底層TCP會處理相同的功能。

創建Modbus TCP環境 modbus_t *modbus_new_tcp(const char *ip, int port);

  1.  
    modbus_t *modbus_new_tcp(const char *ip, int port);
  2.  
    //例子:
  3.  
    modbus_t *ctx;
  4.  
     
  5.  
    ctx = modbus_new_tcp( "127.0.0.1", 1502);
  6.  
    if (ctx == NULL) {
  7.  
    fprintf(stderr, "Unable to allocate libmodbus context\n");
  8.  
    return -1;
  9.  
    }
  10.  
     
  11.  
    if (modbus_connect(ctx) == -1) {
  12.  
    fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));
  13.  
    modbus_free(ctx);
  14.  
    return -1;
  15.  
    }

ip:希望連接的服務器ip地址

port:要使用的 TCP 端口。將端口設置為MODBUS_TCP_DEFAULT_PORT使用默認值之一 (502)。使用大於或等於1024的端口號很方便, 因為沒有必要擁有管理員權限。

返回:成功返回指向modbus_t結構體的指針。否則, 它應返回 NULL 並將 errno 設置為An invalid IP address was given.


TCP PI(IPv4和IPv6)環境

TCP PI(Protocol Indepedent)后端實現用於通過TCP IPv4和IPv6網絡進行通信的Modbus變體。 它不需要校驗和計算,因為較低層負責相同的操作。 與單獨的TCP IPv4后端不同,TCP PI后端提供主機名解析,但它消耗大約1Kb的額外內存。

創建Modbus TCP PI環境modbus_t *modbus_new_tcp_pi(const char *node, const char *service);

  1.  
    modbus_t *modbus_new_tcp_pi(const char *node, const char *service);
  2.  
    //例子
  3.  
    modbus_t *ctx;
  4.  
     
  5.  
    ctx = modbus_new_tcp_pi( "::1", "1502");
  6.  
    if (ctx == NULL) {
  7.  
    fprintf(stderr, "Unable to allocate libmodbus context\n");
  8.  
    return -1;
  9.  
    }
  10.  
     
  11.  
    if (modbus_connect(ctx) == -1) {
  12.  
    fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));
  13.  
    modbus_free(ctx);
  14.  
    return -1;
  15.  
    }

應分配和初始化一個 modbus_t 結構, 以便與一個 IPv4 或 Ipv6 服務器進行通信。

node參數指定要連接的主機的主機名或 IP 地址, 例如。192.168.0.5 ,:: 1server.com.

service參數是要連接到的服務名稱/端口號。要使用默認的接口端口, 請使用字符串 "502"。在許多 Unix 系統上, 使用大於或等於1024的端口號是很方便的, 因為沒有必要擁有管理員權限。

返回值:成功返回指向modbus_t結構的指針。否則, 它應返回 NULL 並將 errno 設置為The node string is empty or has been truncated. The service string is empty or has been truncated。

 


通用函數:

在使用任何libmodbus函數之前,調用者必須使用上述功能分配和初始化 modbus_t環境,然后提供以下函數來修改和釋放環境:

釋放modbus環境void modbus_free(modbus_t *ctx);

void modbus_free(modbus_t *ctx);


設置從站ID int modbus_set_slave(modbus_t *ctx, int slave);(3.1.4版本補充)

  1.  
    int modbus_set_slave(modbus_t *ctx, int slave);
  2.  
    //例子
  3.  
    modbus_t *ctx;
  4.  
     
  5.  
    ctx = modbus_new_rtu( "/dev/ttyUSB0", 115200, 'N', 8, 1);
  6.  
    if (ctx == NULL) {
  7.  
    fprintf(stderr, "Unable to create the libmodbus context\n");
  8.  
    return -1;
  9.  
    }
  10.  
     
  11.  
    rc = modbus_set_slave(ctx, YOUR_DEVICE_ID);
  12.  
    if (rc == -1) {
  13.  
    fprintf(stderr, "Invalid slave ID\n");
  14.  
    modbus_free(ctx);
  15.  
    return -1;
  16.  
    }
  17.  
     
  18.  
    if (modbus_connect(ctx) == -1) {
  19.  
    fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));
  20.  
    modbus_free(ctx);
  21.  
    return -1;
  22.  
    }

設定libmodbus環境中的slave ID。

若為RTU模式

定義遠程設備的從站ID以在主站模式下進行通信,或將內部從站ID設置為從站模式。 根據協議,Modbus設備只接受包含了其從機號碼(slave number)或特殊廣播號碼的消息。

若為TCP模式

如果消息必須到達串行網絡上的設備,則僅在TCP中需要從站號碼。 某些不兼容的設備或軟件(例如modpoll)使用從站ID作為單元標識符,這是不正確的(參見Modbus Messaging Implementation Guide v1.0b的第23頁)沒有從站值,故障的遠程設備或軟件會丟棄請求! 特殊值MODBUS_TCP_SLAVE(0xFF)可用於TCP模式以恢復默認值。

廣播地址是 MODBUS_BROADCAST_ADDRESS 。 當您希望網絡中的所有Modbus設備都收到請求時,必須使用此特殊值。

返回:成功則返回0,否者返回-1並將errno設定為The slave number is invalid.。

 

啟用調試模式 int modbus_set_debug(modbus_t *ctx, int flag);(3.1.4版本補充)

int modbus_set_debug(modbus_t *ctx, int flag);

通過是用flag設置debug調試標志位,默認情況下,布爾標志位flag被設置為FALSE,當falg被設置為TRUE時,會在stdout和stderr上顯示很多冗長的信息,可以用於顯示modbus消息的字節:

  1.  
    [00][14][00][00][00][06][12][03][00][6B][00][03]
  2.  
    Waiting for a confirmation…
  3.  
    <00><14><00><00><00><09><12><03><06><02><2B><00><00><00><00>

返回:成功返回0,否則返回-1.

 

超時設置: 

獲取字節之間的超時 int modbus_get_byte_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec);

  1.  
    int modbus_get_byte_timeout(modbus_t *ctx, uint32_t *to_sec, uint32_t *to_usec);
  2.  
    //例子:
  3.  
    uint32_t to_sec;
  4.  
    uint32_t to_usec;
  5.  
     
  6.  
    /* Save original timeout */
  7.  
    modbus_get_byte_timeout(ctx, &to_sec, &to_usec);

實現在to_secto_usec參數中存儲同一消息的兩個連續字節之間的超時間隔。

返回:成功返回0,否則返回-1

 

設置字節之間超時間隔 void modbus_set_byte_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec);

void modbus_set_byte_timeout(modbus_t *ctx, uint32_t to_sec, uint32_t to_usec);

設置同一消息的兩個連續字節之間的超時間隔。超時是在select()函數返回之前所經過的時間量的上限, 如果時間超過定義的超時, 則等待響應的函數將引發ETIMEDOUT錯誤。to_usec參數的值必須在范圍0到999999之間。

如果to_secto_usec都為零, 則不會使用此超時。在這種情況下, modbus_set_response_timeout ()控制響應的整個處理, 必須在響應超時過期之前接收完整的確認響應。只設置字節超時為1時, 響應超時僅用於等待響應的第一個字節。

返回:成功0,失敗返回-1並設置errno為:The argument ctx is NULL or to_usec is larger than 1000000.

 

獲取響應超時時間void modbus_get_response_timeout(modbus_t *ctx, struct timeval *timeout);

  1.  
    void modbus_get_response_timeout(modbus_t *ctx, struct timeval *timeout);
  2.  
    //例子
  3.  
    struct timeval old_response_timeout;
  4.  
    struct timeval response_timeout;
  5.  
     
  6.  
    /* Save original timeout保存原始的超時參數 */
  7.  
    modbus_get_response_timeout(ctx, &old_response_timeout);
  8.  
     
  9.  
    /* Define a new and too short timeout!定義一個新的更短的超時參數 */
  10.  
    response_timeout.tv_sec = 0;
  11.  
    response_timeout.tv_usec = 0;
  12.  
    modbus_set_response_timeout(ctx, &response_timeout);

modbus_get_response_timeout 函數會保存用於等待超時參數中的響應的超時間隔。

 

設置超時響應時間 void modbus_set_response_timeout(modbus_t *ctx, struct timeval *timeout);

  1.  
    void modbus_set_response_timeout(modbus_t *ctx, struct timeval *timeout);
  2.  
    //例子
  3.  
    struct timeval old_response_timeout;
  4.  
    struct timeval response_timeout;
  5.  
     
  6.  
    /* Save original timeout */
  7.  
    modbus_get_response_timeout(ctx, &old_response_timeout);
  8.  
     
  9.  
    /* Define a new and too short timeout! */
  10.  
    response_timeout.tv_sec = 0;
  11.  
    response_timeout.tv_usec = 0;
  12.  
    modbus_set_response_timeout(ctx, &response_timeout);

modbus_set_response_timeout 函數應設置用於等待響應的超時間隔。如果在接收響應之前等待的時間超過給定的超時時間,則會引發錯誤。

 

設置錯誤恢復模式 int modbus_set_error_recovery(modbus_t *ctx, modbus_error_recovery_mode error_recovery);(3.1.4版本補充)

  1.  
    int modbus_set_error_recovery(modbus_t *ctx, modbus_error_recovery_mode error_recovery);
  2.  
    //例子
  3.  
    modbus_set_error_recovery(ctx, MODBUS_ERROR_RECOVERY_LINK |
  4.  
    MODBUS_ERROR_RECOVERY_PROTOCOL);

用於設置連接失敗或者不期望接收到的字節時應用的錯誤恢復模式,參數  error_recovery 可以是按位(bitewise)或者其他檢誤方式(ed)使用0或者以下的常量。

默認情況下沒有錯誤恢復 (MODBUS_ERROR_RECOVERY_NONE), 因此應用程序負責控制 libmodbus 函數返回的錯誤值, 並在必要時處理它們。

設置(MODBUS_ERROR_RECOVERY_LINK)時, 庫將嘗試在 libmodbus 上下文的響應超時定義的延遲之后重新連接。此模式將嘗試無限關閉/連接的循環, 直到成功發送呼叫, 並只嘗試一次重新建立連接上的選擇/讀呼叫 (如果連接已關閉, 讀取的值肯定是不可用的, 在重聯后, 除了為從機/主機)。此模式還將在某些情況下基於當前響應超時 (例如, 選擇調用超時) 后的延遲運行刷新請求。如果網絡到遠程目標單元已關閉, 重新連接嘗試可能會掛起幾秒鍾。

設置(MODBUS_ERROR_RECOVERY_PROTOCOL)時, 將使用睡眠和沖洗序列來清理正在進行的通信, 這可能發生在消息長度無效時, TID錯誤或接收的函數代碼不是預期的。響應超時延遲將用於睡眠。

模式是掩碼值, 因此它們是互補的。

建議不要為從機/主機啟用錯誤恢復。

返回值:成功返回0,否則返回-1並吧errno設為:The value of the argument error_recovery is not positive.

 

設置環境套接字(socket )int modbus_set_socket(modbus_t *ctx, int s);

  1.  
    int modbus_set_socket(modbus_t *ctx, int s);
  2.  
    //例子
  3.  
    ctx = modbus_new_tcp( "127.0.0.1", 1502);
  4.  
    server_socket = modbus_tcp_listen(ctx, NB_CONNECTION);
  5.  
     
  6.  
    FD_ZERO(&rdset);
  7.  
    FD_SET(server_socket, &rdset);
  8.  
     
  9.  
    /* .... */
  10.  
     
  11.  
    if (FD_ISSET(master_socket, &rdset)) {
  12.  
    modbus_set_socket(ctx, master_socket);
  13.  
    rc = modbus_receive(ctx, query);
  14.  
    if (rc != -1) {
  15.  
    modbus_reply(ctx, query, rc, mb_mapping);
  16.  
    }
  17.  
    }

在libmobus中設置環境套接字火文件描述符,對於管理到同一個主機的多個從機連接非常有效。

返回:成功返回0,否則返回-1並設置errno。

 

獲取環境套接字(socket) int modbus_get_socket(modbus_t *ctx);

int modbus_get_socket(modbus_t *ctx);

返回:成功則返回當前環境的套接字(socket)或文件描述符,否則返回-1並設置errno。

 

檢索當前標頭長度 int modbus_get_header_length(modbus_t *ctx);

int modbus_get_header_length(modbus_t *ctx);

從后端檢索當前報頭長度。此函數便於操作消息, 因此它僅限於低級操作。

返回:整形標頭長度值。


libmodbus的環境是線程安全的,可以在必要時共享盡可能多的應用程序線程, 而調用方不需要任何額外的鎖定。

用於數據操作的宏

MODBUS_GET_HIGH_BYTE(data) 獲取高位字節

MODBUS_GET_LOW_BYTE(data) 獲取低位字節

MODBUS_GET_INT32_FROM_INT16(tab_int16, index) 從兩個int16數據建立一個int32數據,從tab_int16[index]開始。

MODBUS_GET_INT16_FROM_INT8(tab_int8, index)從兩個int8數據建立一個int16數據,從tab_int8[index]開始。

MODBUS_SET_INT16_TO_INT8(tab_int8, index, value)將一個int16數據設置為從tab_int8[index]開始的兩個int8數據。

MODBUS_SET_INT32_TO_INT16(tab_int16, index, value)將一個int32數據設置為從tab_int16[index]開始的兩個int16數據。

MODBUS_SET_INT64_TO_INT16(tab_int16, index, value)將一個int64數據設置為從tab_int16[index]開始的四個int16數據。

 

用於操作位和字節的函數(3.1.4版本修改)

從單個字節值設置多個位void modbus_set_bits_from_byte(uint8_t *dest, int index, const uint8_t value);

void modbus_set_bits_from_byte(uint8_t *dest, int index, const uint8_t value);

從單個字設置多個位,value字節中所有8位都會被寫到dest數組中從index索引開始的位置。

 

從字節數組設置多個位void modbus_set_bits_from_bytes(uint8_t *dest, int index, unsigned int nb_bits, const uint8_t *tab_byte);

void modbus_set_bits_from_bytes(uint8_t *dest, int index, unsigned int nb_bits, const uint8_t *tab_byte);

通過讀取字節數組來設置位,從tab_byte數組第一個開始的所有字節都會被寫到dest數組中從index索引開始的位置。

從多個位獲取數值uint8_t modbus_get_byte_from_bits(const uint8_t *src, int index, unsigned int nb_bits);

uint8_t modbus_get_byte_from_bits(const uint8_t *src, int index, unsigned int nb_bits);

從多個位提取一個值,從srcindex位置開始的的nb_bits位都會被讀取為一個單獨的值,為了獲取一個完整的字節,把nb_bits設置為8。

返回:返回一個讀取后的字節。

 

設置或獲取浮點數

ABCD順序獲取浮點值float modbus_get_float_abcd(const uint16_t *src);

float modbus_get_float_abcd(const uint16_t *src);

從4個字節獲取浮點值。src數組必須是兩個16位數值的指針。例如第一個值為0x0020,第二個值為0xF147,則浮點值被讀為123456.0。

返回:浮點值。

ABCD順序存儲浮點值void modbus_set_float_abcd(float f, uint16_t *dest);

void modbus_set_float_abcd(float f, uint16_t *dest);

f浮點數存儲到dest數組所指的兩個16位值得指針。

 

BADC順序獲取浮點值float modbus_get_float_badc(const uint16_t *src);

float modbus_get_float_badc(const uint16_t *src);

從4個字節獲取浮點值。src數組必須是兩個16位數值的指針。例如第一個值為0x2000,第二個值為0x47F1,則浮點值被讀為123456.0。

返回:浮點值。

BADC順序存儲浮點值void modbus_set_float_badc(float f, uint16_t *dest);

void modbus_set_float_badc(float f, uint16_t *dest);

f浮點數存儲到dest數組所指的兩個16位值得指針。

CDAB順序獲取浮點值float modbus_get_float_cdab(const uint16_t *src);

float modbus_get_float_cdab(const uint16_t *src);

從4個字節獲取浮點值。src數組必須是兩個16位數值的指針。例如第一個值為0x0020,第二個值為0xF147,則浮點值被讀為123456.0。

返回:浮點值。

CDAB順序存儲浮點值void modbus_set_float_cdab(float f, uint16_t *dest);

void modbus_set_float_cdab(float f, uint16_t *dest);

f浮點數存儲到dest數組所指的兩個16位值得指針

DCBA順序獲取浮點值float modbus_get_float_dcba(const uint16_t *src);

float modbus_get_float_dcba(const uint16_t *src);

從4個字節獲取浮點值。src數組必須是兩個16位數值的指針。例如第一個值為0x47F1,第二個值為0x2000,則浮點值被讀為123456.0。

返回:浮點值。

DCBA順序存儲浮點值void modbus_set_float_dcba(float f, uint16_t *dest);

void modbus_set_float_dcba(float f, uint16_t *dest);

f浮點數存儲到dest數組所指的兩個16位值得指針


連接

建立連接 int modbus_connect(modbus_t *ctx);

  1.  
    int modbus_connect(modbus_t *ctx);
  2.  
    //例子
  3.  
    modbus_t *ctx;
  4.  
     
  5.  
    ctx = modbus_new_tcp( "127.0.0.1", 502);
  6.  
    if (modbus_connect(ctx) == -1) {
  7.  
    fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));
  8.  
    modbus_free(ctx);
  9.  
    return -1;
  10.  
    }
  11.  
     

使用參數給定的環境信息,建立與主機、網絡或總線的連接。

返回:成功返回0,錯誤返回-1並將errno設置為底層平台的系統呼叫。

關閉連接 void modbus_close(modbus_t *ctx);

  1.  
    void modbus_close(modbus_t *ctx);
  2.  
    //例子
  3.  
    modbus_t *ctx;
  4.  
     
  5.  
    ctx = modbus_new_tcp( "127.0.0.1", 502);
  6.  
    if (modbus_connect(ctx) == -1) {
  7.  
    fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));
  8.  
    modbus_free(ctx);
  9.  
    return -1;
  10.  
    }
  11.  
     
  12.  
    modbus_close(ctx);
  13.  
    modbus_free(ctx);

關閉與下級建立的連接。

返回值:無

沖洗未連接數據int modbus_flush(modbus_t *ctx);

int modbus_flush(modbus_t *ctx);

用於丟棄已接收到的單未讀取到與ctx環境相匹配的套接字(socket)或文件描述符。

返回:成功返回0或刷新字節數,否則返回-1並設置errno。


主機(客戶端Client)

讀取數據

讀取位(讀取線圈狀態) int modbus_read_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest);

int modbus_read_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest);

用於讀遠程設備的 addr 地址開始的共nb 位(線圈)的狀態,讀取的結果以無符號的字節 (8 位) 設置為TRUE或FALSE存儲在目的數組dest中。

您必須注意分配足夠的內存以將結果存儲在dest位置,至少是nb* sizeof (uint8_t) 的內存大小。

 該函數使用0x01功能碼(讀取線圈狀態)。

返回:成功返回讀取位的數目即nb,失敗返回-1並設置errno為Too many bits requested。

譯者注:即取得一組邏輯線圈的當前狀態(1/0)。

讀取輸入位(讀取輸入狀態) int modbus_read_input_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest);

int modbus_read_input_bits(modbus_t *ctx, int addr, int nb, uint8_t *dest);

用於讀遠程設備的 addr 地址開始的共nb 位(輸入)的狀態。讀取的結果以無符號的字節 (8 位) 設置為TRUE或FALSE存儲在目的數組dest中。

您必須注意分配足夠的內存以將結果存儲在dest位置,至少是nb* sizeof (uint8_t) 的內存大小。

該函數使用0x02 功能碼(讀取輸入狀態)。

返回:成功返回讀取輸入位的數目即nb,失敗返回-1並設置errno為Too many discrete inputs requested。

譯者注:即取得一組開關輸入的當前狀態(1/0)。

讀取保持寄存器 int modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest);

  1.  
    int modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest);
  2.  
    //例子
  3.  
    modbus_t *ctx;
  4.  
    uint16_t tab_reg[64];
  5.  
    int rc;
  6.  
    int i;
  7.  
     
  8.  
    ctx = modbus_new_tcp( "127.0.0.1", 1502);
  9.  
    if (modbus_connect(ctx) == -1) {
  10.  
    fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));
  11.  
    modbus_free(ctx);
  12.  
    return -1;
  13.  
    }
  14.  
     
  15.  
    rc = modbus_read_registers(ctx, 0, 10, tab_reg);
  16.  
    if (rc == -1) {
  17.  
    fprintf(stderr, "%s\n", modbus_strerror(errno));
  18.  
    return -1;
  19.  
    }
  20.  
     
  21.  
    for (i=0; i < rc; i++) {
  22.  
    printf("reg[%d]=%d (0x%X)\n", i, tab_reg[i], tab_reg[i]);
  23.  
    }
  24.  
     
  25.  
    modbus_close(ctx);
  26.  
    modbus_free(ctx);

 用於讀遠程設備的 addr 地址開始的共nb 位(保持寄存器)的狀態。讀取結果以uint (16 位) 的形式存儲在dest數組中。

您必須注意分配足夠的內存以將結果存儲在dest位置,至少是nb* sizeof (uint16_t) 的內存大小。

該函數使用0x03 功能碼 (讀取保持寄存器)。

返回:成功返回讀取輸入位的數目即nb,失敗返回-1並設置errno為Too many registers requested。

 

讀取輸入寄存器int modbus_read_input_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest);

int modbus_read_input_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest);

 用於讀遠程設備的 addr 地址開始的共nb 位(輸入寄存器)的狀態。讀取結果以uint (16 位) 的形式存儲在dest數組中。

您必須注意分配足夠的內存以將結果存儲在dest位置,至少是nb* sizeof (uint16_t) 的內存大小。

該函數使用0x04 函數代碼 (讀取輸入寄存器)。保持寄存器和輸入寄存器具有曾經具有不同的意義, 但現在通常只使用保持寄存器。

返回:成功返回讀取輸入位的數目即nb,失敗返回-1並設置errno為Too many bits requested。

 

讀取控制器(controller)描述  int modbus_report_slave_id(modbus_t *ctx, int max_dest, uint8_t *dest);

  1.  
    int modbus_report_slave_id(modbus_t *ctx, int max_dest, uint8_t *dest);
  2.  
    //例子
  3.  
    uint8_t tab_bytes[MODBUS_MAX_PDU_LENGTH];
  4.  
     
  5.  
    ...
  6.  
     
  7.  
    rc = modbus_report_slave_id(ctx, MODBUS_MAX_PDU_LENGTH, tab_bytes);
  8.  
    if (rc > 1) {
  9.  
    printf("Run Status Indicator: %s\n", tab_bytes[1] ? "ON" : "OFF");
  10.  
    }

用於向控制器發送請求以獲取控制器描述。

存儲在dest中的響應包括:

從機(slave)ID ,此ID實際上完全不是唯一的,所以不能靠它來知道信息在響應中如何打包。

運行指示器狀態(0x00 = OFF, 0xFF = ON)

特定於每個控制器的附加數據,例如: libmodbus 以字符串形式返回庫的版本號。

此函數返回最多max_dest字節數據)到dest,所以要確保dest空間足夠。

返回:成功讀取數據的數量,如果輸出因為max_dest限制而被截斷,則返回值會返回若dest空間足夠情況下應該會寫入到dest的字節數,因此,大於max_dest的返回值意味着響應數據被截斷。失敗返回-1並設置errno。

寫數據

寫一位數據(強置單線圈)int modbus_write_bit(modbus_t *ctx, int addr, int status);

int modbus_write_bit(modbus_t *ctx, int addr, int status);

用於寫遠程設備addr地址處的狀態,值必須是TRUE或者FLASE。

該函數使用0x05功能碼(強置單線圈)。

返回:成功返回1,失敗返回-1並設置errno。

寫單寄存器(預置單寄存器)int modbus_write_register(modbus_t *ctx, int addr, int value);

int modbus_write_register(modbus_t *ctx, int addr, int value);

用於寫遠程設備addr地址處的數值,設置為value。

該函數使用0x06功能碼(預置單寄存器)。

返回:成功返回1,失敗返回-1並設置errno。

寫多位數據(強置多線圈)int modbus_write_bits(modbus_t *ctx, int addr, int nb, const uint8_t *src);

int modbus_write_bits(modbus_t *ctx, int addr, int nb, const uint8_t *src);

nb位 (線圈) 的狀態從src中寫入遠程設備地址addr,src數組必須包含設置為TRUEFALSE的字節.

該函數使用0x0F功能碼(強置多線圈)

返回:成功返回寫入位數nb,失敗返回-1並設置errno。

寫多寄存器(預置多寄存器)int modbus_write_registers(modbus_t *ctx, int addr, int nb, const uint16_t *src);

int modbus_write_registers(modbus_t *ctx, int addr, int nb, const uint16_t *src);

用於將src數組中的內容寫到遠程設備addr地址處的一組nb個寄存器。

該函數使用0x16功能碼(預置多寄存器)。

返回:成功返回寫入寄存器個數nb,失敗返回-1並設置errno。

寫和讀數據

在單個處理中寫入和讀取多個寄存器int modbus_write_and_read_registers(modbus_t *ctx, int write_addr, int write_nb, const uint16_t *src, int read_addr, int read_nb, const uint16_t *dest);

int modbus_write_and_read_registers(modbus_t *ctx, int write_addr, int write_nb, const uint16_t *src, int read_addr, int read_nb, const uint16_t *dest);

將src數組中的內容寫到遠程設備write_addr地址處的一組write_nb個寄存器,然后讀取read_addr處的一組read_nb個寄存器內容並保存到dest數組。

該函數使用0x17 函數代碼 (寫/讀寄存器)。

返回:如果成功, 該函數應返回讀取寄存器的數目。否則, 將返回-1 並設置 errno為:Too many registers requested, Too many registers to write。

原始請求

發送原始請求 int modbus_send_raw_request (modbus_t *ctx, uint8_t *raw_req, int raw_req_length);

  1.  
    int modbus_send_raw_request (modbus_t *ctx, uint8_t *raw_req, int raw_req_length);
  2.  
    //例子
  3.  
    modbus_t *ctx;
  4.  
    /* Read 5 holding registers from address 1 */
  5.  
    uint8_t raw_req[] = { 0xFF, MODBUS_FC_READ_HOLDING_REGISTERS, 0x00, 0x01, 0x0, 0x05 };
  6.  
    int req_length;
  7.  
    uint8_t rsp[MODBUS_TCP_MAX_ADU_LENGTH];
  8.  
     
  9.  
    ctx = modbus_new_tcp( "127.0.0.1", 1502);
  10.  
    if (modbus_connect(ctx) == -1) {
  11.  
    fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));
  12.  
    modbus_free(ctx);
  13.  
    return -1;
  14.  
    }
  15.  
     
  16.  
    req_length = modbus_send_raw_request(ctx, raw_req, 6 * sizeof(uint8_t));
  17.  
    modbus_receive_confirmation(ctx, rsp);
  18.  
     
  19.  
    modbus_close(ctx);
  20.  
    modbus_free(ctx);

通過在ctx環境下的套接口(socket)發送請求,此函數只用於調試,你必須小心的提出有效的請求,此函數只會添加到消息、所選后端的報頭或者CRC(the header or CRC of the selected backend),, 因此raw_req必須啟動並包含至少一個從站/單元的ID和一個函數代碼。此函數可用於發送未由庫處理的請求。

libmodbus 的公共標頭提供了支持的MODBUS_FC_函數代碼的列表, 前綴為MODBUS_FC_READ_HOLDING_REGISTERS, 以幫助建立原始請求。

返回:完整的消息長度,計算與后端有關的額外數據。否則,它將返回- 1並設置errno。

收到確認請求 int modbus_receive_confirmation(modbus_t *ctx, uint8_t *rsp);

  1.  
    int modbus_receive_confirmation(modbus_t *ctx, uint8_t *rsp);
  2.  
    //例子
  3.  
    uint8_t rsp[MODBUS_MAX_ADU_LENGTH];
  4.  
    rc = modbus_receive_confirmation(ctx, rsp);

通過在ctx環境下的套接口(socket)接受請求,此函數只用於調試,因為不會根據初試請求檢查接受到的響應,此函數可用於接受未由庫處理的請求。

響應的最大大小取決於使用的后端, 在 RTU 中,rsp必須是MODBUS_RTU_MAX_ADU_LENGTH字節, 在 TCP 中必須是MODBUS_TCP_MAX_ADU_LENGTH字節。如果要編寫與兩者兼容的代碼, 可以使用常量MODBUS_MAX_ADU_LENGTH (所有 libmodbus 后台的最大值)。注意分配足夠的內存以存儲響應以避免服務器崩潰。

返回:將確認請求存儲於rsp中,並在成功是返回響應長度,如果忽略指示請求,返回的請求長度可以是0(例如,在RTU模式下對另一個從機slave的查詢)。否則返回-1並設置errno。

回復異常

發送一個異常響應*int modbus_reply_exception(modbus_t *ctx, const uint8_t *req, unsigned int exception_code);

*int modbus_reply_exception(modbus_t *ctx, const uint8_t *req, unsigned int exception_code);

基於參數中的exception_code發送異常響應。

libmodbus 提供了以下異常代碼:

MODBUS_EXCEPTION_ILLEGAL_FUNCTION (1)

MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS (2)

MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE (3)

MODBUS_EXCEPTION_SLAVE_OR_SERVER_FAILURE (4)

MODBUS_EXCEPTION_ACKNOWLEDGE (5)

MODBUS_EXCEPTION_SLAVE_OR_SERVER_BUSY (6)

MODBUS_EXCEPTION_NEGATIVE_ACKNOWLEDGE (7)

MODBUS_EXCEPTION_MEMORY_PARITY (8)

MODBUS_EXCEPTION_NOT_DEFINED (9)

MODBUS_EXCEPTION_GATEWAY_PATH (10)

MODBUS_EXCEPTION_GATEWAY_TARGET (11)

建立有效的響應需要初始請求req

返回:成功則返回發送響應的長度,否則返回-1並設置errno為The exception code is invalid。


從機(服務器server)

服務器(server)等待來自於客戶端(client)的請求,並且必須在收到請求的時候回答,libmodbus 提供以下功能來處理請求:

數據映射

分配位(線圈)和寄存器的數組modbus_mapping_t modbus_mapping_new (int nb_bits, int nb_input_bits, int nb_registers, intnb_input_registers);

  1.  
    modbus_mapping_t modbus_mapping_new (int nb_bits, int nb_input_bits, int nb_registers, int nb_input_registers);
  2.  
     
  3.  
    //例子
  4.  
    /* The fist value of each array is accessible from the 0 address. */
  5.  
    mb_mapping = modbus_mapping_new(BITS_ADDRESS + BITS_NB,
  6.  
    INPUT_BITS_ADDRESS + INPUT_BITS_NB,
  7.  
    REGISTERS_ADDRESS + REGISTERS_NB,
  8.  
    INPUT_REGISTERS_ADDRESS + INPUT_REGISTERS_NB);
  9.  
    if (mb_mapping == NULL) {
  10.  
    fprintf(stderr, "Failed to allocate the mapping: %s\n",
  11.  
    modbus_strerror(errno));
  12.  
    modbus_free(ctx);
  13.  
    return -1;
  14.  
    }

分配四數組來存儲位(譯者:線圈)、輸入位、(保持)寄存器和輸入寄存器。指針存儲在 modbus_mapping_t 結構中。數組的所有值都初始化為零。

如果沒有必要為特定類型的數據分配數組, 則可以在參數中傳遞零值, 關聯的指針將賦值為 NULL。

此函數便於處理在服務器/從機中的請求。(譯者注:在modbus中,server(服務器)和slave(從站)含義相同,client(客戶端)和master(主站)含義相同)。

返回:成功,則返回新分配的結構,否則返回NULL並設置errno為Not enough memory。

釋放modbus_mapping_t 結構void modbus_mapping_free(modbus_mapping_t *mb_mapping);

void modbus_mapping_free(modbus_mapping_t *mb_mapping);

釋放 mb_mapping_t 結構的4個數組, 最后由mb_mapping引用的 mb_mapping_t。

接收

收到指示請求 int modbus_receive(modbus_t *ctx, uint8_t *req);

int modbus_receive(modbus_t *ctx, uint8_t *req);

從ctx環境socket接收指示請求,該函數由服務器接收並分析主機/客戶端發送的指示請求。

如果需要使用其他套接字或文件描述符, 而不是在ctx環境中定義的, 請參閱函數modbus_set_socket (3).

返回:將指示請求存儲到req中,並返回請求長度。否則返回-1並設置errno。

回復

響應收到的請求int modbus_reply(modbus_t *ctx, const uint8_t *req, int req_length, modbus_mapping_t *mb_mapping);

int modbus_reply(modbus_t *ctx, const uint8_t *req, int req_length, modbus_mapping_t *mb_mapping);

對收到的請求進行響應,分析給定的req請求,然后使用ctx環境信息建立一個響應並發送。

如果請求指示讀取或寫入一個值,則操作會根據操作的數據類型在mb_mapping映射中執行。

如果發生錯誤, 將發送異常響應。

此功能是為 "服務器(從機)" 設計的。

返回:成功則返回響應的長度。否則返回-1並設置errno為Sending has failed,另外請參閱the errors returned by the syscall used to send the response (eg. send or write).

發送異常響應int modbus_reply_exception(modbus_t *ctx, const uint8_t *req, unsigned int exception_code);

int modbus_reply_exception(modbus_t *ctx, const uint8_t *req, unsigned int exception_code);

基於參數中的exception_code發送異常響應。

libmodbus 提供了以下異常代碼:

MODBUS_EXCEPTION_ILLEGAL_FUNCTION (1)

MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS (2)

MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE (3)

MODBUS_EXCEPTION_SLAVE_OR_SERVER_FAILURE (4)

MODBUS_EXCEPTION_ACKNOWLEDGE (5)

MODBUS_EXCEPTION_SLAVE_OR_SERVER_BUSY (6)

MODBUS_EXCEPTION_NEGATIVE_ACKNOWLEDGE (7)

MODBUS_EXCEPTION_MEMORY_PARITY (8)

MODBUS_EXCEPTION_NOT_DEFINED (9)

MODBUS_EXCEPTION_GATEWAY_PATH (10)

MODBUS_EXCEPTION_GATEWAY_TARGET (11)

建立有效的響應需要初始請求要求。

返回:成功則返回發送的響應的長度,否則返回-1並設置errno為The exception code is invalid。

錯誤處理

libmodbus功能使用POSIX系統上的標准約定處理錯誤。一般來說,這意味着一旦發生故障,libmodbus函數將返回一個NULL值(如果返回一個指針)或一個負值(如果返回一個整數),並且實際的錯誤代碼將被存儲在errno變量中。

提供modbus_strerror()函數將libmodbus特定的錯誤代碼轉換為錯誤消息字符串;

返回錯誤信息const char *modbus_strerror(int errnum);

  1.  
    const char *modbus_strerror(int errnum);
  2.  
    //例子
  3.  
    if (modbus_connect(ctx) == -1) {
  4.  
    fprintf(stderr, "Connection failed: %s\n", modbus_strerror(errno));
  5.  
    abort();
  6.  
    }

會返回一個指向與errnum參數指定的錯誤號對應的錯誤消息字符串的指針。由於 libmodbus 定義了超出操作系統定義的其他錯誤號, 因此應用程序應該使用modbus_strerror ()來優先於標准strerror ()函數發送錯誤消息。

返回:返回一個指向錯誤消息字符串的指針。


雜項

該LIBMODBUS_VERSION_STRING表示libmodbus版本的程序已編譯對應版本。變量libmodbus_version_major, libmodbus_version_minor,libmodbus_version_micro給出程序鏈接的版本。

作者

libmodbus 文檔作者

Stéphane Raimbault<stephane.raimbault@gmail.com>

資源

主頁:http://www.libmodbus.org/

提交問題http://github.com/stephane/libmodbus/issues.

版權協議

根據GNU通用公共許可證(LGPLv2.1 +)的條款,免​​費使用此軟件。有關詳細信息,請參閱COPYING.LESSERlibmodbus發行版隨附的文件。


如有翻譯錯誤,歡迎私信、評論指正,謝謝!

 

RT-Thread libmodbus RS485 RTU主機調試 - STM32F107VCT6

參考路徑:   

https://mp.weixin.qq.com/s?src=11&timestamp=1614069043&ver=2907&signature=GYs5M6ZsiC7jjupf19EXzbJ5LN7knOaDsyccPjjbpGK4qxnITxxNnyn8i2xabion51Fuj37-aP8DYzIBTGdNQvh4g4vcccTREZylxHuBr1CYKX2I6e8Wsqeuddp-N2wR&new=1

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM