开源改变世界

serial.c 直接处理的立即命令字符 #80

推推 grbl 2年前 (2023-01-21) 202次浏览

关闭
西门 开了这个issue 2012 年 3 月 16 日 · 12条评论
关闭

serial.c 直接处理的立即命令字符#80

西门 开了这个issue 2012 年 3 月 16 日 · 12条评论

注释

serial.c 直接处理的立即命令字符 #80
成员

只是一个想法:我看到异步命令字符直接在serial.c中解析和执行。在我看来,这是一种抽象违规,对于外行的 Grbl-hacker 来说,这似乎非常令人惊讶。

你们是否认为每个接收到的字符调用一个函数的成本太高而无法将其移动到它所属的 procol 模块?

serial.c 直接处理的立即命令字符 #80
成员

写的时候稍微考虑了一下。我认为这两种方式都可以。我最终将它保留在原处的主要原因是为了帮助防止新手黑客向中断例程添加过多内容并将其作为一个单独的代码块保留。如果它在组织上转移到协议,黑客可能不完全理解它的来源而不进行一些沉重的评论。

serial.c 直接处理的立即命令字符 #80
成员作者

我一直在反复思考在理想世界中应该如何处理这件事,并且顿悟了:

serial.c 维护其自己的输入缓冲区与协议中正在进行的缓冲串联的事实是 wiring_serial 的遗迹。而不是缓冲区,串行应该有一个函数指针,客户端应用程序可以设置它来调用它想要使用的任何输入处理程序。因此,每个字节在协议模块中都将显得新鲜且未缓冲,以便根据协议立即进行缓冲或处理。

你会欢迎这样的重构吗?

serial.c 直接处理的立即命令字符 #80
成员

绝对地!

Jens 和我曾就消除对协议缓冲区的需求以及让 g 代码解析器直接解析行进行过简短的讨论。这可能会释放所有协议缓冲区空间。这个想法有一些问题,比如让它与 read_double() 很好地配合使用,它仍然需要输入数字长度的字符串缓冲区。由于还没有很好的解决方案,我把它放在一边作为待办事项。

所以,我理解正确,相反,你会摆脱串行读取缓冲区并将传入的字符直接放入协议缓冲区吗?中断是否也需要时间来处理初始解析(删除空格、大写、注释等)?如果是这样,这将始终丢弃不需要的字符并最大化缓冲区实际必须存储的“好”数据量,现在可以通过组合两个缓冲区的内存空间来更大。虽然,我们必须想出一种方法让主程序执行什么以及使用多少缓冲区来解析下一行……这并不难。我认为这是一个很棒的点子!

serial.c 直接处理的立即命令字符 #80
成员作者

是的,这是一般的思路。输入缓冲区将只包含相关字符,并且知道如何将流分成几行并将它们交给 gcode-parser,同时仍然接受新字符。我一直无法想出一个适当简单的方法来实现它,所以仍在思考。我很高兴你喜欢这个方向!

serial.c 直接处理的立即命令字符 #80
成员作者

也许 gcode 解析器可以重构为一次接受一个 gcode“单词”,因此协议可以将行滴入它,从而减少对字符缓冲的整体需求。协议将保​​留两个小的语句缓冲区并在解析器使用另一个时构建一个。

serial.c 直接处理的立即命令字符 #80
成员

嗯。我可以看到这随着滴灌词变得复杂,特别是在添加“$”设置命令并为其他独特命令设置例外时。我们需要一些方法让主程序知道一个单词或一个完整的块(带换行符)已准备好进行处理。通过一些标志或其他东西。

现在我考虑一下,如果我们将提要词滴入解析器,可能会出现操作顺序问题。如果是这样,我们将需要重新编写 g 代码解析器以解决此类问题。也许保持单块执行是可行的方法。这将允许像设置这样的独特表达式仍然可以简单地工作。

假设我们保持单块执行。一种解决方案是让主程序主动搜索缓冲区以查找以 0 结尾的字符,如果找到一个,它就知道它已准备好执行缓冲区的那一部分。这种方法有一些开销,但应该有效。

另一个要问的问题是,我们对每个传入字节执行串行接收中断有多满意。现在,它正在寻找评论字符并在评论中主动忽略。这应该是相当低的开销,但它太多了吗?我在示波器上看到一个问题,即串行中断延迟步进脉冲的结束(也可能也是开始),因为串行中断与步进中断完全同时处理。这种情况很少发生,但很常见,时间延迟大约为 0-3 微秒。不多,但如果我们不小心,可能会变得很重要。

serial.c 直接处理的立即命令字符 #80

对我来说,似乎为步进中断添加另一个时钟,该时钟在步进脉冲边沿时间之前到达设置时间,可以解决随机性问题。然后步进中断例程将允许串行接收中断
中断步进中断,知道串行接收总是比步进脉冲边沿时间之前的设置时间短。然后在串行接收之前和之后,步进中断例程完成加载数据以正确脉冲步进器并轮询步进器脉冲边沿时间时钟以决定何时触发。你会有两个时钟可能相隔 5 微秒——第一个步进中断时钟,然后是步进脉冲边沿时钟。

