一、目的
本文配套的完整工程地址
链接:https://pan.baidu.com/s/1CVN1oKVKvlE_osn9fePxbg
提取码:6u5e
在上一篇《手把手系列--编写Keil MDK 外部FLASH下载算法》我们学会了如何给Keil MDK编写下载算法,本篇我们在这基础上验证我们实现的下载算法。(务必要先看懂前一篇博文)
参考资料仍然是上一篇文档中提供的PDF资料
Programming External Flash used with STM32 Devices
对应章节为
二、准备
STM32H750XBH6_ArtPi开发板
Keil MDK V5.34
三、实战
下面我们操练起来
首先我们需要将上一篇博文中提供的工程下载下来,如下图
我们将整个文件夹以及内部文件的名字重新命名下,例如都改成STM32H750XBH6_ArtPi_QSPI_W25Q64JV_Test,修改后如下图
然后用Keil打开这个工程,如下图
接下来我们进行一些修改操作。
(1)打开C/C++(AC6)选项卡,去除勾选Read-Only Position Independent、Read-Write Position Independent
(2)修改分散加载文件,分散加载的内容是一个很有意思的知识点,这个对初学者还是有一些难度的,网上也有很有资料,我准备后面根据Keil官网的资料再给大家讲解一下。
Target.lin文件内容
; Linker Control File (scatter-loading)
;
LR_ROM 0x20000000 0x0000F000 { ; load region size_region
ER_ROM 0x20000000 0x0000F000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
* (+RO +XO)
}
RW_IRAM1 0x2000F000 0x00002000 { ; RW data
.ANY (+RW +ZI)
}
}
(3)设置程序在RAM里面运行的ini信息,先下面文件的内容放置到工程文件夹下,并且命名为Dbg_RAM.ini
FUNC void Setup (void) {
SP = _RDWORD(0x20000000);
PC = _RDWORD(0x20000004);
_WDWORD(0xE000ED08, 0x20000000);
}
FUNC void OnResetExec(void) {
Setup();
}
LOAD %L INCREMENTAL
Setup();
上图中的信息跟官方文档里面有出入,以我为准,不然你无法正常调试测试。
在Debug选项卡中选中这个文件
(4)在Utilities选项卡中进行如下操作
(5)将system_stm32h7xx.c这个文件从文件分组中取消include,如下图
(6)选中Device分组,将Startup重新选中include
注意(5)(6)这两步骤是前一篇博文中的反操作。
(7)添加Test Code分组,并添加文件FlashTest.c
#include "RTE_Components.h"
#include CMSIS_device_header
#include "FlashOS.h"
#include "quadspi.h"
extern struct FlashDevice const FlashDevice;
void stop_on_error(uint32_t cond) {
if (cond) {
__BKPT(0x1);
while(1) {}
}
}
static uint8_t test_buf[MEMORY_SECTOR_SIZE];
volatile int ret;
int main(void) {
ret = Init(FlashDevice.DevAdr, 0, 1);
stop_on_error(ret);
//ret = EraseChip();
stop_on_error(ret);
for (int i = 0; i < MEMORY_SECTOR_SIZE; i++) {
test_buf[i] = i;
}
ret = ProgramPage(FlashDevice.DevAdr, MEMORY_SECTOR_SIZE, test_buf);
stop_on_error(ret);
for (int i = 0; i < MEMORY_SECTOR_SIZE; i++) {
test_buf[i] = i + 1;
}
ret = ProgramPage(FlashDevice.DevAdr + MEMORY_SECTOR_SIZE, MEMORY_SECTOR_SIZE, test_buf);
stop_on_error(ret);
for (int i = 0; i < MEMORY_SECTOR_SIZE; i++) {
test_buf[i] = i;
}
ret = Verify(FlashDevice.DevAdr, MEMORY_SECTOR_SIZE, test_buf);
for (int i = 0; i < MEMORY_SECTOR_SIZE; i++) {
test_buf[i] = i + 1;
}
ret = Verify(FlashDevice.DevAdr + MEMORY_SECTOR_SIZE, MEMORY_SECTOR_SIZE, test_buf);
ret = UnInit(1);
stop_on_error(ret);
while (1) {}
}
(8)将User选项卡里面的命令去除
下面我们来编译一下。
编译成功,下面我们来调试一下。
我们在ProgramPage那边打个断点
获取一下test_buf的地址
查看一下对应地址的内存数据
至此,我们完成了本博文的目的。
完整工程下载地址
链接:https://pan.baidu.com/s/1CVN1oKVKvlE_osn9fePxbg
提取码:6u5e