Keil debugs STM32 MCU program method from non-0x08000000 address

  When using the serial port IAP upgrade function of the stm32 single-chip microcomputer, it is necessary to debug the bootloader program and the app program. Generally, the bootloader program starts to run from the address 0x08000000. The keil software can be used for direct simulation, but if the app program is debugged, because it is not Starting from address 0x08000000, when using keil simulation, it cannot be simulated. In order to directly use the keil simulation APP program, I found a lot of methods on the Internet, but many methods are messy and inconvenient. The two methods summarized below will be shared.

  The program source code download link used is as follows: https://download.csdn.net/download/qq_20222919/87872428

Method 1: Simulate the APP program by first downloading the bootloader program.

bootloader program

  First look at the bootloader program

#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "stmflash.h"
#include "iap.h"
int main ( void )
{
    
    
    u8 bit_new = 0;					//接收到程序标志
    u8 bit_10s = 0;
    u16 oldcount = 0;				//老的串口接收数据值
    u16 applenth = 0;				//接收到的app代码长度
    u8 t = 0, clearflag = 0;

    SystemInit();
    NVIC_PriorityGroupConfig ( NVIC_PriorityGroup_2 ); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
    uart_init ( 115200 );	//串口初始化为115200
    delay_init();	   	 	//延时初始化

	printf ( "bootloader is running!\r\n" );
    while ( 1 )
    {
    
    
        if ( USART_RX_CNT )
        {
    
    
            if ( oldcount == USART_RX_CNT ) //新周期内,没有收到任何数据,认为本次数据接收完成.
            {
    
    
                applenth = USART_RX_CNT;
                oldcount = 0;
                USART_RX_CNT = 0;
                printf ( "用户程序接收完成!\r\n" );
                printf ( "代码长度:%dBytes\r\n", applenth );
            }
            else oldcount = USART_RX_CNT;
        }

        if ( applenth != 0 )
        {
    
    
            if ( ( ( * ( vu32* ) ( 0X20001000 + 4 ) ) & 0xFF000000 ) == 0x08000000 ) //判断是否为0X08XXXXXX.
            {
    
    
                iap_write_appbin ( FLASH_APP1_ADDR, USART_RX_BUF, applenth ); //更新FLASH代码
                printf ( "固件更新完成!\r\n" );
                bit_new = 1;
            }
            applenth = 0;
        }

        if ( ( bit_10s == 30 ) || ( bit_new == 1 ) )
        {
    
    
            bit_10s = 0;
            bit_new = 0;
            //执行FLASH中的代码

            if ( ( ( * ( vu32* ) ( FLASH_APP1_ADDR + 4 ) ) & 0xFF000000 ) == 0x08000000 ) //判断是否为0X08XXXXXX.
            {
    
    
                printf ( "开始执行FLASH用户代码!!\r\n\r\n" );
                iap_load_app ( FLASH_APP1_ADDR ); //执行FLASH APP代码
            }

            //执行SRAM中的代码
//            if(((*(vu32 *)(0X20001000 + 4)) & 0xFF000000) == 0x20000000) //判断是否为0X20XXXXXX.
//            {
    
    
//                printf("开始执行SRAM用户代码!!\r\n");
//                iap_load_app(0X20001000);//SRAM地址
//            }
        }
        t++;
        delay_ms ( 10 );
        if ( t == 20 )
        {
    
    
            bit_10s++;
            if ( clearflag )
            {
    
    
                clearflag--;
                if ( clearflag == 0 )
                    printf ( "清除显示!\r\n" ); //清除显示
            }
        }
    }
}

  In the bootloader, it has been waiting for the serial port to send the upgrade file. After the serial port has received the upgrade file, it will jump to the flash to execute the APP code. The bootloader code address is set as follows:
insert image description here
insert image description here
  When using keil to debug the bootloader code, it can be debugged normally.
insert image description here

APP program

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"

int main ( void )
{
    
    
    SCB->VTOR = FLASH_BASE | 0x5000;
    SystemInit();
    uart_init ( 115200 );	//串口初始化为115200
    delay_init();
    LED_Init();
    delay_ms( 500 );
    printf ( "\r\n\r\napp is running!\r\n" );

    while ( 1 )
    {
    
    
        delay_ms ( 500 );
        LED = !LED;
        printf ( "led flashing !\r\n" );
    }
}

  After entering the APP program, first set the offset of the address. Then let the LED light flash in the APP program, and then print the information. The APP address is set as follows:
insert image description here
insert image description here
  If you directly use keil to debug the APP program step by step, you will find that the program cannot enter the main function.
insert image description here

  Although the program has been running, it cannot jump to the main function. This is because the program runs the bootloader program directly after power-on, and the bootloader program will always wait for the serial port data, so it will not jump to the APP program. . If you want the program to jump to the APP, you need to use the serial port assistant to send the APP program.
Please add a picture description

  After using the serial port assistant to send the upgrade file, the bootloader program will directly jump to the address where the APP program is located, so that the APP program can be debugged step by step. But it is too troublesome to debug the program in this way, can you directly debug the APP program without using the bootloader', of course it is possible.

Method 2: Simulate the APP program directly through the configuration file

  Using this method does not need to burn the bootloader program in the microcontroller. First look at the configuration of the APP software in keil, the address configuration remains unchanged.
insert image description here
  In the debug option, a configuration file was added at the location of the initialization file.
insert image description here
  The boot.bin file and the project file are placed in the same directory.
insert image description here
  Create a new notepad file, change the name to boot.bin, remember to change the suffix of the notepad to ini, then open the boot.ini file with notepad, and enter the following content in it.

FUNC void Setup (void) 
{
    
     
SP = _RDWORD(0x8005000);          // 堆栈指针 
PC = _RDWORD(0x8005004);          // PC 
_WDWORD(0xE000ED08, 0x8005000);   // 中断向量偏移地址 
} 
load %L incremental
Setup();
g, main                             //跳转到main  

  Pay attention to these three address values ​​in the code. This value is related to the starting address of the APP program. Modify these three values ​​​​according to your own program.
insert image description here
  Keep other settings unchanged
insert image description here
  , and then you can directly debug the APP program in a single step through the keil software.
insert image description here

  After the stand-alone simulation button enters the simulation interface, you will find that the program jumps directly to the main function at this time, and there is no need to use the bootloader program to jump. In this way, through a configuration file, the keil software can directly jump to the main function directly through the configuration file.
insert image description here

  When using this method to debug the APP program, it is not necessary to burn the bootloader program. But when the MCU runs independently, it still needs to burn the bootloader program. This configuration file only works on the keil emulator, and only works when using keil emulation.

Guess you like

Origin blog.csdn.net/qq_20222919/article/details/131076871