0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

libmodbus情景分析

瑞薩MCU小百科 ? 來源:瑞薩MCU小百科 ? 2024-11-25 14:29 ? 次閱讀

11.3libmodbus情景分析

以“modbus_write_bits”函數(shù)為例,分析下圖的執(zhí)行流程:

9ca80230-aae2-11ef-93f3-92fbcf53809c.png

11.3.1

初始化

1. 主設(shè)備初始化

主設(shè)備程序先調(diào)用“modbus_new_rtu”函數(shù),僅僅是分配一個modbus結(jié)構(gòu)體,在里面記錄要使用的串口設(shè)備、參數(shù)

左右滑動查看完整內(nèi)容

modbus_t *
modbus_new_rtu(const char *device, int baud, char parity, int data_bit, int stop_bi
t);

再調(diào)用“modbus_set_slave”,是設(shè)置“要訪問哪個從設(shè)備”。每當(dāng)訪問不同地址的設(shè)備之前,都應(yīng)該調(diào)用這個函數(shù)。

最后調(diào)用“modbus_connect”函數(shù),這個函數(shù)只是打開串口、設(shè)置串口參數(shù),并沒有跟從設(shè)備進(jìn)行數(shù)據(jù)交互。

2. 從設(shè)備初始化

從設(shè)備的初始化,跟主設(shè)備類似,不過多了使用“modbus_mapping_new_start_address”函數(shù)創(chuàng)建寄存器 buffer。

modbus_mapping_t結(jié)構(gòu)體如下定義:

左右滑動查看完整內(nèi)容

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;

它被用來描述DI、DO、AI、AO四類寄存器。以DO寄存器為例,這個結(jié)構(gòu)體里有3個成員:

①nb_bits:DO寄存器個數(shù)。

②start_bits:DO寄存器起始寄存器地址。

③tab_bits:指向一個“uint8_t”類型的數(shù)組,里面每個數(shù)組項(xiàng)表示一個DO寄存器,這個數(shù)組大小為nb_bits。數(shù)組中第0項(xiàng),對應(yīng)第“start_bits”個DO寄存器。

“modbus_mapping_new_start_address”函數(shù)原型

如下:

左右滑動查看完整內(nèi)容

/* Allocates 4 arrays to store bits, input bits, registers and inputs
 registers. The pointers are stored in modbus_mapping structure.
 The modbus_mapping_new_start_address() function shall return the new allocated
 structure if successful. Otherwise it shall return NULL and set errno to
 ENOMEM. */
modbus_mapping_t *modbus_mapping_new_start_address(unsigned int start_bits,
 unsigned int nb_bits,
 unsigned int start_input_bits,
 unsigned int nb_input_bits,
 unsigned int start_registers,
 unsigned int nb_registers,
 unsigned int start_input_registers,
 unsigned int nb_input_registers);

假設(shè)從設(shè)備執(zhí)行了如下代碼:

左右滑動查看完整內(nèi)容

modbus_mapping_t *mb_mapping;
mb_mapping = modbus_mapping_new_start_address(0,
 4, /* DO, 4 個寄存器 */
 0,
 3, /* DI, 3 個寄存器 */
 0, 
 2, /* AO, 2 個寄存器 */
 0,
 1; /* AI, 1 個寄存器 */

將會分配出如下結(jié)構(gòu)體:

9cd4fa60-aae2-11ef-93f3-92fbcf53809c.png

modbus傳輸?shù)谋举|(zhì),就是讀寫上圖中4個數(shù)組。

11.3.2

主設(shè)備發(fā)送請求

主設(shè)備調(diào)用“modbus_write_bits”函數(shù),想寫若干個DO寄存器,比如:

左右滑動查看完整內(nèi)容

01 uint8_t buf[2] = {1, 0};
02 int rc = modbus_write_bits(ctx, 0, 2, buf);

根據(jù)Modbus RTU協(xié)議,它必定執(zhí)行如下操作:

①構(gòu)造數(shù)據(jù)包

②通過串口發(fā)送數(shù)據(jù)包

③等待、讀取回復(fù)

對于上述代碼,數(shù)據(jù)包的內(nèi)容如下:

9cf61e70-aae2-11ef-93f3-92fbcf53809c.png

1. 先構(gòu)造包頭

函數(shù)調(diào)用關(guān)系如下:

9cfccbd0-aae2-11ef-93f3-92fbcf53809c.png

2. 再構(gòu)造數(shù)據(jù)

代碼如下:

9d0a64f2-aae2-11ef-93f3-92fbcf53809c.png

3. 計算檢驗(yàn)碼

在發(fā)送數(shù)據(jù)包的函數(shù)里,先計算檢驗(yàn)碼,代碼如下:

9d25de9e-aae2-11ef-93f3-92fbcf53809c.png

