搜索
bottom↓
楼主: sunnydragon

【开源】自己重构的FreeModbus主机+从机协议栈

  [复制链接]

出0入0汤圆

发表于 2013-12-28 08:35:49 | 显示全部楼层
严重支持一下

出0入0汤圆

发表于 2013-12-28 20:24:09 来自手机 | 显示全部楼层
不错呀。支持一下

出0入0汤圆

发表于 2013-12-28 22:39:34 | 显示全部楼层
主机不用搞得那么麻烦了,发个指令过去,等待个3S没返回就算超时了,没必须搞得那么复杂了,从机就麻烦点

出0入0汤圆

发表于 2013-12-30 15:11:05 | 显示全部楼层
楼主,技术和头像一样吊炸天,学习下。

出0入198汤圆

 楼主| 发表于 2013-12-30 19:02:47 | 显示全部楼层
出其而亮 发表于 2013-12-30 15:11
楼主,技术和头像一样吊炸天,学习下。

呵呵,你真幽默。。。欢迎反馈意见哈

出0入0汤圆

发表于 2013-12-30 19:16:10 | 显示全部楼层
顶一下!吼吼

出0入4汤圆

发表于 2014-1-24 14:54:17 | 显示全部楼层
不错,顶一顶

出0入0汤圆

发表于 2014-1-24 15:03:43 | 显示全部楼层
感觉牛X,mark一下……

出0入0汤圆

发表于 2014-1-24 17:00:10 | 显示全部楼层
顶一个!!!

出0入0汤圆

发表于 2014-1-24 22:51:24 | 显示全部楼层
不错,非常感谢

出0入0汤圆

发表于 2014-1-25 21:25:43 | 显示全部楼层
我也顶一下

出0入0汤圆

发表于 2014-1-29 23:38:52 | 显示全部楼层
看了下,回调函数没从机地址的选项,是通过ucMBMasterGetDestAddress得到当前地址么?
另外有点东西不是很明白,Master能不能连续调用eMBMasterReqReadDiscreteInputs等命令函数?后调用的会不会覆盖前面的?
还有就是有没有什么函数可以获取当前协议栈的状态(前一命令是否执行完?)

出0入198汤圆

 楼主| 发表于 2014-1-30 22:13:21 | 显示全部楼层
本帖最后由 sunnydragon 于 2014-1-30 22:16 编辑
大傻师 发表于 2014-1-29 23:38
看了下,回调函数没从机地址的选项,是通过ucMBMasterGetDestAddress得到当前地址么?
另外有点东西不是很 ...


1、在主机的回调函数源码中,是通过ucMBMasterGetDestAddress()获取到当前正在通信的从机地址;
2、你说的主机连续调用eMBMasterReqReadDiscreteInputs等请求功能是支持的,目前最新源码中,采用信号量的方式,对主机进行加锁,保证统一时刻只有一个命令在执行。同时,主机请求的方法增加了timeout参数,用户可以设置超时时间,参见
  1. /**
  2. * This function will request read discrete inputs.
  3. *
  4. * @param ucSndAddr salve address
  5. * @param usDiscreteAddr discrete start address
  6. * @param usNDiscreteIn discrete total number
  7. * @param lTimeOut timeout (-1 will waiting forever)
  8. *
  9. * @return error code
  10. */
  11. eMBMasterReqErrCode
  12. eMBMasterReqReadDiscreteInputs( UCHAR ucSndAddr, USHORT usDiscreteAddr, USHORT usNDiscreteIn, LONG lTimeOut )

复制代码

3、eMBMasterReqReadDiscreteInputs这类主机请求的API的返回值中有“主机忙”的状态,所有的判断都在该方法内部实现,用户只管调用就是了。
另外:强烈建议采用Github上的最新源码,坛子里的源码已经比较旧了,地址:https://github.com/armink/FreeModbus_Slave-Master-RTT-STM32

出0入0汤圆

发表于 2014-1-31 20:39:16 | 显示全部楼层
sunnydragon 发表于 2014-1-30 22:13
1、在主机的回调函数源码中,是通过ucMBMasterGetDestAddress()获取到当前正在通信的从机地址;
2、你说 ...

大过年的还有空上毯子哈- -||
2、3还是没太明白。2里面提到的信号量是不是需要RTOS支持?
另外是不是可以理解为,连续调用,只有第一次调用的会起作用,之后的调用都会返回一个“忙”?
还有就是有没有相应的回调函数给上层判断本次工作完成了?
最后给个建议,建议发布一个只有单独modbus的包,里面不包括RTT的,像原版freemodbus那样的- -

出0入198汤圆

 楼主| 发表于 2014-1-31 20:57:35 | 显示全部楼层
