STM8(STM8S003F3) Bootloader (IAP) 升级程序

STM8S003这种片内FLASH只有8k的单片机使用bootloader功能貌似没有必要,但如果你的项目只需要6K的程序空间那剩余的2K用作bootloader也是个非常不错的注意:)

一.环境

 编译:STVD V4.3.5 + COSMIC V4.3.4
 Bootloader上位机软件: CAS-BOOT

 二.实现原理

    1.FLASH程序存储器应用
     STM8S003F3集成8K字节的FLASH程序存储器,其地址范围为0x8000 ~  0x9fff
     其中中断向量占用0x8000到0x8080  用户程序可以存储于0x8080到0x9fff
     实现Bootloader时,BOOT代码占用前2K的字节,即0x8000到0x8800
     用户程序占用后6K字节,即0x8800到0x9fff
     笔者使用两个项目来开发这两个程序,也就是说BOOT程序和APP程序开发于不同的项目,BOOT程序编译后生成的可执行代码存储于
     0x8000开始处,而用户APP程序存储于0x8800开始处。这个地址的分配需要在各自的项目中配置,配置方法:
     project -> setting... -> Linker  -> Category -> Input中设定地址范围,如下图:

BOOT程序链接配置

APP程序的链接配置

2.FLASH编程在RAM内执行问题


       BOOT程序实现FLASH编程时,编程执行代码应在RAM内执行,为了实现这个,我们需要一个自定义代码段,将编程代码放入其中,
      这里笔者新增加了一个名为FLASH_CODE的代码段,编程代码如下:
     

      #pragma section (FLASH_CODE)
      void ProgramBlock(uint16_t BlockIndex, uint8_t *Buffer)
      {
      uint16_t Count = 0;
      uint32_t StartAddress = BlockIndex<<6;

      //Standard programming mode
      FLASH->CR2 |= (uint8_t)0x01;
      FLASH->NCR2 &= (uint8_t)~0x01;

      //Copy data bytes from RAM to FLASH memory
      for (Count = 0; Count < BLOCK_SIZE; Count++)
      {
      *((PointerAttr uint8_t*)StartAddress + Count) = ((uint8_t)(Buffer[Count]));
      }
      }
      #pragma section ()


      FLASH_CODE是一个可移动的段,需要在“Boot程序链接配置”的RAM区添加,需要注意的是这个段的名字输入时需要前面加一个点。
      另外,该段的Option需要指定为 “-ic”,以表示这是一个在RAM内执行的可移动代码段。如上面的Boot程序链接配置图所示。

      但在程序初始化时这个代码段仍存储在FLASH中,未复制到RAM对应的区域,所以我们要使用到一个cosmic库函数 _fctcpy('F');
      这个函数帮助我们,将ram内的代码段从FLASH复制过去,其参数为段名的第一个字符。

 

3.中断向量问题
       STM8S的中断向量地址是固定的,也就是0x8000处,这个已经被boot程序占用了,怎么办呢,只能手工中断向量重定向了,办法就是
       boot程序不使用任何中断,boot程序的所有中断都跳转到用户程序的向量处。

       struct interrupt_vector const UserISR_IRQ[32] @ MAIN_USER_RESET_ADDR;

       //redirected interrupt table
       struct interrupt_vector const _vectab[] = {
       {0x82, (interrupt_handler_t)_stext}, /* reset */
       {0x82, (interrupt_handler_t)(UserISR_IRQ+ 1)}, /* trap */
       {0x82, (interrupt_handler_t)(UserISR_IRQ+ 2)}, /* irq0 */
       {0x82, (interrupt_handler_t)(UserISR_IRQ+ 3)}, /* irq1 */
       {0x82, (interrupt_handler_t)(UserISR_IRQ+ 4)}, /* irq2 */
       {0x82, (interrupt_handler_t)(UserISR_IRQ+ 5)}, /* irq3 */
       {0x82, (interrupt_handler_t)(UserISR_IRQ+ 6)}, /* irq4 */
       {0x82, (interrupt_handler_t)(UserISR_IRQ+ 7)}, /* irq5 */
       {0x82, (interrupt_handler_t)(UserISR_IRQ+ 8)}, /* irq6 */
       {0x82, (interrupt_handler_t)(UserISR_IRQ+ 9)}, /* irq7 */
       {0x82, (interrupt_handler_t)(UserISR_IRQ+10)}, /* irq8 */
       {0x82, (interrupt_handler_t)(UserISR_IRQ+11)}, /* irq9 */
       {0x82, (interrupt_handler_t)(UserISR_IRQ+12)}, /* irq10 */
       {0x82, (interrupt_handler_t)(UserISR_IRQ+13)}, /* irq11 */
       {0x82, (interrupt_handler_t)(UserISR_IRQ+14)}, /* irq12 */
       {0x82, (interrupt_handler_t)(UserISR_IRQ+15)}, /* irq13 */
       {0x82, (interrupt_handler_t)(UserISR_IRQ+16)}, /* irq14 */
       {0x82, (interrupt_handler_t)(UserISR_IRQ+17)}, /* irq15 */
       {0x82, (interrupt_handler_t)(UserISR_IRQ+18)}, /* irq16 */
       {0x82, (interrupt_handler_t)(UserISR_IRQ+19)}, /* irq17 */
       {0x82, (interrupt_handler_t)(UserISR_IRQ+20)}, /* irq18 */
       {0x82, (interrupt_handler_t)(UserISR_IRQ+21)}, /* irq19 */
       {0x82, (interrupt_handler_t)(UserISR_IRQ+22)}, /* irq20 */
       {0x82, (interrupt_handler_t)(UserISR_IRQ+23)}, /* irq21 */
       {0x82, (interrupt_handler_t)(UserISR_IRQ+24)}, /* irq22 */
       {0x82, (interrupt_handler_t)(UserISR_IRQ+25)}, /* irq23 */
       {0x82, (interrupt_handler_t)(UserISR_IRQ+26)}, /* irq24 */
       {0x82, (interrupt_handler_t)(UserISR_IRQ+27)}, /* irq25 */
       {0x82, (interrupt_handler_t)(UserISR_IRQ+28)}, /* irq26 */
       {0x82, (interrupt_handler_t)(UserISR_IRQ+29)}, /* irq27 */
       {0x82, (interrupt_handler_t)(UserISR_IRQ+30)}, /* irq28 */
       {0x82, (interrupt_handler_t)(UserISR_IRQ+31)}, /* irq29 */
       };


  其中MAIN_USER_RESET_ADDR为用户程序中断向量地址也就是0x8800。

  三.Boot区保护问题
 BOOT程序主要是靠ST-LINK之类的下载工具写进去的,写进去一次后即可通过BOOTLOADER程序下载用户程序了,为了BOOT区程序不被误
擦除或覆盖,可以在将其保护起来,这可以通过STM8S的OPTION BYTE来配置,OPTION BYTE保护起来的FLASH地址区域是无法再编程的。
STM8S的OPTION BYTE 是在EEPROM区,可通过ST-LINK等下载工具进行配置,如何将前2K字节的FLASH用OPTION BYTE配置进行保护,请参考
STM8S的参考手册。

四.示例源代码下载

    -> 源代码下载

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值