(一) Marlin

您所在的位置:网站首页 g代码g28 (一) Marlin

(一) Marlin

2023-12-30 06:58| 来源: 网络整理| 查看: 265

源码文件

涉及源代码文件

Marlin/src/MarlinCore.h /.cpp Marlin/src/gcode/gcode.h /.cpp Marlin/src/gcode/parser.h /.cpp Marlin/src/gcode/queue.h /.cpp

G-Code 指令的接收和执行

Marlin固件里,G-Code指令的接收和执行分别在主循环loop()函数中的idle()和queue.advance() 函数中完成。下图显示了基本流程。 Marlin数据流图

G-Code 指令的接收与执行 void loop() { do { idle(); queue.advance(); endstops.event_handler(); } while (ENABLED(__AVR__)); // Loop forever on slower (AVR) boards } G-Code 指令的接收

在主循环的idle()函数中,Marlin最终通过调用queue.cpp中的get_serial_commands()和get_sdcard_commands()函数分别从串口和SD卡获取G-Code指令。所接收的G-Code单个指令字符会首先被缓存到line_buffer中,在接收到行尾符号(EOL)后,由enqueue()函数将整条G-Code指令添加到G-Code环形缓存队列ring_buffer中。

G-Code 指令的解析与执行

在主循环loop()函数中,queue.advance()负责从G-Code环形队列中取出队尾的指令,并在解析器parser解析后,送入process_parsed_command()执行相应的指令。

快速解析器 (FASTER_GCODE_PARSER) 扫描

在配置Marlin时,如果开启FASTER_GCODE_PARSER选项,则会使用快速解析法对G-Code命令进行解析。达到扫描一次就完成解析的效果。 快速解析主要用到一个set()函数和两个参数,分别是uint32_t codebits和uint8_t param[26]前者记录了被解析的G-Code指令中存在的字段,后者记录了特定字段后数字相对指令头的偏移位置。

// Set the flag and pointer for a parameter // c 表示当前扫描的字符,ptr表示当前扫描字符跟随数字的指针 static void set(const char c, char * const ptr) { const uint8_t ind = LETTER_BIT(c); if (ind >= COUNT(param)) return; // Only A-Z SBI32(codebits, ind); // parameter exists param[ind] = ptr ? ptr - command_ptr : 0; // parameter offset or 0 }

以下面这条G-Code指令为例

G1 X50 Y25.3 E22.4 F3000

解析器首先提取指令头和指令代码,G和1,然后对剩余的指令字符进行一遍扫描。当扫描到X时,将codebits的第23(‘X’ - ‘A’ = 23)位置1. 同时因为X后存在数字50,所以数字5相对于指令头G的偏移距离4会被存入到param[23]当中。以此类推,直到整条指令被扫描完。

读取

当需要从指令提取值时,例如要提取E的参数22.4,解析器首先调用seen()函数,通过判断codebits的第4(‘E’ - ‘A’ = 4)位是否被置位,来得到当前指令是否存在E字段。如果存在,可以通过param[4],即字母E后数字相对与G指令头的偏移距离 (这里是14),计算出E后数字的地址。在获取数字的起始地址后,便可以用过strtof()或者strtol()提取对应的浮点数或整数。

// Code seen bit was set. If not found, value_ptr is unchanged. // This allows "if (seen('A')||seen('B'))" to use the last-found value. static bool seen(const char c) { const uint8_t ind = LETTER_BIT(c); if (ind >= COUNT(param)) return false; // Only A-Z const bool b = TEST32(codebits, ind); if (b) { if (param[ind]) { char * const ptr = command_ptr + param[ind]; value_ptr = valid_number(ptr) ? ptr : nullptr; } else value_ptr = nullptr; } return b; } // Code value as a long or ulong static int32_t value_long() { return value_ptr ? strtol(value_ptr, nullptr, 10) : 0L; }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3