大傻师 发表于 2014-1-31 20:39
大过年的还有空上毯子哈- -||
2、3还是没太明白。2里面提到的信号量是不是需要RTOS支持?
另外是不是可以 ...

新年好啊。
信号量当然需要操作系统的支持,连续调用时,如果在超时的时间内总线空闲了,那么这个命令就会被正常的发送出去,反之,到超时时间后还没有等待到总线空闲,那么会返回总线忙。
主机的本次命令执行完成后,如果没有进入异常处理,那么肯定是正常执行完成了。现在还没有单个命令执行完成的回调函数,我考虑下这个功能的必要性,你也可以给我说下你这个功能的使用场合,我也可以通过别的途径满足你的需求。
目前是只支持RTT操作系统,未来我先考虑支持了UCOS,最后会再考虑裸机运行。

出0入0汤圆

发表于 2014-1-31 21:07:13 | 显示全部楼层
sunnydragon 发表于 2014-1-31 20:57
新年好啊。
信号量当然需要操作系统的支持,连续调用时,如果在超时的时间内总线空闲了,那么这个命令就 ...

看来我理解有问题
现在那几个命令是阻塞调用的?完成后才返回?
我准备用在无RTOS的场合- -

出0入198汤圆

 楼主| 发表于 2014-1-31 22:01:58 | 显示全部楼层
大傻师 发表于 2014-1-31 21:07
看来我理解有问题
现在那几个命令是阻塞调用的?完成后才返回?
我准备用在无RTOS的场合- - ...

目前所有的命令都支持这种模式的。
如果用在非rtos的场合,只需要模拟锁方式实现portevent_m.c 中的vMBMasterRunResInit,xMBMasterRunResTake及vMBMasterRunResRelease(一个全局变量作为flag就行),这样唯一的缺点就是不支持等待功能,同时主机的请求方法是非阻塞的。

出0入0汤圆

发表于 2014-1-31 22:18:43 | 显示全部楼层
本帖最后由 大傻师 于 2014-1-31 22:19 编辑
sunnydragon 发表于 2014-1-31 22:01
目前所有的命令都支持这种模式的。
如果用在非rtos的场合,只需要模拟锁方式实现portevent_m.c 中的vMBMa ...


呃- -其实我是说那几个命令- -意思是主机命令的那几个命令- -|
也就是说,现在的版本是支持没OS的非阻塞调用跟有OS的阻塞与非阻塞调用?

出0入198汤圆

 楼主| 发表于 2014-2-1 09:48:30 | 显示全部楼层
大傻师 发表于 2014-1-31 22:18
呃- -其实我是说那几个命令- -意思是主机命令的那几个命令- -|
也就是说,现在的版本是支持没OS的非阻塞 ...

是的,你可以试试。

出0入0汤圆

发表于 2014-2-1 10:03:17 | 显示全部楼层
mark            

出0入0汤圆

发表于 2014-2-13 21:12:32 | 显示全部楼层
支持

出0入0汤圆

发表于 2014-2-13 21:21:57 | 显示全部楼层
这个不错,要标记下

出0入0汤圆

发表于 2014-2-18 09:15:46 | 显示全部楼层
持续关注

出0入0汤圆

发表于 2014-4-13 17:29:02 | 显示全部楼层
好东西!

出0入0汤圆

发表于 2014-4-14 10:27:17 | 显示全部楼层
楼主不错,主机MODBUS也重构了,学习

出0入0汤圆

发表于 2014-4-14 20:40:17 | 显示全部楼层
这个是很不错的。

出0入0汤圆

发表于 2014-5-14 20:40:19 | 显示全部楼层
感谢分享!

出0入0汤圆

发表于 2014-5-21 08:43:38 | 显示全部楼层
标记,freemodbus重构主机。
刚搞定freemodbus,学习中,顶楼主。

出0入0汤圆

发表于 2014-5-21 15:12:31 | 显示全部楼层
没有不是基于OS的版本么

出0入198汤圆

 楼主| 发表于 2014-5-21 16:43:29 | 显示全部楼层
yueliangz0123 发表于 2014-5-21 15:12
没有不是基于OS的版本么

有计划做基于裸机的主机软件,现在正在测试。。
Watch我在github上的项目就可以知道项目最新进展了。。https://github.com/armink/FreeModbus_Slave-Master-RTT-STM32

出0入0汤圆

发表于 2014-5-26 10:03:08 | 显示全部楼层
MARK一下,以后用到主机再说

出0入0汤圆

发表于 2014-5-26 14:54:51 | 显示全部楼层
看看吧看看吧看看吧看看吧

出0入0汤圆

发表于 2014-5-27 14:55:53 | 显示全部楼层
MARK一下

出0入0汤圆

发表于 2014-6-5 11:05:23 | 显示全部楼层
顶一个,非常支持

