開源Marlin2.x源代碼架構(gòu)學(xué)習(xí)筆記
點(diǎn)擊上方「嵌入式云IOT技術(shù)圈」,選擇「置頂公眾號(hào)」第一時(shí)間查看嵌入式筆記!
最近兩個(gè)月MBA美帝在職研的課程即將結(jié)束,經(jīng)過個(gè)人的努力,目前兩門課:全球商務(wù)、定量決策均分績(jī)點(diǎn)如下,基本上逼近滿分(凡爾賽了,哈哈哈),光鮮亮麗的背后,帶領(lǐng)小組始終沖在了班級(jí)的最前面,同時(shí)也付出了不少精力和汗水,通宵了不知道多少個(gè)夜晚,交完學(xué)期項(xiàng)目以后就結(jié)課啦,開始進(jìn)入下一門課的學(xué)習(xí)!所以開始有時(shí)間可以折騰新東西啦:(不少同學(xué)應(yīng)該知道我開了個(gè)知識(shí)星球,專門分享這些內(nèi)容,這里就不好放出來啦,有興趣和我說即可)
Marlin相當(dāng)龐大,自2.x版本開始,陸陸續(xù)續(xù)開始集成了32位機(jī),主流的STM32、LPC等高性能MCU逐漸取代了以Arduino2560等8位機(jī)的3D打印機(jī)方案。Marlin,龐大到讓每個(gè)初學(xué)者開始學(xué)習(xí)看代碼都會(huì)覺得聞風(fēng)喪膽,當(dāng)然我剛開始接觸的時(shí)候也不例外,但是不管是學(xué)什么東西,只要把大方向掌握了,那么細(xì)節(jié)的東西用到了再慢慢研究也不遲,同時(shí),Marlin的文檔非常少,對(duì)于初學(xué)者來說,是非常不友好的!以下這些介紹也是Marlin剛開放不久的說明文檔,筆者英語水平有限,如有翻譯失誤,盡情糾正與諒解!
1、Marlin代碼工程架構(gòu)
以下是原版的Marlin固件解壓下來的顯示情況:當(dāng)使用 PlatformIO 構(gòu)建Marlin時(shí),它會(huì)在.pio此處創(chuàng)建一個(gè)文件夾,并且在shell中使用git的時(shí)候,這 是當(dāng)前的工作目錄,如下圖所示:1.2、 buildroot 文件夾
該目錄包含開發(fā)人員的幫助腳本、字體工具、CI測(cè)試工具、Marlin圖標(biāo)和其它數(shù)據(jù)1.3、 buildroot/share/PlatformIO 文件夾
電路板定義、環(huán)境變量、鏈接腳本和構(gòu)建腳本會(huì)存放在這個(gè)地方,這個(gè)文件夾內(nèi)的構(gòu)建環(huán)境會(huì)經(jīng)常引用 ini文件夾1.4、 ini 文件夾
包含按 MCU 類型組織的所有 PlatformIO 環(huán)境設(shè)置, platformio.ini 文件將這些引入為 PlatformIO 提供構(gòu)建/上傳/調(diào)試設(shè)置,有一個(gè)文件特別有用:即是Marlin自定義構(gòu)建腳本 features.ini 在構(gòu)建開 始時(shí)用于根據(jù)啟用的功能過濾源文件,因此構(gòu)建能夠完成得更快。1.5、 Marlin 文件夾
構(gòu)建Marlin時(shí),配置文件就放在這個(gè)位置:1.6、 Marlin/src 文件夾
包含Marlin應(yīng)用程序,Marlin基于 Arduino 框架進(jìn)行開發(fā),所以它含有 Arduino 框架的setup()
?和?loop()
?功能。2、Marlin應(yīng)用源代碼Marlin/src 文件夾
Marlin應(yīng)用源代碼主要由以上文件夾組成,核心的入口程序文件是?MarlinCore.cpp
?,MarlinCore.h
?會(huì)做一些宏和變量以及函數(shù)的聲明,在這個(gè)文件中可以找到基于?Arduino
?框架的?setup()
?和?loop()
?函 數(shù),其余的文件夾包含的源碼主要的作用如下:- core文件夾
inc/MarlinConfig.h
?就可以確保這些文件按預(yù)期順序包含在內(nèi)。- feature文件夾
- gcode 文件夾
GCodeParser
?類的定義以及所有G代碼命令的實(shí)現(xiàn)(有一些不在這里實(shí)現(xiàn),但大部分是的),這 些功能都被包裝在一個(gè)名為?GcodeSuite
?的類里,G代碼實(shí)現(xiàn)的文件被捆綁在多個(gè)類別的子文件夾 中,這些文件被命令為具體的G代碼,因此可以使用 IDE 的查找功能找到它們。- HAL文件夾
Marlin2.x
?版本實(shí)現(xiàn)了硬件抽象層,更好的屏蔽了平臺(tái)的差異性,使其它的平臺(tái)更好的兼容?Arduino
?框架。- inc文件夾
Conditionals*.h
?和?SanityCheck.h
文件 。- lcd 文件夾
LCD
、TFT
、OLED
、編碼器、按鈕和串行控制器的相關(guān)代碼都放在這里,語言翻譯通常僅 適用于外部控制器,因此語言翻譯也放在這里。- libs文件夾
- module文件夾
- pins文件夾
pins.h
?根據(jù)?MOTHERBOARD
?設(shè)置進(jìn)行包含,由于?pins.h
?是?MarlinConfig.h
?的包 含文件注意,因此它不會(huì)包含在其它的地方。- sd 目錄
CardReader
?類是Marlin用 于導(dǎo)航目錄、打開G-code
文件和從SD卡(或其他媒體)打印的主界面。自從Marlin 2.0.8
以來,所有 的媒體類型都派生自?DiskIODriver
?抽象類。3、Marlin的配置
馬林是高度可配置的。您將在源代碼的許多地方發(fā)現(xiàn)應(yīng)用配置選項(xiàng)來打開和關(guān)閉代碼、更改行為和提供 值。- Marlin源文件如何獲得它需要的所有配置值?
conditionals_ad.h
)的代碼都 必須包含?inc/ marlinconfigpreh
?,而任何需要完全實(shí)現(xiàn)的硬件配置的代碼都必須包含 inc/MarlinConfig.h
。讓我們仔細(xì)看看每個(gè)文件包含的頭文件。3.1、 MarlinConfigPre.h
3.2、 MarlinConfig.h4、一個(gè)典型的源文件
將這些內(nèi)容放在一起,典型的源文件至少將包含 marlinconfigpreh ,以便它可以預(yù)先檢查一些配置 值。只有在需要時(shí),才會(huì)包含其他頭文件。有些源文件包含一些特性的頭文件是很常見的。/**
*?(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頭文件不會(huì)像源文件一樣使用?#if…#endif
?來包裝。相反,如果不需要頭文件,那么它就不會(huì)被 包含。Marlin還避免使用c風(fēng)格的?#ifdef
?包裝器,并且只在自己的頭文件上使用?#pragma
?一次。/**
*?(c)?2021?Marlin?Firmware
*?A?typical?Marlin?header.h?file.
*/
#pragma?once
extern?int?my_feature_var;
void?do_feature_stuff();
當(dāng)該特性被禁用時(shí),一些頭文件將提供空函數(shù)。這使得在單個(gè)點(diǎn)關(guān)閉東西更容易,并且可以使其他地方 的代碼更整潔。/**
*?(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的構(gòu)建過程
一個(gè)Marlin式的結(jié)構(gòu)可能需要一段時(shí)間,但它像其他任何草圖一樣工作。Marlin中的所有 .cpp 文件及 其依賴項(xiàng)都將被編譯,以及它們包含的任何內(nèi)容。使用 PlatformIO 的Marlin構(gòu)建將使用 ini 文件夾中 的文件以及?buildroot/share/PlatformIO
?中的腳本,根據(jù)您的配置過濾掉未使用的源文件,從而使 其更快。7、程序和命令流程
Marlin程序的執(zhí)行從?MarlinCore.cpp
?開始,setup()
函數(shù)初始化,loop()
函數(shù)主循環(huán),就像 Arduino 草 圖一樣。loop()
函數(shù)非常小,主要負(fù)責(zé)調(diào)用idle()
,然后在隊(duì)列前面運(yùn)行下一個(gè)G-code命令。Marlin中的大多數(shù)任務(wù)都是通過空閑函數(shù)執(zhí)行的,該函數(shù)調(diào)用?manage_inactivity
?和?thermalManager.manage_heater
?。您將看到許多對(duì)空閑的調(diào)用,因?yàn)樗械却h(huán)都使用它來保持 機(jī)器運(yùn)行。如果Marlin太長(zhǎng)時(shí)間沒有呼叫空閑,看門狗就會(huì)被觸發(fā),為了安全重新啟動(dòng)機(jī)器。這個(gè)程序架構(gòu)需要一些注意,因?yàn)槲覀儾幌M硞€(gè)函數(shù)被idle本身調(diào)用,直到堆棧爆炸為止。在Marlin 只有少數(shù)的再入守衛(wèi),所以在實(shí)踐中它工作得很好。從空閑狀態(tài)跟蹤函數(shù)調(diào)用,可以很直觀地看到Marlin是如何使所有設(shè)備和特性在程序上下文中運(yùn)行的。一些特性一直在進(jìn)行活動(dòng),但是Marlin所做的大部分工作都是由G-code命令發(fā)起的。8、中斷服務(wù)例程
Marlin定義了一些中斷服務(wù)例程( ISRs ):- 步進(jìn) ISR 反復(fù)運(yùn)行,通過向步進(jìn)電機(jī)的STEP和DIR引腳發(fā)送脈沖以高速移動(dòng)規(guī)劃隊(duì)列和步進(jìn)電機(jī)。這種中斷的頻率與移動(dòng)速度有關(guān)。
- 溫度 ISR 以接近 1KHz 的頻率讀取溫度傳感器,并在讀數(shù)準(zhǔn)備好時(shí)向主程序發(fā)送信號(hào)。它還管理不 需要非常高基頻的加熱器和風(fēng)扇配置的軟件/慢 PWM 。
- 終止 ISR 可以被激活,如果終止引腳是中斷能力的。它只在結(jié)束引腳的輸入狀態(tài)改變時(shí)觸發(fā)。
- Tone Timer由 Arduino 為某些平臺(tái)定義,由Marlin為其他平臺(tái)定義。它處理脈沖壓電蜂鳴器來創(chuàng) 建音調(diào),它運(yùn)行的頻率是當(dāng)前音調(diào)的兩倍。
- 伺服定時(shí)器提供了用于伺服系統(tǒng)的 PWM 信號(hào)。
9、G代碼的處理
接下來,讓我們看看如何處理 G 代碼并遵循程序流程。- 0.緊急解析器
- 1.從Serial和SD讀取
manage_inactivity
函數(shù)調(diào)用queue.get_available_commands()
,該函數(shù)檢查即時(shí)緩沖區(qū),查詢串行 端口,并讀取活動(dòng)的SD打印文件,將行復(fù)制到命令隊(duì)列中,目的是使其充滿。- 2.彈出G代碼
queue.advance()
獲取隊(duì)列前面的命令并立即運(yùn)行它。在命令完成之前,Marlin不會(huì)返回到loop()
。注意```queue.advance() ````在隊(duì)列之前運(yùn)行內(nèi)部命令,因此Marlin可以命令自身在常規(guī)命令流中 執(zhí)行一些操作。- 3.預(yù)掃描G代碼
queue.advance()
選擇了下一個(gè)命令,它就調(diào)用解析器對(duì)G-code行進(jìn)行預(yù)處理。預(yù)處理程序驗(yàn)證行號(hào)和校驗(yàn)和,如果一切正常,它會(huì)在調(diào)用特定的G-code處理程序之前對(duì)參數(shù)進(jìn)行快速預(yù)掃描。- 4.處理G代碼
GcodeSuite::G28()
?),盡管有一些在其他地方實(shí)現(xiàn)。G-code處理程序是一個(gè)簡(jiǎn)單的沒有返回值的void方法。它不是從函數(shù)調(diào)用中獲取參數(shù),而是查詢 GCodeParser 類來檢查參數(shù)并讀取它們的值。例如,處理程序使用parser.seen('X')
來檢查'X'參數(shù)是否存在,然后調(diào)用parser.value_float()
以浮點(diǎn)數(shù)的形式獲取其數(shù)值。請(qǐng)參閱gcode/parser.h
獲取所有可用的方法。G-code處理程序幾乎可以做任何事情,所以它們被分成單獨(dú)的文件,每個(gè)文件只包含它需要的頭文件。所有處理程序必須包括gcode.h
,這將包括parser.h
。- 5.命令阻塞
往期精彩
步進(jìn)電機(jī)驅(qū)動(dòng)在3D打印應(yīng)用的學(xué)習(xí)筆記(一)光固化3D打印懸空和支撐講解3D打印過程與最近的學(xué)習(xí)成果
兩個(gè)最常用的3D打印機(jī)切片軟件
3D打印機(jī)marlin固件框架與GCode命令總結(jié)
3D打印機(jī)Marlin固件串口功能解析和程序移植
讓野火F103開發(fā)板支持Marlin2.0固件是什么體驗(yàn)?3D打印主控板成員 1
C語言映射表在嵌入式串口解析、UI設(shè)計(jì)中的應(yīng)用(值得收藏并實(shí)踐的精華帖)
覺得本次分享的文章對(duì)您有幫助,隨手點(diǎn)
[在看]
并轉(zhuǎn)發(fā)分享,也是對(duì)我的支持。