Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
Modbus
利用FreeModbus库做主机时,从机超时引起thread任务锁死分析
发布于 2020-03-03 14:24:58 浏览:4644
订阅该版
* 本帖最后由 FVFN_5228 于 2020-3-3 14:24 编辑 * 最近在学习rt-thread,因为工作中用到mosbus,因此在使用freemodbus库,遇到了点问题,折磨了好几天,终于找到原因,跟大家分享下心得: 软硬件环境配置 硬件采用STM32F103,modbus采用串口3,115200,串口3的TX/RX引脚直接接入串口透传无线收发模块,经另一个无线收发模块连接电脑USB口调试;调试口采用uart4 软件采用RT-Thread Studio,添加freemodbus库,运行sample_mb_master.c例程,从机目标地址1 问题描述 下载程序后,在终端输入"mb_master_sample",启动modbus主机程序; 从机采用Modbus Slave模拟,可以看到Modbus Slave可以更新一次寄存器数据,但是之后再也不更新了,并且主机也不再发送写入寄存器指令,但是闪灯程序(main函数内)运行正常;将从机关闭(不回复,只监听),重新启动程序,可以看到主机周期性发送“01 10 00 02 00 02 04 3F D7 00 02 4F 9B”写寄存器指令。 死机后的mosbus如果用从机继续发指令返回给主机,主机可以再被唤醒,继续周期性发送“01 10 00 02 00 02 04 3F D7 00 02 4F 9B”指令 分析过程 由于usart3采用了无线透传模块,因此从机回复时间会超时(默认100个周期) 于是在send_thread_entry任务跟mb_master_poll任务设断点分析,当从机返回一次指令后,两个任务均不再被调度; mb_master_poll所需资源为 EV_MASTER_READY | EV_MASTER_FRAME_RECEIVED | EV_MASTER_EXECUTE |EV_MASTER_FRAME_SENT | EV_MASTER_ERROR_PROCESS, 五个event事件; send_thread_entry 所需资源为信号量 xMasterRunRes 再查,信号量xMasterRunRes释放函数vMBMasterRunResRelease()有两个地方,都在mb_master_poll任务里(mb_m.c),line354,line358 因此,可以初步查出这freemodbus主机例程两个任务死锁原因在mb_master_poll任务中event没有触发,继续追查mb_master_poll中调用了xMBMasterPortEventGet( &eEvent ) 函数,代码如下: BOOL xMBMasterPortEventGet( eMBMasterEventType * eEvent ) { rt_uint32_t recvedEvent; /* waiting forever OS event */ rt_event_recv(&xMasterOsEvent, EV_MASTER_READY | EV_MASTER_FRAME_RECEIVED | EV_MASTER_EXECUTE | EV_MASTER_FRAME_SENT | EV_MASTER_ERROR_PROCESS, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER, &recvedEvent); /* the enum type couldn't convert to int type */ switch (recvedEvent) { case EV_MASTER_READY: *eEvent = EV_MASTER_READY; break; case EV_MASTER_FRAME_RECEIVED: *eEvent = EV_MASTER_FRAME_RECEIVED; break; case EV_MASTER_EXECUTE: *eEvent = EV_MASTER_EXECUTE; break; case EV_MASTER_FRAME_SENT: *eEvent = EV_MASTER_FRAME_SENT; break; case EV_MASTER_ERROR_PROCESS: *eEvent = EV_MASTER_ERROR_PROCESS; break; } return TRUE; } 这个函数采用了switch case结构,如果只有一个事件到来,没有任何问题,如果有两个事件同时到来,函数的返回值为TRUE,但是* eEvent的返回值就是一个不确定的数。我在测试过程发现,如果从机返回数据超时,会同时触发 EV_MASTER_FRAME_RECEIVED 和 EV_MASTER_ERROR_RESPOND_TIMEOUT两个事件,变量recvedEvent值为0x12。 在mb_master_poll函数中,由于返回值为TRUE,所以可以继续运行下去,但是eEvent已经不是一个确定的值了,导致下面的switch ( eEvent ),不会进入任何一个case语句中,只能进入default:break; 下面为eMBMasterPoll( void )部分代码 由于不能进入case语句中,所以不能释放所需event资源及信号量xMasterRunRes,导致send_thread_entry任务跟mb_master_poll任务,均不会再运行。当从机继续返回数据时,xMBMasterPortEventGet()函数可以接收到EV_MASTER_FRAME_RECEIVED事件,这就能够解释可以把两个锁死的任务解开了。 if( xMBMasterPortEventGet( &eEvent ) == TRUE ) { switch ( eEvent ) { case EV_MASTER_READY: eMBState = STATE_ESTABLISHED; break; case EV_MASTER_FRAME_RECEIVED: 验证过程 把函数xMBMasterPortEventGet( eMBMasterEventType * eEvent )中的default:break;改为如下代码,将*eEvent = EV_MASTER_FRAME_RECEIVED 返回给上一级函数 default: *eEvent = EV_MASTER_FRAME_RECEIVED; break; 烧写程序运行后,即便从机返回超时,主机的两个任务也不会锁死,下一个周期可以继续发送寄存器写入指令给从机。 总结 在modbus总线中,会经常遇到从机超时或者返回数据不正确情况,因此主机要有强大的稳定性以便应付这些故障。以上我的一点测试心得,欢迎大家交流指正
查看更多
12
个回答
默认排序
按发布时间排序
天涯咫尺
2020-05-11
这家伙很懒,什么也没写!
这的确是个问题,这几天刚上了Freemodbus,在测试过程中的确是会出现不在发送数据的现象,出现这种情况之后,使用从机主动给主机发送数据即可重新激活通信,楼主分析的这一块的确存在问题,希望官方能修复一下这个BUG
crystal
2021-02-04
这家伙很懒,什么也没写!
感谢楼主分享,昨天也是突然遇到了这种情况,不过和楼主触发的原因稍有不同,楼主同时触发 EV_MASTER_FRAME_RECEIVED 和 EV_MASTER_ERROR_RESPOND_TIMEOUT两个事件,而我是同时触发了EV_MASTER_FRAME_RECEIVED 和 EV_MASTER_FRAME_SENT两个事件,正如楼主所说,正常情况下不可能同时出现两种事件的 分析一下发现:poll线程和send线程都包含有互相需要等待的事件,当send线程在post(post(EV_MASTER_FRAME_SENT)后等待挂起,直到poll线程释放send线程等待的事件,在这个过程中,poll线程是事件处理和调度的核心,同一时刻一旦有某个事件需要poll线程处理,其最好能够被立即唤醒并处理,我们发现例程中poll线程中有一个延时,这个延时会带来事件的堆积后果,一旦事件产生了堆积,poll线程无法处理,也就形成了死锁。 楼主的解决方法是相当于给了一个默认的事件,而不会出现不确定的事件,避免多个事件同时发生。 还有个方法就是在不修改协议栈的基础上,去掉poll线程中的延时,增大响应超时时间(MB_MASTER_TIMEOUT_MS_RESPOND),目的也就是尽可能避免事件产生堆积。
ren
2020-03-03
这家伙很懒,什么也没写!
你好,请问主机读从机数据,数据在哪个寄存器里面,怎么读取呢。
FVFN_5228
2020-03-04
这家伙很懒,什么也没写!
>你好,请问主机读从机数据,数据在哪个寄存器里面,怎么读取呢。 --- 我还没有测试到这一步,刚刚测试下例程
飞龙马
2020-03-18
这家伙很懒,什么也没写!
非常感谢, 以前我测试时不定时随机出现,一直没找到问题原因,现在明白了.
woodtower
2020-03-25
这家伙很懒,什么也没写!
非常感谢
yunqingabc
2020-03-27
这家伙很懒,什么也没写!
楼主牛人,分析的很棒!
zyk6271
2020-06-02
这家伙很懒,什么也没写!
感谢大神,成功解决modbus线程假死的问题
AVR_DIY
2020-08-23
这家伙很懒,什么也没写!
看来很多人遇到这个问题,我也遇到了,感谢楼主分享!
lixunhuan
2020-11-02
这家伙很懒,什么也没写!
有效,十分感谢! ![1.png](/uploads/20201102/b83abdce9732127755da49c5056f045a.png) 确如楼主所述,会发生2个事件,由于原代码里没有此判断分支,导致信号量不能释放。
撰写答案
登录
注册新账号
关注者
1
被浏览
4.6k
关于作者
FVFN_5228
这家伙很懒,什么也没写!
提问
1
回答
1
被采纳
0
关注TA
发私信
相关问题
1
ModbusRTU协议栈漏发送最后一个字节
2
3.0 增加freemodbus,编译不过
3
RT_THREAD上面的串口MODBUSRTU为啥没功能码?
4
关于 freemodbus 里存在的一点问题分享
5
请教如何使用组件里的FreeMODBUS
6
求一个FreeModbus的从机测试程序
7
FreeModbus的从机调试说明(含测试程序)
8
rtt_freemodbus
9
freemodbus怎么配置到uart
10
FreeModeBus从机调试问题
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
开源共生 商业共赢 | RT-Thread 2024开发者大会议程正式发布!
2
【24嵌入式设计大赛】基于RT-Thread星火一号的智慧家居系统
3
RT-Thread EtherKit开源以太网硬件正式发布
4
如何在master上的BSP中添加配置yml文件
5
使用百度AI助手辅助编写一个rt-thread下的ONVIF设备发现功能的功能代码
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
rt_mq_消息队列_msg_queue
keil_MDK
ulog
MicroPython
C++_cpp
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
a1012112796
19
个答案
2
次被采纳
张世争
9
个答案
2
次被采纳
rv666
6
个答案
2
次被采纳
用户名由3_15位
13
个答案
1
次被采纳
本月文章贡献
程序员阿伟
9
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
RTT_逍遥
1
篇文章
6
次点赞
大龄码农
1
篇文章
5
次点赞
ThinkCode
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部