出0入0汤圆

发表于 2014-6-19 08:23:34 | 显示全部楼层
mark下,精品!

出0入0汤圆

发表于 2014-7-12 17:06:56 | 显示全部楼层
你好!也准备使用操作系统跑STM32,请问前辈对于UCOS 和RTT上开发项目那个更容易上手呢?比如你使用modbus建立通信的过程那个更简单呢?谢谢!

出0入198汤圆

 楼主| 发表于 2014-7-12 18:42:06 | 显示全部楼层
XIUQIN 发表于 2014-7-12 17:06
你好!也准备使用操作系统跑STM32,请问前辈对于UCOS 和RTT上开发项目那个更容易上手呢?比如你使用modbus ...

直接用RTT吧,项目默认是RTT作为操作系统平台,对RTT支持的更好。建立过程的复杂度都差不多。
可以直接去https://github.com/armink/FreeModbus_Slave-Master-RTT-STM32克隆最新源码,里面还有最新使用说明

出0入0汤圆

发表于 2014-7-13 09:49:17 来自手机 | 显示全部楼层
标记,modbus主从机实现

出0入0汤圆

发表于 2014-7-14 08:03:47 | 显示全部楼层
sunnydragon 发表于 2014-7-12 18:42
直接用RTT吧,项目默认是RTT作为操作系统平台,对RTT支持的更好。建立过程的复杂度都差不多。
可以直接去 ...

谢谢你的回复!学习中。。。。。

出0入0汤圆

