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

    文章

    16197

    浏览量

    177388
  • 协议栈
    +关注

    关注

    2

    文章

    140

    浏览量

    33608
  • SDK
    SDK
    +关注

    关注

    3

    文章

    1026

    浏览量

    45772

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

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

收藏 人收藏

    评论

    相关推荐

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

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

    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

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

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

    01:i.MX RT的市场应用和参考解决方案

    i.MX RT产品是今年市场上最受欢迎的跨界MCU产品。i.MX RT定位为一款MCU产品,它可以重复利用传统的Arm MCU生态系统。除此之外,本次讲座还将简要介绍
    的头像 发表于 01-21 07:13 3318次阅读
    01:<b class='flag-5'>i.MX</b> <b class='flag-5'>RT</b>的市场应用和参考解决方案

    恩智浦i.MX RT1170开创GHz MCU时代

    自2017年上市以来,i.MX RT系列取得了优秀的市场表现。i.MX RT1170跨界MCU是恩智浦i.MX
    的头像 发表于 03-22 11:14 3433次阅读

    恩智浦i.MX RT1170在将该系列带上了更高的层面

    自2017年上市以来,i.MX RT系列取得了优秀的市场表现。i.MX RT1170跨界MCU是恩智浦i.MX
    的头像 发表于 05-18 11:15 3742次阅读

    i.MX RT开发笔记-08 | i.MX RT1062嵌套中断向量控制器NVIC(按键中断检测)

    系列文章目录i.MX RT开发笔记-01 | 初识 i.MX RT1062 跨界MCUi.MX RT
    发表于 12-01 13:51 2次下载
    <b class='flag-5'>i.MX</b> <b class='flag-5'>RT</b>开发笔记-08 | <b class='flag-5'>i.MX</b> <b class='flag-5'>RT</b>1062嵌套中断向量控制器NVIC(按键中断检测)

    RT-Thread & NXP 发布 i.MX RT 系列 BSP 新框架

    前言i.MX RT 是 NXP 推出的跨界处理器系列。该系列下又包括 i.MX RT1020、i.MX
    发表于 12-07 13:06 2次下载
    <b class='flag-5'>RT</b>-Thread & NXP 发布 <b class='flag-5'>i.MX</b> <b class='flag-5'>RT</b> 系列 BSP 新框架

    适用于i.MX RT500和i.MX RT600 MCU的Xtensa音频框架介绍

    在众多的恩智浦i.MX RT跨界处理器当中,您可能会发现有些系列除了Arm内核之外还结合了高性能的DSP,利用集成DSP的技术优势,可提供高性能音频数字信号处理能力,并包含特定算法操作,可实现完全
    的头像 发表于 11-10 09:39 2605次阅读

    RT-Thread文档_野火 I.MX RT1052上手指南

    RT-Thread文档_野火 I.MX RT1052 上手指南
    发表于 02-22 18:25 2次下载
    <b class='flag-5'>RT</b>-Thread文档_野火 <b class='flag-5'>I.MX</b> <b class='flag-5'>RT</b>1052上手指南

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

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

    使用LwIP协议浅析实战分析(i.MX RT

    既可以移植到操作系统上运行,也可以在无操作系统的情况下独立运行。     TCP/IP协议的模型结构如下图所示,由于TCP/IP
    的头像 发表于 02-02 17:05 1592次阅读
    使用LwIP<b class='flag-5'>协议</b><b class='flag-5'>栈</b>浅析实战分析(<b class='flag-5'>i.MX</b> <b class='flag-5'>RT</b>)

    如何在i.MX RT微控制器上初始化LWIP协议

    i.MX RT微控制器上初始化LWIP协议是一个复杂但有趣的过程,它涉及多个步骤和关键组件的配置.
    的头像 发表于 10-12 11:48 291次阅读
    如何在<b class='flag-5'>i.MX</b> <b class='flag-5'>RT</b>微控制器上初始化LWIP<b class='flag-5'>协议</b><b class='flag-5'>栈</b>