STM32 Bootloader UDS 技术概要

STM32在单片机领域因性价比高受到广大工程师的青睐,笔者最近做了一个STM32 M3内核的BootLoader现在把技术的要点梳理如下:

1、首先是对ROM分区的规划,把ROM划分为BOOT区和APP区,划分在KEIL的sct文件完成。

      Boot分区

; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************

LR_IROM1 0x08000000 0x00005800  {    ; load region size_region
  ER_IROM1 0x08000000 0x00005800  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY ;(+RO)
  }
  
  IRAM1 0x20000000 0x00004000  {  ; RW data
   .ANY (+RW +ZI)
   *.o (RAMCODE)
   ac78xx_eflash.o (+RO +RW)
  }

  IRAM2 0x20004000 0x00002000  {  ; RW data
   .ANY (pg_data1)
  }
  IRAM3 0x20006000 0x00002000  {  ; RW data (+RW +ZI)
   .ANY (pg_data2)
  }
}

      APP分区

; *************************************************************
; *** Scatter-Loading Description File generated by uVision ***
; *************************************************************

LR_IROM1 0x08006000 0x00019000  {    ; load region size_region
  ER_IROM1 0x08006000 0x00019000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY ;(+RO)
  }
  
  DATA_FLASH 0x0801f000 0x00001000  {  ; load address = execution address
   * (flash_data) 
  }
  IRAM1 0x20000000 0x00004000  {  ; RW data
   .ANY (+RW +ZI)
  }
  IRAM2 0x20004000 0x00002000  {  ; RW data
   .ANY (pg_data1)
  }
  IRAM3 0x20006000 0x00002000  {  ; RW data (+RW +ZI)
   .ANY (pg_data2)
  }
}

KEIL工程选择对应的文件

2、BOOT工作完成后向APP跳转,跳转前要关闭中断,避免单片机跑飞。

void JumpApp(uint32_t ApplicationAddress)
{
    uint32_t JumpAddress;
    pFunction Jump_To_Application;
	
    __set_FAULTMASK(1);

    if (((*(__IO uint32_t *)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000)
    {
        /* Jump to user application */
        JumpAddress = *(__IO uint32_t *) (ApplicationAddress + 4);
        Jump_To_Application = (pFunction) JumpAddress;
        /* Initialize user application's Stack Pointer */
        __set_MSP(*(__IO uint32_t*) ApplicationAddress);
        Jump_To_Application();
    }
	
}

3、APP中要调整中断向量表的位置,接收到升级指令时复位进入Bootloader

SCB->VTOR = APP_START_ADDR;
mdelay(20);
__set_FAULTMASK(1);
            			
mdelay(5);			
NVIC_SystemReset();

4、在进行擦除、编程FLASH时,要关闭中断和看门狗,避免进入非法中断。

5、在进行BootLoader自身更新时需要将相关代码放入RAM中。

__attribute__((section("RAMCODE")))

void * UserMemCpy(uint8_t * dest, const uint8_t * src, int count)  
{  
    uint8_t * tmp = (uint8_t *) dest;
    uint8_t * s = (uint8_t *)src;  
  
    while (count--)  
        *tmp++ = *s++;  
  
    return dest;  
}

在sct文件中对应

IRAM1 0x20000000 0x00004000  {  ; RW data
   .ANY (+RW +ZI)
   *.o (RAMCODE)
   ac78xx_eflash.o (+RO +RW)
  }

6、用CAPL编程完成上位机

完成效果如下

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章