日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

uip+freemodbus网络通信

發(fā)布時間:2023/12/20 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 uip+freemodbus网络通信 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前言:

TCP/IP協(xié)議通過uip協(xié)議棧來實現(xiàn),應(yīng)用層的modbus協(xié)議使用freemodbus來實現(xiàn),另外還需要一個網(wǎng)卡(筆者使用的是KSZ8851網(wǎng)卡控制器)來實現(xiàn)底層的數(shù)據(jù)傳輸(包括物理層、數(shù)據(jù)鏈路層)。
下面先介紹uip協(xié)議棧和freemodbus庫的使用,后續(xù)移植過程和測試結(jié)果再更新

一、uip協(xié)議棧

uIP協(xié)議棧去掉了完整的TCP/IP中不常用的功能,簡化了通訊流程,但保存了網(wǎng)絡(luò)通訊必須使用的協(xié)議,設(shè)計重點放在了IP/TCP/ICMP/UDP/ARP這些網(wǎng)絡(luò)層和傳輸層協(xié)議上,保證了其代碼的通用性和結(jié)構(gòu)的穩(wěn)定性。UIP提供的是封裝的策略。
由上往下逐步封裝用戶的數(shù)據(jù),如:
應(yīng)用層----------傳輸層--------網(wǎng)絡(luò)層------數(shù)據(jù)鏈路層-----物理層
應(yīng)用數(shù)據(jù)—TCP封裝頭部—IP封裝頭部-----mac封裝+尾部-----發(fā)送

  • uIP協(xié)議棧與底層的交互
    uIP提供了三個函數(shù)到底層,既uip_init(), uip_input() 和uip_periodic(),同時還提供了許多函數(shù)與堆棧交互。當(dāng)設(shè)備驅(qū)動放一個輸入包到包緩存里(up_buf),系統(tǒng)將調(diào)用uip_input()函數(shù).函數(shù)將會處理這個包和需要時調(diào)用應(yīng)用程序。當(dāng)uip_input()返回,一個輸出包放在包緩存里。包的大小由全局變量uip_len約束。如果uip_len是0,則說明沒有包要發(fā)送。周期計時是用于驅(qū)動所有的uIP內(nèi)部時鐘事件。當(dāng)周期計時激發(fā),每一個TCP連接應(yīng)該調(diào)用uIP函數(shù)uip_periodic()。連接編號傳遞的是作為自變量給uip_periodic()函數(shù)的。類似于uip_input()函數(shù),當(dāng)uip_periodic()函數(shù)返回,輸出的IP包要放到包緩存里。任何的事物需要經(jīng)過一定的初始階段,在UIP協(xié)議里面通過uip_init()來初始化。
  • uIP協(xié)議棧與應(yīng)用程序的接口
    應(yīng)用程序作為單獨的模塊由用戶實現(xiàn),uIP協(xié)議棧提供一系列接口函數(shù)供用戶程序調(diào)用。用戶需要將應(yīng)用層入口程序作為接口提供給uIP協(xié)議棧,定義為宏UIP_APPCALL()。uIP在接受到底層傳來的數(shù)據(jù)包后,若需要送到上層應(yīng)用程序處理,它就調(diào)用UIP_APPCALL()。在uIP協(xié)議中有一個uip_buf緩沖用來接收和發(fā)送數(shù)據(jù)。
  • uIP 提供的接口函數(shù)有:
    ? 初始化 uIP 協(xié)議棧:uip_init()
    ? 處理輸入包:uip_input()
    ? 處理周期計時事件:uip_periodic()
    ? 開始監(jiān)聽端口:uip_listen()
    ? 連接到遠(yuǎn)程主機:uip_connect()
    ? 接收到連接請求:uip_connected()
    ? 主動關(guān)閉連接:uip_close()
    ? 連接被關(guān)閉:uip_closed()
    ? 發(fā)出去的數(shù)據(jù)被應(yīng)答:uip_acked()
    ? 在當(dāng)前連接發(fā)送數(shù)據(jù):uip_send()
    ? 在當(dāng)前連接上收到新的數(shù)據(jù):uip_newdata()
    ? 告訴對方要停止連接:uip_stop()
    ? 連接被意外終止:uip_aborted()
  • 二、應(yīng)用層modbus協(xié)議(FreeModbus)

    FreeModbus是針對通用的Modbus協(xié)議棧在嵌入式系統(tǒng)中應(yīng)用的一個實現(xiàn)。Modbus協(xié)議是一個在工業(yè)制造領(lǐng)域中得到廣泛應(yīng)用的一個網(wǎng)絡(luò)協(xié)議。一個Modbus通信協(xié)議棧包括兩層:定義了數(shù)據(jù)結(jié)構(gòu)和功能Modbus應(yīng)用協(xié)議和網(wǎng)絡(luò)層。目前版本的FreeModbus支持如下的功能碼:讀輸入寄存器 (0x04);讀保持寄存器 (0x03);寫單個寄存器 (0x06);寫多個寄存器 (0x10);讀/寫多個寄存器 (0x17);讀取線圈狀態(tài) (0x01);寫單個線圈 (0x05);寫多個線圈 (0x0F);讀輸入狀態(tài) (0x02);報告從機標(biāo)識 (0x11);
    應(yīng)用Modbus TCP協(xié)議,當(dāng)準(zhǔn)備處理一個新數(shù)據(jù)幀的時候,移植層就必須首先向協(xié)議棧發(fā)送一個事件標(biāo)志。然后,協(xié)議棧調(diào)用一個返回值為接收到的Modbus TCP數(shù)據(jù)幀的函數(shù),并且開始處理這個數(shù)據(jù)幀。如果數(shù)據(jù)有效,則相應(yīng)的Modbus反饋幀將提供給移植層生成反饋幀。最后,該反饋被發(fā)送到客戶端。
    FreeModbus必須首先調(diào)用初始化功能eMBInit()函數(shù)(使用modbus TCP模式時使用eMBTCPInit()函數(shù)),然后調(diào)用eMBEnable(),最后在循環(huán)體中調(diào)用eMBPoll()函數(shù)。

  • eMBTCPInit()函數(shù)
    該函數(shù)主要設(shè)置偵聽的端口和對需要調(diào)用的函數(shù)指針進行復(fù)制:
    pvMBFrameStartCur = eMBTCPStart;
    pvMBFrameStopCur = eMBTCPStop;
    peMBFrameReceiveCur = eMBTCPReceive;
    peMBFrameSendCur = eMBTCPSend;
    pvMBFrameCloseCur = MB_PORT_HAS_CLOSE ? vMBTCPPortClose : NULL;
    ucMBAddress = MB_TCP_PSEUDO_ADDRESS;
    eMBCurrentMode = MB_TCP;
    eMBState = STATE_DISABLED;
    右邊的函數(shù)如eMBTCPStart、eMBTCPStop等定義在mbtcp.c中
  • eMBEnable()函數(shù)
    ? 檢查modbus功能是否都被關(guān)閉,如果不是關(guān)閉(可能是沒有初始化或者已經(jīng)打開),就返回錯誤;
    ? 如果是disable狀態(tài),主要做兩件事:首先調(diào)用pvMBFrameStartCur,在eMBTCPInit()函數(shù)中指向了eMBTCPStart函數(shù);然后將eMB狀態(tài)改為使能狀態(tài),即初始化結(jié)束。
  • eMBPoll()總線偵聽函數(shù)
    檢查是否有事件發(fā)送,如果有,則根據(jù)不太類型的事件響應(yīng):
    ? EV_READY事件,表示系統(tǒng)剛剛進入偵聽狀態(tài),則什么都不做;
    ? EV_FRAME_RECEIVED事件,表示接收到完整的幀,做兩件事情:調(diào)用peMBFrameReceiveCur()函數(shù),解析出地址、數(shù)據(jù)和長度;然后檢查地址,如果是廣播地址或本機地址(廣播地址表示從機接收,本機地址表示從機發(fā)送),就調(diào)用xMBPortEventPost( EV_EXECUTE ),將接收器的狀態(tài)更改為EV_EXECUTE;
    ? EV_EXECUTE事件,在函數(shù)列表中檢查,有沒有與命令字段相符合的函數(shù),若有則執(zhí)行響應(yīng)的函數(shù),否則返回非法功能碼;然后再次檢查地址,如果不等于廣播地址(即表示從機為發(fā)送狀態(tài)),則調(diào)用peMBFrameSendCur()函數(shù),開始發(fā)送數(shù)據(jù)包
    ? EV_FRAME_SENT事件,直接break(響應(yīng)寫進EV_EXECUTE事件中)
  • 三、移植過程

    先展示一下加入的uip協(xié)議棧和freemodbus庫在工程中的示例

    運行的主函數(shù)

    int main() {timer_typedef periodic_timer, arp_timer;uip_ipaddr_t ipaddr;/* 設(shè)定查詢定時器 ARP定時器 *//* TCP定時器修改為100ms */timer_set(&periodic_timer, CLOCK_SECOND / 10);timer_set(&arp_timer, CLOCK_SECOND * 10);/* IO口初始化 主要是為了避免SPI總線上的其他設(shè)備 *//* 配置systic作為1ms中斷 *///uIP協(xié)議棧需要使用時鐘,為TCP和ARP的定時器服務(wù)。//需根據(jù)芯片調(diào)整/* 初始化SPI2 *///我這里的網(wǎng)卡和芯片的通信是spi協(xié)議,所以還需要初始化spi口/* KSZ8851初始化 *///網(wǎng)卡初始化/* UIP協(xié)議棧初始化 */uip_init();/* 設(shè)置本機IP地址 */uip_ipaddr(ipaddr, 192,168,1,15); uip_sethostaddr(ipaddr);/* 設(shè)置默認(rèn)路由器IP地址 */uip_ipaddr(ipaddr, 192,168,1,1); uip_setdraddr(ipaddr);/* 設(shè)置網(wǎng)絡(luò)掩碼 */uip_ipaddr(ipaddr, 255,255,255,0); uip_setnetmask(ipaddr); // MODBUS TCP偵聽默認(rèn)端口 502eMBTCPInit(MB_TCP_PORT_USE_DEFAULT); eMBEnable();/* 打印本機IP地址 */ // printf("\r\nuip start!\r\n"); // printf("ipaddr:192.168.1.15\r\n");while (1){ /*總線偵聽*/eMBPoll();/* 讀取以太網(wǎng)數(shù)據(jù)包,返回數(shù)據(jù)長度 */uip_len = tapdev_read();/* 收到數(shù)據(jù) */if(uip_len > 0) {/* 收到IP數(shù)據(jù)包,調(diào)用uip_input()處理IP數(shù)據(jù)包 */if(BUF->type == htons(UIP_ETHTYPE_IP)){uip_arp_ipin();uip_input();/* 處理完成后如果UIP_BUF里有數(shù)據(jù),即uip_len>0,則發(fā)送出去*/if (uip_len > 0){uip_arp_out();tapdev_send();}}/* 收到ARP數(shù)據(jù)包,調(diào)用uip_arp_arpin處理ARP報文 */else if (BUF->type == htons(UIP_ETHTYPE_ARP)){uip_arp_arpin();/* 查看是否有要發(fā)送的數(shù)據(jù)并發(fā)送*/if (uip_len > 0){tapdev_send();}}}/* 0.5秒定時器超時 查看0.5s是否到了,調(diào)用uip_periodic處理TCP超時程序*/if(timer_expired(&periodic_timer)) {timer_reset(&periodic_timer);/* 處理TCP連接, UIP_CONNS缺省是10個 */for(uint8_t i = 0; i < UIP_CONNS; i++){/* 處理TCP通信事件 */uip_periodic(i); if(uip_len > 0){uip_arp_out();tapdev_send();}} /* 定期ARP處理 10s到了就處理ARP*/if (timer_expired(&arp_timer)){timer_reset(&arp_timer);uip_arp_timer();}}} }

    四、測試

  • 測試環(huán)境
    局域網(wǎng)下板卡與路由器采用網(wǎng)線連接,PC端模擬上位機通過wifi接入局域網(wǎng),使用Modbus Poll模擬modbus主機,向從機發(fā)出查詢指令。
  • 測試內(nèi)容
    ? 串口打印信息:初始化各模塊、建立連接、收到請求、關(guān)閉連接
    ? Wireshark抓包信息:TCP三次握手、keep-alive幀、modbus的收發(fā)。
    ? Modbus poll讀值:Modbus poll作為modbus主機能讀到從機對應(yīng)傳感器值的變化
  • 測試結(jié)果
    ? 串口打印信息

    ? Wireshark抓包信息
    下圖中192.168.2.2是PC的ip地址,而192.168.2.10為板卡設(shè)置的ip地址。

    ? Modbus poll讀值
    下圖中左邊一列為傳感器的名稱,右邊為讀取相應(yīng)傳感器的數(shù)據(jù)。
  • 總結(jié)

    以上是生活随笔為你收集整理的uip+freemodbus网络通信的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 亚洲热av| 啪啪短视频 | 性欧美大战久久久久久久免费观看 | 影音先锋 日韩 | 在线观看黄色免费网站 | 久久久久久国产精品视频 | 狠狠摸狠狠操 | 精品国产丝袜一区二区三区乱码 | 国产尤物av尤物在线看 | 肉性天堂 | 日本人妻一区 | 97久久久久久久久久 | 少妇人妻一区二区三区 | 亚洲日本在线观看视频 | 国产成人精品无码免费看在线 | 91精品国产视频 | 91视频在线观看网站 | 亚洲综合射 | 欧美黄在线观看 | 午夜免费视频观看 | 久久叉 | 麻豆传媒网址 | 成人综合激情 | 涩涩视屏| 日韩美女视频网站 | 久久精品一本 | 五月天婷婷在线观看 | 国产精品一区在线观看 | wwwxxx日韩| 给我看高清的视频在线观看 | 午夜精品三级久久久有码 | 成人动漫在线免费观看 | 日本在线一级片 | 巨乳免费观看 | 日本亚洲色大成网站www久久 | 亚洲日本免费 | 精品国产乱码一区二区 | 17c一起操| 99精品乱码国产在线观看 | 在线观看av网 | 18禁超污无遮挡无码免费游戏 | 男女在楼梯上高潮做啪啪 | 久久国产一级片 | 亚洲第一精品在线观看 | 色呦呦入口 | 欧美激情影音先锋 | 97人妻人人揉人人躁人人 | 国产chinesehd精品 | 麻豆传媒视频入口 | 日本三级吃奶头添泬 | 亚洲精品男人天堂 | 摸丰满大乳奶水www免费 | 妖精视频污 | 亚洲精品影视 | se综合| 成人看片在线观看 | 亚洲欧洲综合网 | 日韩有码一区 | 日韩免费视频一区二区 | 美女流白浆视频 | 欧美日韩丝袜 | 黑人精品无码一区二区三区 | 四虎免费影视 | 椎名由奈av一区二区三区 | 无码播放一区二区三区 | 亚洲玖玖爱 | 欧美日韩字幕 | www.xxx.日本| 超碰97观看 | 久久老熟女一区二区三区 | 国产一区二区三区视频 | 在线视频这里只有精品 | 少妇激情一区二区三区 | 国产肉体xxxx裸体784大胆 | 精品伦精品一区二区三区视频密桃 | 国产又大又长又粗 | 一本一道久久 | 成人性爱视频在线观看 | 午夜a级片| www日日| 天天想你在线观看完整版电影免费 | 在线播放a | 狠狠干男人的天堂 | av老司机在线播放 | 天天摸天天碰天天爽天天弄 | 可以直接看av的网址 | 一二三四精品 | 亚洲a视频在线 | 日韩五十路 | 日韩国产精品视频 | 天堂在线中文字幕 | 欧美日韩国产精品一区 | 在线观看欧美视频 | 成人精品视频在线观看 | 妞干网精品 | 成人毛片a| 中文综合网 | 欧美精品在线播放 | xxxwww在线观看 |