讓野火F103開發(fā)板支持Marlin2.0固件是什么體驗(yàn)?3D打印主控板成員 1
點(diǎn)擊上方「嵌入式云IOT技術(shù)圈」,選擇「置頂公眾號(hào)」第一時(shí)間查看嵌入式筆記!
???? 寫這篇文章之前默認(rèn)各位的VSCode PlatfromIO以及Marlin的開發(fā)環(huán)境都已搭建成功,如果不懂怎么搭建開發(fā)環(huán)境的,請(qǐng)移步Marlin官方,查看官方文檔講解:
marlinfw.org
??? 3D 打印進(jìn)入國內(nèi)算是比較晚的,所以在百度上學(xué)習(xí)和參考的資料都比較少,并且大部分的技術(shù)文章基本上都只是講怎么配置,其它的內(nèi)容其實(shí)非常少,包括對(duì)源代碼的分析等等。以下是我自己學(xué)習(xí)爬坑總結(jié)的將一個(gè)全新的開發(fā)板適配到Marlin固件經(jīng)驗(yàn):1、下載最新的Marlin官方固件然后對(duì)固件進(jìn)行解壓:2、移植Marlin2.x到野火STM32F103ZET6開發(fā)板2.1、導(dǎo)入該工程到Visual Studio Code2.2、添加硬件平臺(tái)編號(hào)????要讓Marlin能夠識(shí)別到硬件平臺(tái),我們需要在? boards.h 中定義相應(yīng)的板級(jí)編號(hào),如下所示:
/Marlin/src/core/boards.h
2.3、為新板創(chuàng)建新的引腳分配文件/Marlin/src/pins/stm32f1/
????由于野火的這款開發(fā)板是 STM32F1 系列,Marlin已經(jīng)做了相應(yīng)的支持,所以我們直接在這個(gè)上面這個(gè)路徑下創(chuàng)建一個(gè)文件 pins_WildFire_V1.h ,然后找到這個(gè)目錄下另外一個(gè)相同芯片相似的引腳配置文件復(fù)制過來即可,接下來的工作就是修改管腳:????在前面我們看到,Marlin固件支持的一款MKS_ROBIN的主控芯片就是 STM32F103ZET6 ,所以我們找到這款芯片的引腳分配文件,然后將這個(gè)文件里的所有代碼復(fù)制到 pins_WildFire_V1.h 中去:#define BOARD_MKS_ROBIN 4011 // MKS Robin (STM32F103ZET6)
將這個(gè)文件里的所有代碼復(fù)制到 pins_WildFire_V1.h 中去:2.4、配置板級(jí)編譯環(huán)境并綁定硬件平臺(tái)2.4.1、綁定編號(hào)與管腳的關(guān)系/Marlin/pins/pins.h
2.4.2、python腳本編寫????這部分主要是為了讓 buildroot 構(gòu)建環(huán)境的時(shí)候能夠準(zhǔn)確的匹配到具體的硬件平臺(tái),指定固件名稱并告訴固件上傳的時(shí)候要鏈接到MCU上的哪個(gè)地址。/buildroot/share/PlatformIO/scripts/
新建一個(gè)python腳本 wildfire_v1.py ,把鏈接地址、鏈接腳本名稱、最終生成的文件按以下格式寫入:#
# buildroot/share/PlatformIO/scripts/wildfire_v1.py
#
import marlin
marlin.prepare_robin("0x08007000",?"wildfire_v1.ld","wildfire.bin")
2.4.3、鏈接腳本編寫????鏈接腳本在2.4.2中已經(jīng)在python腳本中指定,當(dāng)系統(tǒng)進(jìn)行編譯時(shí),會(huì)找到這個(gè)鏈接文件。/buildroot/share/PlatformIO/ldscripts/
????新建一個(gè)鏈接腳本 wildfire_v1.ld ,按鏈接腳本的格式編寫各個(gè)段:MEMORY
{
?ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K - 40
?rom (rx) : ORIGIN = 0x08007000, LENGTH = 512K - 28K
}
/* Provide memory region aliases for common.inc */
REGION_ALIAS("REGION_TEXT", rom);
REGION_ALIAS("REGION_DATA", ram);
REGION_ALIAS("REGION_BSS", ram);
REGION_ALIAS("REGION_RODATA", rom);
/* Let common.inc handle the real work. */
INCLUDE common.inc
2.4.4、新板環(huán)境適配????由于 Marlin2.0 已經(jīng)支持 STM32F1 系列,也為 STM32F1 系列編寫了相應(yīng)的 ini 配置文件,我們只需要參考這個(gè)文件里的配置腳本,然后照葫蘆畫瓢即可。/ini/stm32f1.ini
????添加新板環(huán)境適配,以下的section以及ini配置屬于platformio的部分,感興趣可以去了解,后續(xù)會(huì)寫一篇文章專門來講解:#
# wildfire_v1 (STM32F103ZET6)
#
[env:wildfire_v1]
platform ???= ${common_stm32f1.platform}
extends ???= common_stm32f1
board ????= genericSTM32F103ZE
extra_scripts = ${common_stm32f1.extra_scripts}
buildroot/share/PlatformIO/scripts/wildfire_v1.py #指定用哪個(gè)python腳本進(jìn)行構(gòu)建
build_flags ?= ${common_stm32f1.build_flags}
-DSS_TIMER=4 -DSTM32_XL_DENSITY
debug_tool ??= stlink
upload_protocol = stlink
3、配置并下載Marlin 2. x 固件/Marlin/Configuration.h
3.1、修改串口號(hào)??? STM32 沒有串口0,我們需要改下串口號(hào)為1,否則Marlin編譯的時(shí)候會(huì)報(bào)錯(cuò),當(dāng)然也可以修改為其它的串口號(hào),只要硬件平臺(tái)支持就可以。3.2、修改串口波特率通常,把串口波特率修改為115200就可以了。3.3、設(shè)置主板將主板改為我們?cè)?2.1 章節(jié)里的那個(gè)宏3.4、將移植好的Marlin固件進(jìn)行編譯關(guān)掉Visual Studio Code,重新打開進(jìn)行編譯,可以看到,編譯成功!編譯好的固件的位置在這里:然后點(diǎn)擊Upload,上傳到 STM32 開發(fā)板成功:然后打開串口調(diào)試助手,發(fā)現(xiàn)沒有任何信息輸出:????這是因?yàn)闆]有 bootloader 的原因,因?yàn)?app 的地址是從 0x8007000 開始運(yùn)行的,而 MCU 是從0x8000000 開始運(yùn)行的,所以我們需要一個(gè)啟動(dòng)程序,啟動(dòng)的直接將地址指向 0x8007000 ,這樣Marlin固件就可以跑起來了。4、編寫bootloader 啟動(dòng)程序由于在鏈接地址中,我們已經(jīng)指定了地址:????所以直接將編譯好的 Marlin 固件上傳到 STM32 開發(fā)板是無法執(zhí)行成功的,所以我們需要編寫一個(gè)bootloader ,用于啟動(dòng)并跳轉(zhuǎn)地址到 0x8007000 這個(gè)地址,這樣 Marlin 固件才能跑起來。????思考一下,為什么Marlin要這么做?這是是為了后期 3D 打印機(jī)的 IAP 固件升級(jí)功能,可以實(shí)現(xiàn)線下更新固件。接下來我們就來實(shí)現(xiàn)這個(gè) bootloader 。4.1、 STM32CubeMX 配置4.1.1、時(shí)鐘配置4.1.2、指定 SWD 為調(diào)試端口
4.1.3、定義一個(gè)LED提示燈
4.1.4、生成基礎(chǔ)工程
然后打開這個(gè)工程進(jìn)行代碼編寫4.1.5、編寫 bootloader 代碼定義公共變量和宏
typedef ?void (*pFunction)(void);
//APP在內(nèi)部FLASH的起始地址
#define APP_RUNING_ADDRESS ?0x8007000
main函數(shù)編寫如下:/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
//uint8_t timeout = 3 ;
uint32_t JumpAddress;
pFunction Jump_To_Application;
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
//判斷在0x8007000區(qū)域有沒有APP,如果有則跳轉(zhuǎn)到APP代碼區(qū)
if (((*(__IO uint32_t*)APP_RUNING_ADDRESS)