发表于 2014-7-14 13:29:55 | 显示全部楼层
大侠,膜拜了你的最新代码,感觉很厉害。在主机侦听的函数里,我有一个问题不太明白:MODBUS协议里主机广播发送请求之后,从机是没有任何应答的。但你的主机侦听函数里,有对广播之后的处理,
if ( xMBMasterRequestIsBroadcast() )
{
        usLength = usMBMasterGetPDUSndLength();
        for(j = 1; j <= MB_MASTER_TOTAL_SLAVE_NUM; j++
        {
                vMBMasterSetDestAddress(j);
                eException = xMasterFuncHandlers[i].pxHandler(ucMBFrame, &usLength);
        }
}
这个好像有问题吧 ,实在不明白,请多指教。

出0入198汤圆

 楼主| 发表于 2014-7-14 18:24:17 | 显示全部楼层
cdh 发表于 2014-7-14 13:29
大侠,膜拜了你的最新代码,感觉很厉害。在主机侦听的函数里,我有一个问题不太明白:MODBUS协议里主机广播 ...

因为主机有所有从机的缓冲区,在发送完广播之后需要更新全部从机缓冲区的数据。

出0入0汤圆

发表于 2014-7-15 11:34:14 | 显示全部楼层
sunnydragon 发表于 2014-7-14 18:24
因为主机有所有从机的缓冲区,在发送完广播之后需要更新全部从机缓冲区的数据。 ...

但是缓冲区的数据不是在主机请求之后才开始打包装入的吗?广播之后,如果没有其他发送请求,为何又立即更新这个缓冲区呢?不解,请指教啊.

出0入198汤圆

 楼主| 发表于 2014-7-15 12:49:24 | 显示全部楼层
cdh 发表于 2014-7-15 11:34
但是缓冲区的数据不是在主机请求之后才开始打包装入的吗?广播之后,如果没有其他发送请求,为何又立即更 ...

不管是广播还是非广播请求,每次请求都需要更新从机数据缓冲区,这样才能保证主机软件从缓冲区中取出的数据是最新的。
“但是缓冲区的数据不是在主机请求之后才开始打包装入的吗?”我说的缓冲区是主机存放的从机数据缓冲区。而且缓冲区的数据除了广播,都是在主机接收到从机响应之后立刻更新。
“广播之后,如果没有其他发送请求,为何又立即更新这个缓冲区呢?”广播之后,如果没有其他发送请求,当然不会更新数据缓冲区,你是不是把请求和响应的逻辑搞错了。在Modbus里面只有主机可以主动发送请求,从机只能被动接受主机的请求,同时给主机做出响应。

出0入0汤圆

发表于 2014-7-15 15:42:15 | 显示全部楼层
本帖最后由 cdh 于 2014-7-15 15:44 编辑
sunnydragon 发表于 2014-7-14 18:24
因为主机有所有从机的缓冲区,在发送完广播之后需要更新全部从机缓冲区的数据。 ...


----------因为主机有所有从机的缓冲区,在发送完广播之后需要更新全部从机缓冲区的数据。----------
我好像越来越糊涂了。
问题1:“主机有所有从机的缓冲区“,你是指主机里针对所有从机都单独开辟一个缓冲区?也就是有多少从机,主机里就有多少个缓冲区?好像不是这样的吧。主机里发送缓冲区和接收缓冲区各一个的吧。
问题2:“在发送完广播之后需要更新全部从机缓冲区的数据”。是主机负责更新还是从机负责更新?

出0入198汤圆

 楼主| 发表于 2014-7-15 16:30:35 | 显示全部楼层
cdh 发表于 2014-7-15 15:42
----------因为主机有所有从机的缓冲区,在发送完广播之后需要更新全部从机缓冲区的数据。----------
我 ...

问题1:主机确实是针对所有从机都单独开辟一个缓冲区,也就是有多少从机,主机里就有多少个缓冲区。注意,这个缓冲区是Modbus数据缓冲区,和你说的串口发送、接收缓冲区没关系哦~
问题2:在主机程序这边,主机存放了所有从机的数据缓冲区,自然主机需要在接收响应后,判断是哪个从机的,将对应的从机的数据缓冲区进行更新。在从机程序这边,从机只需要更新自己的数据缓冲区即可。

出0入0汤圆

发表于 2014-7-15 18:29:00 | 显示全部楼层
mark一下,好东西,请问我现在在有个HMI,下位机(单片机),上位机(组态软件),现在我采取的是单片机——freemodbus(slave)——上位机,HMI -——(232,自定义协议)——下位机,用了两个串口,有什么更好的方法吗,比如他们之间都是modbus。

出0入0汤圆

发表于 2014-7-15 19:56:11 | 显示全部楼层
                 你好!看了一天你的例子,第一次玩操作系统,对于下面这个线程是干啥的不明白,字面了解是"系统监控"。程序是在板子上跑起来了用POLL测试,从机跑了几百万个字节很稳定,就是不知在那加上一些应用,如我想加上SPI flash保存主机接收的数据,把主机收到的从机数据再转发等等。。。没头绪 看来我需要深入学习这个RTT系统。
        rt_thread_init(&thread_SysMonitor,
                                        "SysMonitor",
                                        thread_entry_SysMonitor,
                                        RT_NULL,
                                        thread_SysMonitor_stack,
                                        sizeof(thread_SysMonitor_stack),
                                        thread_SysMonitor_Prio,
                                        5);
        rt_thread_startup(&thread_SysMonitor);

出0入198汤圆

 楼主| 发表于 2014-7-15 20:29:03 | 显示全部楼层
SmartlifeStyle 发表于 2014-7-15 18:29
mark一下,好东西,请问我现在在有个HMI,下位机(单片机),上位机(组态软件),现在我采取的是单片机— ...

让单片机做Modbus主机,HMI和上位机软件都用Modbus从机,总线采用485总线,这样会简单些~

出0入198汤圆

 楼主| 发表于 2014-7-15 20:38:40 | 显示全部楼层
XIUQIN 发表于 2014-7-15 19:56
你好!看了一天你的例子,第一次玩操作系统,对于下面这个线程是干啥的不明白,字面了解是 ...

你要先了解下Modbus通信原理,一主多从的模式通信流程是什么样子的等。。我的源码中还有很多Visio格式的状态转换图及流程图,会对你阅读源码提供很多帮助。建议使用Github上最新源码进行使用或学习,github上还有我最新编写的主机使用说明。学习协议栈不要着急,太浮躁后期还得再重新学习。
线程中的代码就相当于一段被定时调用的代码,那么系统监控线程类似定期获取回来当前系统的状态,然后再与从机通信,将自己的状态告诉从机,或者获取从机的状态。记住Modbus主机永远是通信的发起者,属于最主动的设备哦~

出0入0汤圆

发表于 2014-7-16 08:05:46 | 显示全部楼层
sunnydragon 发表于 2014-7-15 20:38
你要先了解下Modbus通信原理,一主多从的模式通信流程是什么样子的等。。我的源码中还有很多Visio格式的 ...

谢谢回复和指点 努力学习。。。。。。

出0入0汤圆

发表于 2014-7-16 09:53:13 | 显示全部楼层
sunnydragon 发表于 2014-7-15 20:29
让单片机做Modbus主机,HMI和上位机软件都用Modbus从机,总线采用485总线,这样会简单些~ ...

按照我现在的设计是10个下位机(从机),一个主机(上位机),这样每个下位机都成为主机,这样可以吗?

出0入0汤圆

发表于 2014-7-16 10:51:40 | 显示全部楼层
本帖最后由 XIUQIN 于 2014-7-16 11:59 编辑
sunnydragon 发表于 2014-7-15 20:38
你要先了解下Modbus通信原理,一主多从的模式通信流程是什么样子的等。。我的源码中还有很多Visio格式的 ...


你好!今天试跑了你的新程序(只对Modbus从机测试),用了一个裸机Freemobus 和其对比发现用操作系统的会不时的报错Timeout, 不知何故,不知是否是因为操作系统在不停中断时间节拍并启动主机发数据造成从机的延误。(同是9600bps和10个寄存器)................................试了,屏蔽了主机不停询从机这条函数就无误了errorCode = eMBMasterReqWriteCoil(1,8,0xFF00,RT_WAITING_FOREVER);个人理解一个设备里同时存在主机和从机MODBUS时 从机的优先级高于一切,主机数据自己可控,从机接收数据却是突然来到的完全没有前兆,若是再稍等片刻就可能造成一次超时丢包。操作系统里是不是可以在从机接收数据时停止一切干扰它的其它线程 ,请前辈指点。。。。。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入198汤圆

 楼主| 发表于 2014-7-16 17:33:11 | 显示全部楼层
SmartlifeStyle 发表于 2014-7-16 09:53
按照我现在的设计是10个下位机(从机),一个主机(上位机),这样每个下位机都成为主机,这样可以吗? ...

不行~Modbus是1主多从的模式,一个总线内只有一个主机哦~

出0入198汤圆

 楼主| 发表于 2014-7-16 18:26:55 | 显示全部楼层
XIUQIN 发表于 2014-7-16 10:51
你好!今天试跑了你的新程序(只对Modbus从机测试),用了一个裸机Freemobus 和其对比发现用操作系统的会不 ...

系统负荷越大,当然系统的实时性就会越差,如果你觉得从机优先级高,可以把从机线程优先级提高,这些都是用户根据自己的需求随意选择的。真出错的问题,和软、硬件都有关系,很多时候是没法避免的,所以设计好的容错机制才能解决这些问题。

出0入0汤圆

发表于 2014-7-16 19:23:13 | 显示全部楼层
强大。曾经我也写过一个主机,后来换工作了就没继续下去。有时间下载来学习一下

出0入198汤圆

 楼主| 发表于 2014-7-16 20:15:26 | 显示全部楼层
source.ant 发表于 2014-7-16 19:23
强大。曾经我也写过一个主机,后来换工作了就没继续下去。有时间下载来学习一下 ...

好啊~建议下载GIthub上最新的源码,记得watch或start哦,这样有更新会立刻通知你。

出0入0汤圆

发表于 2014-7-17 10:36:57 | 显示全部楼层
记号,收藏

出0入0汤圆

发表于 2014-7-17 12:59:37 | 显示全部楼层
我发现freemodbus从机接收完一帧,并没有关闭接收,请问下楼主这样有没有问题啊。。。。



3.5T超时,认为接收到一帧数据,但是这里只是禁用了超时定时器,然后置接收状态为空闲状态



但,我注意到接收轮询操作分好几个步奏,并不是临界区操作。而且也没有重新拷贝接收缓冲区。



但是处理数据过程中,如果意外再接收到一个字节什么数据 ,整个缓冲区是否就会被破坏掉。
然后处理循环里如果接着处理的话,会不会导致错误的操作结果。。。。。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入198汤圆

 楼主| 发表于 2014-7-17 16:14:31 | 显示全部楼层
zhangshixing 发表于 2014-7-17 12:59
我发现freemodbus从机接收完一帧,并没有关闭接收,请问下楼主这样有没有问题啊。。。。

你说的这种情况在极端条件下确实可能存在,我过会更新下~感谢反馈哦~

出0入0汤圆

发表于 2014-7-17 16:18:04 | 显示全部楼层
不过我看到官网上面freemodbus也有这一种情况。这种情况可能会导致写入,读取错误的数据值。

出0入198汤圆

 楼主| 发表于 2014-7-17 16:46:19 | 显示全部楼层
zhangshixing 发表于 2014-7-17 16:18
不过我看到官网上面freemodbus也有这一种情况。这种情况可能会导致写入,读取错误的数据值。 ...


是的~官方源码也存在这个问题,可能这种情况的触发概率非常低,官方没有在意。
主机和从机代码都已经更新完成了~

出0入0汤圆

发表于 2014-7-17 17:23:14 | 显示全部楼层
t3.5中断到来后,串口接收关闭,防止缓冲区被覆盖,那什么时候打开这个串口接收呢,这个也得有的啊

出0入0汤圆

发表于 2014-7-17 17:24:41 | 显示全部楼层
不知道更改了是不是有没打开接收的情况啊,楼主这个要检查下啊。。。

出0入198汤圆

 楼主| 发表于 2014-7-17 21:11:18 | 显示全部楼层
cdh 发表于 2014-7-17 17:23
t3.5中断到来后,串口接收关闭,防止缓冲区被覆盖,那什么时候打开这个串口接收呢,这个也得有的啊 ...

这些肯定是有的哦~否则协议栈没发正常运行的,这个协议栈已经在多个工业级项目中使用了~

出0入198汤圆

 楼主| 发表于 2014-7-17 21:17:38 | 显示全部楼层
本帖最后由 sunnydragon 于 2014-7-17 21:21 编辑
zhangshixing 发表于 2014-7-17 17:24
不知道更改了是不是有没打开接收的情况啊,楼主这个要检查下啊。。。


之前的打开接收和关闭接收的逻辑是没有问题的,而且软件在很多的工业级的产品上已经运行很久了。
晚上真机测试了下你说的优化方案,目前这种实现策略和FreeModbus自身的策略有些冲突,在FreeModbus的从机中,都是默认尽可能多的时间让从机处于接收状态,而新的优化方案如果采用接收完数据就立刻转为发送状态和设计的策略是背离的,所以我还是之前的设计方案,不到必须需要发送的时候,其余时间从机串口都是处于接收状态。现在这个版本稳定性已经很高了,等我后期有时间还会尽可能的从别的角度去优化特殊条件下缓冲区会被覆盖的问题。

出0入0汤圆

发表于 2014-8-22 21:30:23 | 显示全部楼层
你好!在看你的主机源码,有点问题请教前辈。当调用了这个读保持寄存器函数后 eMBMasterReqReadHoldingRegister(1,0,120,0); 其会产生一个(帧发送事件),然后在主机巡检函数eMBMasterPoll( void )里对事件进行解析在case EV_MASTER_FRAME_SENT:里又 调用了函数  eMBMasterRTUSend()  进行封包并打开发送中断,就是没发现在那个函数把这个包往串口BUF里扔数据。。。。但串口是有数据传出来了。        

出0入198汤圆

 楼主| 发表于 2014-8-23 09:16:46 | 显示全部楼层
XIUQIN 发表于 2014-8-22 21:30
你好!在看你的主机源码,有点问题请教前辈。当调用了这个读保持寄存器函数后 eMBMasterReqReadHoldingRegi ...

我用的是串口发送中断,一但串口发送缓冲区为空,MCU自动触发该中断,中断函数中有Modbus的发送接口,然后通过该接口进行数据发送。明白了吗?

出0入0汤圆

发表于 2014-8-23 10:57:42 | 显示全部楼层
sunnydragon 发表于 2014-8-23 09:16
我用的是串口发送中断,一但串口发送缓冲区为空,MCU自动触发该中断,中断函数中有Modbus的发送接口,然 ...

谢谢!昨天也了解了下TXE中断,加上今天看到你的回复,我的理解是当这里激活发射后 USART_ITConfig(USART2, USART_IT_TXE, ENABLE),这时因为还没往发送缓冲区写数据,所以为空,TXE是发送数据寄存器空中断,所以其就直接进串口的发送中断函数里prvvUARTTxReadyISR(),在这里做后续的数据帧发送。

出0入0汤圆

发表于 2014-8-23 16:32:51 | 显示全部楼层
谢谢楼主分享

出0入0汤圆

发表于 2014-8-23 17:05:13 | 显示全部楼层
十分感谢楼主

出0入198汤圆

 楼主| 发表于 2014-8-23 21:03:13 | 显示全部楼层
XIUQIN 发表于 2014-8-23 10:57
谢谢!昨天也了解了下TXE中断,加上今天看到你的回复,我的理解是当这里激活发射后 USART_ITConfig(USART ...

就是这样哦~~~

出0入0汤圆

发表于 2014-9-1 08:54:12 | 显示全部楼层
本帖最后由 XIUQIN 于 2014-9-1 15:07 编辑

你好!在调试你的程序是发现一个问题(1)errorCode = eMBMasterReqReadHoldingRegister(1,0,120,RT_WAITING_FOREVER);(2) errorCode = eMBMasterReqReadHoldingRegister(1,0,120,RT_WAITING_NO); 带阻塞的1可以正常运行不死机,不带阻塞的2运行一会就会死机(从机还是在正常的收发,只是主机停止了请求,LED也停止闪动),问题应该是资源没有释放造成请求函数永远得不到资源,但主事件巡检里已对成功请求或不成功请求的末尾都做了释放资源的操作,本人太菜看了半天也没找到原因。------------- 试了半天又发现带阻塞1长期工作(1个小时左右)也会照成同不带阻塞2一样的情况,主机波特率115200,不停的由modbus PoLL 从起始地址0读120个数据,从机波特率9600,不停的由modbus slave响应本程序主机请求,同样起始地址0,120个数据。被我改动的还有保持寄存器数量从前辈的100改为120,请求间隔(LED延时)设为20ms.是最新程序,其它没动。
                            

出0入0汤圆

发表于 2014-9-1 09:46:59 | 显示全部楼层
标记,RTT modbus主从机实现.

出0入0汤圆

发表于 2014-9-3 10:05:56 | 显示全部楼层
昨天看了一下,感觉在超时中断里的帧无效分支里应该加上产生帧错误事件给主机监控使用用来释放主机资源,不然在串口接收中断里的正在接收分支产生帧无效时若再进入超时中断后因为接收状态为(帧无效),发送状态为(闲置),这时若为单播就会造成无法产生任何事件给主机监控程序判断,从而又照成无法释放主机资源,造成请求函数获取不到资源死等的现象(信号为阻塞的情况),前辈的思路应该是请求成不成功都应该释放资源并回传请求的结果。本人有点菜,请前辈指点。
/*************************************************************************************************/

BOOL//定时器中断服务程序接口
xMBMasterRTUTimerExpired(void)
{
        BOOL xNeedPoll = FALSE;

        switch (eRcvState)  //主机接收器状态
        {
                                /* 定时器T35过期。启动阶段结束  Timer t35 expired. Startup phase is finished. */
                        case STATE_M_RX_INIT:                                  
                                           xNeedPoll = xMBMasterPortEventPost(EV_MASTER_READY);
                                break;

                        case STATE_M_RX_RCV:    //当接收机处在接收帧的状态时发生了超时中断进入这里,后下面就向主机巡检函数发送帧接收事件给其处理
                                xNeedPoll = xMBMasterPortEventPost(EV_MASTER_FRAME_RECEIVED); //主机巡检函数发送帧接收事件
                                break;
               
                        case STATE_M_RX_ERROR://?????????????????????????????????????????????????????????????????????????????????????????????
                                break;

                                /* Function called in an illegal state. */
                        default:
                                assert_param(
                                                ( eRcvState == STATE_M_RX_INIT ) || ( eRcvState == STATE_M_RX_RCV ) ||
                                                ( eRcvState == STATE_M_RX_ERROR ) || ( eRcvState == STATE_M_RX_IDLE ));
                                break;
        }
        eRcvState = STATE_M_RX_IDLE;  //每次进入超时中断都会将接收机状态重新设为闲置状态

        switch (eSndState)   //在串口中服里设发射机为闲置状态
        {

                        case STATE_M_TX_XFWR:  
                                if ( xFrameIsBroadcast == FALSE ) {  
                                        vMBMasterSetErrorType(EV_ERROR_RESPOND_TIMEOUT);         
                                        xNeedPoll = xMBMasterPortEventPost(EV_MASTER_ERROR_PROCESS);
                                }
                                break;
                        /* Function called in an illegal state. */
                        default:
                                assert_param(
                                                ( eSndState == STATE_M_TX_XFWR ) || ( eSndState == STATE_M_TX_IDLE ));
                                break;
        }
        eSndState = STATE_M_TX_IDLE;   //设置发射机状态为闲置状态

        vMBMasterPortTimersDisable( ); //失能定时器,定时器将停止计数
        if (eMasterCurTimerMode == MB_TMODE_CONVERT_DELAY)  //如果是设置定时器按照广播帧的转换延时时间开始计数( 在主机串口发送中服里设置)
        {     
                 xNeedPoll = xMBMasterPortEventPost( EV_MASTER_EXECUTE ); //发送执行功能事件
        }

        return xNeedPoll;
}

出0入198汤圆

 楼主| 发表于 2014-9-4 08:33:50 | 显示全部楼层
XIUQIN 发表于 2014-9-3 10:05
昨天看了一下,感觉在超时中断里的帧无效分支里应该加上产生帧错误事件给主机监控使用用来释放主机资源,不 ...

恩~大致听懂了你的意思了。
这个STATE_M_RX_ERROR是在接收数据长度大于MB_SER_PDU_SIZE_MAX即PDU最大长度后才会被触发,我这边一直没有使用过超过256字节长度的帧,所以没暴露这个问题。我稍后修改测试下。
感谢反馈哦~

出0入0汤圆

发表于 2014-9-4 14:43:28 | 显示全部楼层
不得不赞一个  我也在用MODBUS的主从机,系统是UCOSII的 总体感觉从机简单,主机麻烦些。特别是和UI接口的时候,做主机大多时候要有UI,不管是数码管还是液晶屏,UI和modbus之间的接口做好了 使用才方便。不知楼主的实现思想是怎样的。

出0入0汤圆

发表于 2014-9-6 09:05:20 | 显示全部楼层
   本人现在已将前辈的程序移植到UCOS里了,主从机都是按每帧120个寄存器跑了一夜,有上千万的字节,没死机。后续待测。。。。。。。。。。。。。。。

出0入198汤圆

 楼主| 发表于 2014-9-6 09:20:56 | 显示全部楼层
XIUQIN 发表于 2014-9-6 09:05
本人现在已将前辈的程序移植到UCOS里了,主从机都是按每帧120个寄存器跑了一夜,有上千万的字节,没死机 ...

不错~~回头测试通过后,要跟网友们分享下哦~

出0入0汤圆

发表于 2014-9-6 09:28:13 | 显示全部楼层
sunnydragon 发表于 2014-9-6 09:20
不错~~回头测试通过后,要跟网友们分享下哦~

0K!

出0入0汤圆

发表于 2014-9-6 09:35:57 | 显示全部楼层
谢谢  分享/。。

出0入0汤圆

发表于 2014-9-6 09:46:10 | 显示全部楼层
感觉前辈的英文不错,注释都是英文的,我都是把注释考到百度翻译慢慢理解的,这两天为了更好的理解你的主机重构思路,参照程序把流程图写满了2张A3的纸,但能力有限,有些还是不理解,自己在慢慢摸索中。。。。。。。。。。。

出0入198汤圆

 楼主| 发表于 2014-9-6 12:04:37 | 显示全部楼层
XIUQIN 发表于 2014-9-6 09:46
感觉前辈的英文不错,注释都是英文的,我都是把注释考到百度翻译慢慢理解的,这两天为了更好的理解你的主机 ...

呵呵,你误会了,我英语很烂,上面很多都是Google翻译的 ,为了保证和从机的代码风格一致及软件国际化,所以尽量使用英文。
让大家对软件架构理解这么费劲,也有我的问题,可能是里面的Visio图及说明文档写的不够完善。如果你觉得不太好理解的,及有歧义的也欢迎随时多提建议,大家一起来完善,开源软件离不开大家每个人的努力

出0入0汤圆

发表于 2014-9-6 13:49:06 | 显示全部楼层
谢谢分享,共同学习进步!

出0入0汤圆

发表于 2014-10-4 22:32:37 | 显示全部楼层
谢谢分享!!

出5入42汤圆

发表于 2014-10-5 00:49:47 来自手机 | 显示全部楼层
支持,留名备用

出0入0汤圆

发表于 2014-10-5 08:14:12 | 显示全部楼层
学习学习

出0入0汤圆

发表于 2014-10-6 17:10:38 | 显示全部楼层
请问前辈,针对从机的0X03读保持寄存器和0X10写多个寄存器,这两个功能码操作的都是保持寄存器,我想若是分别对应两个分开的寄存器是不是方便点,0X03针对的就是保持寄存器,里面是从机需要上传给主机的数据,0X10针对的是普通寄存器,里面是主机给从机下发的数据,以上纯属个人观点,只是在Modbus的一个文档里,说16 (0x10) 是写多个寄存器,这里是不是指不是保持寄存器呢?

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入198汤圆

 楼主| 发表于 2014-10-6 21:54:11 | 显示全部楼层
XIUQIN 发表于 2014-10-6 17:10
请问前辈,针对从机的0X03读保持寄存器和0X10写多个寄存器,这两个功能码操作的都是保持寄存器,我想若是分 ...

没太看懂你前面说的话。但可以纠正你的一个错误的理解,寄存器中,保持寄存器是能够被主机读或者写,而输入寄存器,主机只能去从机那读。

出0入0汤圆

发表于 2014-10-7 10:09:43 | 显示全部楼层
谢谢!是我理解的不透彻。

出0入0汤圆

发表于 2014-10-7 10:16:24 | 显示全部楼层
mark

出0入0汤圆

发表于 2014-11-27 03:56:54 | 显示全部楼层

谢谢!好好理解。

出0入0汤圆

发表于 2014-11-27 08:19:13 | 显示全部楼层
mark         

出0入0汤圆

发表于 2014-11-27 08:25:15 | 显示全部楼层
反正我试了一下,没用起来,不晓得为啥,也没空去折腾;

出0入0汤圆

发表于 2014-11-27 17:26:39 | 显示全部楼层
厉害,支持楼主

出0入0汤圆

发表于 2014-11-27 19:34:59 | 显示全部楼层
modbus在工程领域用的挺广的,谢谢楼主的开源贡献。

出0入0汤圆

发表于 2014-11-27 20:03:54 | 显示全部楼层
谢谢分享,mark

出0入0汤圆

发表于 2014-11-27 20:22:57 | 显示全部楼层
这中做得不错哦学习一下。

出50入0汤圆

发表于 2014-11-27 20:27:38 | 显示全部楼层
标记一下

出0入0汤圆

发表于 2014-11-27 20:33:54 | 显示全部楼层
cool!!!在用FREEMODBUS~~

出0入0汤圆

发表于 2014-12-7 15:02:31 | 显示全部楼层
恩,楼主研究这个花费很多精力,致敬!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-29 22:49

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表