0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

i.MX RT1024:移植MODBUS TCP协议栈教程

恩智浦MCU加油站 来源:恩智浦MCU加油站 2023-05-31 17:28 次阅读

教程简介 MODBUS是一种基于主从结构的控制协议,由一个主机和多个从机组成。 MODBUS是施耐德电气于1979年为可编程逻辑控制器PLC通信所开发并发布的协议,至今已有相当长的历史。 以前它主要基于串口,但由于物联网的发展,基于TCP的MODBUS现在被越来越广泛地使用。恩智浦的i.MX RT 系列控制器的SDK中没有相关的demo,本文的目标是向大家介绍如何在SDK中的lwip_ping_freertos例程基础上添加MODBUS TCP。

MODBUS 协议栈的下载地址:

https://www.embedded-experts.at/en/freemodbus/

测试软件QModMaster 的下载地址:

https://sourceforge.net/projects/qmodmaster/

我在本次教程使用了MIMXRT1024-EVK 作为硬件平台,MIMXRT1024-EVK 和电脑都连接到一台路由器组成一个测试网络。使用 MCUXpresso IDE 作为开发环境,MIMXRT1024-EVK SDK 版本是 2.12.1。 一、文件复制

下载完协议栈后,先解压,随后将其中的 modbus 目录完整复制到 lwip_ping_freertos 工程目录下,添加 modbus 及其所有子文件夹到工程的 include paths 中。

95aac492-ff8d-11ed-90ce-dac502259ad0.png

在协议栈里有一个demo 目录,里面是modbus 被移植到各个厂商处理器上的demo, 可惜没有i.MX RT。仔细对比各个 demo 就可以发现,原来这些 demo 有很多就是基于freertos 和 lwip 的。我们就从 MCF5235 TCP 下手,它既有freertos 又有lwip,完美符合我们的项目。可以把它的 port 目录复制到我们项目的modbus 目录下。把其中的文件全部涵盖进来。

二、修改程序

接下来首先是在 lwip_ping_freertos.c 中include “mb.h”。这个文件包含了 freemodbus 协议栈提供的所有接口函数。

1.程序结构

Lwip 协议栈为用户应用程序的编写提供 3 种编程接口:

第一种是Raw Callback API,这种方式下协议栈与用户程序间通过回调函数实现通信。而且协议栈同应用程序处在同一个进程中,彼此间的执行都会互相制约。

第二种是 Sequential API 方式,用户向内核注册回调函数,并通过直接调用内核 UDP 或TCP 相关操作函数来完成应用程序的编写。在这种方式下,协议栈内核运行于进程 tcpip_thread, 而应用程序进程也是一个单独的进程。独立的进程结构可以使协议栈和应用程序的执行互不影响。通过使用邮箱和信号量等机制,内核进程可以直接将数据递交给应用程序邮箱中然后继续执行,不必阻塞等待。

第三种是使用 BSD socket 函数进行应用程序开发。本来这是最简单的方式,但是由于BSD socket 函数在实现上高度抽象,不适合小型嵌入式TCP/IP 应用,所以 lwip 里的socket 函数并不是非常完整。

为实现与 lwip 协议栈之间的相互调用,freemodbus 协议栈采用的是sequential API 方式。具体的调用顺序如下:在 mb.c 中提供了 eMBTCPInit() 函数, 这个函数调用eMBTCPDoInit()函数, 随后层层调用下去,最后在 xMBTCPPortInit()函数中调用 tcp_bind()。这个函数是 lwip 的 tcp.c 提供的。下图反映出了 modbus 协议栈的层次结构。

95c43224-ff8d-11ed-90ce-dac502259ad0.png

最下层的tcp_bind()函数的作用是将一个连接结构与本地 IP地址addr和端口号 port 进行绑定。作为服务器端程序,执行这一步操作是必要的,服务器必须与熟知端口进行绑定才能接受客户端的连接请求。这里可以看到,freemodbus协议栈并没有以最标准的方式调用netconn_bind()进行绑定,而是直接调用 tcp_bind()。原因应该是这样做可以免去IPC 通信过程,在无操作系统的环境下也能工作。

