十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Marlin SAMD21 HAL 深入解析:架构、构建验证与移植避坑指南

Marlin SAMD21 HAL 深入解析:架构、构建验证与移植避坑指南 Marlin SAMD21 HAL 深入解析架构、构建验证与移植避坑指南【免费下载链接】MarlinMarlin is a firmware for RepRap 3D printers optimized for both 8 and 32 bit microcontrollers. Marlin supports all common platforms. Many commercial 3D printers come with Marlin installed. Check with your vendor if you need source code for your specific machine.项目地址: https://gitcode.com/GitHub_Trending/ma/Marlin本篇技术指南以Marlin/src/HAL/SAMD21/AGENTS.md为核心系统讲解 Marlin 固件中 SAMD21Atmel SAMD21J18ARM Cortex-M0硬件抽象层HAL的整体架构、构建与测试流程、框架集成方式以及源码中不易察觉的七类关键陷阱。读者将掌握 SAMD21 HAL 的串口/SPI/ADC/EEPROM 实现原理、mftest验证命令的正确用法以及新增 SAMD21 板卡环境时必须满足的编译前提可直接用于二次开发与移植实践。一、SAMD21 HAL 概览与仓库布局SAMD21 HAL 位于仓库 Marlin/src/HAL/SAMD21/由 Bart Meijerbrupje开发基于 Giuliano Zaro 的 SAMD51 HAL 改写而来见 HAL.h。该目录承担了 Marlin 在 SAMD21 平台上的全部底层能力包括串口原生 USB-CDC 与硬件 UARTSERCOM封装SPI基于上游SPIClass的硬件 SPI 驱动MarlinSPI.h、HAL_SPI.cppADC12 位 ADC 自由运行扫描与中断采集HAL.cpp定时器/伺服/引脚timers.cpp、Servo.cpp、fastio.hEEPROM 后端eeprom/ 下的eeprom_wired.cpp、eeprom_flash.cpp、eeprom_qspi.cpp三种实现u8g LCD 驱动u8g/ 下的 I2C/硬件 SPI 例程。与 HAL 配套的板级引脚文件位于 Marlin/src/pins/samd/目前包含四块板卡引脚文件对应板卡pins_MINITRONICS20.hReprapWorld Minitronics v2.0SAMD21J18pins_BRICOLEMON_V1_0.hBricolemon V1.0pins_BRICOLEMON_LITE_V1_0.hBricolemon Lite V1.0pins_RAMPS_144.hRAMPS 1.4.4 适配构建环境的接入点则分散在两处ini/samd21.ini定义平台环境buildroot/share/PlatformIO/scripts/SAMD21_minitronics20.py提供按环境定制的构建脚本。二、构建与测试用mftest验证 SAMD21 目标SAMD21 家族目前只有一个真实测试目标SAMD21_minitronics20它是 SAMD21 最严格也是唯一的约束条件——只要它构建通过并保持绿色就代表该家族整体得到覆盖。2.1 执行验证命令仓库推荐使用mftest进行验证因为它会按目标重新生成Marlin/Configuration.h而裸执行pio run -e无法可靠地做到这一点cd $(git rev-parse --show-toplevel) buildroot/bin/mftest -t SAMD21_minitronics20 -n1 -y # ReprapWorld Minitronics 2.0, SAMD21J18其中-t指定测试目标-n1表示仅执行一次-y自动确认。测试目标的真实配置位于 buildroot/tests/SAMD21_minitronics20/config-01.ini其[config:base]段落给出了该板卡的参考配置例如motherboard BOARD_MINITRONICS20 serial_port -1 x_driver_type DRV8825 y_driver_type DRV8825 z_driver_type DRV8825 e0_driver_type DRV8825 bltouch on endstop_interrupts_feature on filament_runout_sensor on lin_advance on eeprom_settings on reprapworld_graphical_lcd on该配置开启了 BLTouch、限位中断、断料检测、线性提前、EEPROM 设置、图形 LCD 等一揽子特性是 SAMD21 上功能全开的构建压力测试。注意不要把SAMD51_grandcentral_m4buildroot/tests/SAMD51_grandcentral_m4/config-01.ini与 SAMD21 混淆前者属于 SAMD51 家族两者架构并不相同。2.2 清理与重建规则禁止使用rm -rf .pio/build/...强制重建——交叉配置的写保护会拦截该操作且本身不安全。正确做法是pio run -e SAMD21_minitronics20 -t clean或者直接让mftest自行触发重建。2.3 环境配置要点SAMD21_minitronics20是 SAMD21 唯一的 PlatformIO 环境定义于 ini/samd21.ini[env:SAMD21_minitronics20] platform atmelsam board minitronics20 build_flags ${common.build_flags} -stdgnu17 -DUSBCON -DUSBD_USE_CDC -D__SAMD21__ -DARDUINO_SAMD_MINITRONICS20 -Wno-deprecated-declarations -DDEBUG -IMarlin/src/HAL/SAMD21/u8g build_unflags -stdgnu11 build_src_filter ${common.default_src_filter} src/HAL/SAMD21 extra_scripts ${common.extra_scripts} pre:buildroot/share/PlatformIO/scripts/SAMD21_minitronics20.py debug_tool atmel-icebuildroot/share/PlatformIO/scripts/SAMD21_minitronics20.py是 per-env 额外脚本其作用仅是根据MARLIN_FEATURES中的RX_BUFFER_SIZE/TX_BUFFER_SIZE调整串口缓冲区BUILD_FLAGS取两者与 350 的最大值不涉及其他逻辑改动。三、框架与平台集成上游atmelsam并非内置副本与 AT32 等平台不同SAMD21 的 Arduino 核心是PlatformIO 上游atmelsam平台framework-arduino-samd-*例如framework-arduino-samd-reprap/...-adafruit仓库内没有Marlin 自带的 vendored 副本buildroot/share/PlatformIO/下不存在。因此Marlin 特有的胶水代码分布在三处Marlin/src/HAL/SAMD21/——HAL 本体Marlin/src/pins/samd/——板级引脚定义buildroot/share/PlatformIO/scripts/SAMD21_minitronics20.py 与 ini/samd21.ini——构建胶水。因为框架来自上游所以不存在mirror-to-installed-package镜像到已安装包警告——该警告只适用于 vendored 的 AT32 核心。四、源码中不明显的七个陷阱Gotchas这是 AGENTS.md 的核心实战部分以下逐条结合源码印证。4.1 编译器宏是__SAMD21__由构建参数注入而非核心定义HAL 的所有源码都通过#ifdef __SAMD21__门控编译包括 HAL.cpp、HAL_SPI.cpp 以及eeprom/下的各实现。但上游 Arduino SAMD 核心定义的宏是ARDUINO_ARCH_SAMD并不定义__SAMD21__。正是 ini/samd21.ini 通过-D__SAMD21__注入该宏。移植铁律新增任何 SAMD21 板卡环境必须在build_flags中包含-D__SAMD21__否则该 HAL 目录下的一切代码都不会参与编译。4.2 主串口是原生 USB-CDC而非 UARTHAL.h 中typedef ForwardSerial1Class decltype(SerialUSB) DefaultSerial1; extern DefaultSerial1 MSerialUSB; typedef ForwardSerial1Class decltype(Serial1) DefaultSerial2; typedef ForwardSerial1Class decltype(Serial2) DefaultSerial3; extern DefaultSerial2 MSerial0; extern DefaultSerial3 MSerial1; ... #define USB_SERIAL_PORT(...) MSerialUSBDefaultSerial1绑定SerialUSB即MSerialUSB而Serial1/Serial2通过 SERCOM 映射到硬件 UARTMSerial0/MSerial1。构建参数中的-DUSBCON -DUSBD_USE_CDCini/samd21.ini使SerialUSB得以存在。因此测试配置 config-01.ini 中serial_port -1表示放弃 UART、完全依赖 USB。若某块板卡没有原生 USB必须重新指定串口端口否则无法与主机通信。4.3 软件 SPI 是硬性#errorHAL_SPI.cpp 中#if ANY(SOFTWARE_SPI, FORCE_SOFT_SPI) #error Software SPI not supported for SAMD21. Use Hardware SPI. #else即启用SOFTWARE_SPI或FORCE_SOFT_SPI会直接编译失败。MarlinSPI只是SPIClass的别名MarlinSPI.h即上游 SAMD SERCOM SPI 驱动。spiSendBlock()HAL_SPI.cpp注释中声称Uses DMA但实际调用的是阻塞式SPI.transfer()——这在功能上没有问题只是不要指望 SD 卡路径获得 DMA 卸载。硬件 SPI 的速率映射HAL_SPI.cppMarlin 速率常量实际时钟SPI_FULL_SPEED8 MHzSPI_HALF_SPEED4 MHzSPI_QUARTER_SPEED2 MHzSPI_EIGHTH_SPEED1 MHzSPI_SIXTEENTH_SPEED500 kHzSPI_SPEED_5250 kHzSPI_SPEED_6125 kHz默认4 MHz4.4 EEPROM 后端按板卡选择不自动探测SAMD21 HAL 的 eeprom/ 目录提供三种PersistentStore实现I2C EEPROMeeprom_wired.cpp经USE_WIRED_EEPROM使能但对 SAMD21 而言该宏是显式#errorUSE_WIRED_EEPROM emulation Not implemented on SAMD21Flash 模拟 EEPROMeeprom_flash.cpp经FLASH_EEPROM_EMULATION使能通过 NVMCTRL 按 ROW 擦除、按页写入数据保存在__attribute__((__aligned__(256)))的flashdata静态数组中容量由MARLIN_EEPROM_SIZE决定QSPI EEPROMeeprom_qspi.cpp QSPIFlash.cpp经QSPI_EEPROM使能代码已写好但同样以#error QSPI_EEPROM emulation Not implemented on SAMD21拒绝eeprom_qspi.cpp当前没有任何板卡选用。各板卡的实际默认见 pins_MINITRONICS20.h//#define FLASH_EEPROM_EMULATION //#define I2C_EEPROM // EEPROM on I2C-0 #define MARLIN_EEPROM_SIZE 500U // 4000 bytesBRICOLEMON_*与RAMPS_144默认I2C_EEPROMMINITRONICS20保持FLASH_EEPROM_EMULATION注释状态并定义MARLIN_EEPROM_SIZE 500U注意注释中4000 bytes的表述与 500U 存在出入实际容量以MARLIN_EEPROM_SIZE为准QSPI_EEPROM已编码但当前无板卡启用。4.5WDT宏与 CMSIS 结构体字段冲突在 HAL.cpp 中get_reset_source()的函数体被特意包裹在宏推送/弹出中#pragma push_macro(WDT) #undef WDT // Required to be able to use .bit.WDT. Compiler wrongly replace struct field with WDT define uint8_t MarlinHAL::get_reset_source() { return 0; } #pragma pop_macro(WDT)原因在于REG_WDT_CTRL会解析为.bit.WDT而预处理器会错误地把WDT宏替换进结构体字段。不要试图通过重命名字段来修复此问题——必须保留宏 push/pop 结构。4.6 ADC 是自由运行的 INPUTSCAN 扫描传感器顺序被重映射HAL.h 定义#define HAL_ADC_FILTERED 1 // Disable Marlins oversampling. The HAL filters ADC values. #define HAL_ADC_VREF_MV 3300 #define HAL_ADC_RESOLUTION 12 #define HAL_ADC_AIN_START ADC_INPUTCTRL_MUXPOS_PIN3 #define HAL_ADC_AIN_NUM_SENSORS 3adc_init()HAL.cpp将 12 位 ADC 配置为 16 位均值结果32 次采样累加、ADJRES(4)、GAIN_DIV2、自由运行模式并扫描 3 个连续 AINADC_INPUTCTRL_INPUTSCAN(HAL_ADC_AIN_LEN)。SAMD21 的 ADC 只能扫描连续的 AIN因此ADC_Handler()通过ADC-INPUTCTRL.bit.INPUTOFFSET将结果写入adc_results[pos]数组HAL.cppadc_start()在应用层把引脚的 AIN 重新映射回数组索引HAL.cpppos PIN_TO_INPUTCTRL(pin) - HAL_ADC_AIN_START 1当pos等于传感器数时归零。此外HAL_ADC_FILTERED 1意味着Marlin 自身的过采样被关闭——HAL 层已经完成了滤波32 次平均上层无需重复处理。4.7 48 MHz Cortex-M0无 FPUSAMD21 最高主频 48 MHz且没有硬件浮点单元。在热路径如运动规划、温度 PID中应尽量使用整数/定点运算。另外freeMemory()HAL.cpp实现为基于_sbrk/__bss_end__的堆尾估算int freeMemory() { int free_memory, heap_end (int)_sbrk(0); return (int)free_memory - (heap_end ?: (int)__bss_end__); }这只是一个粗略的堆尾 hack并非真正的栈检查不应据此判断栈溢出风险。五、SAMD21 代码约定Conventions所有 HAL 源码均由#ifdef __SAMD21__门控——新增源文件或新板卡环境时务必注入-D__SAMD21__见 4.1。修改边界清晰HAL 改动放入 Marlin/src/HAL/SAMD21/板级引脚改动放入 Marlin/src/pins/samd/构建胶水放入 buildroot/share/PlatformIO/scripts/per-env或 ini/samd21.ini。原生 USB CDC 是预期的主机链路默认将SerialUSB/MSerialUSB视为主端口除非板卡显式迁移到 UART。六、看门狗与复位语义补充实现细节虽然 AGENTS.md 未展开但 HAL.cpp 中的看门狗实现值得了解watchdog_init()将 GCLK2 配置为 1.024 kHz对 32.768 kHz OSCULP32K 分频喂给 WDT并设置 4 秒WATCHDOG_DURATION_8S时 8 秒复位超时watchdog_refresh()通过写入WDT_CLEAR_CLEAR_KEY清狗。注意初始化后必须至少每 4 秒刷新一次否则 SAMD21 会进入紧急复位流程。MarlinHAL::reboot()直接调用NVIC_SystemReset()重启固件。七、与共享 HAL 的协作关系SAMD21 HAL 复用了 Marlin/src/HAL/shared/ 中的共享 APIeeprom_api、SPI 辅助函数等例如PersistentStore的eeprom_exclude_size语义、HAL_SPI.h的接口声明都来自共享层。在阅读 SAMD21 特定实现时需要与共享目录对照理解接口约定。结语SAMD21 HAL 是一个麻雀虽小、五脏俱全的移植范本上游框架 少量胶水 严格宏门控是其骨架USB-CDC 主串口、SERCOM SPI、自由运行 ADC、按板卡选择的 EEPROM 后端是其血肉而__SAMD21__宏注入、WDT宏冲突规避、软件 SPI 拒绝等约定则是所有后续移植者必须遵守的边界条件。以mftest -t SAMD21_minitronics20为唯一验证闸门即可在新增板卡时快速确认家族完整性。【免费下载链接】MarlinMarlin is a firmware for RepRap 3D printers optimized for both 8 and 32 bit microcontrollers. Marlin supports all common platforms. Many commercial 3D printers come with Marlin installed. Check with your vendor if you need source code for your specific machine.项目地址: https://gitcode.com/GitHub_Trending/ma/Marlin创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表