基于正点原子战舰V3做的简易bootloader
找到需要修改的bootloader
1、这里直接使用正点原子网盘下载的示例程序实验1跑马灯实验
修改程序
修改bootloader
1、首先对于bootloader程序,我们需要设置flash上的程序跳转地址
/* 第一个应用程序起始地址(存放在内部FLASH) 保留 0X08000000~0X08008FFF(36KB) 的空间为 Bootloader 使用*/
#define FLASH_APP1_ADDR 0x08010000
2、再编写跳转程序,代码如下
typedef void (*iapfun)(void);
iapfun jump2app;
static __inline void __set_MSP(uint32_t topOfMainStack)
{
register uint32_t __regMainStackPointer __ASM("msp");
__regMainStackPointer = topOfMainStack;
}
/**
* @brief 设置栈顶地址
* @note 左侧的红X, 属于MDK误报, 实际是没问题的
* @param addr: 栈顶地址
* @retval 无
*/
void sys_msr_msp(uint32_t addr)
{
__set_MSP(addr); /* 设置栈顶地址 */
}
/**
* @brief 跳转到应用程序段(执行APP)
* @param appxaddr : 应用程序的起始地址
* @retval 无
*/
void iap_load_app(uint32_t appxaddr)
{
/* 检查栈顶地址是否合法.可以放在内部SRAM共64KB(0x20000000) */
if (((*(volatile uint32_t *)appxaddr) & 0x2FFE0000) == 0x20000000)
{
/* 用户代码区第二个字为程序开始地址(复位地址) */
jump2app = (iapfun) * (volatile uint32_t *)(appxaddr + 4);
/* 初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址) */
sys_msr_msp(*(volatile uint32_t *)appxaddr);
/* 跳转到APP */
jump2app();
}
}
3、对于bootloader而言,这里做一个led灯的闪烁,等闪烁倒计时完后,进入跳转程序。
int main(void)
{
Stm32_Clock_Init(9);//系统时钟设置
delay_init(72); //延时初始化
LED_Init(); //初始化与LED连接的硬件接口
while(nIndex--) //黄色
{
LED0=0;
LED1=1;
delay_ms(500); //延时300ms
LED0=0;
LED1=0;
delay_ms(500); //延时300ms
}
/* 判断FLASH里面是否有APP,有的话执行 */
if (((*(volatile uint32_t *)(FLASH_APP1_ADDR + 4)) & 0xFF000000) == 0x08000000)
{
delay_ms(10);
/* 跳转执行APP代码 */
iap_load_app(FLASH_APP1_ADDR);
}
}
修改app
APP的修改就特别简单,就是设置程序的启动地址。
1、首先修改魔术棒->Target的ROM起始地址
2、代码中增加程序的启动地址修改函数
void sys_nvic_set_vector_table(uint32_t baseaddr, uint32_t offset)
{
/* 设置NVIC的向量表偏移寄存器,VTOR低9位保留,即[8:0]保留 */
SCB->VTOR = baseaddr | (offset & (uint32_t)0xFFFFFE00);
}
3、再在主程序里面添加启动地址偏移和灯闪烁代码
int main(void)
{
sys_nvic_set_vector_table(FLASH_BASE,0x10000);/*bootloader区大小64KB*/
Stm32_Clock_Init(9);//系统时钟设置
delay_init(72); //延时初始化
LED_Init(); //初始化与LED连接的硬件接口
while(1) //黄色
{
LED0=1;
LED1=0;
delay_ms(500); //延时300ms
LED0=0;
LED1=0;
delay_ms(500); //延时300ms
}
}
4、一定一定注意需要勾选 Use Memory Layout from Target Dialog,不然设置的启动地址无法同步到map表中,因为这个问题,我折腾了好久。
查看map表
这样就完成了APP程序的编写。
最后下载到开发板即可
观察开发板闪烁情况。