tcp_listen()的任务是让 tcp 内核监听这个端口;tcp_accept()是为新的连接注册一个回调函数prvxMBTCPPortAccept()。在tcpip_thread()进程监听到有效连接后会回调这个函数。而这个函数会把 modbus 的数据包从 tcp 数据包中复制出来,随后发送 mailbox 信息给modbus 的进程,用来处理消息。

2. 修改接口

95cefef2-ff8d-11ed-90ce-dac502259ad0.png

95cefef2-ff8d-11ed-90ce-dac502259ad0.png

随后是修改porttcp.c。在这个文件中的 prvxMBTCPPortReceive()函数有一个致命问题必须被改正。这个函数是 tcpip_thread()核心进程在收到 modbus 包后的回调函数。当数据处理完成后它会调用pbuf_free()函数释放pbuf包并返回 ERR_OK。tcpip_thread()核心进程收到ERR_OK就知道数据已经处理完了,就可以放心踏实的干别的事情了。然而不知为何,这里的 prvxMBTCPPortReceive() 函数在某些时候释放了pbuf却并不返回 ERR_OK。于是tcpip_thread()核心进程在没有收到正确的返回值时会认为数据包没有被处理,会把这个实际已经废弃的包暂存下来,下次再处理。等到下次处理时就会产生 pbuf错误,使得整个程序被锁死。

以下是修改的地方:

95eac7e0-ff8d-11ed-90ce-dac502259ad0.png

3. 上层代码编写

接下去是为上层应用写的示例代码。以下 code 全部都是在 lwip_ping_freertos.c 中。 3.1 Tcpip协议栈初始化 我没有指定 IP 地址,而是由路由器来分配。

96145ab0-ff8d-11ed-90ce-dac502259ad0.png

962106de-ff8d-11ed-90ce-dac502259ad0.png

3.2Modbus协议栈初始化

96367dde-ff8d-11ed-90ce-dac502259ad0.png

964ab6e6-ff8d-11ed-90ce-dac502259ad0.png

这个进程首先是等 DHCP 拿到路由器给的 IP 地址,随后就可以初始化 modbus 协议,并采用轮询方式等待连接。

3.3编写各种命令对应的程序9662114c-ff8d-11ed-90ce-dac502259ad0.png

966f3142-ff8d-11ed-90ce-dac502259ad0.png

9686d4be-ff8d-11ed-90ce-dac502259ad0.png

96a11d92-ff8d-11ed-90ce-dac502259ad0.png

三、验证 连接所有线路后编译下载。我们的程序会在串口打印出路由器给它分配的 IP 地址。

96b7dffa-ff8d-11ed-90ce-dac502259ad0.png

打 开 QModMaster, Modbus 模式选 TCP;

选项->Modbus TCP->从机 IP 填获得的 IP 地址,端口是 502;功能码选Read Holding Register (0x03),起始地址 100;

寄存器数量选 6,Data Format 选 16 进制; 按连接按钮,QModMaster 就能和我们的板子连上,按钮变成连接起来的样子;按旁边读写按钮,就能读出register的值(见程序vTask_HoldingRegister())。 一切顺利,移植成功!

96d03a14-ff8d-11ed-90ce-dac502259ad0.png

QModMaster有一个总线监视器窗口,可以看到收发的数据。

96f4fb56-ff8d-11ed-90ce-dac502259ad0.png

审核编辑 :李倩

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 控制器
    +关注

    关注

    112

    文章

    15223

    浏览量

    171187
  • 协议栈
    +关注

    关注

    2

    文章

    129

    浏览量

    33456
  • SDK
    SDK
    +关注

    关注

    3

    文章

    966

    浏览量

    44696

原文标题:i.MX RT1024: 移植 MODBUS TCP协议栈教程

