(一) Marlin-2.1.x 源码解析:G-Code指令的接收、解析与执行
源码文件
涉及源代码文件
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-ZSBI32(codebits, ind); // parameter existsparam[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-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指令的接收、解析与执行相关推荐
- 老李推荐:第8章2节《MonkeyRunner源码剖析》MonkeyRunner启动运行过程-解析处理命令行参数...
老李推荐:第8章2节<MonkeyRunner源码剖析>MonkeyRunner启动运行过程-解析处理命令行参数 MonkeyRunnerStarter是MonkeyRunner启动时的入 ...
- 【Flink】Flink 源码阅读笔记(15)- Flink SQL 整体执行框架
1.概述 转载:Flink 源码阅读笔记(15)- Flink SQL 整体执行框架 在数据处理领域,无论是实时数据处理还是离线数据处理,使用 SQL 简化开发将会是未来的整体发展趋势.尽管 SQL ...
- 以太坊源码深入分析(9)-- 以太坊通过EVM执行交易过程分析
上一节分析了同步一个新的区块准备插入本地BlockChain之前需要重放并执行新区块的所有交易,并产生交易收据和日志.以太坊是如何执行这些交易呢?这就要请出大名鼎鼎的以太坊虚拟机. 以太坊虚拟机在执行 ...
- 基于AS开发的手机App源码 可以配合单片机wifi通信接收单片机数据
基于AS开发的手机App源码 可以配合单片机wifi通信接收单片机数据 注:只有文字描述的功能,其它功能无法实现,也不会制作 ID:6939642638150328Uun丶
- 三菱FX3U底层源码,PLSR源码 总体功能和指令可能支持在RUN中下载程序,支持注释的写入和读取
三菱FX3U底层源码,PLSR源码 总体功能和指令可能支持在RUN中下载程序,支持注释的写入和读取,支持脉冲输出与定位指令(包括PLSY /PWM/PLSR/PLSV/DRVI /DRVA 等指令). ...
- 三菱FX3U底层源码,PLSR源码 总体功能和指令可能支持在RUN中下载程序
三菱FX3U底层源码,PLSR源码 总体功能和指令可能支持在RUN中下载程序,支持注释的写入和读取,支持脉冲输出与定位指令(包括PLSY /PWM/PLSR/PLSV/DRVI /DRVA 等指令). ...
- 三菱FX3U底层源码,PLSR源码 总体功能和指令可能支持在RUN中下载程序,支持注释的写入和读取,有脉冲输出与定位指令
三菱FX3U底层源码,PLSR源码 总体功能和指令可能支持在RUN中下载程序,支持注释的写入和读取,有脉冲输出与定位指令(包括PLSY /PWM/PLSR/PLSV/DRVI /DRVA 等指令)的代 ...
- 源码分析(一) 进程cleos的命令解析
EOS版本:4.0 一.进程cleos的作用 cleos,即为client eos.从名字就可以猜出来,它是一个标准的客户端程序,而实际上,它也确实为一个标准的client^_^ 准确地说,它具有以下 ...
- spring系列-注解驱动原理及源码-声明式事务使用及原理解析
目录 一.环境准备 1.JdbcTemplate使用实例 2.事务添加 二.声明式事务源码分析 1.原理(与AOP非常相似) 一.环境准备 1.JdbcTemplate使用实例 (1)pom文件添加依 ...
- vuex 源码分析_前端入门之(vuex-router-sync解析)
前端入门之(vuex-router-sync解析) 发布时间:2018-11-14 13:31, 浏览次数:513 , 标签: vuex router sync 前言:vue全家桶的内容我们已经研究过 ...
最新文章
- SpringBoot中@ControlAdvice的使用
- 使用ArcGIS API for Silverlight实现地形坡度在线分析
- Redis入门教程(二)
- 使用 AngularJS 和 Electron 构建桌面应用
- 【张其中】中本聪,我们究竟需要怎样的加密货币?
- 浅析Block的内部结构 , 及分析其是如何利用 NSInvocation 进行调用
- 阿里云产品专家解读链路追踪(Tracing Analysis)
- word文档如何插入目录
- 全景图如何上传至百度地图?
- Word——从任意页开始设置页码的方法
- 智能识别系统设计---图像特征提取
- Oracle中的空值问题
- mac上Latex的安装及使用教程
- 设置Adobe Reader为default的PDF阅读工具
- 智慧海派 移动智能终端“双系统”操作系统领跑者
- 平衡面板数据中的缺失值可以存在吗?
- nodename nor servname provided的解决
- ETag 和 Last-modified
- 蓝桥杯-Sine之舞-java
- 斐讯K3刷OPENWRT(LEDE)-使用 KodExplorer 搭建私有云存储(nginx+php7)学习记录
热门文章
- 报错Uncaught ReferenceError: *** is not defined at HTMLTableRowElement.onc
- 2018宁夏网络赛 B Goldbach (米勒拉宾素数测试)
- latex 中手写l的输入方法
- 互联网安全初创企业Cylance获 1 亿美元融资
- prf###.tmp临时文件导致磁盘资源不足
- java url正则校验,Java正则验证
- 我的项目_唐诗可视化项目
- 英国脑科学领域_来自英国A级算法崩溃的数据科学家的4课
- python小游戏——俄罗斯方块
- FTP客户端代码解析