|
【GD32F350 LogicKids】flash跳转
[复制链接]
本帖最后由 ljj3166 于 2018-9-12 22:24 编辑
在logickids的规划中
需要将F350的FLASH区域进行划分
其中比较重要的是分为boot区和app区
其中boot区用于升级F350的固件
App区用于解析脚本数据
就是FLASH的跳转
今天尝试对F350进行了简单的分区
基本上和STM32F1系列的操作一直
几乎可以直接拷贝使用
先看看workspace的工程
Boot代码工程的Flash划分
起始地址是0x8000000
使用了5000H的空间,20kB
APP代码工程的Flash划分
起始地址是0x8005000
剩余的1B000H空间全部分给了脚本解析
基本片上外设驱动也包括在里面
懒得剥离了
看看boot的代码
- #include "bootmain.h"
- typedef void (*pFunction)(void);
- #define AppAddress 0x08005000 //应用程序入口地址
- uint32_t JumpAddress = 0;
- pFunction Jump_To_Application = 0; //应用程序地址指针
- volatile bool jump_flag = false, flash_flag = false;
- void SYSRESET(void) {__disable_fault_irq(); NVIC_SystemReset();}
- void go_app(void)
- {
- uint32_t ApplicationAddress=0;
- ApplicationAddress = AppAddress;
- if (((*(volatile uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000)//判断Flash数据是否合法
- {
- debug("go app code...\r\n");
- OLED_ShowString(5,1,"Go Application...",16);
- delay_1ms(1000);
- //各种deinit和禁用IRQ,准备跳转
- usart_deinit(USART0);
- usart_deinit(USART1);
- i2c_deinit(I2C0);
- spi_i2s_deinit(SPI1);
- rcu_deinit();
- __disable_irq() ;
- __disable_fault_irq();
- nvic_vector_table_set(NVIC_VECTTAB_FLASH, 0x5000); //地址映射
- JumpAddress = *(volatile uint32_t*)(ApplicationAddress + 4);
- Jump_To_Application = (pFunction)JumpAddress;
- __set_MSP(*(volatile uint32_t*)ApplicationAddress); //初始化堆栈指针
- Jump_To_Application();
- }
- else {
- debug("no app in board,please download....\r\n");
- OLED_ShowString(15,1,"NO Firmware...",16);
- while(1);
- }
- }
复制代码
比较关键的是AppAddress
这个是app程序的起始地址
然后定义一个程序指针
typedef void (*pFunction)(void);
pFunction Jump_To_Application = 0;
当Jump_To_Application指向这个地址的时候,就发生了Flash的跳转
有个比较重要的动作----软件重启指令
void SYSRESET(void) {__disable_fault_irq(); NVIC_SystemReset();}
最后是最重要的地址映射
GD库中提供了nvic_vector_table_set函数来处理
很方便,至少不需要把中断向量一个个copy出来了
它执行后会重启F350
跳转基本流程在代码中都有注释了
再来看看app中的处理
- void VectorTabs_setup(void)
- {
- __disable_irq() ;
- __disable_fault_irq();
- usart_deinit(USART0);
- usart_deinit(USART1);
- i2c_deinit(I2C0);
- i2c_deinit(I2C1);
- spi_i2s_deinit(SPI1);
- spi_i2s_deinit(SPI0);
- rcu_deinit();
- nvic_vector_table_set(NVIC_VECTTAB_FLASH, 0x5000);
- __enable_irq();
- __enable_fault_irq();
- SystemInit();
- }
复制代码
禁用IRQ
把所有在boot中初始化过的外设全部deinit一次,包括时钟
然后使能IRQ
接着调用SystemInit
其实SystemInit在boot代码的main函数之前就已经调用过
这里调用是因为
Logickids有2种重启方式
一种是单板重启,相当于重新上电
从boot进入app
另一种是app重启,仅重启APP区域的代码
目前采用的方式是将app使用的相关变量置零后
直接调用main完成app的重启
所以这里将SystemInit又重新调用了一次
上个动图
上电进入boot,显示logickids的logo
显示booting,显示进入app
在boot代码中,mcu_led是快速闪烁的
接下来进入app,硬件检测,显示hardware check
然后读取外置Flash的脚本数据,没有的话显示NO APP DATA
在app代码中,mcu_led是慢速闪烁的
As top
|
|