完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980
第82章 STM32H7的QSPI总线应用之QSPI Flash执行程序(BOOT+APP方式)
本章节为大家讲解QSPI Flash执行程序。
82.1 初学者重要提示
82.2 下载算法存放位置
82.3 QSPI Flash的Bootloader说明
82.4 QSPI Flash的APP应用程序说明
82.5 QSPI Flash的APP应用程序调试下载配置
82.6 实验例程说明
82.7 总结
82.1 初学者重要提示
- QSPI Flash的相关知识点可以看第78章和79章。
- 操作本章配套例子前务必先将QSPI Flash的下载算法放到MDK安装目录。
- QSPI Flash执行程序的BOOT和APP作用:
-
- BOOT程序需要下载到内部Flash。主要用于跳转到外部QSPI Flash执行程序。那么问题来了,我们可不可以不使用BOOT,上电就直接执行QSPI Flash的程序?不行,因为QSPI Flash不像内部Flash,无需初始化,上电就可以使用,而QSPI Flash不行。
- APP应用程序要下载到QSPI Flash里面。APP应用程序可以在QSPI Flash里面执行主要是因为W25Q256支持XIP(Execution In Place),并且STM32H7的QSPI Flash支持内存映射。
82.2 下载算法存放位置
编译例子:V7-060_QSPI Flash的MDK下载算法制作,生成的算法文件位于此路径下:
生成算法文件后,需要大家将其存到到MDK安装目录,有两个位置可以存放,任选其一,推荐第2种:
- 第1种:存放到MDK的STM32H7软包安装目录里面:KeilSTM32H7xx_DFP2.6.0CMSISFlash(软包版本不同,数值2.6.0不同)。
- 第2种:MDK的安装目录 ARMFlash里面。
82.3 QSPI Flash的Bootloader说明
Bootloader的实现比较简单,需要大家将其下载到内部Flash。程序实现上主要注意以下两点即可。
82.3.1 初始化QSPI Flash并设置内存映射模式
在bsp.c文件中初始QSPI Flash并设置为内存映射模式。
/* ********************************************************************************************************* * 函 数 名: bsp_Init * 功能说明: 初始化所有的硬件设备。该函数配置CPU寄存器和外设的寄存器并初始化一些全局变量。只需要调用一次 * 形 参:无 * 返 回 值: 无 ********************************************************************************************************* */ void bsp_Init(void) { /* 配置MPU */ MPU_Config(); /* 使能L1 Cache */ CPU_CACHE_Enable(); /* STM32H7xx HAL 库初始化,此时系统用的还是H7自带的64MHz,HSI时钟: - 调用函数HAL_InitTick,初始化滴答时钟中断1ms。 - 设置NVIV优先级分组为4。 */ HAL_Init(); /* 配置系统时钟到400MHz - 切换使用HSE。 - 此函数会更新全局变量SystemCoreClock,并重新配置HAL_InitTick。 */ SystemClock_Config(); /* Event Recorder: - 可用于代码执行时间测量,MDK5.25及其以上版本才支持,IAR不支持。 - 默认不开启,如果要使能此选项,务必看V7开发板用户手册第8章 */ #if Enable_EventRecorder == 1 /* 初始化EventRecorder并开启 */ EventRecorderInitialize(EventRecordAll, 1U); EventRecorderStart(); #endif /* 针对不同的应用程序,添加需要的底层驱动模块初始化函数 */ bsp_InitQSPI_W25Q256(); /* 配置SPI总线 */ QSPI_MemoryMapped(); }
82.3.2 程序跳转的实现
从内部Flash跳转到外部QSPI Flash的实现代码如下
1. /* 2. ****************************************************************************************************** 3. * 函 数 名: JumpToApp 4. * 功能说明: 跳转到应用JumpToApp 5. * 形 参: 无 6. * 返 回 值: 无 7. ****************************************************************************************************** 8. */ 9. static void JumpToApp(void) 10. { 11. uint32_t i=0; 12. void (*AppJump)(void); /* 声明一个函数指针 */ 13. __IO uint32_t AppAddr = 0x90000000; /* APP 地址 */ 14. 15. 16. /* 关闭全局中断 */ 17. DISABLE_INT(); 18. 19. /* 设置所有时钟到默认状态,使用HSI时钟 */ 20. HAL_RCC_DeInit(); 21. 22. /* 关闭滴答定时器,复位到默认值 */ 23. SysTick->CTRL = 0; 24. SysTick->LOAD = 0; 25. SysTick->VAL = 0; 26. 27. /* 关闭所有中断,清除所有中断挂起标志 */ 28. for (i = 0; i < 8; i++) 29. { 30. NVIC->ICER[i]=0xFFFFFFFF; 31. NVIC->ICPR[i]=0xFFFFFFFF; 32. } 33. 34. /* 使能全局中断 */ 35. ENABLE_INT(); 36. 37. /* 跳转到应用程序,首地址是MSP,地址+4是复位中断服务程序地址 */ 38. AppJump = (void (*)(void)) (*((uint32_t *) (AppAddr + 4))); 39. 40. /* 设置主堆栈指针 */ 41. __set_MSP(*(uint32_t *)AppAddr); 42. 43. /* 在RTOS工程,这条语句很重要,设置为特权级模式,使用MSP指针 */ 44. __set_CONTROL(0); 45. 46. /* 跳转到系统BootLoader */ 47. AppJump(); 48. 49. /* 跳转成功的话,不会执行到这里,用户可以在这里添加代码 */ 50. while (1) 51. { 52. 53. } 54. }
这里把程序设计中的几个关键地方做个说明:
- 第12行,声明一个函数指针。
- 第13行,QSPI Flash地址在0x90000000。
- 第20行,此函数比较省事,可以方便的设置H7所有时钟到复位值,内部时钟使用HSI。
- 第23到25行,设置滴答定时器到复位值。
- 第28到32行,清除所有中断挂起标志并关闭中断,这里是直接通过一个for循环设置了NVIC所有配置位,共8组。
- 第38行,将系统bootLoader的中断复位服务程序的入口地址赋给第12行声明的函数,用户执行这个函数时,就会直接跳转过去。
- 第41行,设置主堆栈指针位置,即QSPI Flash应用程序首地址存储的就是栈地址。
- 第44行,这个设置在RTOS应用程序中比较重要,因为基于Cortex-M内核的RTOS任务堆栈基本都是使用线程堆栈指针PSP。但系统bootLoader使用的是主堆栈指针MSP,所以务必要设置下,同时让M内核工作于特权级。此寄存器的作用如下:
- 第47行,跳转到系统bootLoader。
82.4 QSPI Flash的APP应用程序说明
APP应用程序是由第53章配套例子:V7-033_LCD的汉字小字库和全字库制作 简单修改而来,主要修改如下两个地方:
82.4.1 设置Flash地址
设置Flash地址为QSPI Flash首地址0x90000000:
82.4.2 设置中断向量表
在main函数最开始就设置中断向量表到QSPI Flash首地址0x90000000,也可以按照本教程第28章的说明,将中断向量表设置到DTCM里面。
int main(void) { uint16_t ucBright; /* 背光亮度(0-255) */ uint8_t ucKeyCode; /* 按键代码 */ uint8_t ucStatus; /* 主程序状态字 */ uint8_t fRefresh; /* 刷屏请求标志,1表示需要刷新 */ SCB->VTOR = 0x90000000; /* 设置中断向量表地址 */ bsp_Init(); /* 硬件初始化 */ PrintfLogo(); /* 打印例程名称和版本等信息 */ PrintfHelp(); /* 打印操作提示 */ 省略未写 }
82.5 QSPI Flash的APP应用程序调试下载配置
将下面两个地方配置后,就可以像使用内部Flash一样使用QSPI Flash进行调试了。
82.5.1 下载配置
注意这里一定要够大,否则会提示算法文件无法加载:
我们这里是将其加到DTCM中,即首地址为0x20000000,大家也可以存储到任意其它RAM地址,只要空间还够加载算法文件即可。推荐使用AXI SRAM(地址0x24000000),因为这块RAM空间足够大。
如果要下载程序到QSPI Flash里面,需要做如下配置:
82.5.2 调试配置
注意这里一定要够大,否则会提示算法文件无法加载:
我们这里是将其加到DTCM中,即首地址为0x20000000,大家也可以存储到任意其它RAM地址,只要空间还够加载算法文件即可。
如果要做调试下载,需要做如下配置:
82.5.3 程序调试效果
APP应用程序调试效果如下:
82.6 实验例程说明
本章配套了两个例子:
- V7-062_QSPI Flash运行程序(Bootloader)。
- V7-063_QSPI Flash运行程序(用户APP)。
Bootloader例子需要大家先下载到内部Flash里面,然后按照本章第5小节的说明配置后,就可以像使用内部Flash一样调试下载QSPI Flash了。
82.7 总结
本章节就为大家讲解这么,为了熟练掌握,建议大家是操作练习下。