简体   繁体   English

开始在 IAR 中为 stm32l0 编写引导加载程序

[英]Start to writing a bootloader for stm32l0 in IAR

What are the appropriate steps to write add a custom bootloader for stm32l0 in IAR?在 IAR 中为 stm32l0 添加自定义引导加载程序的适当步骤是什么? The following questions are not clear:以下问题不清楚:

  • Do I make a new IAR Project?我要创建一个新的 IAR 项目吗?
    • If yes, do I write the bootloader like a normal project and just change my original .icf file so there is a small ROM and an small RAM region for the bootloader?如果是,我是否像普通项目一样编写引导加载程序,只是更改我的原始 .icf 文件,以便引导加载程序有一个小 ROM 和一个小 RAM 区域?
    • if no, what things do I have to configure in the IAR proejct apart from icf file and code?如果不是,除了 icf 文件和代码之外,我还需要在 IAR proejct 中配置哪些内容?
  • what other things do I need to think of?我还需要考虑哪些其他事情?

I'm having trouble starting into this.我很难开始这个。

So the icf would be for the main project:所以icf将用于主要项目:

__region_ROM_start__ = 0x08000000;
__region_ROM_end__ = 0x08008FFF;

So the icf would be for the bootloader project:所以 icf 将用于引导加载程序项目:

__region_Bootloader_ROM_start__ = 0x08009000;
__region_Bootloader_ROM_end__ = 0x08009FFF;

and the same thing for about 0xFF of RAM?和大约0xFF的 RAM 相同?

You do not need to restrict the RAM - you can use all of it because when you switch to the application a new run-time environment will be established and the RAM will be reused.您不需要限制 RAM - 您可以使用所有 RAM,因为当您切换到应用程序时,将建立一个新的运行时环境并且将重复使用 RAM。

The flash you reserve for the bootloader must be a whole number of flash pages starting from the reset address The STM32L0 has very small flash pages so there should be minimal waste, but you don't want to have to change it if your bootloader grows, because then you will have to rebuild your application code for the new start address and old application images will no longer be loadable.您为引导加载程序保留的闪存必须是从复位地址开始的整数闪存页面 STM32L0 具有非常小的闪存页面,因此应该尽量减少浪费,但是如果引导加载程序增长,您不想更改它,因为那样你将不得不为新的起始地址重建你的应用程序代码,并且旧的应用程序图像将不再可加载。 So consider giving yourself a little headroom.所以考虑给自己一点空间。

The bootloader can be built just like any other STM32L0xx project;引导加载程序可以像任何其他 STM32L0xx 项目一样构建; the application code ROM configuration must start from an address above the bootloader.应用程序代码 ROM 配置必须从引导加载程序上方的地址开始。 So for example say you have a 1Kbyte bootloader:例如,假设您有一个 1Kbyte 的引导加载程序:

Boot ROM Start:    0x0800 0000
Boot ROM End:      0x0800 03FF
Application Start: 0x0800 0400
Application End:   Part size dependent.

The bootloader itself must have a means of determining that an update is available, if an update is available it must then read the application data and write it to the application flash memory, it must then disable any interrupts that may have been enabled, it may also be necessary to deinitialise any peripherals used (if they remain active when the switch to the application is made it may cause problems), then the switch to the application code is made.引导加载器本身必须有确定的更新是可用的,如果可用的更新,那么它必须读取应用数据并将其写入到应用程序闪存,它必须然后禁用可能已被启用的任何中断的手段,它可以还需要取消初始化任何使用的外围设备(如果它们在切换到应用程序时保持活动状态,则可能会导致问题),然后切换到应用程序代码。

It is possible if the bootloader and application both run from the same clock configuration to minimise the configuration in the application and rely on the bootloader.如果引导加载程序和应用程序都从相同的时钟配置运行,则可以最大限度地减少应用程序中的配置并依赖引导加载程序。 This is a small space saving, but less flexible.这是一个很小的空间节省,但不太灵活。 If for example you make the bootloader run using the internal RC oscillator it will be portable across multiple hardware designs that may have differing application speed and clocking requirements and different external oscillator frequencies例如,如果您使用内部 RC 振荡器使引导加载程序运行,它将可移植到多个硬件设计中,这些硬件设计可能具有不同的应用程序速度和时钟要求以及不同的外部振荡器频率

The switch to the application is pretty simple on Cortex-M, it simply requires the vector table to be switched to the application's vector table, then the program-counter to be loaded - the latter requires a little assembly code.在 Cortex-M 上切换到应用程序非常简单,它只需要将向量表切换到应用程序的向量表,然后加载程序计数器 - 后者需要一些汇编代码。 The following is for Cortex-M3, it may need some adaptation for M0+ but possibly not:以下是针对 Cortex-M3 的,它可能需要对 M0+ 进行一些调整,但可能不需要:

Given the following in-line assembly function:给定以下内联汇编函数:

__asm void boot_jump( uint32_t address )
{
   LDR SP, [R0]       ;Load new stack pointer address
   LDR PC, [R0, #4]   ;Load new program counter address
}

The bootloader switched to the application image thus:引导加载程序因此切换到应用程序映像:

// Switch off core clock before switching vector table
SysTick->CTRL = 0 ;

// Switch off any other enabled interrupts too
...

// Switch vector table
SCB->VTOR = APPLICATION_START_ADDR ;

//Jump to start address
boot_jump( APPLICATION_START_ADDR ) ;

Where APPLICATION_START_ADDR is the base address of the application area;其中APPLICATION_START_ADDR是应用区的基地址; this address is the start of the application's vector table, which starts with the initial stack pointer and reset vector, the boot_jump() function loads these into the SP and PC registers to start the application as if it had been started at reset.这个地址是应用程序向量表的开始,它以初始堆栈指针和复位向量开始, boot_jump()函数将这些加载到 SP 和 PC 寄存器中以启动应用程序,就像它在复位时启动一样。 The application's reset vector contains the application's execution start address.应用程序的复位向量包含应用程序的执行起始地址。

Your needs may vary, but in my experience a serial bootloader (using UART) using XMODEM and decoding an image in Intel Hex format takes about 4Kb of Flash.您的需求可能会有所不同,但根据我的经验,使用 XMODEM 并解码 Intel Hex 格式图像的串行引导加载程序(使用 UART)需要大约 4Kb 的闪存。 On an STM32L0 you may want to use something simpler - 1Kb is probably feasible if you simply stream raw binary the data and use hardware flow control (you need to control data flow because erasing and programming the flash takes time and also stops the CPU from running because you cannot on STM32 write flash memory while simultaneously fetching instructions from it).在 STM32L0 上,您可能想要使用更简单的东西 - 如果您只是将原始二进制数据流式传输并使用硬件流控制(您需要控制数据流,因为擦除和编程闪存需要时间并且还会停止 CPU 运行),那么 1Kb 可能是可行的因为您不能在 STM32 上写入闪存,同时从中获取指令)。

See also: How to jump between programs in Stellaris另请参阅: 如何在 Stellaris 中的程序之间跳转

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM