源码文件

涉及源代码文件

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 codebitsuint8_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-ZSBI32(codebits, ind);                      // parameter existsparam[ind] = ptr ? ptr - command_ptr : 0;  // parameter offset or 0}

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

G1 X50 Y25.3 E22.4 F3000

解析器首先提取指令头和指令代码,G1,然后对剩余的指令字符进行一遍扫描。当扫描到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-Zconst bool b = TEST32(codebits, ind);if (b) {if (param[ind]) {char * const ptr = command_ptr + param[ind];value_ptr = valid_number(ptr) ? ptr : nullptr;}elsevalue_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;
}

(一) Marlin-2.1.x 源码解析:G-Code指令的接收、解析与执行相关推荐

  1. 老李推荐:第8章2节《MonkeyRunner源码剖析》MonkeyRunner启动运行过程-解析处理命令行参数...

    老李推荐:第8章2节<MonkeyRunner源码剖析>MonkeyRunner启动运行过程-解析处理命令行参数 MonkeyRunnerStarter是MonkeyRunner启动时的入 ...

  2. 【Flink】Flink 源码阅读笔记(15)- Flink SQL 整体执行框架

    1.概述 转载:Flink 源码阅读笔记(15)- Flink SQL 整体执行框架 在数据处理领域,无论是实时数据处理还是离线数据处理,使用 SQL 简化开发将会是未来的整体发展趋势.尽管 SQL ...

  3. 以太坊源码深入分析(9)-- 以太坊通过EVM执行交易过程分析

    上一节分析了同步一个新的区块准备插入本地BlockChain之前需要重放并执行新区块的所有交易,并产生交易收据和日志.以太坊是如何执行这些交易呢?这就要请出大名鼎鼎的以太坊虚拟机. 以太坊虚拟机在执行 ...

  4. 基于AS开发的手机App源码 可以配合单片机wifi通信接收单片机数据

    基于AS开发的手机App源码 可以配合单片机wifi通信接收单片机数据 注:只有文字描述的功能,其它功能无法实现,也不会制作 ID:6939642638150328Uun丶

  5. 三菱FX3U底层源码,PLSR源码 总体功能和指令可能支持在RUN中下载程序,支持注释的写入和读取

    三菱FX3U底层源码,PLSR源码 总体功能和指令可能支持在RUN中下载程序,支持注释的写入和读取,支持脉冲输出与定位指令(包括PLSY /PWM/PLSR/PLSV/DRVI /DRVA 等指令). ...

  6. 三菱FX3U底层源码,PLSR源码 总体功能和指令可能支持在RUN中下载程序

    三菱FX3U底层源码,PLSR源码 总体功能和指令可能支持在RUN中下载程序,支持注释的写入和读取,支持脉冲输出与定位指令(包括PLSY /PWM/PLSR/PLSV/DRVI /DRVA 等指令). ...

  7. 三菱FX3U底层源码,PLSR源码 总体功能和指令可能支持在RUN中下载程序,支持注释的写入和读取,有脉冲输出与定位指令

    三菱FX3U底层源码,PLSR源码 总体功能和指令可能支持在RUN中下载程序,支持注释的写入和读取,有脉冲输出与定位指令(包括PLSY /PWM/PLSR/PLSV/DRVI /DRVA 等指令)的代 ...

  8. 源码分析(一) 进程cleos的命令解析

    EOS版本:4.0 一.进程cleos的作用 cleos,即为client eos.从名字就可以猜出来,它是一个标准的客户端程序,而实际上,它也确实为一个标准的client^_^ 准确地说,它具有以下 ...

  9. spring系列-注解驱动原理及源码-声明式事务使用及原理解析

    目录 一.环境准备 1.JdbcTemplate使用实例 2.事务添加 二.声明式事务源码分析 1.原理(与AOP非常相似) 一.环境准备 1.JdbcTemplate使用实例 (1)pom文件添加依 ...

  10. vuex 源码分析_前端入门之(vuex-router-sync解析)

    前端入门之(vuex-router-sync解析) 发布时间:2018-11-14 13:31, 浏览次数:513 , 标签: vuex router sync 前言:vue全家桶的内容我们已经研究过 ...

最新文章

  1. SpringBoot中@ControlAdvice的使用
  2. 使用ArcGIS API for Silverlight实现地形坡度在线分析
  3. Redis入门教程(二)
  4. 使用 AngularJS 和 Electron 构建桌面应用
  5. 【张其中】中本聪,我们究竟需要怎样的加密货币?
  6. 浅析Block的内部结构 , 及分析其是如何利用 NSInvocation 进行调用
  7. 阿里云产品专家解读链路追踪(Tracing Analysis)
  8. word文档如何插入目录
  9. 全景图如何上传至百度地图?
  10. Word——从任意页开始设置页码的方法
  11. 智能识别系统设计---图像特征提取
  12. Oracle中的空值问题
  13. mac上Latex的安装及使用教程
  14. 设置Adobe Reader为default的PDF阅读工具
  15. 智慧海派 移动智能终端“双系统”操作系统领跑者
  16. 平衡面板数据中的缺失值可以存在吗?
  17. nodename nor servname provided的解决
  18. ETag 和 Last-modified
  19. 蓝桥杯-Sine之舞-java
  20. 斐讯K3刷OPENWRT(LEDE)-使用 KodExplorer 搭建私有云存储(nginx+php7)学习记录

热门文章

  1. 报错Uncaught ReferenceError: *** is not defined at HTMLTableRowElement.onc
  2. 2018宁夏网络赛 B Goldbach (米勒拉宾素数测试)
  3. latex 中手写l的输入方法
  4. 互联网安全初创企业Cylance获 1 亿美元融资
  5. prf###.tmp临时文件导致磁盘资源不足
  6. java url正则校验,Java正则验证
  7. 我的项目_唐诗可视化项目
  8. 英国脑科学领域_来自英国A级算法崩溃的数据科学家的4课
  9. python小游戏——俄罗斯方块
  10. FTP客户端代码解析