在 LPC5528 上搭建 Klipper 底层开发环境及驱动编程方法

1.    前言

本篇博文将介绍如何在 LPC5528 搭建 Klipper 底层开发环境和对 Klipper 的底层驱动的编程方法进行介绍。

2.    开发环境搭建

2.1    下载虚拟机 VirtualBox 和安装 Ubuntu

通过链接 Oracle VM VirtualBox 进行下载,安装即可。

安装 Ubuntu 18.04 或 20.04,这里不做介绍。

2.2    下载 git 和 clone klipper 程序

在 Ubuntu 控制台下依次执行以下命令:

    sudo apt-get update

    sudo apt-get upgrade

    sudo apt install git

    sudo git clone https://github.com/Klipper3d/klipper.git


2.3    安装依赖包和编译器

安装依赖包

sudo apt-get install build-essential gcc make perl dkms

安装编译器

在网页端 Downloads | GNU Arm Embedded Toolchain Downloads – Arm Developer 下载 gcc-arm-none-eabi-10.3-2021.10-x86_64-linux.tar.bz2 解压放到 /usr/local/arm 文件夹中,在下载的后编译器目录下解压压缩包,进入解压后的文件夹中打开终端,执行以下指令:

sudo cp -R gcc-arm-none-eabi-10.3-2021.10/ /usr/local/arm

在 /usr/local/arm下将有如图所示的文件

 

图 1,2. 移动编译器到指定目录

添加环境变量

vi /etc/profile

在文件末尾添加

export PATH=$PATH:/usr/local/arm/ gcc-arm-none-eabi-10.3-2021.10/bin

使能环境变量

source /etc/profile

可以通过 VScode 打开文件夹的操作,打开 git 克隆的 klipper-master 文件夹,以打开 Klipper 工程,可方便文件的查看,也可以在 VScode 下打开终端进行命令行操作。

3.    工程建立

3.1    建立思路

以 STM32F407 为例,打开工程目录的 /src/stm32/stm32f4.c 文件,此文件是底层驱动主函数函数 void armcm_main(void) 所在之处,通过观察可以知道,Klipper 底层的应用层程序是和上位机程序配合的接口,其中的逻辑是写好的,即主函数的应用层是不需要改动的,对于想要使用一个新的单片机,主要的编程在于对应用层需要调用的底层驱动函数的编写,通 STM32 和 LPC176 可以看到,需要编写的驱动有 gpio、uart、usbcdc、adc、pwm、i2c、spi 等的控制和通信的驱动。

在安装好编译器后,接来下最重要的是如何去编译写好的驱动,以及下载和验证程序的正确性。这时就要参照 lpc176x 和 STM32 的工程去建立 lpc552x 工程,在 /src 目录下新建一个 lpc552x 的文件夹,在文件夹中添加驱动文件以及 Kconfig 和 Makefile 文件。

3.2    编写 Kconfig

想要实现编译,就需要配置 Kconfig 文件,在其中提供编译需要的一些信息,

在 /src 文件夹下的 Kconfig 文件中的对应位置添加一些两个信息:

1.

config MACH_LPC552X

bool "LPC552x (MKS Robin)"

2.

source "src/lpc552x/Kconfig"


在 /src/lpc552x 的 Kconfig 下添加 lpc5528 的设备信息,下面是作者的 Kconfig 文件用于参考:

# Kconfig settings for LPC552x processors

 

if MACH_LPC552X

 

config LPC55_SELECT

    bool

    default y

    select HAVE_GPIO

    select HAVE_GPIO_ADC

    select HAVE_GPIO_I2C

    select HAVE_GPIO_SPI

    select HAVE_GPIO_BITBANGING

    select HAVE_STRICT_TIMING

    select HAVE_CHIPID

    select HAVE_GPIO_HARD_PWM

    select HAVE_STEPPER_BOTH_EDGE

    select HAVE_BOOTLOADER_REQUEST

 

config BOARD_DIRECTORY

    string

    default "lpc552x"

 

choice

    prompt "Processor model"

    config MACH_LPC5528

        bool "lpc5528 (150 MHz)"

endchoice

 

config MCU

    string

    default "lpc5528" if MACH_LPC5528

 

config CLOCK_FREQ

    int

    default 150000000 if MACH_LPC5528

 

config FLASH_SIZE

    hex

    default 0xA0000

 

config FLASH_BOOT_ADDRESS

    hex

    default 0x0

 

config RAM_START

    hex

    default 0x20000000

 

config RAM_SIZE

    hex

    default 0x30000

 

config STACK_SIZE

    int

    default 400

 

 

######################################################################

# Bootloader

######################################################################

 

choice

    prompt "Bootloader offset"

    config LPC55_FLASH_START_4000

        bool "16KiB bootloader (Smoothieware bootloader)"

    config LPC55_FLASH_START_0000

        bool "No bootloader"