serial.c 直接处理的立即命令字符 #80
成员

嗨杰格里森。不确定你在这里的意思。在 Grbl 中,有两个时钟控制步进脉冲,串行中断可以在步进脉冲启动后中断步进器。两者在完成或被 sei() 中断之前都非常短。我认为这个问题来自这样一个事实,即步进脉冲频率随着加速度和进给率而迅速变化,并且很难保证串行中断不会在步进脉冲中断之前的纳秒开始。一旦发生这种情况,您就会从中断处理中获得 2-3 微秒的延迟。(至少我认为这是造成这种情况的原因。)

从示波器来看,这种情况很少发生,并且应该不会对步进运动造成任何问题,除了可能在 Grbl 支持的范围之外的极高步进频率。

serial.c 直接处理的立即命令字符 #80

在 2012/07/13 10:23,Sonny Jeon 写道:

我认为这个问题来自这样一个事实,即步进脉冲频率随着加速度和进给率而迅速变化,并且很难保证串行中断不会在步进脉冲中断之前的纳秒开始。

是的,我不熟悉你的两个时钟,所以也许我的建议是再添加一个,或者改变什么
时候完成,但是可以将串行数据处理放在一个时隙中并且知道你有时间回来脉冲处理,
以免它们重叠。那是因为一旦接收到一个字符,将有许多
5 usec 的时间段,直到另一个字符到来。我只是说相隔 5 微秒的两个步进脉冲将允许
中断例程函数不及时重叠。

约翰格里森

生态感官德克萨斯州奥斯汀

serial.c 直接处理的立即命令字符 #80
成员

步进频率(通常 >5kHz)及其相位不断变化,与串行中断无关。像这样的碰撞很可能发生,尽管概率很低。要执行您的建议,我想需要某种监督程序代码通过不断的时移来管理这些冲突,而不影响步进脉冲和串行中断,这两者都需要准时尽可能。

当这些碰撞的概率和频率对于步进电机的物理响应可以忽略不计时,我看不出通过添加另一个计时器和更多代码在计算上有优势。如果我们收到报告并确认这会导致某些设置出现问题,我们可能需要重新访问并研究您的建议。不过幸运的是,我们对最新版本在机器上的运行方式只有轻微的抱怨和问题。

serial.c 直接处理的立即命令字符 #80

在 2012 年 7 月 13 日下午 03:08,Sonny Jeon 写道:

当这些碰撞的概率和频率对于步进电机的物理响应可以忽略不计时,我看不出通过添加另一个计时器和更多代码在计算上有优势。

测量有多少随机
错误的时间会导致步进器错过动作并不是一件容易的事。

这个建议只是正常的实时控制风格——
用少量的中断代码隔离独立的事件——所以短的其他人仍然可以及时完成

正如我通过添加时钟所建议的那样,通过为“完成事情”创建单独的时间段,使独立事件变得相互依赖而不是干扰。

添加一个时钟是更多的代码,但不是程序的更多“待办事项”,只是定义何时执行它。
计时器在硬件中,不是一个小问题,所以不是每秒指令的成本。

我现在不能停下来编写代码,所以不要勉强它,只是指出我看到
的东西,以防有一天它很重要。

约翰

serial.c 直接处理的立即命令字符 #80
成员

实时时间控制是个好主意,但正如人们所说,如果它
没有坏,就不要修理它。同意从根本上添加另一个时钟
不应该增加太多开销,但它确实增加了更多的复杂性。

因此,如果我们查看 grbl 支持的最大步进频率 30KHz,则
必须每 33 微秒发送一个脉冲。如果存在随机但
不频繁的中断冲突,该冲突会使脉冲延迟 2-3
微秒。它不应该影响步进器。尤其是
考虑到大多数 CNC 设置的运行频率低于 10khz,或
每个脉冲 100 微秒。除了管理
加速计时器的计时器中的错误外,更有可能导致更多的计时
错误。

桑尼

2012 年 7 月 13 日下午 5:17,John Griessen
reply@reply.github.com
写道:

在 2012 年 7 月 13 日下午 03:08,Sonny Jeon 写道:

当这些碰撞的概率和频率对于步进电机的物理响应可以忽略不计时,我看不出通过添加另一个计时器和更多代码在计算上有优势。

测量有多少随机
错误的时间会导致步进器错过动作并不是一件容易的事。

这个建议只是正常的实时控制风格——
用少量的中断代码隔离独立的事件——所以短的其他人仍然可以及时完成

正如我通过添加时钟所建议的那样,通过为“完成事情”创建单独的时间段,使独立事件变得相互依赖而不是干扰。

添加一个时钟是更多的代码,但不是程序的更多“待办事项”,只是定义何时执行它。
计时器在硬件中,不是一个小问题,所以不是每秒指令的成本。

我现在不能停下来编写代码,所以不要勉强它,只是指出我看到
的东西,以防有一天它很重要。

约翰


直接回复此邮件或在 GitHub 上查看:
#80(评论)

喜欢 (0)