Contact me: hankecnc@gmail.com

缓冲区溢出/意外响应 #133

推推 grbl 3年前 (2023-02-02) 295次浏览
关闭
andrewismoody 打开了这个问题 2017 年 2 月 18 日 · 59条评论
关闭

缓冲区溢出/意外响应#133

andrewismoody 打开了这个问题 2017 年 2 月 18 日 · 59条评论

评论

缓冲区溢出/意外响应 #133
安德鲁斯穆迪 评论了 2017 年 2 月 18 日  

我对此不是 100% 确定,但我一直在解决我的 gcode 文件被错误地发送到 GRBL 的问题。我收到关于遗漏单词和错误数字格式的奇怪回复,这让我相信缓冲区溢出了。
我今天四处闲逛,试图了解发生了什么,我能说的最好的是,问题出在发送者队列之外的定时器上发送的定期状态查询,直接写入串行端口。我正在查看 GrblContoller.js 的第 319 和 324 行。我不认为,按照它的编写方式,这些命令被计入缓冲区计数。我认为最好将它们注入发送者队列并允许缓冲区计数器包含这些字节以防止缓冲区溢出。

考虑了几分钟后,我认为也许状态查询应该作为文件解析器的一部分定期注入到发送者队列中。这将消除竞争条件和假设的缓冲区溢出。或者可能每次发送方队列 while 循环进入一次,这样它就不会被许多非常小的命令调用得太频繁。

缓冲区溢出/意外响应 #133
合作者
奇顿 评论了 2017 年 2 月 18 日  

// https://github.com/cncjs/cncjs/blob/master/src/app/controllers/Grbl/GrblController.js#L112
this.sender = new Sender(SP_TYPE_CHAR_COUNTING, {
    // Consider periodic commands ('$G\n', '?') to make sure the buffer doesn't overflow
    bufferSize: (128 - 4) // The default buffer size is 128 bytes
});

Grbl 默认有 128 字节的缓冲空间。我从缓冲区大小中扣除了 4 个字节以排除周期性命令(即 len(‘$G\n’) + len(‘?’) = 4),但我担心这可能不够安全以防止缓冲区溢出.

你能提供我以下资料吗?谢谢。

  1. 您当前使用的是哪个版本的 cncjs

  2. 你的 Grbl 版本 ($I) 和设置 ($$)

  3. 附上您的一些 g 代码文件,这些文件有时甚至可以重现缓冲区溢出问题

  4. 尝试将缓冲区大小更改为低于 124 并再次测试。也就是说,120 字节的缓冲区大小应该足够安全。您必须以这种方式找到实际文件位置:

    $ dirname `which cncjs`
    /Users/cheton/.nvm/versions/node/v6.9.4/bin
    $ cd /Users/cheton/.nvm/versions/node/v6.9.4/bin
    $ cd ../lib/node_modules/cncjs/dist/cnc/app/
    $ vim index.js
    // Find the line of "bufferSize: 128 - 4"
    
缓冲区溢出/意外响应 #133

我今天刷到了 Grbl 1.1f。我运行的是 0.9i,我认为这可能是罪魁祸首,但问题仍然存在于最新的 Grbl 版本中。
我正在运行 cncjs 的最新稳定版本 1.8.16。
我将尝试更改缓冲区大小,但我认为这将被状态查询本身覆盖,它会重置缓冲区大小以匹配 grbl 报告的内容,对吧?(GrblController.js 第 156 行)我想这也可以更改,但我认为这只是解决问题。
此外,我已经看到这些计时器命令在作业结束时聚集在一起,而不是穿插运行。我认为也许 javascript 的假线程模型(这会转移到节点吗?)可能会阻止注入尝试。这是我建议定期将它们注入发送者队列的部分原因,因为它可以防止任何类型的竞争条件。如果我对情况的理解是正确的,那么定时器功能并没有在预期的时候具体执行,并且多个调用堆积起来,然后淹没了串行端口。
我担心尝试分叉构建以执行故障排除,但考虑到您直接在我的 Raspberry Pi 上编辑文件的提示,我将尝试敲定细节并报告我的发现。
我认为这个日志输出将支持这个假设:
缓冲区溢出/意外响应 #133

缓冲区溢出/意外响应 #133
合作者

是的,我忘记了你提到的行(GrblController.js 第 156 行),你必须在编辑 index.js 文件时更新该行。这是为了支持 GRBL-Mega,它的缓冲区空间为 255 字节,请参见#115

