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編程完成上位機

完成效果如下

 

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