一个让人抓狂的现场前年做的一个数据采集项目,现场有十几个采集节点,通过一条总线挂到主控上。主控轮询每个节点,读回数据再上传。调试阶段一切正常,实验室里跑了两周没出过问题。到了现场,噩梦开始。操作员在界面上点一个按钮,要求刷新某个节点的实时状态。点下去,界面转圈,等了三四秒才出结果。有时候更快,有时候更慢,最长的一次等了将近十秒。操作员以为死机了,反复点,越点越卡。更诡异的是,用调试工具直接抓总线上的报文,发现主控发出查询请求到节点回复数据,中间隔了很长一段时间。这段时间里总线上什么都没发生,纯粹的静默。一开始怀疑是节点处理慢。换了节点固件,没用。怀疑总线干扰,加了终端电阻、换了屏蔽线,也没用。怀疑主控任务调度有问题,把轮询任务优先级提到最高,还是没用。最后定位到的问题,说出来很不起眼:某个设备配置项里,一个叫“响应延迟”的参数被设成了500毫秒。这个参数的本意是给慢速设备留出处理时间,避免主控发完请求立刻超时。但它被加在了每个节点的轮询周期里,而且是串行的。十几个节点,每个都等500毫秒,一轮下来就是好几秒。界面上看到的“响应迟钝”,其实是主控在慢慢等每个节点的延迟窗口过去。延迟设置到底在等什么很多总线协议或者设备驱动里都有类似的延迟参数。名字可能不一样,有的叫“响应超时”,有的叫“帧间隔”,有的叫“设备就绪等待”。它们干的事情本质上是一类:在发出请求之后,强制等待一段时间,再去读取回复。为什么会有这种东西?一种情况是历史遗留。早期的总线设备处理器很慢,主控发出请求后,设备需要几毫秒甚至几十毫秒才能准备好
一个让人抓狂的现场前年做的一个数据采集项目,现场有十几个采集节点,通过一条总线挂到主控上。主控轮询每个节点,读回数据再上传。调试阶段一切正常,实验室里跑了两周没出过问题。到了现场,噩梦开始。操作员在界面上点一个按钮,要求刷新某个节点的实时状态。点下去,界面转圈,等了三四秒才出结果。有时候更快,有时候更慢,最长的一次等了将近十秒。操作员以为死机了,反复点,越点越卡。更诡异的是,用调试工具直接抓总线上的报文,发现主控发出查询请求到节点回复数据,中间隔了很长一段时间。这段时间里总线上什么都没发生,纯粹的静默。一开始怀疑是节点处理慢。换了节点固件,没用。怀疑总线干扰,加了终端电阻、换了屏蔽线,也没用。怀疑主控任务调度有问题,把轮询任务优先级提到最高,还是没用。最后定位到的问题,说出来很不起眼:某个设备配置项里,一个叫“响应延迟”的参数被设成了500毫秒。这个参数的本意是给慢速设备留出处理时间,避免主控发完请求立刻超时。但它被加在了每个节点的轮询周期里,而且是串行的。十几个节点,每个都等500毫秒,一轮下来就是好几秒。界面上看到的“响应迟钝”,其实是主控在慢慢等每个节点的延迟窗口过去。延迟设置到底在等什么很多总线协议或者设备驱动里都有类似的延迟参数。名字可能不一样,有的叫“响应超时”,有的叫“帧间隔”,有的叫“设备就绪等待”。它们干的事情本质上是一类:在发出请求之后,强制等待一段时间,再去读取回复。为什么会有这种东西?一种情况是历史遗留。早期的总线设备处理器很慢,主控发出请求后,设备需要几毫秒甚至几十毫秒才能准备好