4. 發(fā)送數(shù)據(jù)包

前面構(gòu)造好了數(shù)據(jù)包,發(fā)送就比較簡單:調(diào)用write函數(shù)進(jìn)行發(fā)送即可。代碼如下:

9d3135aa-aae2-11ef-93f3-92fbcf53809c.png

11.3.3

從設(shè)備接收請求

從設(shè)備的程序一直在等待主機(jī)發(fā)來的消息,示例代碼如下:

9d449f14-aae2-11ef-93f3-92fbcf53809c.png

“modbus_receive”函數(shù)內(nèi)部實(shí)現(xiàn)為:

①使用select機(jī)制,逐個讀取字符

②根據(jù)讀到的字符,分辨還需要讀多少數(shù)據(jù)

1. 讀取單個字符

函數(shù)調(diào)用關(guān)系如下:

9d4cf434-aae2-11ef-93f3-92fbcf53809c.png

2. 判斷還需要讀取多少數(shù)據(jù)

從設(shè)備讀取主設(shè)備發(fā)來的請求包時,步驟為:

①先讀取“功能碼”

②再根據(jù)功能碼判斷后續(xù)要的包頭數(shù)據(jù)還剩多少,讀取包頭

③最后根據(jù)包頭數(shù)據(jù)解析要讀多少數(shù)據(jù),讀取數(shù)據(jù)。

流程如下圖所示:

9d58f090-aae2-11ef-93f3-92fbcf53809c.png

確定第1個階段數(shù)據(jù)長度的代碼如下:

9d75852a-aae2-11ef-93f3-92fbcf53809c.png

讀到功能碼后,根據(jù)功能碼計算剩下的包頭的數(shù)據(jù):

9d8dfa6a-aae2-11ef-93f3-92fbcf53809c.png

讀到完整的包頭后,計算剩下的數(shù)據(jù)長度:

9d9d0442-aae2-11ef-93f3-92fbcf53809c.png

3. 判斷數(shù)據(jù)完整性

就是根據(jù)校驗(yàn)碼判斷數(shù)據(jù)是否有錯誤,代碼如下:

9dc86a4c-aae2-11ef-93f3-92fbcf53809c.png

11.3.4

從設(shè)備回應(yīng)

從設(shè)備接收到請求后,調(diào)用如下函數(shù)進(jìn)行處理、回應(yīng):

9dd553f6-aae2-11ef-93f3-92fbcf53809c.png

在“modbus_reply”函數(shù)內(nèi)部,它會:

①對于寫請求:把請求包中的數(shù)據(jù)解析出入,填入 mb_mapping中對應(yīng)的寄存器buffer;

②對于讀請求:從mb_mapping中對應(yīng)的寄存器buffer取出數(shù)據(jù);

③構(gòu)造回復(fù)包,發(fā)送給主設(shè)備。

本情景分析中,主設(shè)備調(diào)用“modbus_write_bits”函數(shù),想寫兩個DO寄存器,比如:

左右滑動查看完整內(nèi)容

01 uint8_t buf[2] = {1, 0};
02 int rc = modbus_write_bits(ctx, 0, 2, buf);

從設(shè)備使用“modbus_reply”函數(shù)處理。

1. 根據(jù)請求包設(shè)置寄存器buffer

代碼如下:

9df04e9a-aae2-11ef-93f3-92fbcf53809c.png

2. 構(gòu)造回復(fù)包

對于“寫多個DO寄存器”的請求,它的回復(fù)包格式如下:

9e1f1a18-aae2-11ef-93f3-92fbcf53809c.png

下面的代碼,構(gòu)造的回復(fù)包里含有上圖1、2的信息(在發(fā)送回復(fù)包時才構(gòu)造校驗(yàn)碼):

9e31e6c0-aae2-11ef-93f3-92fbcf53809c.png

3. 發(fā)送回復(fù)包

最后,從設(shè)備發(fā)送回復(fù)包:

9e3d09ba-aae2-11ef-93f3-92fbcf53809c.png

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • MODBUS
    +關(guān)注

    關(guān)注

    28

    文章

    1812

    瀏覽量

    77134
  • MPU
    MPU
    +關(guān)注

    關(guān)注

    0

    文章

    374

    瀏覽量

    48869
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4340

    瀏覽量

    62791
  • LibModbus
    +關(guān)注

    關(guān)注

    0

    文章

    9

    瀏覽量

    7260

原文標(biāo)題:libmodbus情景分析 - RZ MPU工業(yè)控制教程連載(39)

