自行构建RepRapFirmware固件
本文最后更新于:2026年5月22日 晚上
前言
RepRapFirmware是一款开源且功能全面的运动控制固件,广泛用于各种DIY机器,常见于CNC和3D打印,也可以自定义各种复杂运动学,并且无需其他硬件,全部控制由ARM芯片完成,进一步提升了机器运行时的稳定性。
该官方固件目前只适配了Duet出品的主板,而第三方开源主板并不能使用,好在gloomyandy对其进行了扩展,适配了部分开源3D打印主板,但是随着RRF源码变得越来越复杂,构建的固件体积也越来越大,截止到目前稳定版本(v3.6),已经有相当一部分的主板由于芯片Flash空间只有512Kb而被淘汰(仅可以使用之前的老版本),当前最新稳定版仅支持Flash空间大于或等于1024Kb的芯片才可使用。
其实还有一小部分支持的主板可以使用当前最新版的RRF固件,例如:MKS Robin Nano V3.0(STM32F407VGT6),可不知为何gloomyandy并未发布相关固件,所以在查阅大量资料后,打算自己在本地来构建该主板可用的RRF固件,并对过程进行记录,仅供参考。
安装工具
安装构建所需工具请查看网页说明:Firmware Building Instructions
对于编译工具链请查看以下说明:Instructions for building under Windows,请根据具体构建的RRF版本选择合适的工具链版本,否则后续构建可能会报错。
项目分析
构建流程
以下构建流程分析来自DeepSeek AI,请注意甄别。
1 | |
观察并打开各流程的文件进行查看,暂时不要修改任何文件,直接在Git Bash终端运行任务build octopus pro f4 firmware进行初次构建,留意构建日志信息。
构建日志
1 | |
RRFBuild项目已经对源码进行了封装与集中化管理,在编译构建时不涉及任何PIN引脚功能配置(默认硬件核心功能除外),生成的base_stm32f4.bin文件对于STM32F4系列芯片为通用文件(可搭配SD卡sys文件夹中的board.txt、rrfboot.txt、rrfpins.txt进行自定义使用),只在最后步骤使用CrcAppender工具对相应boards文件夹下的板级描述文件(rrfboot.txt、rrfpins.txt)进行打包合并,生成适用于对应主板的firmware_octopuspro1_0_f4.bin文件。
这也体现了RepRapFirmware固件的一个特点:编译时硬件无关,运行时动态选择,所以接下来我们只需要编写一个适合MKS Robin Nano V3.0(STM32F407VGT6)主板的板级描述文件,然后让工具打包生成所需固件即可。
构建便捷固件
便捷固件构建简单快捷,无需过多修改原项目的文件即可构建出RRF固件,但是需要先使用Jlink等工具通过SWD接口烧录一个其他相同芯片型号的主板Bootloader(对于本次使用的主板可以选择Fly E3 V2),然后再根据Bootloader的偏移量烧录RRF固件,但这种与主板不匹配的Bootloader可能会在实际使用过程造成启动失败,请谨慎操作,该方法仅作为实验性质。
如需专用且匹配的Bootloader,请查看后续构建稳定固件方法。
新建板级描述文件
在boards文件夹下,新建一个mks/robin_nano_f4文件夹,新建以下文件并填入相应内容:
boards\mks\robin_nano_f4\rrfboot.txt
1 | |
以下内容来自RepRapFirmware\src\Hardware\STM32\BoardConfig.cpp文件,并对其中各项参数进行中文注释,翻译不一定准确,具体参数功能请查阅项目源码。
由于RRF固件是逐行解析rrfboot.txt文件,所以对参数定义顺序有要求,部分重要参数不能随意调换位置,可查看boards文件夹下的其他板级描述文件作为参考。
请注意,不是每个参数必须定义然后对其进行配置,部分参数有其默认值,详情请查阅项目源码。
Nomal
board:主板型号
board.longName:主板名称
leds.diagnostic:LED诊断指示灯引脚
leds.diagnosticOn:是否开启LED诊断指示灯功能,默认值为true
leds.activity:LED运行指示灯引脚
leds.activityOn:是否开启LED运行指示灯,默认值为truePin States
pins.SetHigh:设置引脚初始化为高电平
pins.SetLow:设置引脚初始化为低电平Internal SDCard
sdcard.internal.type:内部SD卡通道组,默认值为SD_UNKNOWN,可配置为以下选项(输入分析结论中的数字即可):1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22//以下内容来自RepRapFirmware\src\Hardware\STM32\BoardConfig.cpp文件的第58行
typedef enum {
SD_SPI1_A, //enum SDConfigs::SD_SPI1_A = 0
SD_SPI1_B, //enum SDConfigs::SD_SPI1_B = 1
SD_SDIO, //enum SDConfigs::SD_SDIO = 2
SD_SPI3_A, //enum SDConfigs::SD_SPI3_A = 3
SD_SPI3_B, //enum SDConfigs::SD_SPI3_B = 4
SD_SPI2_A, //enum SDConfigs::SD_SPI2_A = 5
SD_UNKNOWN = 0xfe, //enum SDConfigs::SD_UNKNOWN = 254
SD_NONE = 0xff //enum SDConfigs::SD_NONE = 255
} SDConfigs;
/*以下分析结论来自RepRapFirmware\src\Hardware\STM32\BoardConfig.cpp文件的第59行与第598行
0:SD_SPI1_A 对应的引脚号为:PA5(SCK)、PA6(MISO)、PB5(MOSI)、PA4(CS)
1:SD_SPI1_B 对应的引脚号为:PA5(SCK)、PA6(MISO)、PA7(MOSI)、PA4(CS)
2:SD_SDIO 对应的引脚号为:PC8(SDIO_D0)、PC9(SDIO_D1)、PC10(SDIO_D2)、PC11(SDIO_D3)、PC12(SDIO_CK)、PD2(SDIO_CMD)
3:SD_SPI3_A 对应的引脚号为:PC10(SCK)、PC11(MISO)、PC12(MOSI)、PC9(CS)
4:SD_SPI3_B 对应的引脚号为:PC10(SCK)、PC11(MISO)、PC12(MOSI)、PA15(CS)
5:SD_SPI2_A 对应的引脚号为:PB13(SCK)、PB14(MISO)、PB15(MOSI)、PB12(CS)
254:SD_UNKNOWN 未知SD卡
255:SD_NONE 无SD卡
*/sdCard.internal.spiFrequencyHz:内部SD卡SPI通道频率,默认值为25000000,即频率为25MHzExternal SDCard
sdCard.external.csPin:外部SD卡Cs引脚,默认值为PA4(SD_SPI1_A CS)
sdCard.external.cardDetectPin:外部SD卡检测引脚,默认值为NoPin
sdCard.external.spiFrequencyHz:外部SD卡SPI通道频率,默认值为4000000,即频率为4MHz
sdCard.external.spiChannel:外部SD卡使用的SPI通道组,既可以配置为SPI Channel中的SPI通道组,也可以配置为以下源码内置的通道组,默认值为SSPNONE1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31//以下内容来自CoreN2G\src\STM32\SharedSPI\SPI.h文件的第22行
enum SSPChannel : uint8_t
{
//Hardware SPI
SSP1 = 0,
SSP2,
SSP3,
//Software SPI
SWSPI0,
SWSPI1,
SWSPI2,
//Additional Hardware devices
# if STM32H7
SSP4,
SSP5,
SSP6,
# endif
SSPMAX,
// Hardware SDIO
SSPSDIO = 0xef, //239
// Not defined
SSPNONE = 0xff //255
};
//以下内容来自RepRapFirmware\src\Hardware\STM32\BoardConfig.cpp文件的第598行
{SSP1, {PA_5, PA_6, PB_5, PA_4, NoPin, NoPin}, {0x502, 0x502, 0x502, 0x1}}, // SKR Pro
{SSP1, {PA_5, PA_6, PA_7, PA_4, NoPin, NoPin}, {0x502, 0x502, 0x502, 0x1}}, // GTR
{SSPSDIO, {PC_8, PC_9, PC_10, PC_11, PC_12, PD_2}, {0xc02, 0xc02, 0xc02, 0xc02, 0xc02, 0xc02}}, // Fly/SDIO
{SSP3, {PC_10, PC_11, PC_12, PC_9, NoPin, NoPin}, {0x602, 0x602, 0x602, 0x1}}, // MKS?
{SSP3, {PC_10, PC_11, PC_12, PA_15, NoPin, NoPin}, {0x602, 0x602, 0x602, 0x1}}, // BTT BX
{SSP2, {PB_13, PB_14, PB_15, PB_12, NoPin, NoPin}, {0x502, 0x502, 0x502, 0x1}}, // BTT kraken?SPI Channel
SPI0.pins
SPI1.pins
SPI2.pins
SPI3.pins
SPI4.pins
SPI5.pins
SPI通道组,严格遵循以下定义顺序:SCK,MISO,MOSI;对于构建STM32F4系列芯片,最多有6个SPI通道,所以为了程序上的最大兼容性,必须申明0~5所有的SPI通道组,若实际芯片没有这么多SPI通道,剩余部分可以填写NoPinSteppers
stepper.powerEnablePin:电机驱动电源开启引脚,没有则填写NoPin
stepper.enablePins:电机驱动Enable引脚组
stepper.stepPins:电机驱动Step引脚组
stepper.directionPins:电机驱动Dir引脚组
stepper.digipotFactor:数字电位器系数(电路板是否内置了通过数字电位器实现的电流控制?)
stepper.numSmartDrivers:支持TMC电机驱动总个数
stepper.TmcUartPins:TMC驱动Uart引脚组
stepper.DriverType:电机驱动类型组,可配置为以下选项:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15//以下选项来自以下RepRapFirmware\src\Hardware\STM32\Pins_STM32.h文件的第202行
NamedEnum(DriverType, uint8_t,
unknown,
none,
stepdir,
tmcuartauto,
tmc2208,
tmc2209,
tmc2660,
tmcspiauto,
tmc5160,
tmc2240,
tmcauto,
invalid);stepper.num5160Drivers:支持TMC5160电机驱动总个数
stepper.spiChannel:电机驱动使用的SPI通道组,详细配置说明请查看External SDCard ->sdCard.external.spiChannel,默认值为SSPNONEstepper.csDelay:电机驱动SPI通道Cs延迟时间
stepper.TmcDiagPins:TMC驱动Diag引脚组ATX Power
atx.powerPin:ATX电源引脚,没有则填写NoPin
atx.powerPinInverted:ATX电源引脚信号反相
atx.initialPowerOn:ATX电源初始化时开启引脚,默认值为truePower
power.VInDetectPin:电源供电检测引脚,没有就填写NoPin
power.voltage:电源供电电压,默认值为24SBC Cofig
sbc.TfrReadyPin:SBC模式Tfr就绪引脚
sbc.csPin:SBC模式Cs引脚,默认值为PB12(SD_SPI2_A CS)
sbc.spiChannel:SBC模式使用的SPI通道组,详细配置说明请查看External SDCard ->sdCard.external.spiChannel,默认值为SSP2sbc.loadConfig:SBC模式是否从单板计算机加载配置,默认值为true- 该选项为true,且External SDCard ->
sdCard.external.spiChannel配置为SSPNONE,代表没有外部SD卡,因此处于SBC模式从单板计算机加载配置 - 该选项为true,且External SDCard ->
sdCard.external.spiChannel配置外部SD卡,不管外部SD卡是否存放配置文件,都会优先从单板计算机上进行加载,如果没有则从外部SD卡加载 - 该选项为false,且External SDCard ->
sdCard.external.spiChannel配置外部SD卡,则从外部SD卡加载配置
sbc.sbcMode:是否开启SBC模式,0为关闭,1为开启- 该选项为true,且External SDCard ->
WIFI Cofig
ESP8266
8266wifi.espDataReadyPin:ESP8266模块数据就绪引脚
8266wifi.TfrReadyPin:ESP8266模块Tfr就绪引脚
8266wifi.lpcTfrReadyPin:ESP8266模块Tfr就绪引脚,该配置和上述8266wifi.TfrReadyPin其实是一样的,仅作为兼容性被保留
8266wifi.espResetPin:ESP8266模块复位引脚
8266wifi.csPin:ESP8266模块SPI Cs引脚,默认为PB12(SD_SPI2_A CS)
8266wifi.serialRxTxPins:ESP8266模块Rx、Tx引脚,严格遵循以下定义顺序:RX,TX
8266wifi.spiChannel:ESP8266模块使用的SPI通道组,详细配置说明请查看External SDCard ->sdCard.external.spiChannel,默认值为SSP28266wifi.clockReg:ESP8266模块时钟寄存器
8266wifi.moduleType:WIFI模块类型,可配置为以下选项:1
2
3
4
5
6
7
8
9
10
11//以下选项来自以下RepRapFirmware\src\Hardware\STM32\Pins_STM32.h文件的第350行
//目前该项目仅支持esp8266或者esp32,其他类型可能是测试用途,请注意区分
NamedEnum(NetworkModuleType, uint8_t,
espauto,
none,
esp8266,
esp32,
esp32eth,
esp32s3,
esp32c3,
esp32c5);ESP32
wifi.espDataReadyPin:ESP32模块数据就绪引脚
wifi.TfrReadyPin:ESP32模块Tfr就绪引脚
wifi.espResetPin:ESP32模块复位引脚
wifi.csPin:ESP32模块SPI Cs引脚,默认为PB12(SD_SPI2_A CS)
wifi.serialRxTxPins:ESP32模块Rx、Tx引脚,严格遵循以下定义顺序:RX,TX
wifi.spiChannel:ESP32模块使用的SPI通道组,详细配置说明请查看External SDCard ->sdCard.external.spiChannel,默认值为SSP2wifi.clockReg:ESP32模块时钟寄存器
wifi.moduleType:WIFI模块类型,详细配置说明请查看WIFI Cofig -> ESP8266 ->8266wifi.moduleType
Heater & Sensors
heat.tempSensePins:热敏引脚组
heat.spiTempSensorCSPins:SPI通道热敏Cs引脚组
heat.spiTempSensorChannel:SPI通道热敏通道组,默认值为255
heat.thermistorSeriesResistor:热敏上拉电阻阻值,默认值为4700.0MINI12864
lcd.lcdCSPin:LCD片选引脚
lcd.lcdBeepPin:LCD蜂鸣器引脚
lcd.encoderPinA:LCD编码器引脚A
lcd.encoderPinB:LCD编码器引脚B
lcd.encoderPinSw:LCD编码器按钮引脚
lcd.lcdDCPin:LCD数据/指令引脚
lcd.panelButtonPin:LCD面板按钮引脚
lcd.spiChannel:LCD使用的SPI通道组,详细配置说明请查看External SDCard ->sdCard.external.spiChannel,默认值为SSP2,默认值为255,即未配置SPI通道Serial
serial.aux.rxTxPins:辅助串口组,严格遵循以下定义顺序:RX,TX,默认值为PA10、PA9
serial.aux2.rxTxPins:辅助2串口组,严格遵循以下定义顺序:RX,TXRGB
led.neopixelPin:RGB信号引脚accelerometer
accelerometer.spiChannel:加速度计使用的SPI通道组,详细配置说明请查看External SDCard ->sdCard.external.spiChannel,默认值为255,即没有加速度计CAN Bus
can.spiChannelCAN Bus使用的SPI通道组,详细配置说明请查看External SDCard ->sdCard.external.spiChannelcan.csPinCAN Bus片选引脚
can.spiFrequencyHzCAN Bus SPI通道频率,默认值为15000000,即为15MHz
can.readPinCAN Bus数据读取引脚,仅STM32H7系列芯片支持,默认值为PB8
can.writePinCAN Bus数据写入引脚,仅STM32H7系列芯片支持,默认值为PB9
can.exp.addressCAN Bus扩展地址,默认地址为255
boards\mks\robin_nano_f4\rrfpins.txt
1 | |
A.1 e0temp,t0
前面为对应引脚号,后面则为引脚别名,有多个别名使用逗号分隔,便于在sys/config.g中使用
修改构建脚本
.vscode\tasks.json
在适当位置添加以下内容:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31{
"label": "build robin nano f4 firmware",
"type": "shell",
"command": "bash ./testbuild.sh Debug STM32 STM32F4 STM32F4 COMBINED mks robin_nano_f4",
"osx": {
"options": {
"env": {
"PATH": "${env:PATH}"
}
}
},
"linux": {
"options": {
"env": {
"PATH": "${env:PATH}"
}
}
},
"windows": {
"options": {
"env": {
"PATH": "${env:PATH}"
}
}
},
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": "$gcc"
},
开始构建常规固件
在git bash终端运行任务:build robin nano f4 firmware,等待构建完成就会生成firmware_robin_nano_f4.bin文件。
构建稳定固件
稳定固件需要使用MKS曾经为该主板适配的早期版本(v3.2)RepRapFirmware-for-MKS-Boards中的Bootloader文件,该文件对使用RRF固件做了适配,并且提供SD卡更新固件的功能,方便后续升级。
但是该文件的Bootloader偏移量为48KB,而原项目默认为32KB,所以想要构建的RRF固件正常使用,就需要修改以下部分文件内容。
修改文件记录
先按文章前面部分构建便捷固件中的新建板级描述文件以及修改构建脚本进行操作,再执行以下修改!
RepRapFirmware\src\Hardware\STM32\variants\STM32F407\ldscript.ld
原文件:1
2
3VECTOR (rx) : ORIGIN = 0x8008000, LENGTH = 16K
RESETDATA (rx) : ORIGIN = 0x800C000, LENGTH = 16K
FLASH (rx) : ORIGIN = 0x8010000, LENGTH = 1024K - 64K修改为:
1
2
3VECTOR (rx) : ORIGIN = 0x800C000, LENGTH = 16K
RESETDATA (rx) : ORIGIN = 0x8010000, LENGTH = 64K
FLASH (rx) : ORIGIN = 0x8020000, LENGTH = 1024K - 128KRepRapFirmware\src\Hardware\STM32\Pins_STM32.h
原文件:1
2
3
4# define FIRMWARE_NAME "RepRapFirmware for STM32F4 based Boards"
...
# define FLASH_DATA_LENGTH (16*1024) //size of the Software Reset Data in Flash修改为:
1
2
3
4# define FIRMWARE_NAME "RepRapFirmware for STM32F4 based Boards"
...
# define FLASH_DATA_LENGTH (64*1024) //size of the Software Reset Data in Flash
开始构建稳定固件
在Git Bash终端运行任务:build robin nano f4 firmware,等待构建完成就会生成firmware_robin_nano_f4.bin文件。
特别鸣谢
Building RepRapFirmware
RepRapFirmware-for-MKS-Boards
[FR] Robin Nano v3 support?