STM32N6在LRUN模式下从Nor_Flash启动并执行代码详解
简介
以STM32N6570-DK板为例。STM32N6系列的芯片没有内置的Flash,需要把代码存储到外部的Nor_Flash里面去,上电时,boot ROM 将 FSBL 二进制文件从Nor_Flash复制到内部 SRAM,FSBL 在内部 RAM 中执行,完成必要设置后,FSBL 将应用程序二进制文件从Nor_Flash复制到内部 SRAM,再跳转到应用程序入口点执行
ST提供了两种关于外部Flash运行代码的方案:
XIP 模式:应用程序直接在外部 Flash 中执行,无需将代码复制到内部 RAM。这种模式适用于外部 Flash 速度足够快,能够满足程序执行要求的场景。
LRUN 模式:应用程序在内部 RAM 中执行,FSBL 会先将应用程序二进制文件从外部 Flash 复制到内部 RAM。这适用于外部 Flash 速度较慢,或者应用程序需要频繁访问内部资源的情况。
本文将使用LRUN 模式
说明:理应可以完全通过cubemx生成该项目,但我一直跑不起来,代码大体和我移植后的相同,通过深入的代码对比应该可以找到问题,由于时间问题,我将采用cubemx+代码移植完成该工程的搭建
一、准备工作
软件:
我的软件版本(用最新的,不然会出bug): STM32CubeMX–6.14 STM32CubeProgrammer–2.19.0 STM32CubeIDE–1.18.1
硬件:
STM32N6570-DK板
软件包:
官方代码链接:https://www.st.com.cn/zh/embedded-software/stm32cuben6.html

我用的是1.1.0的版本,下载完后,解压出STM32Cube_FW_N6_V1.1.0文件
DK板的BOOT拨码开关:

DEV Boot模式:用于调试or下载代码
Flash Boot模式:用于板子从外部Flash运行代码
二、工程操作:
创建工程:二选一即可
1、创建cubemx工程->选择STM32N657X0H3Q芯片->选择Secure domain only->进入工程
2、直接用STM32Cube_FW_N6_V1.1.0\Projects\STM32N6570-DK\Examples\XSPI\XSPI_NOR_AutoPolling_DTR\XSPI_NOR_AutoPolling_DTR.ioc,直接放到空文件夹下(比如我的文件夹名->NOR_FLASH)
1、cubemx配置
①XSPIM的配置

②XSPI2的配置

③配置XSPI2的时钟

这里没有配置EXTMEM_MANAGER(手动做移植)
④配置GPIO

⑤生成代码

2、代码移植部分
以下文件移植做个简单的说明:
STM32Cube_FW_N6_V1.1.0…是官方下载下来的代码路径
NOR_FLASH…是我创建的工程代码路径
按照你的实际情况做修改即可
①添加文件
把STM32Cube_FW_N6_V1.1.0\Middlewares\ST下的STM32_ExtMem_Manager文件copy到NOR_FLASH\FSBL\Drivers\下

②删除文件
NOR_FLASH\FSBL\Drivers\STM32_ExtMem_Manager\boot下面的代码,因为lrun和xip会冲突

③加入.c文件
把STM32Cube_FW_N6_V1.1.0\Projects\STM32N6570-DK\Templates\Template_FSBL_LRUN\FSBL\Src|extmem.c copy到NOR_FLASH\FSBL\Src

④加入.h文件
把STM32Cube_FW_N6_V1.1.0\Projects\STM32N6570-DK\Templates\Template_FSBL_LRUN\FSBL\Inc\2个.h copy到NOR_FLASH\FSBL\Inc

3、进入cubeide
①加入头文件路径

②添加代码
在XSPI_NOR_Appli下的main.c添加以下代码,这里添加完代码后,可以debug跑一下,看看效果
这里注意,要把硬件上的BOOT1拨到H的部分(DEV Boot模式)
while (1)
{
HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin); //add
HAL_Delay(250); //add
}
在XSPI_NOR_FSBL下添加以下代码
/* USER CODE BEGIN Includes */
#include "extmem.h" //add
/* USER CODE END Includes */
/* USER CODE BEGIN 2 */
MX_EXTMEM_Init(); //add --外部存储器初始化
BOOT_Application(); //add --Boot跳转到应用程序
/* USER CODE END 2 */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
__NOP(); //add 延时
}
编译完后,在对应的工程路径下会出现
D:\C desk\NOR_FLASH\Appli\Debug\XSPI_NOR_Appli.bin
D:\C desk\NOR_FLASH\FSBL\Debug\XSPI_NOR_FSBL.bin
三、烧录
1、添加标头
这里说明下,N6和传统的烧录方式不同,需要打上标头,烧录进去才能运行!
我喜欢吧两个文件复制到一个空的文件夹下去操作~
操作:windows下win+r,输入cmd,打开命令窗口分别对上述两个bin文件添加标头
"E:\Program Files\STMicroelectronics\STM32Cube\STM32CubeProgrammer\bin\STM32_SigningTool_CLI.exe" -bin XSPI_NOR_Appli.bin -nk -of 0x80000000 -t fsbl -o Appli-trusted.bin -hv 2.3 -dump Appli-trusted.bin
"E:\Program Files\STMicroelectronics\STM32Cube\STM32CubeProgrammer\bin\STM32_SigningTool_CLI.exe" -bin XSPI_NOR_FSBL.bin -nk -of 0x80000000 -t fsbl -o FSBL-trusted.bin -hv 2.3 -dump FSBL-trusted.bin
1、这里"…\STM32_SigningTool_CLI.exe"是你STM32CubeProgrammer 安装路径下的CLI
2、XSPI_NOR_Appli是ide生成将要打标头的.bin
3、Appli-trusted.bin是打完标头的文件(烧录用的是这个!!!)

输出效果如上图
生成了Appli-trusted.bin、FSBL-trusted.bin
2、选好烧录器

3、烧录工程
说明:
- 选择文件
- 烧录地址
- 烧录工程

分别烧录以下2个文件
1、FSBL-trusted.bin,地址填入0x7000 0000,点击Start
2、Appli-trusted.bin,地址填入0x7010 0000,点击Start

烧录完成以后,要把硬件上的BOOT1拨到L的部分(从外部Flash启动)
查看板子的效果,此时DK板子上的LED1丝印对应的灯在闪烁!!!
参考链接:
[如何使用 STM32N6 从外部串行 NOR 执行代码XIP]_stm32n6 xip-CSDN博客
作者:Leopold James Fitz