endchoice

config FLASH_APPLICATION_ADDRESS

    hex

    default 0x4000 if LPC55_FLASH_START_4000

    default 0x0000

 

 

######################################################################

# Communication inteface

######################################################################

 

choice

    prompt "Communication interface"

    config LPC55_USB

        bool "USB"

        select USBSERIAL

    config LPC55_SERIAL_UART0_P030_P029

        bool "Serial (on UART0 P0.30/P0.29)"

        select SERIAL

endchoice

 

endif

 

Kconfig 编写完成之后,可以在命令行中执行 sudo make menuconfig 来调出 menuconfig 配置菜单,如下图是作者的配置:

 

图 3. Kconfig 配置

3.3    驱动文件编写和库文件包含

驱动文件中可以参照 lpc176x 中的 API 接口函数编写对应适配 LP5528 底层的 API 函数,这些函数为了提高效率,多数是直接操作寄存器的。

图 4. 驱动文件建立

为了可以直接操作寄存器,还需要在 /lib 目录下建立 /lpc552x/device 加入头文件包含,以及对于内核的操作,由于 LPC5528 采用的是 cortex-m33 内核,还需要在 /lib/cmsis-core 文件夹下添加内核头文件 core_cm33.h。由此实现驱动文件对一些宏、结构体和函数的调用。




图 5,6. 库文件添加

可以先编写一个简单的驱动程序,用于验证程序的可执行性,从最简单的 GPIO 开始,先写好 GPIO 的驱动的 API 函数,然后我们可以在主函数中直接调用 API 函数,比如实现一个闪灯的程序,以验证程序可执行性。

3.4       Makefile 文件编写和编译及下载工程

做完以上的工作,接下来是编写 Makefile 文件,Makefile 是编译的规则,指定了需要编译的文件和编译的执行过程,下面是作者的 Makefile 文件:

# lpc552x build rules

 

# Setup the toolchain

CROSS_PREFIX=/usr/local/arm/bin/arm-none-eabi-

 

dirs-y += src/lpc552x src/generic lib/lpc552x/device

 

CFLAGS += -mthumb -mcpu=cortex-m33 -Ilib/lpc552x/device -Ilib/cmsis-core

 

CFLAGS_klipper.elf += --specs=nano.specs --specs=nosys.specs

CFLAGS_klipper.elf += -T $(OUT)src/generic/armcm_link.ld

$(OUT)klipper.elf: $(OUT)src/generic/armcm_link.ld

 

# Add source files

src-y += lpc552x/main.c lpc552x/gpio.c

src-y += generic/armcm_boot.c generic/armcm_irq.c generic/armcm_timer.c

src-y += generic/armcm_reset.c generic/crc16_ccitt.c

src-y += ../lib/lpc552x/device/system_LPC55S28.c

src-y += ../lib/lpc552x/device/fsl_common_arm.c

src-y += ../lib/lpc552x/device/fsl_common.c

src-y += ../lib/lpc552x/device/fsl_power.c

src-y += ../lib/lpc552x/device/fsl_reset.c

src-y += ../lib/lpc552x/device/fsl_clock.c

src-y += ../lib/lpc552x/device/clock_config.c

src-y += ../lib/lpc552x/device/pin_mux.c

src-y += ../lib/lpc552x/device/fsl_gpio.c

 

src-$(CONFIG_HAVE_GPIO_ADC) += lpc552x/adc.c

src-$(CONFIG_HAVE_GPIO_I2C) += lpc552x/i2c.c

src-$(CONFIG_HAVE_GPIO_SPI) += lpc552x/spi.c

src-$(CONFIG_USBSERIAL) += lpc552x/usbserial.c lpc552x/chipid.c

src-$(CONFIG_USBSERIAL) += generic/usb_cdc.c

src-$(CONFIG_SERIAL) += lpc552x/serial.c generic/serial_irq.c

src-$(CONFIG_HAVE_GPIO_HARD_PWM) += lpc552x/hard_pwm.c

 

# Build the additional bin output file

target-y += $(OUT)klipper.bin

 

$(OUT)klipper.bin: $(OUT)klipper.elf

    @echo "  Creating bin file $@"

    $(Q)$(OBJCOPY) -O binary $< $@

 

# Flash rules

flash: $(OUT)klipper.bin

    @echo "  Flashing $< to $(FLASH_DEVICE)"

    $(Q)$(PYTHON) ./scripts/flash_usb.py -t $(CONFIG_MCU) -d "$(FLASH_DEVICE)" $(if $(NOSUDO),--no-sudo) $(OUT)klipper.bin# lpc552x build rules

 

# Setup the toolchain

CROSS_PREFIX=/usr/local/arm/bin/arm-none-eabi-

 

