(一) Marlin |
您所在的位置:网站首页 › g代码g28 › (一) Marlin |
源码文件
涉及源代码文件 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() 函数中完成。下图显示了基本流程。 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 |