我同意你的建议,发送者队列、馈线队列和周期性命令应该使用优先级队列组合成一个,以防止竞争条件。我可能会在不久的将来尝试重构这部分。

缓冲区溢出/意外响应 #133
合作者
奇顿 评论了 2017 年 2 月 18 日  

我猜想这可能是由于在发送 gcode 期间动态更改缓冲区大小引起的:

// Detect the buffer size if Grbl is set to report the rx buffer (#115)
if (res && res.buf && res.buf.rx) {
    const rx = Number(res.buf.rx) || 0;
    // Deduct the length of periodic commands ('$G\n', '?') to prevent from buffer overrun
    const bufferSize = (rx - 8);
    if (bufferSize > this.sender.sp.bufferSize) {
        this.sender.sp.bufferSize = bufferSize;
    }
}

它应该像下面这样更正。

//  Update buffer size only when the workflow state is idle
if (this.workflowState === WORKFLOW_STATE_IDLE && res && res.buf && res.buf.rx) {
    :   :   :
}

更新:
RX 值可能无法反映 gcode 发送期间的实际缓冲区空间,应从发送方适当控制。

缓冲区溢出/意外响应 #133
合作者

我将在今天晚些时候为 1.8.x 版本和 1.9.x 预发布版本提供热修复更新。

缓冲区溢出/意外响应 #133
合作者

@andrewismoody

您可以查看 1.8.17 以获取新的更新。

缓冲区溢出/意外响应 #133

我现在正在安装 v1.8.17 进行测试。我仍然认为删除状态更新命令上的计时器并将它们嵌入到队列逻辑中有一些好处。我对如何实现这一点有一些想法,我将尝试对我的本地副本进行一些测试,看看我是否可以处理它。我使用 JavaScript 的经验让我对计时器非常谨慎。JavaScript 有一个非常不可预测的线程模型。
我最初的想法是在发送者中定义一组状态更新命令。然后每个控制器可以适当地填充该数组。当 next() 函数开始填充缓冲区时,我们将这些状态更新命令放在缓冲区的前面。
这里有一些伪代码(基本上只是复制了 while 循环中的逻辑),将尝试在我的本地副本上进行这些更改。将需要一些额外的构造函数和类定义代码以及对 GrblController 的调整以将状态命令注入数组。无论如何,我认为删除定时器逻辑值得一试。我会让你知道我的测试进行得如何。
也许我们可以在类定义中添加一个时间戳变量 (lastStatusRequest) 来跟踪最后一个状态被请求的时间。然后在调用 process() 之前检查 next() 函数中的时间戳,如果经过的时间大于或等于我们预定的状态间隔,我们将注入状态命令。

var elapsedStatusDelta = now – lastStatusRequest;
if (elapsedStatusDelta >= allowedStatusDelta)
{
for (let statusCommand of statusCommands) {
if ((statusCommand.length > 0) && ((sp.dataLength + statusCommand.length) >= sp.bufferSize)) {
break;
}
sp.dataLength += statusCommand.length;
sp.queue.push(statusCommand.length);
this.emit(‘data’, statusCommand);
}
lastStatusRequest = 现在;
}

我可能会在这方面走得更远,所以如果我有任何成功,我会告诉你。

缓冲区溢出/意外响应 #133

1.8.17 补丁似乎对这个问题没有任何影响。我可能误诊了。在 gcode 发送期间,我没有看到任何状态命令被写入日志,但我仍然看到 Grbl 报告的许多错误。当我停止作业时,大量的状态命令正在写入日志文件。在作业期间,工具位置未在控制台中更新,因此这使我相信状态命令实际上在作业结束之前并未排队。下面的屏幕截图 – 第一个是暂停的作业,第二个是停止的作业。我会继续四处寻找,看看是否能有所发现。
我真的很喜欢这个项目,这里有一些惊人的功能。希望能顺利进行!
缓冲区溢出/意外响应 #133
缓冲区溢出/意外响应 #133

缓冲区溢出/意外响应 #133

我打算切换到 v1.9.0-alpha.3 版本,因为它有很多很好的修复,将使测试更容易。

缓冲区溢出/意外响应 #133
合作者

您介意粘贴您的 gcode 文件和 Grbl 设置吗?这将有助于从我这边找出问题。

缓冲区溢出/意外响应 #133 奇顿 添加了 调查 标签 2017 年 2 月 19 日
缓冲区溢出/意外响应 #133

这是我当前的 Grbl 设置。我无法发布我正在测试的 gcode,我将尝试制作一个非专有的类似代码,看看我是否可以重现该问题。
$0=10 (step pulse, usec)
$1=255 (step idle delay, msec)
$2=0 (step port invert mask:00000000)
$3=7 (dir port invert mask:00000111)
$4=0 (step enable invert, bool )
$5=0 (limit pins invert, bool)
$6=0 (probe pin invert, bool)
$10=15 (这会返回所有东西)
$11=0.010 (这使得转角更慢以提高准确性)
$12=0.002 (arc tolerance, mm )
$13=0(报告英寸,布尔)
$20=0(软限制,布尔)
$21=0(硬限制,布尔)
$22=1(归位周期,布尔)
$23=7(归位方向反转掩码:00000111)
$24=25.000(归位进给,毫米/分钟)
$25=250.000(归位寻道,毫米/分钟)
$26=30(归位去抖,毫秒)
$27=1.000(归位牵引,毫米)
$100=40.000(x,步长/毫米)
$101=40.000 (y, step/mm)
$102=94.474 (z, step/mm)
$110=5000.000 (x max rate, mm/min)
$111=5000.000 (y max rate, mm/min)
$112=500.000 ( z 最大速率,毫米/分钟)
$120=250.000(x 加速度,毫米/秒^2)
$121=250.000(y 加速度,毫米/秒^2)
$122=50.000(z 加速度,毫米/秒^2)
$130=290.000 (x 最大行程,毫米)
$131=290.000(y 最大行程,毫米)
$132=100.000(z 最大行程,毫米)

缓冲区溢出/意外响应 #133

好的,谢谢你对我的耐心。我认为这里还有一些其他问题实际上使状态循环看起来像是罪魁祸首,但实际上,这似乎是串行端口通信的问题。我现在正在运行 1.9.0-alpha.3。我正在闲置地观察日志中的状态更新,它们运行平稳,直到我突然在控制台中看到“错误:2”。此时,状态更新停止。我发一个?来自控制台小部件的命令,它是成功的,然后状态更新统计再次在日志中流动,直到另一个随机“错误:2”发生并停止一切。
我对代码进行了如此深入的挖掘,现在看起来好像发生了完全不同的事情,这让我觉得有点傻。
我在通过运行 Grbl v1.1f 的 USB 连接到 Arduino Uno 的 Raspberry Pi 2 上运行 Raspbian Wheezy 4.4.38-v7+。
节点版本是 v4.0.0
我在安装 cncjs 时看到一个关于构建串行端口组件的“警告”,因为没有找到正确的版本,但最初没有考虑任何事情。
现在我还记得,我在安装节点时确实遇到了一些麻烦。找不到 Wheezy 的 v4 的 apt-get 包,所以我从这里手动安装它:https
://nodejs.org/dist/v4.0.0/node-v4.0.0-linux-armv7l.tar.gz 也许我只需要碰到杰西再试一次。
很抱歉浪费你的时间。我会在串口上做一些更多的故障排除,看看我是否能解决问题。

缓冲区溢出/意外响应 #133

我将节点升级到 v6.9.5,删除了 cncjs,并重新安装了 alpha.3。我收到了关于构建 4.0.7 的类似串口警告,因为 6.9.5 没有受支持的二进制文件。构建期间还有很多其他警告。
之后,一切都和以前几乎一模一样。所以,我做了更多搜索,发现了这个链接:
https ://github.com/grbl/grbl/wiki/Known-Bugs

Arduino 固件和 USB 到串行通信似乎存在“已知问题”。我不记得通用 GCode 发送器有这个问题,但也许它正在解决它。

稍后我会尝试刷新 Arduino,看看是否能解决问题。

缓冲区溢出/意外响应 #133

我通过 Universal GCode Sender 运行了同样的工作,但我没有看到所有错误:2 和错误:25 问题,但我确实偶尔看到错误:1 响应(我认为我之前没有仔细看过)。我认为这证实至少部分问题与我的 Arduino Atmel 固件版本有关。

缓冲区溢出/意外响应 #133
合作者

您可以尝试将串口升级到“5.0.0-beta3”吗?
https://github.com/EmergingTechnologyAdvisors/node-serialport/releases/tag/5.0.0-beta3

如果您可以在您的环境中进行构建,只需替换 package.json 中的行并重新安装:

"dependencies": {
    "serialport": "5.0.0-beta3"
}

安装依赖项并创建生产版本:

$ node -v
喜欢 (0)