在STM32N6中使用SDMMC1接口的eMMC作为外部存储器时,需注意以下关键点:
1. 地址配置与存储布局
- eMMC物理地址:eMMC以块/扇区(通常为512字节或4KB)为单位寻址,而非内存映射地址。需通过SDMMC接口以块设备方式访问。
- 存储分区建议:
- FSBL:通常放置在eMMC起始扇区(例如扇区0开始,占用若干扇区)。
- 应用程序:从预留扇区开始(例如扇区2048),需在链接脚本中指定加载地址(
Load Address)为eMMC位置,运行地址(Run Address)为RAM地址。
2. STM32CubeProgrammer下载配置
- 地址选择:
- 在STM32CubeProgrammer中选择扇区号(Sector Offset)而非内存地址。例如:
- FSBL写入扇区0(起始地址0x0)。
- 应用程序写入扇区2048(假设扇区大小512B,则对应地址0x100000)。
- 需在CubeProgrammer的下载选项中设置目标类型为
eMMC,并指定起始扇区。
- External Loader配置:
- 需为eMMC开发或使用ST提供的External Loader(
.stldr文件)。
- Loader需实现SDMMC1初始化、块读写接口,参考ST提供的SDMMC Loader模板修改。
- 将生成的
.stldr文件放入CubeProgrammer的/ExternalLoaders目录。
3. 启动模式与执行流程
- 必须使用FSBL + Load & Run模式:
- FSBL在内部Flash:STM32从内部Flash启动,执行FSBL代码。
- FSBL初始化eMMC:配置SDMMC1接口,读取eMMC中的应用程序到RAM。
- 跳转到RAM执行:FSBL将应用程序从eMMC拷贝到RAM后,通过函数指针跳转到RAM入口地址。
4. 关键实现步骤
- FSBL开发:
- 实现SDMMC1/eMMC驱动,包括初始化、块读取功能。
- 从eMMC指定扇区读取应用程序到RAM(例如
0x20000000)。
- 使用
SCB->VTOR重定向向量表到RAM地址,并跳转执行。
- 应用程序配置:
- 修改链接脚本(
.ld),设置FLASH为RAM地址(例如0x20000000),确保代码位置无关(-fPIC编译选项)。
- 生成
.bin文件时,确保加载地址与eMMC存储位置对应。
5. 示例代码片段
// FSBL中加载应用程序到RAM的示例
void Load_App_from_eMMC(void) {
uint32_t app_sector = 2048; // 应用程序起始扇区
uint32_t app_size = 64 * 1024; // 假设应用程序64KB
uint8_t *ram_addr = (uint8_t*)0x20020000; // RAM目标地址
// 从eMMC读取数据到RAM
if (HAL_MMC_ReadBlocks(&hmmc, ram_addr, app_sector, app_size/512) == HAL_OK) {
// 关闭中断,跳转到应用程序
__disable_irq();
void (*app_entry)(void) = (void (*)(void))(ram_addr + 4); // 跳过初始SP值
app_entry();
}
}
6. 验证与调试
- 检查eMMC连接:使用
HAL_MMC_Init验证SDMMC1是否成功识别eMMC。
- External Loader测试:在CubeProgrammer中使用
Memory Read功能确认能否读取eMMC数据。
- 日志输出:在FSBL中添加串口日志,跟踪eMMC读取和跳转过程。
通过以上步骤,可实现STM32N6通过eMMC存储和启动应用程序,满足非XIP场景下的需求。
在STM32N6中使用SDMMC1接口的eMMC作为外部存储器时,需注意以下关键点:
1. 地址配置与存储布局
- eMMC物理地址:eMMC以块/扇区(通常为512字节或4KB)为单位寻址,而非内存映射地址。需通过SDMMC接口以块设备方式访问。
- 存储分区建议:
- FSBL:通常放置在eMMC起始扇区(例如扇区0开始,占用若干扇区)。
- 应用程序:从预留扇区开始(例如扇区2048),需在链接脚本中指定加载地址(
Load Address)为eMMC位置,运行地址(Run Address)为RAM地址。
2. STM32CubeProgrammer下载配置
- 地址选择:
- 在STM32CubeProgrammer中选择扇区号(Sector Offset)而非内存地址。例如:
- FSBL写入扇区0(起始地址0x0)。
- 应用程序写入扇区2048(假设扇区大小512B,则对应地址0x100000)。
- 需在CubeProgrammer的下载选项中设置目标类型为
eMMC,并指定起始扇区。
- External Loader配置:
- 需为eMMC开发或使用ST提供的External Loader(
.stldr文件)。
- Loader需实现SDMMC1初始化、块读写接口,参考ST提供的SDMMC Loader模板修改。
- 将生成的
.stldr文件放入CubeProgrammer的/ExternalLoaders目录。
3. 启动模式与执行流程
- 必须使用FSBL + Load & Run模式:
- FSBL在内部Flash:STM32从内部Flash启动,执行FSBL代码。
- FSBL初始化eMMC:配置SDMMC1接口,读取eMMC中的应用程序到RAM。
- 跳转到RAM执行:FSBL将应用程序从eMMC拷贝到RAM后,通过函数指针跳转到RAM入口地址。
4. 关键实现步骤
- FSBL开发:
- 实现SDMMC1/eMMC驱动,包括初始化、块读取功能。
- 从eMMC指定扇区读取应用程序到RAM(例如
0x20000000)。
- 使用
SCB->VTOR重定向向量表到RAM地址,并跳转执行。
- 应用程序配置:
- 修改链接脚本(
.ld),设置FLASH为RAM地址(例如0x20000000),确保代码位置无关(-fPIC编译选项)。
- 生成
.bin文件时,确保加载地址与eMMC存储位置对应。
5. 示例代码片段
// FSBL中加载应用程序到RAM的示例
void Load_App_from_eMMC(void) {
uint32_t app_sector = 2048; // 应用程序起始扇区
uint32_t app_size = 64 * 1024; // 假设应用程序64KB
uint8_t *ram_addr = (uint8_t*)0x20020000; // RAM目标地址
// 从eMMC读取数据到RAM
if (HAL_MMC_ReadBlocks(&hmmc, ram_addr, app_sector, app_size/512) == HAL_OK) {
// 关闭中断,跳转到应用程序
__disable_irq();
void (*app_entry)(void) = (void (*)(void))(ram_addr + 4); // 跳过初始SP值
app_entry();
}
}
6. 验证与调试
- 检查eMMC连接:使用
HAL_MMC_Init验证SDMMC1是否成功识别eMMC。
- External Loader测试:在CubeProgrammer中使用
Memory Read功能确认能否读取eMMC数据。
- 日志输出:在FSBL中添加串口日志,跟踪eMMC读取和跳转过程。
通过以上步骤,可实现STM32N6通过eMMC存储和启动应用程序,满足非XIP场景下的需求。
举报