网上有大牛已经实现了把程序下载到HyperFlash调试,这里我经过实际验证,又加了一些自己的理解,写下这篇文档,供热爱底层调试的同行参考。
HyperFlash加载算法,MDK已经提供了,这里使用官方例程中的Helloworld为例,对MDK的详细配置进行说明,调试器使用评估板自带的CMSIS-DAP,具体方法如下:
(1)使用MDK5.23以上的版本打开官方例程,代码路径为SDK_2.3.0_EVK-MIMXRT1050\boards\evkmimxrt1050\demo_apps\hello_world\mdk;
(2)选择如下图所示的工程进行编译,这个工程就是烧录到HyperFlash的工程:
(3)对DEBUG中的调试器及MDK加载到HyperFlash的算法进行配置,如下图所示:
点击Settiing进入调试器配置,下图红框中的配置很重要,如果选择不对,会导致无法下载
下图中的RAM大小配置成0x8000,这个是用来运行MDK集成的烧录HyperFlash算法的,空间小了会导致运行失败,切记
(4)配置MDK中的LOAD设置,如下图所示:
Update Target before Debugging不能勾选,勾选之后无法进行DEBUG调试,后面会详细介绍DEBUG调试方法;
(5)评估板上电,插上USB下载线,boot模式使用串口下载模式或者HyperFlash模式都可以,即配置拨码开关SW7为0101或0110,然后点击LOAD按钮就可以把代码烧录到HyperFlash中了;
(6)配置boot模式为HyperFlash模式,复位评估板就可以在串口终端上看到hello world输出了。现实是这里还看不到终端输出,因为IVT还没有烧录到flash里,后面介绍为什么要这么做;
(7)保留第六步里的boot模式,复位评估板,然后点击DEBUG按钮就可以在flash里在线调试代码了;
(8)想要flash里的代码运行起来,还必须烧录IVT和512字节的加载头,这个在开发手册第八章有详细的介绍,这里我只简单说下IVT每个字段的含义:
volatile const uint32_t_ivt[] __attribute__((at(0X60001000))) = { 0x412000D1, //头字节,是固定的 0x60002000, //程序镜像存放的起始地址,因为后面的DCD字段最大为1768字节,所以程序存放地址要大于这个地址 0, //保留字段,写0 0, //DCD存放地址,这里没有用到DCD,所以写0 0x60001020, //bootdata存放的地址,手册中要求IVT存放的地址为0x1000处,而IVT总共有32个字节,bootdata需要紧跟IVT后面,所以地址为0x1020 0x60001000, //IVT存放的地址,手册中要求IVT存放的地址为0x1000处 0, //csf没有用到,写0 0, //保留字段,写0 boot_data数据格式,在下图中介绍 0x60000000, //boot起始地址,就是HyperFlash的起始地址 0x04000000, //boot空间大小,就是HyperFlash的空间大小 0, //plugin flag,没有用到,写0 };
boot_data数据格式如下:
(9)512字节的加载头,好像是用来设置flash的一些运行参数的,具体在手册8.6有详细的介绍,这里只贴上需要填充的数据
static const uint32_tboot_data[] __attribute__((at(0X60000000))) = { 0x42464346,0x56010400, 0x00000000, 0x03030303, 0x00000000, 0x00000000, 0x00000000,0x00000000, 0x00000000,0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,0x00000000, 0x00000059,0x01080800, 0x00000000, 0x00000000, 0x04000000, 0x00000000, 0x00000000,0x00000000, 0x00000000,0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000F,0x0001000F, 0x8B1887A0,0xA7048F10, 0x00000000, 0x00000000, 0x87008700, 0x87AA8700, 0x87058700,0x87708700, 0x8B1887A0,0xB70B8F10, 0x0000A704, 0x00000000, 0x87008700, 0x87AA8700, 0x87058700,0x87AA8700, 0x87008700,0x87558700, 0x87028700, 0x87558700, 0x87008700, 0x87AA8700, 0x87058700,0x87808700, 0x87008700,0x87AA8700, 0x87058700, 0x87AA8700, 0x87008700, 0x87558700, 0x87028700,0x87558700, 0x8B188700,0x87008F10, 0x00008730, 0x00000000, 0x87008700, 0x87AA8700, 0x87058700,0x87A08700, 0x8B188700,0xA3808F10, 0x00000000, 0x00000000, 0x87008700, 0x87AA8700, 0x87058700,0x87808700, 0x87008700,0x87AA8700, 0x87058700, 0x87AA8700, 0x87008700, 0x87558700, 0x87028700,0x87558700, 0x87008700,0x87AA8700, 0x87058700, 0x87108700, 0x00000000, 0x00000000, 0x00000000,0x00000000, 0x00000000,0x00000102, 0x00000302, 0x00000504, 0x00000902, 0x00000B04, 0x00000000,0x00000000, 0x00000000,0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,0x00000000, 0x00000200,0x00040000, 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000,0x00000000, 0x00000000,0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, };
(10)把上面两段C代码添加到helloworld.c文件里一起编译,就可以把整个程序镜像烧录到HyperFlash中了,到这里复位评估板,就可以在串口终端上看到hello world了。 |