文章出处:【微信号:NXP_SMART_HARDWARE,微信公众号:恩智浦MCU加油站】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    i.Mx RT平台内存建议

    哪些超总线存储器被推荐用于NXP的I.MX RT平台。CyPress的超闪存/HyrRAM MCP设备与NXP的I.MX RT系列兼容吗?应用笔记和用户体验将不胜感激。 以上来自于百
    发表于 09-05 14:33

    【大联大品佳 NXP i.MX RT1050试用申请】基于 NXP i.MX RT1050工业机器人开发

    移植RTTheard,RTOS下编写任务驱动GPIO测试,串口测试,SPI测试,IIC测试,PWM测试,每种出一片报告。3,软件,硬件吃透以后,进行项目开发, i.MX RT1050工业机器人,驱动TFT显示,无刷电机,蓝牙,
    发表于 08-10 18:23

    i.MX RT处理器系列

    我对i.MX RT处理器系列很感兴趣,因为它是机器学习研究项目中有吸引力的解决方案。机器学习需要大量的计算能力,而且由于i.MX RT ARM Cortex-M7的运行频率高达600
    发表于 07-22 07:53

    基于RT-Thread实现的Agile Modbus协议

    基于 RT-Thread 实现的支持 Modbus 固件升级的 Bootloader:HPM6750_Boot  特性  支持 rtu 及 tcp 协议,使用纯 C 开发,不涉及任何硬
    发表于 10-08 15:04

    i.MX RT1020到i.MX RT1010的迁移手册

    i.MX RT1020到i.MX RT1010的迁移指南
    发表于 12-12 06:25

    使用i.MX RT的FlexRAM的教程

    使用i.MX RT的FlexRAM
    发表于 12-12 07:36

    开发基于i.MX RT的UVC设备

    基于i.MX RT开发一个简单的UVC设备
    发表于 12-12 06:03

    i.MX RT1060到i.MX RT1064的迁移手册

    i.MX RT1060到i.MX RT1064的迁移指南
    发表于 12-12 07:21

    i.MX RT1024功耗测量应用说明在哪里?

    NXP 文档 i.MX RT1024工业产品跨界处理器数据表提到i.MX RT1024 功耗测量应用说明- 但该说明未在 RT1024
    发表于 03-23 08:17

    如何使用SEMC将iMX RT1024连接到MRAM?

    我想将 iMX RT1024 连接到 MR5A16A MRAM MR5A16A MRAM 数据表声明它与 SRAM 接口兼容但是,通过比较 MR5A16A 数据表和 iMX RT1024 参考手册
    发表于 04-17 07:52

    MX RT1024支持Linux或Andriod操作系统吗?

    各位,我们将 MX RT1024 与裸机应用程序一起用于我们的原型设计。现在由于一些需求变化,我们需要托管 Linux 或 Android 操作系统,最好是 Linux。处理器是否支持这个。从闪存或
    发表于 04-20 07:09

    如何使用sdphost的ROM引导加载程序中区分i.MX RT1062和i.MX RT 1064?

    有什么方法可以通过读取特定寄存器来确定微控制器类型,而不是系列或 UID?我想在使用 sdphost 的 ROM 引导加载程序中区分 i.MX RT1062 和 i.MX RT 106
    发表于 04-27 08:37

    如何将i.MX RT1024与外部64MB SDRAM一起使用?

    我想将 i.MX RT1024 与外部 64MB SDRAM 一起使用。根据数据表,它支持 8/16 位 SDRAM 外部存储器接口。从性能的角度来看,哪种模式更好?如何?如果有任何链接/参考可以通过此详细信息,请告诉我。谢谢
    发表于 05-05 11:17

    i.MX RT10xx使用FlexIO实现XY2-100振镜控制协议

    本文介绍了如何使用i.MX RT系列芯片上的FlexIO实现XY2-100激光振镜控制协议。FlexIO模块是NXP Kinetis和i.MX RT
    的头像 发表于 05-18 09:21 4004次阅读
    在<b class='flag-5'>i.MX</b> <b class='flag-5'>RT</b>10xx使用FlexIO实现XY2-100振镜控制<b class='flag-5'>协议</b>

    i.MX RT的FlexRAM配置问题

    i.MX RT的FlexRAM配置问题
    的头像 发表于 10-24 15:46 285次阅读
    <b class='flag-5'>i.MX</b> <b class='flag-5'>RT</b>的FlexRAM配置问题