文章出處:【微信號:瑞薩MCU小百科,微信公眾號:瑞薩MCU小百科】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    第6章_libmodbus使用

    libmodbus是一個免費(fèi)的跨平臺支持RTU和TCP的Modbus庫,遵循LGPL V2.1+協(xié)議。libmodbus支持Linux、Mac Os X、FreeBSD、QNX和Windows等
    的頭像 發(fā)表于 06-29 14:36 ?2601次閱讀
    第6章_<b class='flag-5'>libmodbus</b>使用

    情景分析-ARM內(nèi)核、不錯的ARM內(nèi)核資料

    情景分析-ARM內(nèi)核、不錯的ARM內(nèi)核資料
    發(fā)表于 05-21 23:42

    Linux內(nèi)核情景分析 非掃描版

    珍藏資料放送Linux內(nèi)核情景分析非掃描版
    發(fā)表于 03-12 20:10

    【圖書分享】《Linux內(nèi)核源代碼情景分析

    本帖最后由 小Z 于 2014-3-21 14:06 編輯 書名:《Linux內(nèi)核源代碼情景分析》目錄:附件:
    發(fā)表于 03-19 15:16

    Linux內(nèi)核情景分析_上下全集高清版pdf

    國內(nèi)Linux內(nèi)核分析經(jīng)典書籍-Linux內(nèi)核源代碼情景分析(上下全集卷).pdf需要的自行下載
    發(fā)表于 11-15 16:41

    Linux內(nèi)核源代碼情景分析

    Linux內(nèi)核源代碼情景分析
    發(fā)表于 03-03 10:19

    libmodbus使用ubuntu系統(tǒng)

    libmodbus使用ubuntu系統(tǒng)使用libmodbusarm-linux使用libmodbus解壓安裝移植編譯modbus從機(jī)模擬ubuntu系統(tǒng)使用libmodbusubuntu系統(tǒng)可以直接
    發(fā)表于 11-04 07:57

    基于select操作的libmodbus

    libmodbus庫從軟件包里啟用, libmodbus是基于select操作的,依賴于文件系統(tǒng)和libc,需要在rt-thread中開啟對應(yīng)的支持。一開始以為作為主站時,有函數(shù)可以自動的指定讀取
    發(fā)表于 01-11 08:13

    Linux內(nèi)核源代碼情景分析(上冊)浙江大學(xué)

    本書著重于對LINUX系統(tǒng)最新版本(2.4.0)內(nèi)核源代碼進(jìn)行情景描述和情景分析. 上冊共6章.
    發(fā)表于 06-10 14:40 ?0次下載
    Linux內(nèi)核源代碼<b class='flag-5'>情景</b><b class='flag-5'>分析</b>(上冊)浙江大學(xué)

    Linux內(nèi)核源代碼情景分析(下冊)浙江大學(xué)

    本書著重于對LINUX系統(tǒng)最新版本(2.4.0)內(nèi)核源代碼進(jìn)行情景描述和情景分析. 上冊共3章.
    發(fā)表于 06-10 14:43 ?0次下載

    JFFS2源代碼情景分析

    jiffs2 源代碼情景分析 簡單明白 適合初學(xué)者
    發(fā)表于 02-23 15:50 ?15次下載

    Linux內(nèi)核源代碼情景分析(全冊高清帶書簽)pdf下載

    Linux內(nèi)核源代碼情景分析需要的拿走吧
    發(fā)表于 01-04 16:57 ?9次下載

    LINUX內(nèi)核源代碼情景分析上冊PDF電子書免費(fèi)下載

    《LINUX內(nèi)核源代碼情景分析(上冊)》采取類似于英語教學(xué)中行之有效的情景會話的教學(xué)方法,全面深入地剖析了Linux最新版本核心源代碼,并對Linux核心的獨(dú)特優(yōu)點(diǎn)和需要進(jìn)一步改進(jìn)的問題作了精辟
    發(fā)表于 10-12 15:52 ?90次下載
    LINUX內(nèi)核源代碼<b class='flag-5'>情景</b><b class='flag-5'>分析</b>上冊PDF電子書免費(fèi)下載

    libmodbus之嵌入式Linux使用及測試

    libmodbus使用ubuntu系統(tǒng)使用libmodbusarm-linux使用libmodbus解壓安裝移植編譯modbus從機(jī)模擬ubuntu系統(tǒng)使用libmodbusubuntu系統(tǒng)可以直接
    發(fā)表于 11-01 16:57 ?15次下載
    <b class='flag-5'>libmodbus</b>之嵌入式Linux使用及測試

    libmodbus源碼框架分析

    libmodbus作為一個優(yōu)秀且免費(fèi)開源的跨平臺支持RTU 和 TCP模式的Modbus開發(fā)庫,非常值得大家借鑒和學(xué)習(xí)。本章對libmodbus源代碼進(jìn)行閱讀和分析。
    的頭像 發(fā)表于 11-21 13:47 ?490次閱讀
    <b class='flag-5'>libmodbus</b>源碼框架<b class='flag-5'>分析</b>