art-pi2 上手记录(二)
功能比较庞杂,写得不好,抛砖引玉
预备知识
stm32 默认从主闪存0x08000000启动
art-pi2的psram 映射0x90000000
art-pi2的8线ospi flash 映射0x70000000
-
stm32h7比较灵活,通过修改选项字节,可以实现从
0x0000 0000 到 0x3FFF 0000 地址进行启动,这里不展开,感兴趣参考:【不是问题的问题】为什么STM32的Flash地址要设置到0x08000000 - STM32H7 - 硬汉嵌入式论坛 - Powered by Discuz!
-
stm32h7r系列内部flash只有64k,支持在外部flash上xip运行代码
内存映射原理
将内核对地址的访问操作转为对ospi/xspi总线的操作,需要内核支持且外设配置进入内存映射模式(初始化),进入内存映射模式后就可以xip运行代码;可以类比fsmc对扩展sdram的操作
下载算法flash loader
下载算法大致原理为调试器通过jtag/swd将一小段可执行程序传输到板子的ram,并通过jtag/swd调用其中的init、erase、read、write等函数,以操作内部/外部flash;原理参考下图:
- flm/stldr格式本质也是elf可执行程序,不含main程序;.stldr可以导出给cubeprogram等软件使用,studio的APP工程也有使用;keil的下载算法格式为.flm
下载和运行流程
通过stlink下载app的流程:swd传输下载算法,将用户app的elf写入0x70000000然后重启,由bl完成剩余操作
运行流程:从0x08000000启动bl,初始化psram和外部flash,进行内存映射HAL_XSPI_MemoryMapped;跳转到0x70000000(外部flash映射后的地址),开始XIP运行
app下载到外部flash需要设置下载算法(默认已配好):
- 注意下载算法运行在ram中,仅操作外部flash,不能替代bootloader,不能完成上电到跳转app的过程
- 也可以使用stm32 cubeprogram下载,支持回读外部flash的内容
bootloader工程
在studio中新建工程,选择基于开发板/art-pi2/示例工程/art_pi2_bootloader
在main中完成了外部flash和psram的初始化,并进入xip模式;
随后跳转到外部flash运行app程序;比较常规
int main(void)
{MX_FLASH_Init();EXTMEM_Init();EXTMEM_Flash_Probe();EXTMEM_PSRAM_Probe();EXTMEM_Flash_EnterXIP();EXTMEM_PSRAM_EnterXIP();rt_kprintf("\nJump to APP...\n");rt_hw_interrupt_disable();JumpToApplication();return RT_EOK;
}
#define APPLICATION_ADDRESS XSPI2_BASE //(uint32_t)0x70000000int JumpToApplication(void)
{typedef void (*pFunction)(void);pFunction JumpToApp;uint32_t Application_vector;/* Suspend SysTick */SysTick->CTRL = 0;/* Disable I-Cache---------------------------------------------------------*/SCB_DisableICache(); //TODO SCB_Disables Cache and jump success/* Disable D-Cache---------------------------------------------------------*/SCB_DisableDCache();/* Apply offsets for image location and vector table offset */// Application_vector += EXTMEM_XIP_IMAGE_OFFSET + EXTMEM_HEADER_OFFSET;Application_vector = APPLICATION_ADDRESS;SCB->VTOR = (uint32_t)Application_vector;JumpToApp = (pFunction)(*(__IO uint32_t *)(Application_vector + 4u));__set_MSP(*(__IO uint32_t *)Application_vector);__set_CONTROL(0);JumpToApp();return 0;
}
- 注意:bootloader工程这里选择全片擦除,扇区擦除可能无法烧写
app示例工程
art_pi2_blink_led
重点看看链接脚本lds文件,text段放在了QFLASH中,如下图,链接时会将代码链接到外部flash中
程序中注意重定向中断向量表,然后就可以愉快地写应用了~
#define XSPI2_BASE 0x70000000UL /*!< XSPI2 base address */
static int vtor_config(void)
{/* Vector Table Relocation in Internal XSPI2_BASE */SCB->VTOR = XSPI2_BASE; return 0;
}
INIT_BOARD_EXPORT(vtor_config);
- 下载算法配置:ART-Pi2_ST_winbond_64MB.stldr
补充
-
对裸机感兴趣的可以看看 @lizimu2020 的仓库 https://gitee.com/lizimu2020/ART_Pi2
-
对于全片跑在sram方案(章节7/8 RT-Thread-ART-Pi2移植CMSIS-DAP(基于CherryUSB协议栈)RT-Thread问答社区 - RT-Thread ),如果无需频繁修改bootloader程序(固定跑在0x70000000的外置flash上,仅做应用开发),使用默认bootloader即可