首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >STM32F107 UART引导加载程序mikroC

STM32F107 UART引导加载程序mikroC
EN

Stack Overflow用户
提问于 2019-06-15 02:44:15
回答 1查看 359关注 0票数 1

我尝试采用mikroelektronika的UART引导程序,它是为STM32F051r8 (https://www.st.com/resource/en/datasheet/stm32f051r8.pdf)编写的。

到STM32F107VCT7 (https://www.mouser.de/datasheet/2/389/CD00220364-490297.pdf)

以下是原始代码:

代码语言:javascript
复制
/*
 * Project name:
     USB_UART_Bootloader
 * Copyright:
     (c) MikroElektronika, 2018.
 * Revision History:
     - initial release;
 * Description:
     MCU flash. It is used, instead of programming tools, to
     load real program code into the MCU. Real program code can
     be passed from PC to bootloader by specific PC application
     (Bootloader Tool) over numerous communication interfaces.

     This bootloader communicates with PC over UART inteface
     by using mikroE bootloader protocol. It is designed to
     work in conjuction with mikroE's 'mikroBootloader'
     PC application.

 * Test configuration:
     MCU:             STM32F051R8
                      https://www.st.com/resource/en/datasheet/stm32f051r8.pdf
     Dev.Board:       MINI-M0 for STM32
                      https://www.mikroe.com/mini-stm32f0
     Oscillator:      48.000000
     Ext. Modules:    None
     SW:              mikroC PRO for ARM v6.0.0
                      https://www.mikroe.com/mikroc-arm
 * NOTES:
     - It's recommended not to alter the start address of the main().
       Otherwise, less space in ROM will be available for the
       application being bootloaded.
*/
////////////////////////////////////////////////////////////////////////////////
#include <built_in.h>
////////////////////////////////////////////////////////////////////////////////
#pragma orgall 0xEC00
#define BOOTLOADER_START_ADDR   0xEC00
#define START_PROGRAM_ADDR      0xFC00
////////////////////////////////////////////////////////////////////////////////
static char block[1024];
////////////////////////////////////////////////////////////////////////////////
void Start_Program() org START_PROGRAM_ADDR{

}
////////////////////////////////////////////////////////////////////////////////
unsigned short UART_Write_Loop(char send, char receive){
  unsigned int rslt = 0;

  while(1){
    Delay_5ms();
    UART_Write(send);
    Delay_5ms();

    rslt++;
    if (rslt == 0x0200)
      return 0;
    if(UART_Data_Ready()) {
      if(UART_Read() == receive)
        return 1;
    }
  }
}
////////////////////////////////////////////////////////////////////////////////
void FLASH_EraseWritePage(unsigned long address) {
  unsigned int i = 0;
  unsigned int dataToWrite;

  FLASH_ErasePage(address);

  for (i = 0; i < 512; i++)
  {
    dataToWrite = block[i * 2] | (block[i * 2 + 1] << 8);
    FLASH_Write_HalfWord(address + i*2, dataToWrite);
  }
}
////////////////////////////////////////////////////////////////////////////////
void Write_Begin(){
  unsigned int i;
  unsigned long* ptr;
  unsigned char appResetVector[16];
  unsigned long arm_m0_inst;
  unsigned int dataToWrite;

  //LDR R0, PC+X
  arm_m0_inst = 0x4800 + 1;

  appResetVector[0] = arm_m0_inst;
  appResetVector[1] = arm_m0_inst >> 8;

  //MOV SP, R0
  arm_m0_inst = 0x4685;

  appResetVector[2] = arm_m0_inst;
  appResetVector[3] = arm_m0_inst >> 8;

  //LDR R0, PC+Y
  arm_m0_inst = 0x4800 + 1;

  appResetVector[4] = arm_m0_inst;
  appResetVector[5] = arm_m0_inst >> 8;

  //BX R0
  arm_m0_inst = 0x4700;
  appResetVector[6] = arm_m0_inst;
  appResetVector[7] = arm_m0_inst >> 8;

  //SP
  appResetVector[8] = block[0];
  appResetVector[9] = block[1];
  appResetVector[10] = block[2];
  appResetVector[11] = block[3];

  //PC
  appResetVector[12] = block[4];
  appResetVector[13] = block[5];
  appResetVector[14] = block[6];
  appResetVector[15] = block[7];

  FLASH_ErasePage(START_PROGRAM_ADDR);

  for (i = 0; i < 8; i++)
  {
    dataToWrite = appResetVector[i * 2] | (appResetVector[i * 2 + 1] << 8);
    FLASH_Write_HalfWord(START_PROGRAM_ADDR + i*2, dataToWrite);
  }

  ptr = (unsigned long*)0x00000000;
  block[0] = LoWord(*ptr);
  block[1] = LoWord(*ptr) >> 8;
  block[2] = HiWord(*ptr);
  block[3] = HiWord(*ptr) >> 8;

  ptr++;

  block[4] = LoWord(*ptr);
  block[5] = LoWord(*ptr) >> 8;
  block[6] = HiWord(*ptr);
  block[7] = HiWord(*ptr) >> 8;
}
////////////////////////////////////////////////////////////////////////////////
void Start_Bootload(){
  unsigned int i = 0;
  char xx, yy;
  long j = 0;

  while (1) {
    if (i == 1024) {
      //--- If 256 words (1024 bytes) recieved then write to flash
      if (!j)
        Write_Begin();
      if (j < BOOTLOADER_START_ADDR) {
        FLASH_EraseWritePage(j);
      }

      i = 0;
      j += 0x400;
    }
    //--- Ask for yy
    UART_Write('y');
    while (!UART_Data_Ready()) ;
    //--- Read yy
    yy = UART_Read();
    //--- Ask for xx
    UART_Write('x');
    while (!UART_Data_Ready()) ;
    //--- Read xx
    xx = UART_Read();
    //--- Save xxyy in block[i]
    block[i++] = yy;
    block[i++] = xx;
  }
}
////////////////////////////////////////////////////////////////////////////////
void main() org BOOTLOADER_START_ADDR{
// Main program
 // UART1_Init_Advanced(115200, _UART_8_BIT_DATA, _UART_NOPARITY, _UART_ONE_STOPBIT, &_GPIO_MODULE_USART1_PA9_10);   // Display
    // Delay_ms(1000);

    UART2_Init_Advanced(115200, _UART_8_BIT_DATA, _UART_NOPARITY, _UART_ONE_STOPBIT, &_GPIO_MODULE_USART2_PD56);              // USB Serial
    Delay_ms(1000);


  Delay_100ms();

  if (UART_Write_Loop('g','r')) {     // Send 'g' for ~5 sec, if 'r'
    Start_Bootload();                 //   received start bootload
  }
  else {
    Start_Program();                  //   else start program
  }
}
////////////////////////////////////////////////////////////////////////////////

我想我唯一需要修改的就是下面这几行:

代码语言:javascript
复制
#pragma orgall 0xEC00
#define BOOTLOADER_START_ADDR   0xEC00
#define START_PROGRAM_ADDR      0xFC00

我研究了STM32F051r8数据表,找不到任何关于0xEC00作为闪存起始的参考资料。

STM32F107VCT7需要哪些值?

当我使用顶部的值并将其编译为107时,它可以工作,但同时上传MCU股票。

EN

回答 1

Stack Overflow用户

发布于 2019-06-16 13:37:11

你好,我想你在地址和配置上有很多问题,我使用了这段代码,它工作正常

对于从闪存中擦除主程序:

代码语言:javascript
复制
#define Applicationend 0x08040000
#define ApplicationAddress    0x8003000
#define FLASH_PAGE_SIZE    ((uint16_t)0x400)
//////////////////////////////////

     FLASH_UnlockBank1();
   NbrOfPage = (Applicationend - ApplicationAddress) / FLASH_PAGE_SIZE;
   FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);    
     for(EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++)
            {
            FLASHStatus = FLASH_ErasePage(ApplicationAddress + (FLASH_PAGE_SIZE * EraseCounter));
            }   

要对闪存进行编程:

代码语言:javascript
复制
 while((Address < (size_of_program)) && (FLASHStatus == FLASH_COMPLETE))
  {

    df_read_open(Address+temp);
  df_read(update_r,2); 

    FLASHStatus = FLASH_ProgramHalfWord((Address+ApplicationAddress),( update_r[0]|(update_r[1]<<8)));
    Address = Address + 2;
  } 
    FLASH_LockBank1();

并用于运行主程序

代码语言:javascript
复制
    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();
}   
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56603647

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档