在瑞士卢塞恩应用科学与艺术大学推出tinyK22开发板之后,我就开始想着在本周末写一篇文章,介绍如何使用该开发板的Flash内置引导程序。
内容简介 本文主要介绍如何使用Flash内置引导加载程序来编程和使用恩智浦K22微控制器。我尽量使得本文使用的代码尽可能通用,这样的话您就可以使用任何其他基于Eclipse的IDE(Kinetis Design Studio或NXP MCUXpresso IDE)。有关使用的示例项目和源代码,请参阅本文结尾处的GitHub链接。
如果您对另一个非常好的开源BootLoader感兴趣,请查看μTasker项目页面(http://www.utasker.com/kinetis/tinyK22.html)。该引导程序提供MSD加载功能,也小得多。
硬件方面,我们使用的是Kinetis K22FN512微控制器。该ARM Cortex-M4F微控制器位于tinyK22开发板上,和FRDM-K22F开发板一样。
USB HID引导加载程序 使用基于USB HID的引导程序是在微控制器上加载应用程序的一种很酷的方式。对于USB HID,Windows / Mac / Linux主机不需要特殊驱动程序,因为USB HID驱动程序是主机操作系统的一部分。缺点是USB是一个相当复杂的协议,因此需要目标设备上的USB硬件和USB堆栈。
我移植了恩智浦KBOOT提供的工程,并使用该软件包附带的实用程序。实施的引导程序是一个flash内置引导程序。这意味着我首先使用引导程序对微控制器进行编程,并保留在闪存中,然后用于加载我想要的任何应用程序。通过优化-O1集,我得到了一个USB HID引导程序,它使用大约26 KB的FLASH。
工程结构 以下屏幕截图显示了bootloader工程结构。
● link:包含链接器文件。引导加载程序向量表和地址映射为0x0000'0000,这是ARM Cortex-M的默认向量表 ● MK22F51212:包含Kinetis K22微控制器的特定硬件端口。该文件夹中的bootloader_config.h文件用于配置引导加载程序。 ● src:包含所有bootloader源代码,都是通用的。
Bootloader工程的自定义 该项目使用几个全局自定义来配置引导加载程序:
以上自定义禁用多余的调试消息,将USB堆栈设置为裸跑(不使用RTOS),配置器件(MK22和ARM Cortex-M4)。最后一个自定义将引导程序配置为使用FLASH内置。
引导加载程序配置 头文件MK22F51212 \ bootloader_config.h用于配置引导加载程序,例如支持哪些通信协议。在下面的设置中,我将其配置为仅使用USH HID: - #if !defined(BL_CONFIG_SCUART)
- #define BL_CONFIG_SCUART (0)
- #endif
- #if !defined(BL_CONFIG_I2C)
- #define BL_CONFIG_I2C (0)
- #endif
- #if !defined(BL_CONFIG_DSPI)
- #define BL_CONFIG_DSPI (0)
- #endif
- #if !defined(BL_CONFIG_USB_HID)
- #define BL_CONFIG_USB_HID (1)
- #endif
- #if !defined(BL_CONFIG_USB_MSC)
- #define BL_CONFIG_USB_MSC (0)
- #endif
- #if !defined(BL_TARGET_FLASH)
- #define BL_TARGET_FLASH (1)
- #endif
复制代码
使用越多或越复杂的通信协议,引导加载程序占用的FLASH内存就越多。在启用USB HID的情况下,FLASH大小约为26 KB,它占用了0xb000以下的内存区域,可以从下面列出的输出看出来: - arm-none-eabi-size --format=berkeley "tinyK22_KBOOT_bootloader.elf"
- text data bss dec hex filename
- 26204 1856 14000 42060 a44c tinyK22_KBOOT_bootloader.elf
复制代码
例如,如果我使用UART与Bootloader进行通信,则只需要21 KB的FLASH内存。
引导加载程序可以使用GPIO引脚在复位后进入引导加载程序模式(POR,上电复位)。在 MK22F51212 \ hardware_init_K22F512文件中配置了使用哪个引脚: - #define BOOT_PIN_NUMBER 17
- #define BOOT_PIN_PORT PORTB
- #define BOOT_PIN_GPIO GPIOB
- #define BOOT_PIN_ALT_MODE 1
复制代码
通过上面的代码,我使用GPIO引脚PTB17。函数is_boot_pin_asserted()用于检查该引脚。通常,在启动期间,该引脚通过上拉电阻拉至高电平,并进入引导加载模式。 如果不使用任何引导加载程序引脚,则可以配置bootloader_config.h中指定的引导加载程序超时值: - #define BL_DEFAULT_PERIPHERAL_DETECT_TIMEOUT 5000
复制代码
通过上述设置,复位后它将等待5秒钟以等待主机的任何通信,直到引导加载程序继续。如果这种超时是不可取的,那么我建议配置一个专用的引导加载程序引脚。
bootloader_config.h中的另一个设置是应用程序的向量表所在的位置。基本上这定义了我的应用程序FLASH存储空间的起始位置。下面我将它设置为0xC000,这意味着引导程序可以使用0x0000到0xBFFF。 - // The bootloader will check this address for the application vector table upon startup.
- #if !defined(BL_APP_VECTOR_TABLE_ADDRESS)
- #define BL_APP_VECTOR_TABLE_ADDRESS 0xc000
- #endif
复制代码
编程引导加载程序 引导加载程序需要使用SWD / JTAG调试探头(例如Segger J-Link,P&E Multilink或CMSIS-DAP)对微控制器进行编程。 使用调试器停止引导加载程序将显示它等待传入的USB数据包:
构建Bootloader要加载的应用程序 引导加载程序要加载的应用程序需要链接到引导加载程序所需的正确地址。如上所述,我的应用程序的起始地址在0x0000'C000(实际上是它的向量表地址)。
使用该链接器文件,我创建S19和/或应用程序的二进制文件,我想要使用引导加载程序加载该文件。
连接到bootloader KBOOT包含两个与引导加载程序通信的实用程序: ● blhost:命令行实用程序 ● KinetisFlashTool:与上面相同,但带有GUI
使用0x15A2作为VID,0x0073作为PID,连接到USB HID Bootloader:
如果连接成功,将会显示引导加载程序的信息:
同样的,blhost实用程序可用于在命令行上连接到器件(USB VID / PID是可选的): - blhost --usb 0x15a2,0x0073 - get-property 1
复制代码
一旦连接上,我可以使用引导程序更新二进制文件。由于二进制文件不包含任何目标地址信息,我必须在对话框中指定地址(0x0000c000,这是我的应用程序以矢量表开始的地方):
使用blhost命令行可以完成同样的事情: 要将二进制文件加载到地址0xc000,可以使用: - blhost.exe --usb 0x15A2,0x0073 write-memory 0xC000 tinyK22_KBOOT_led_blinky_1Hz_0xC000.bin
复制代码
加载S19文件,使用flash-image命令: - blhost.exe --usb 0x15A2,0x0073 flash-image tinyK22_KBOOT_led_blinky_1Hz_0xC000.srec
复制代码
复位开发板,然后新的应用程序开始运行。
总结
Flash内置引导加载程序可以进行配置,然后烧写到单片机的FLASH存储器中。我可以将其通讯协议配置为外部环境使用的协议(本例中为USB HID),然后使用GUI或命令行工具连接到器件并更新应用程序。如果我有一个现场设备,并且必须使用新固件更新它们而不需要调试器,这种方式非常有用。
参考链接 ● GitHub的源代码: https://github.com/ErichStyger/m ... xamples/KDS/tinyK22 ● NXP KBOOT页面:http://nxp.com/KBOOT ● 用于tinyK22的μTasker工程:http://www.utasker.com/kinetis/tinyK22.html |