| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 网络协议 -> FreeModbus 移植笔记- 1-认识FreeModbus -> 正文阅读 |
|
[网络协议]FreeModbus 移植笔记- 1-认识FreeModbus |
FreeModbus 移植笔记 目录 ???????3.4?Modbus Configuration ???????3.7?FreeModbus Examples ???????3.8?Porting for RTU/ASCII ???????3.8.4?Modbus-RTU/ASCII的移植 ??????? 1 FreeMODBUS介绍FreeMODBUS 是针对通用的Modbus协议栈在嵌入式系统中应用的一个实现。Modbus协议是一个在工业制造领域中得到广泛应用的一个网络协议。一个Modbus通信协议栈包括两层:定义了数据结构和功能Modbus应用协议和网络层。在FreeMODBUS的当前版本中,提供了Modbus Application Protocol v1.1a 的实现并且支持在Modbus over serial line specification 1.0中定义的RTU/ASCII传输模式。从0.7版本开始,FreeModbus也支持在TCP defined in Modbus Messaging on TCP/IP Implementation Guide v1.0a中定义的TCP传输。Freemodbus遵循BSD[1] ,这意味着本协议栈的实现代码可以应用于商业用途。目前版本的FreeModbus支持如下的功能码: 读输入寄存器 (0x04) 读保持寄存器 (0x03) 写单个寄存器 (0x06) 写多个寄存器 (0x10) 读/写多个寄存器 (0x17) 读取线圈状态 (0x01) 写单个线圈 (0x05) 写多个线圈 (0x0F) 读输入状态 (0x02) 报告从机标识 (0x11) 本实现基于最新的标准并且与标准完全兼容。接收和传输Modbus RTU/ASCII数据帧是通过一个由硬件提取层的调用来驱动状态机来实现的。这就使得该协议非常容易移植到其他的平台之上。当收到一个完整的数据帧后,该数据帧被传入Modbus应用层,数据帧的内容在该层得到解析。为例方便增加新的Modbus功能,Freemodbus在应用层通提供了Hooks。 如果用到了Modbus TCP协议,那么当准备处理一个新数据帧的时候,移植层就必须首先向协议栈发送一个事件标志。然后,协议栈调用一个返回值为接收到的Modbus TCP数据帧的函数,并且开始处理这个数据帧。如果数据有效,则相应的Modbus反馈帧将提供给移植层生成反馈帧。最后,该反馈被发送到客户端。 2 FreeMODBUS官网及源码下载地址官网地址:https://www.embedded-experts.at/en/freemodbus/about/ 源码下载地址:https://www.embedded-experts.at/en/freemodbus-downloads/ 3 移植之前的准备在移植FreeModbus之前,应该先看一下freeModbus的API文档,了解一下freeModbus的接口和使用方法,对freeModbus建立初步认识。 https://www.embedded-experts.at/en/freemodbus/api-documentation/ 上面网站可以打开FreeModbus的API文档. ???????3.1?FreeModbus V1.6? FreeModbus中简单介绍了FreeModbus版本的演进和功能的增加,然后Port列出了不同类型单片机的移植示例名称。 ???????3.2?Modbus? Modbus文件中详细说明了mb.h文件中的宏定义,枚举含义,调用的函数已经FreeModbus的使用方法。 重点:FreeModbus的应用方法。 先调用eMBInit(),然后调用eMBEnable()使能协议站,最后在循环中调用eMBPoll()。??????? 3.3 Modbus Registers? Modbus Register文件中说明了输入寄存器、保持寄存器、线圈、离散输入寄存器各种寄存器回调函数的功能、参数和返回值的含义。 ???????3.4?Modbus Configuration? Modbus Configuration文件说明了mbconfig.h文件中宏定义的功能,通过对宏定义的配置可实现对FreeModbus的裁剪,如,如果不使用Modbus-ASCII和Modbus-TCP可以配置MB_ASCII_ENABLED(0),MB_TCP_ENABLED(0). ???????3.5?Utilities? Utilities文件说明了Modbus中位和字符串数组操作函数的功能和参数返回值。 主要在操作线圈和离散寄存器时使用。 ???????3.6?移植和头文件移植和头文件只列举例文件名称。 ? ? ???????3.7?FreeModbus Examples列举了各类单片机的移植示例代码和说明 ? ???????3.8?Porting for RTU/ASCII描述了modbus移植步骤和需要移植的文件 ? 这部分内容非常重要。 ???????3.8.1?创建移植文件及目录第一步,为移植文件创建目录。推荐创建“demo/PLATFORM”的顶层目录,用于存放应用文件和工程文件,在”PLATFORM”的次级文件目录下创建“port”文件夹用于存放FreeModbus移植文件,如下图: ? 可以直接复制下载的freeModbus的源码中的“demo/BARE”文件夹的内容到新建的工程中,开始移植工作。 ???????3.8.2?平台特性(port.h)应该检查一下port.h文件,检查其是否适合当前的平台,并且定义两个宏定义ENTER_CRITICAL_SECTION和EXIT_CRITICAL_SECTION。用于关闭全局中断和打开全局中断。 注意:进入临界区ENTER_CRITICAL_SECTION和退出临界区EXIT_CRITICAL_SECTION主要应用于保护数据的完整性,尤其是使用操作系统后,避免一组数据在读取和写入时别打断而造成数据错位的情况发生。 ???????3.8.3?定时器功能实现Modbus协议栈需要一个定时器来检测数据帧的末尾。这个定时器的精度应该是半个字符的传输时间。例如,假设一个字符需要11位,波特率位38400时,一个字符的传输时间大约是280us。两帧数据之间最小的超时时间间隔是3.5个字符传输间隔。 首先应该实现xMBPortTimersInit( USHORT usTim1Timerout50us) 和 vMBPortTimersEnable( )这两个函数。测试代码如下: ? 在中断函数中调用pxMBPortCBTimerExpired,并且设置一个断点或者反转LED.在调用vMBPortTimersEnable( )之后,应该每隔1ms发生一次中断,最后需要检查vMBPortTimersDisable( )是否工作正常。 注:xMBPortTimersInit( USHORT usTim1Timerout50us)实现的是50us整数倍的定时间隔,参数usTim1Timerout50us用于设置50us的倍数。 ???????3.8.4?Modbus-RTU/ASCII的移植串口层的移植需要实现以下功能:串口的初始化、接收功能的使能和失能、发送功能的使能和失能、单个字符的接收和发送回调函数等。 需要实现的函数有: 串口初始化函数xMBPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity )。 串口接收发送设置函数vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable ). 此外,还需要创建两个串口的中断服务程序,一个是接收中断,一个是发送中断,通常从接收中断开始创建比较简单。 调用如下代码开始测试接收中断程序, ? 创建串口接收中断,设置断点并且检查xMBPortSerialGetByte( CHAR * pucByte )是否正确返回了接收到的字符。 串口接收中断如下: ? 接下来,实现发送中断部分,测试代码如下: ? 开启要给终端程序,并且在发送缓存空中断中仅调用xMBPortSerialPutByte( 'a' ),发送中断的测试代码如下: ? 如果上面的功能都测试正常,就可以在portserial.c中逐个实现。 ???????3.8.5?事件队列的实现如果你的工程没有使用操作系统,那么事件队列的的实现已经完成。如果您有幸在操作系统中使用FreeModbus协议栈,其不同之处如下: 1、在启动时创建一个任务,在循环中调用eMBPoll(),如下图: ? 可以参照STR71x对FreeRTOS的移植例子。 2、修改xMBPortEventPost函数,发送一个事件到队列。请注意,此函数将从中断服务程序(ISR)调用,因此请查看RTOS文档 3、修改xMBPortEventGet从队列中接收事件。eMBPoll()会定期去查询队列,直到有事件发送到队列时,eMBPoll都应该是阻塞的。 此外,必须修改串口和定时器中断功能。每当协议处理程序回调函数pxMBFrameCBByteReceived、pxMBFrameCBTransmitterEmpty和pxMBPortCBTimerExpired返回TRUE时,都应在退出ISR后进行上下文切换,因为事件已发布到队列。忘记这样做会导致协议栈的性能降低 ???????3.9?TipsTips文件中说明了如何优化代码的方法。 ? 这部分为使用FreeMODBUS协议栈提供一些使用技巧。 减少存储的使用。 FreeMODBUS对存储的使用情况可以通过下面几个方法改变。这里有几个基础的技巧而且很容易实现。
如果对存储空间有更严格的限制,可以尝试下面几个选项,注意这几个选项对协议栈的特性有影响。
|
|
网络协议 最新文章 |
使用Easyswoole 搭建简单的Websoket服务 |
常见的数据通信方式有哪些? |
Openssl 1024bit RSA算法---公私钥获取和处 |
HTTPS协议的密钥交换流程 |
《小白WEB安全入门》03. 漏洞篇 |
HttpRunner4.x 安装与使用 |
2021-07-04 |
手写RPC学习笔记 |
K8S高可用版本部署 |
mySQL计算IP地址范围 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/25 22:41:53- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |