开源改变世界

竞争条件访问 sys_position #541

推推 grbl 3年前 (2023-01-22) 146次浏览

打开
bdurbrow 打开了这个问题 2018 年 10 月 15 日 · 18条评论
打开

竞争条件访问 sys_position#541

bdurbrow 打开了这个问题 2018 年 10 月 15 日 · 18条评论

注释

竞争条件访问 sys_position #541
黑眉 评论了 2018 年 10 月 15 日  

如果我没看错,我认为存在访问 sys_position 数组的竞争条件。

sys_position 在中断时由 stepper.c 中的 ISR 更新;但是可以在整个代码库的多个位置访问,而不会在访问期间禁用中断。

这也会影响 Grbl 的 mega2560 端口。

竞争条件访问 sys_position #541

AFAICT 唯一可能成为问题的地方是 report.c,因为其他位置在没有运动时访问数组。在 report.c 中制作了一个副本,当然是为了最大限度地减少报告中使用的数据不一致的风险。作为旁注,在 32 位处理器上运行时风险微不足道 – 很可能报告的位置在到达发件人时已经过时。

竞争条件访问 sys_position #541
贡献者

谢谢。我知道这个潜在的问题。在过去的几年里,我一直在关注位置变量的这个 int32 读取。似乎没有不良影响,因为访问变量的大部分时间都是受控的。它要么在停止处,要么在改变它的中断内。作为@terjeio唯一一次不是在生成状态报告时,这是非关键的。

也就是说,我不完全记得为什么我最终省略了原子读取。可能是懒惰或不想关闭全局中断以减少抖动或可能丢失一些传入数据(不要以为我曾经测试过这个)。

竞争条件访问 sys_position #541
作者

生成非关键状态报告时。

我要礼貌地反对这一点,因为根据该数据报告回位置的垃圾数据可能会导致任何应用程序出现任何数量的问题。无论如何,Grbl 的输出应该总是正确的。

我不认为用 cli 包装 memcpy 引入的延迟将是一个重大问题,因为几乎所有与 Grbl 一起使用的驱动程序都是微步进的(或者很少是实际的伺服系统)……也许是这样的150 个时钟周期?如果我算对了,也许是 10 微秒?

我要试一试,看看我的 O-scope 上关于时序和抖动影响的结果。

竞争条件访问 sys_position #541
贡献者

@bdurbrow:尚未报告与潜在竞争条件相关的报告生成问题。但是,不要让它阻止您对其进行测试。我自己很好奇。

至于非关键报告,还有其他同步位置的方法,比如来自通信协议本身。报告位置旨在用于 DRO 目的,而不是用于关键过程,主要是因为它是伪实时的。当 Grbl 有时间发送消息时,消息会被发回,并且可以以最大 10Hz 左右的速率生成一条消息。comm 协议要快得多。

竞争条件访问 sys_position #541

@bdurbrow

我要试一试,看看我的 O-scope 上关于时序和抖动影响的结果。

IMO 尝试隔离由使 memcpy 原子化引起的时序问题/抖动是浪费时间 – 为此,您需要找到任何时序中断被相对罕见的状态报告延迟的位置。它肯定会被更频繁发生的其他中断淹没。

我有时会查看编译器生成的汇编代码,例如。对于 ARM,memcpy 是这样实现的:

	.dwpsn	file "../GRBL/report.c",line 625,column 5,is_stmt,isa 1
        LDR       A1, $C$CON84          ; [DPU_3_PIPE] |625|  - get address of sys_position
        LDMIA     A1, {A3, A2, A1}      ; [DPU_3_PIPE] |625|  - load sys position into registers
        STMIA     SP, {A3, A2, A1}      ; [DPU_3_PIPE] |625|  - store it to current_position (on the stack)

这里它甚至不是一个函数调用,但是 LDMIA 指令是可中断的——但我相信不是在单个寄存器加载的中间——可能导致报告最多减少一步(这可能会四舍五入)。虽然这是针对 32 位处理器的,但 8 位 Atmel 代码将大不相同。

因此,如果您可以使编译生成一个汇编程序列表,您将能够评估由于使其成为原子而引起的最坏情况抖动,这是通过将 memcpy 加上中断禁用/启用所需的时钟周期相加来进行的。

竞争条件访问 sys_position #541

在 32 位处理器上使用 32 位变量这不是问题,在 8 位处理器上它而不是禁用中断我认为更有意义的是进行“安全”读取以检查读取后 msb 是否已更改并且重试

竞争条件访问 sys_position #541
作者

IMO 尝试隔离由 memcpy 原子化引起的时序问题/抖动是浪费时间

嗯…无论如何我需要做一些其他相关的时间测量,所以检查这个并没有超出我的范围…

为此,您需要找到相对罕见的状态报告延迟任何定时中断的位置

实际上,不……你只需要诱导类似的行为。

我还在玩它,但我今晚所做的是将 sys_position 的原子副本放入 protocol_execute_realtime(),并将一些端口引脚翻转到原子副本和主步进器 ISR 的顶部。所以,我在 o-scope 上看到的是 a) 当原子复制开始时(我的 o-scope 通道 1 上引脚输出脉冲的上升沿)和结束(下降沿);当 ISR 触发时(我的 o-scope 的通道 2 上的脉冲)。

原子副本在进行长距离快速移动时以大约 25khz 左右的频率发射(基本上,我告诉它在小行星带中寻找某个地方 :-) 并且原子副本需要大约 6 微秒才能完成(比我之前的 guestamate 为 10 微秒)。我今晚看到的明显抖动大约是 10 微秒;原子副本的时间和步进 ISR 的触发之间存在明显的冲突。

竞争条件访问 sys_position #541

@bdurbrow:不要忘记处理器周期是一种有限的资源。

实际上,不……你只需要诱导类似的行为。

以 10Hz 与 25Khz 运行 memcpy 是完全不同的,后者消耗了大量的可用周期(增加 CPU 负载)。在 10Hz 时,原子复制增加抖动的风险很小 – 例如。与将报告字符串移出到 UART 引入的抖动相比。但是你的测试并没有触发报告,所以这也可能会影响结果,通过相对减少 CPU 负载……

如果您担心抖动,也许值得考虑切换到 32 位平台,我上面列出的 memcpy 运行 15 个周期,如果我正确地添加它们的话 – 小于 200nS @ 80MHz。或许 ESP32 将成为生成无抖动步进脉冲的最终处理器,如果优先考虑的话——如果 RMT 外设可用于脉冲生成。

竞争条件访问 sys_position #541
贡献者

@terjeio:作为参考,我确实听到了 SAMD21 端口在阶跃生成方面的明显改进。只是转向更快一点的东西并更好地处理中断转换确实会产生很大的不同。

@bdurbrow:请记住,还有两个其他中断进程会引入 Grbl 抖动。步骤复位和串行接收中断。我发现 AVR 需要大约 2-3 微秒来处理这些。产生最大抖动的是串行接收,当它发生在步进复位或步进发生器中断之前。

竞争条件访问 sys_position #541
作者

10hz 与 25khz 是完全不同的——但我只是在寻找最坏的情况;并试图引起延迟,因此它会出现在示波器上以进行测量。我在猜测,但我认为真实世界的结果可能是每秒或每两秒发生一次额外的 10 微秒抖动事件……如果是这样的话。我不认为它会成为 Grbl 用于的机器种类的一个有意义的因素……

@chamnit– 是的,还有一个设备驱动程序使用的额外的(1khz 计时器 – 这是在我的 Mega2560 端口的修改版本上测试的;所以它有用于 lcd、SD 卡和集成矩阵键盘的驱动程序)。FWIW,然而,我昨晚在没有串行数据输入的情况下测量了明显的抖动,所以串行中断不是该测试的一个因素……

竞争条件访问 sys_position #541
贡献者

@bdurbrow:忘了还有串行写中断。它很小,但是全局中断开销是固定的。如果您有串行输出,它可能是一个促成因素。

竞争条件访问 sys_position #541
危机 评论了 2018 年 10 月 17 日 通过电子邮件
竞争条件访问 sys_position #541

我想你是想标记@bdurbrow ?

竞争条件访问 sys_position #541

@cri-s:你的代码片段中的 uint8_t 数组索引不应该是 3 吗?(对于小端 32 位变量)。

竞争条件访问 sys_position #541
危机 评论了 2018 年 10 月 17 日 通过电子邮件
竞争条件访问 sys_position #541

或者…
我不像你们那么擅长,所以我做了一些完全不同的事情。我的主机和 grbl 之间有一个单独的 2560。当你发送一个 ? 时,它不会去 grbl,它首先被中间人控制器接收,并且它一直在监视 gbl 发送的步进和方向脉冲。它实时知道机器一直在哪里。Grbl 除了接收 g 代码之外什么都不做。也许偶尔的设置更改会传递给 grbl。

竞争条件访问 sys_position #541

@shooter64738这如何与归位、偏移和工作坐标系一起工作?

竞争条件访问 sys_position #541

如果你设置一个工作坐标偏移量,它只是从已知的机器位置中减去它,然后将 G54、G55 等发送到 grbl。从那时起,工作位置可能与机器位置不同。
至于归位,我目前不在我的机器上使用归位。但是任何命令都可以通过,如果你愿意的话甚至可以归位。
我过度简化了它的作用,因为我不想太糟糕地劫持这个线程。:) 它的主要功能是添加固定循环、CRC、向前看、位置的即时反馈。它旨在替代主机

喜欢 (0)