【STM32H7教程】第82章 STM32H7的QSPI总线应用之QSPI Flash执行程序(BOOT+APP方式)

2020-11-24 11:00:01 浏览数 (1)

完整教程下载地址: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 初学者重要提示

  1. QSPI Flash的相关知识点可以看第78章和79章。
  2. 操作本章配套例子前务必先将QSPI Flash的下载算法放到MDK安装目录。
  3. 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并设置为内存映射模式。

代码语言:javascript复制
/*
*********************************************************************************************************
*    函 数 名: 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的实现代码如下

代码语言:javascript复制
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里面。

代码语言:javascript复制
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 总结

本章节就为大家讲解这么,为了熟练掌握,建议大家是操作练习下。

0 人点赞