产品需要开发Bootloader功能。查了相关的资料总结如下。
1、认识ROM API
mimxrt1064片上有1个rom,存放的是出厂的 ROM bootloader,大小是128KB,地址是
ROM bootloader没有用完全部空间,厂商把一些常用模块驱动(WDOG,FLASH)等链接到该rom空间,并提供rom api给用户调用。API原型是 bootloader_api_entry_t ,在fsl_romapi.c定义,厂商以该原型定义了一个常量,将该常量的地址保存到 0x0020001c,用户通过指针的方式调用。其中一个成员是flexspi nor falsh驱动 flexspi_nor_driver_interface_t
#define g_bootloaderTree ((bootloader_api_entry_t *)*(uint32_t *)0x0020001cU)
typedef struct
{
const uint32_t version; /*!< Bootloader version number */
const char *copyright; /*!< Bootloader Copyright */
void (*runBootloader)(void *arg); /*!< Function to start the bootloader executing */
const uint32_t *reserved0; /*!< Reserved */
const flexspi_nor_driver_interface_t *flexSpiNorDriver; /*!< FlexSPI NOR Flash API */
const uint32_t *reserved1[5]; /*!< Reserved */
} bootloader_api_entry_t;
ROM API在 SDK目录下SDK\devices\MIMXRT1064\drivers fsl_romapi.c fsl_romapi.h文件中。里面有flexspi对nor flash的驱动。
2、使用ROM API的flexspi nor驱动
2.1、获取nor flash的配置
instance参数是flexspi实例,1064使用FlexSPI2接到片上flash。
//根据芯片型号定义flexspi实例
#if ( defined CPU_MIMXRT1064DVL6A )
#define FlexSpiInstance 1U
#define EXAMPLE_FLEXSPI_AMBA_BASE FlexSPI2_AMBA_BASE
#define FLASH_SIZE 0x400000UL /* 4MBytes */
#elif ( defined CPU_MIMXRT1062DVL6A )
#define FlexSpiInstance 0U
#define EXAMPLE_FLEXSPI_AMBA_BASE FlexSPI_AMBA_BASE
#define FLASH_SIZE 0x800000UL /* 8MBytes */
#endif
/*
定义nor flash配置和选项
option.option0.U = 0xC0000008是option配置字,不同的flash,用不同的配置字。
*/
static flexspi_nor_config_t norConfig;
/*
定义简化的串行nor Flash配置值0xc0000007(表示一般的四线QSPI)来初始化FlexSPI以及Flash
*/
static serial_nor_config_option_t option = {
.option0.U = 0xc0000007U, // QuadSPI NOR, Frequency: 133MHz
.option1.U = 0U,
};
/*
根据简化的serial_nor_config_option_t,将从Flash里读回的SFDP表的FDCB结构体赋值给flexspi_nor_config_t。FDCB大小是521字节,放在Flash开始或偏移0x400处。
*/
status_t ROM_FLEXSPI_NorFlash_GetConfig(uint32_t instance,
flexspi_nor_config_t *config,
serial_nor_config_option_t *option)
{
status_t status = g_bootloaderTree->flexSpiNorDriver->get_config(instance, config, option);
if (status == kStatus_Success)
{
if (config->memConfig.readSampleClkSrc == (uint8_t)kFLEXSPIReadSampleClk_LoopbackInternally)
{
config->memConfig.readSampleClkSrc = (uint8_t)kFLEXSPIReadSampleClk_LoopbackFromDqsPad;
}
}
return status;
}
2.2