dirs-y += src/lpc552x src/generic lib/lpc552x/device

 

CFLAGS += -mthumb -mcpu=cortex-m33 -Ilib/lpc552x/device -Ilib/cmsis-core

 

CFLAGS_klipper.elf += --specs=nano.specs --specs=nosys.specs

CFLAGS_klipper.elf += -T $(OUT)src/generic/armcm_link.ld

$(OUT)klipper.elf: $(OUT)src/generic/armcm_link.ld

 

# Add source files

src-y += lpc552x/main.c lpc552x/gpio.c

src-y += generic/armcm_boot.c generic/armcm_irq.c generic/armcm_timer.c

src-y += generic/armcm_reset.c generic/crc16_ccitt.c

src-y += ../lib/lpc552x/device/system_LPC55S28.c

src-y += ../lib/lpc552x/device/fsl_common_arm.c

src-y += ../lib/lpc552x/device/fsl_common.c

src-y += ../lib/lpc552x/device/fsl_power.c

src-y += ../lib/lpc552x/device/fsl_reset.c

src-y += ../lib/lpc552x/device/fsl_clock.c

src-y += ../lib/lpc552x/device/clock_config.c

src-y += ../lib/lpc552x/device/pin_mux.c

src-y += ../lib/lpc552x/device/fsl_gpio.c

 

src-$(CONFIG_HAVE_GPIO_ADC) += lpc552x/adc.c

src-$(CONFIG_HAVE_GPIO_I2C) += lpc552x/i2c.c

src-$(CONFIG_HAVE_GPIO_SPI) += lpc552x/spi.c

src-$(CONFIG_USBSERIAL) += lpc552x/usbserial.c lpc552x/chipid.c

src-$(CONFIG_USBSERIAL) += generic/usb_cdc.c

src-$(CONFIG_SERIAL) += lpc552x/serial.c generic/serial_irq.c

src-$(CONFIG_HAVE_GPIO_HARD_PWM) += lpc552x/hard_pwm.c

 

# Build the additional bin output file

target-y += $(OUT)klipper.bin

 

$(OUT)klipper.bin: $(OUT)klipper.elf

    @echo "  Creating bin file $@"

    $(Q)$(OBJCOPY) -O binary $< $@

 

# Flash rules

flash: $(OUT)klipper.bin

    @echo "  Flashing $< to $(FLASH_DEVICE)"

    $(Q)$(PYTHON) ./scripts/flash_usb.py -t $(CONFIG_MCU) -d "$(FLASH_DEVICE)" $(if $(NOSUDO),--no-sudo) $(OUT)klipper.bin

编译的过程可能会报错,这时我们只需要按照报错的信息去处理对应的地方即可,一般是可以解决的。

至此,万事具备,我们只需要在命令行下执行:

sudo make

就可以编译生成 klipper.bin 文件,klipper.bin 在工程目录下的 /out 文件夹下面。

图 7. Klipper.bin 所在位置

 

可以将此文件放到 J-Flash 中对程序进行烧录和验证。

 

图 8. 将 Klipper.bin 放到 J-Flash 进行程序烧写

 

4.    编程中发现的问题

1. 关于内存的分散加载,是在 src/generic 下的 armcm_link.lds.S 文件下进行的。


图 9. armcm_link.lds.S 所在位置

2. 关于启动文件,可以发现这里没有了 sartup.s 文件,那么这些启动引导程序放到了哪里呢?其实也是有相应的配置程序的,它们被写在 /src/generic 下的 armcm_boot.c 文件中。


图 10. armcm_boot.c 所在位置


3. 需要用到的中断要使用 armcm_enable_irq 进行声明,比如 USART0 的中断采用下面的语句进行声明:

armcm_enable_irq(FLEXCOMM0_IRQHandler, FLEXCOMM0_IRQn, 0);

通过实验发现声明之后的中断向量才会出现在中断向量表中,至于中断向量表如何生成,通过搜索 VectorTable 发现其是在 /scripts 下的 buildcommands.py 文件下的 Handle_arm_irq 类中处理,这里对此不做深入分析了。

 

图 11. Handle_arm_irq 所在位置

 

5.    参考资料

  1. GitHub - Klipper3d/klipper: Klipper is a 3d-printer firmware

   https://github.com/Klipper3d/klipper

  1. 欢迎 - Klipper 文档 (klipper3d.org)

    https://www.klipper3d.org/zh/

★博文内容均由个人提供,与平台无关,如有违法或侵权,请与网站管理员联系。

★文明上网,请理性发言。内容一周内被举报5次,发文人进小黑屋喔~

评论

후랑이

후랑이

6 个月前
我用了翻译器。 我想按照您的帖子进行操作,但我无法添加库文件。 可以分享一下源代码吗?