QSPI、OSPI與FSMC的區別與內存映射分析
基本概念與區別
1. FSMC (靈活靜態存儲控制器)
- 接口類型:并行接口,通常8/16位數據總線
- 總線標準:傳統并行總線協議
- 速度:相對較低,通常最高約100MHz
- 應用場景:SRAM、NOR Flash、PSRAM、LCD等并行接口外設
2. QSPI (四線串行外設接口)
- 接口類型:串行接口,1/2/4線數據傳輸
- 總線標準:SPI協議的擴展
- 速度:中等,通常最高約108MHz,有效帶寬達到50MBytes/s (4線x108MHz/8位)
- 應用場景:Serial NOR Flash、EEPROM等
3. OSPI (八線串行外設接口)
- 接口類型:串行接口,1/2/4/8線數據傳輸
- 總線標準:QSPI的擴展,兼容QSPI
- 速度:較高,通常最高約200MHz,有效帶寬可達到200MBytes/s (8線x200MHz/8位)
- 應用場景:高速Serial NOR Flash、Hyperflash、Hyper RAM
內存映射功能對比
FSMC內存映射
- 直接映射:FSMC直接將外部存儲設備映射到CPU的地址空間
- 訪問方式:CPU直接通過地址訪問,無需專用命令
- 優勢:實現簡單,無需特殊初始化序列
- 延遲:相對較低,通常1-2個時鐘周期
- 地址范圍:STM32上通常映射到0x6000 0000 - 0x6FFF FFFF
QSPI內存映射
- 間接映射:通過QSPI控制器將閃存內容映射到系統地址空間
- 訪問流程:
- 控制器發送特定命令(通常是0x0B/0xEB)
- 發送地址
- 插入可選的虛擬周期
- 連續讀取數據
- 映射機制:QSPI控制器自動處理命令序列
- 地址范圍:典型映射到0x9000 0000 - 0x9FFF FFFF
OSPI內存映射
- 增強型映射:支持QSPI的所有功能,并增加了8線模式支持
- 訪問流程:與QSPI相似,但可以使用8線傳輸
- 高級特性:
- 支持更復雜的命令序列
- 雙閃存同時訪問(STM32H7系列)
- 內存映射期間支持XIP緩存
- 地址范圍:類似QSPI,但可能有所擴展
XIP (執行時位置)實現方式
FSMC-XIP實現
// FSMC配置NOR Flash映射
void FSMC_NOR_Init(void) {FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;FSMC_NORSRAMTimingInitTypeDef p;// 配置基本時序p.FSMC_AddressSetupTime = 0x06;p.FSMC_AddressHoldTime = 0x00;p.FSMC_DataSetupTime = 0x0B;// ...其他時序配置// 配置NOR控制器FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM1;FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_NOR;FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;// ...其他控制器配置FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE);// 映射后可直接訪問和執行,無需額外步驟
}// 代碼執行示例
typedef void (*pFunction)(void);
pFunction Jump_To_Application;
void ExecuteFromNOR(void) {// 直接跳轉到NOR Flash中的代碼Jump_To_Application = (pFunction)(0x60000000 + 0x1000); // 示例地址Jump_To_Application();
}
QSPI-XIP實現
// QSPI內存映射模式配置
void QSPI_MemoryMapped_Init(void) {QSPI_CommandTypeDef s_command;QSPI_MemoryMappedTypeDef s_mem_mapped_cfg;// 配置讀取命令s_command.InstructionMode = QSPI_INSTRUCTION_1_LINE;s_command.Instruction = QUAD_INOUT_FAST_READ_CMD; // 通常是0xEBs_command.AddressMode = QSPI_ADDRESS_4_LINES;s_command.AddressSize = QSPI_ADDRESS_24_BITS;s_command.DataMode = QSPI_DATA_4_LINES;// ...其他命令配置// 配置內存映射參數s_mem_mapped_cfg.TimeOutActivation = QSPI_TIMEOUT_COUNTER_DISABLE;// 啟用內存映射模式HAL_QSPI_MemoryMapped(&hqspi, &s_command, &s_mem_mapped_cfg);// 此時Flash已映射到地址空間,可以執行代碼
}// 代碼執行示例
typedef void (*pFunction)(void);
pFunction Jump_To_Application;
void ExecuteFromQSPI(void) {// 使能Cache以提高XIP性能SCB_EnableICache();SCB_EnableDCache();// 跳轉到QSPI映射區域的代碼Jump_To_Application = (pFunction)(0x90000000 + 0x1000); // 示例地址Jump_To_Application();
}
OSPI-XIP實現
// OSPI內存映射模式配置 (STM32H7系列示例)
void OSPI_MemoryMapped_Init(void) {OSPI_RegularCmdTypeDef sCommand;OSPI_MemoryMappedTypeDef sMemMappedCfg;// 配置讀取命令 (8線模式)sCommand.OperationType = HAL_OSPI_OPTYPE_READ_CFG;sCommand.FlashId = HAL_OSPI_FLASH_ID_1;sCommand.Instruction = OCTO_READ_CMD; // 例如0x8B/0xECsCommand.InstructionMode = HAL_OSPI_INSTRUCTION_8_LINES;sCommand.InstructionSize = HAL_OSPI_INSTRUCTION_8_BITS;sCommand.AddressMode = HAL_OSPI_ADDRESS_8_LINES;sCommand.AddressSize = HAL_OSPI_ADDRESS_32_BITS;sCommand.DataMode = HAL_OSPI_DATA_8_LINES;// ...其他命令配置// 配置內存映射參數sMemMappedCfg.TimeOutActivation = HAL_OSPI_TIMEOUT_COUNTER_DISABLE;// 啟用OSPI內存映射模式HAL_OSPI_MemoryMapped(&hospi, &sCommand, &sMemMappedCfg);// 此時可以直接執行映射區域的代碼
}// 代碼執行示例
typedef void (*pFunction)(void);
pFunction Jump_To_Application;
void ExecuteFromOSPI(void) {// 使能Cache以提高XIP性能SCB_EnableICache();SCB_EnableDCache();// 跳轉到OSPI映射區域的代碼Jump_To_Application = (pFunction)(0x90000000 + 0x1000); // 示例地址Jump_To_Application();
}
性能與應用對比
XIP性能對比
-
訪問延遲:
- FSMC: 低延遲,但總體帶寬受限
- QSPI: 首次訪問延遲高,但連續讀取性能好
- OSPI: 首次訪問延遲較高,但連續讀取性能最佳
-
緩存影響:
- 三種接口都受益于CPU緩存
- 對于QSPI/OSPI,緩存幾乎是必需的
- STM32H7還為QSPI/OSPI提供了專用的ART加速器
-
代碼執行速度:
- FSMC: ~15-30MB/s
- QSPI: ~30-50MB/s
- OSPI: ~80-200MB/s
適用場景
-
FSMC:
- 需要兼容舊設備
- 需要簡單直接的訪問方式
- 接口引腳數量不受限
-
QSPI:
- 需要節省PCB空間(較少引腳)
- 中等執行性能要求
- 大多數現代系統選擇
-
OSPI:
- 高性能應用
- 運行復雜應用程序
- 需要支持大容量閃存
總結
FSMC、QSPI和OSPI代表了嵌入式系統外部存儲接口的發展歷程:從并行到串行,從單線到多線。在內存映射和XIP方面,三種接口都支持,但實現復雜度和性能各不相同。對于現代STM32應用,QSPI和OSPI因其更好的性能/空間比和靈活性而成為更流行的選擇,特別是對于需要執行復雜代碼的應用程序。