Я пытаюсь принять загрузчик UART от микроэлектроники, написанный для STM32F051r8 (https://www.st.com/resource/en/datasheet/stm32f051r8.pdf)
для STM32F107VCT7 (https://www.mouser.de/datasheet/2/389/CD00220364-490297.pdf)
Вот исходный код:
/*
* 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
}
}
////////////////////////////////////////////////////////////////////////////////
Я думаю, что единственное, что мне нужно изменить, это строки:
#pragma orgall 0xEC00
#define BOOTLOADER_START_ADDR 0xEC00
#define START_PROGRAM_ADDR 0xFC00
Я изучаю таблицу данных STM32F051r8 и не могу найти ссылку на 0xEC00 как на начало флэш-памяти.
Какие значения мне нужны для STM32F107VCT7?
Когда я использую значения сверху и компилирую их в 107, это работает, но при загрузке акций MCU.