http://blog.csdn.net/daniellee_ustb/article/details/8743276
<div class="article_content" id="article_content">
<p align="center"><span style="font-size:24px">基于EncEthernet的FreeModbus-TCP</span></p>
<p align="center"><span style="font-size:24px">在stm32上的移植与<a class="replace_word" href="http://lib.csdn.net/base/softwaretest" rel="noopener noreferrer" style="color:#df3434; font-weight:bold" target="_blank" title="软件测试知识库">测试</a></span></p>
<p align="center"><span style="font-size:14px">DanielLee_USTB 2013-3-27</span></p>
<p align="center"><span style="font-size:14px">QQ:382899443</span></p>
<p align="left"><span style="font-size:18px"> 昨天移植好了<span style="font-size:18px">modbus-RTU,</span>今晚开始在EncEthernet上的free modbus-TCP的移植,使用的开发板为火牛开发板,stm32f103+enc28j60网络方案。主流的TCP/IP协议栈包括uIP、LwIP等,EncEthernet协议栈是一款比较简单的协议栈,由厂家提供在stm32的开发板已经移植好,所以就直接使用,其他的协议的移植方法应该都大同小异。</span></p>
<p align="left"><span style=""><span style="font-size:18px"><span style="font-size:18px; background-color:rgb(255,255,255)"> </span><span style="background-color:lime">一、相关知识</span></span></span></p>
<p align="left"><span style="font-size:18px"> Modbus TCP/IP数据帧除了TCP已经有的包头外,还有modbus TCP协议数据单元(ADU),包括MBAP帧头以及与RTU数据内容相同的应用数据单元(PDU),地址码除外。</span></p>
<p align="left"></p>
<p align="left"></p>
<div style="text-align:center">
<span style="font-size:18px"><img alt="" src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-341d8fb0fc02b2c029a42629e2b374a5.jpg"></span>
</div>
<div style="text-align:left">
<span style="font-size:18px"> 其中与单纯的TCP/IP或是modbus-RTU相比,多的内容就是一个MBAP报文头,这是个什么东西,规定了什么内容呢?先来看看都包含哪些东西。</span>
</div>
<div style="text-align:center">
<span style="font-size:18px"><img alt="" src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-b1ca28d7b255c0ffca380c29009726be.jpg"></span>
</div>
<p></p>
<p align="center"></p>
<p align="center"><span style="font-size:18px">MBAP报文头定义</span></p>
<p align="left"><span style="font-size:18px"> 可以看出来,MBAP报文头主要添加了以下附加信息,为了识别是请求还是响应而设置的事务元标识符、为了判断协议类型设置的协议标识符、为了区分可变长度数据帧结束的数据帧长度、还有用于标识从站地址,与RTU不同的是,从地址放在了MBAP帧头里。</span></p>
<p align="left"><span style=""><span style="font-size:18px"><span style="font-size:18px; background-color:rgb(255,255,255)"><span style="color:#ffffff"> </span></span><span style="background-color:lime">二、代码移植</span></span></span></p>
<p align="left"><span style="font-size:18px"> 前两天已经基于BARE工程移植好RTU模式,仿照相应思路实现TCP的一些函数功能,在mbtcp.c中可以发现,包括TCP初始化(xMBTCPPortInit)、TCP启动(eMBTCPStart)、TCP停止(eMBTCPStop)、TCP接收一个数据包(xMBTCPPortGetRequest)、TCP发送一个数据包(xMBTCPPortSendResponse)等,为了实现free-modbus与EncEthernet对接,在port文件夹下建立porttcp.c文件,在其中包含头文件ip_arp_udp_tcp.h。</span></p>
<p align="left"><span style="font-size:18px"> (1) xMBTCPPortInit( ucTCPPort )</span></p>
<p><span style="font-size:18px"> 这是以太网TCP端口初始化函数,怎么觉得参数有点少呢,绑定TCP端口至少需要mac地址、ip地址以及端口地址吧,这里面只与端口有关,看来只能把他们隐藏了。</span></p>
<p><span style="font-size:18px"> 于是加入</span></p>
<p align="left"><span style="font-size:18px"> enc28j60Init(mymac);</span></p>
<p align="left"><span style="font-size:18px"> enc28j60PhyWrite(PHLCON,0x476);</span></p>
<p align="left"><span style="font-size:18px"> init_ip_arp_udp_tcp(mymac,myip,mywwwport);</span></p>
<p align="left"><span style="font-size:18px"> 这个几个函数作为TCP端口初始化。</span></p>
<p align="left"><span style="font-size:18px"> (2) eMBTCPStart</span></p>
<p align="left"><span style="font-size:18px"> 其实在EncEthernet中只要进行了协议栈的初始化,就已经启动了协议栈,可直接使用。</span></p>
<p align="left"><span style="font-size:18px"> (3) eMBTCPStop</span></p>
<p align="left"><span style="font-size:18px">这个函数是作为TCP端口关闭的函数,其实在modbus中调用它的是eMBClose,而在协议中没有调用eMBClose把modbus给关掉,所以这个函数不用去实现。</span></p>
<p align="left"><span style="font-size:18px"> (4) xMBTCPPortGetRequestTCP接收一个数据包</span6 |
|