完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
Marlin相当庞大,自2.x版本开始,陆陆续续开始集成了32位机,主流的STM32、LPC等高性能MCU逐渐取代了以Arduino2560等8位机的3D打印机方案。Marlin,庞大到让每个初学者开始学习看代码都会觉得闻风丧胆,当然我刚开始接触的时候也不例外,但是不管是学什么东西,只要把大方向掌握了,那么细节的东西用到了再慢慢研究也不迟,同时,Marlin的文档非常少,对于初学者来说,是非常不友好的!以下这些介绍也是Marlin刚开放不久的说明文档,笔者英语水平有限,如有翻译失误,尽情纠正与谅解!
1、Marlin代码工程架构 以下是原版的Marlin固件解压下来的显示情况: 当使用 PlatformIO 构建Marlin时,它会在.pio此处创建一个文件夹,并且在shell中使用git的时候,这 是当前的工作目录,如下图所示: 1.2、 buildroot 文件夹 该目录包含开发人员的帮助脚本、字体工具、CI测试工具、Marlin图标和其它数据 1.3、 buildroot/share/PlatformIO 文件夹 电路板定义、环境变量、链接脚本和构建脚本会存放在这个地方,这个文件夹内的构建环境会经常引用 ini文件夹 1.4、 ini 文件夹 包含按 MCU 类型组织的所有 PlatformIO 环境设置, platformio.ini 文件将这些引入为 PlatformIO 提供构建/上传/调试设置,有一个文件特别有用:即是Marlin自定义构建脚本 features.ini 在构建开 始时用于根据启用的功能过滤源文件,因此构建能够完成得更快。 1.5、 Marlin 文件夹 构建Marlin时,配置文件就放在这个位置: 1.6、 Marlin/src 文件夹 包含Marlin应用程序,Marlin基于 Arduino 框架进行开发,所以它含有 Arduino 框架的setup() 和 loop() 功能。 2、Marlin应用源代码Marlin/src 文件夹 Marlin应用源代码主要由以上文件夹组成,核心的入口程序文件是 MarlinCore.cpp ,MarlinCore.h 会做一些宏和变量以及函数的声明,在这个文件中可以找到基于 Arduino 框架的 setup() 和 loop() 函 数,其余的文件夹包含的源码主要的作用如下:
包含Marlin源文件需要的类型、宏、使用程序功能等等,大多数源文件只需要包含 inc/MarlinConfig.h 就可以确保这些文件按预期顺序包含在内。
包含一些可选功能的支持代码,当然这个文件夹下的代码有些功能是非常简单的,只需要添加一个 G代码或者在公共代码中插入更改即可完成。如果一个特性需要定义一个类或者一组函数,这些附 加的文件将放在这个位置。
包含GCodeParser 类的定义以及所有G代码命令的实现(有一些不在这里实现,但大部分是的),这 些功能都被包装在一个名为 GcodeSuite 的类里,G代码实现的文件被捆绑在多个类别的子文件夹 中,这些文件被命令为具体的G代码,因此可以使用 IDE 的查找功能找到它们。
每个控制器系列都提供控制硬件的功能,但并非所有控制器系列都使用相同的接口, Marlin2.x 版本实现了硬件抽象层,更好的屏蔽了平台的差异性,使其它的平台更好的兼容 Arduino 框架。
包含了Marlin版本、配置条件等等的基本内容,请注意,每个HAL还包含自己的 Conditionals*.h 和 SanityCheck.h文件 。
所有与 LCD、TFT、OLED、编码器、按钮和串行控制器的相关代码都放在这里,语言翻译通常仅 适用于外部控制器,因此语言翻译也放在这里。
任何通用数据函数实现或者与硬件库代码都放在这里,如蜂鸣器代码、 CRC16 校验和实现、 3X3 矩阵、数字到字符串的转换功能、用于二进制传输的 HeatShrink ,甚至还有几个 EEPROM 。
这里定义了机器的所有典型功能,包括 3D 打印机拥有的所有的组件,例如:加热器和传感器、热 床探测、路径规划算法、将命令转换为分段运动的高级运动功能、将毫米分段快速转换为步进块的 运动路径规划,以及将块段转换为中断时序和STEP信号的步进器 ISR 。
Marlin所有的板定义都在这个文件夹中,这里有不同的硬件架构,每个架构下的每块板都有自己独 特的引脚文件, pins.h 根据 MOTHERBOARD 设置进行包含,由于 pins.h 是 MarlinConfig.h 的包 含文件注意,因此它不会包含在其它的地方。
在这里您可以找到所有实现实际文件和文件夹的高级文件系统代码。 CardReader 类是Marlin用 于导航目录、打开G-code文件和从SD卡(或其他媒体)打印的主界面。自从Marlin 2.0.8以来,所有 的媒体类型都派生自 DiskIODriver 抽象类。 3、Marlin的配置 马林是高度可配置的。您将在源代码的许多地方发现应用配置选项来打开和关闭代码、更改行为和提供 值。
在inc、core、HAL和pins文件夹中头文件的包含顺序很重要,因为每个头文件都是建立在其前身文件之 上的。为了确保始终遵循正确的包含顺序,任何需要配置和条件文件(直到conditionals_ad.h)的代码都 必须包含 inc/ marlinconfigpreh ,而任何需要完全实现的硬件配置的代码都必须包含 inc/MarlinConfig.h。 让我们仔细看看每个文件包含的头文件。 3.1、 MarlinConfigPre.h 3.2、 MarlinConfig.h 4、一个典型的源文件 将这些内容放在一起,典型的源文件至少将包含 marlinconfigpreh ,以便它可以预先检查一些配置 值。只有在需要时,才会包含其他头文件。有些源文件包含一些特性的头文件是很常见的。 /** * (c) 2021 Marlin Firmware * A typical Marlin source.cpp file. */ #include “inc/MarlinConfigPre.h” #if ENABLED(MY_COOL_FEATURE) #if ENABLED(EXTENSIBLE_UI) #include “lcd/extui/ui_api.h” #endif #endif // MY_COOL_FEATURE 5、典型的头文件 Marlin头文件不会像源文件一样使用 #if…#endif 来包装。相反,如果不需要头文件,那么它就不会被 包含。Marlin还避免使用c风格的 #ifdef 包装器,并且只在自己的头文件上使用 #pragma 一次。 /** * (c) 2021 Marlin Firmware * A typical Marlin header.h file. */ #pragma once extern int my_feature_var; void do_feature_stuff(); 当该特性被禁用时,一些头文件将提供空函数。这使得在单个点关闭东西更容易,并且可以使其他地方 的代码更整洁。 /** * (c) 2021 Marlin Firmware * A typical Marlin header.h file. */ #pragma once #include “inc/MarlinConfigPre.h” #if ENABLED(MY_COOL_FEATURE) extern int my_feature_var; void do_feature_stuff(); #else inline void do_feature_stuff() {} #endif 6、Marlin的构建过程 一个Marlin式的结构可能需要一段时间,但它像其他任何草图一样工作。Marlin中的所有 .cpp 文件及 其依赖项都将被编译,以及它们包含的任何内容。使用 PlatformIO 的Marlin构建将使用 ini 文件夹中 的文件以及 buildroot/share/PlatformIO 中的脚本,根据您的配置过滤掉未使用的源文件,从而使 其更快。 7、程序和命令流程 Marlin程序的执行从 MarlinCore.cpp 开始,setup()函数初始化,loop()函数主循环,就像 Arduino 草 图一样。loop()函数非常小,主要负责调用idle(),然后在队列前面运行下一个G-code命令。 Marlin中的大多数任务都是通过空闲函数执行的,该函数调用 manage_inactivity 和 thermalManager.manage_heater 。您将看到许多对空闲的调用,因为所有等待循环都使用它来保持 机器运行。如果Marlin太长时间没有呼叫空闲,看门狗就会被触发,为了安全重新启动机器。 这个程序架构需要一些注意,因为我们不希望某个函数被idle本身调用,直到堆栈爆炸为止。在Marlin 只有少数的再入守卫,所以在实践中它工作得很好。 从空闲状态跟踪函数调用,可以很直观地看到Marlin是如何使所有设备和特性在程序上下文中运行的。一些特性一直在进行活动,但是Marlin所做的大部分工作都是由G-code命令发起的。 8、中断服务例程 Marlin定义了一些中断服务例程( ISRs ):
9、G代码的处理 接下来,让我们看看如何处理 G 代码并遵循程序流程。
G-code处理程序几乎可以做任何事情,所以它们被分成单独的文件,每个文件只包含它需要的头文件。所有处理程序必须包括gcode.h,这将包括parser.h。
当一个命令需要等待计划器或用户反馈中的空闲空间等内容时,它将调用空闲函数以保持机器的活动和 运行。idle函数甚至会将传入的命令读取到队列中,但是由于idle函数并不会分发g代码或推进队列,所 以在处理程序结束并返回之前,队列不能获得任何空的命令。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1786 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1622 浏览 1 评论
1089 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
730 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1680 浏览 2 评论
1941浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
739浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
576浏览 3评论
598浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
560浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-25 10:38 , Processed in 1.426882 second(s), Total 78, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号