感谢琳的出现,陪我度过开心的每一天。开心的日子总是过得很快,离上次写博客已经快两个月了。历经一年半的阴云密布,终于迎来了久违的万丈阳光,希望未来的岁月带来的是更多美好甜蜜,开心认真过好每一天。 乘着周五晚上的空闲,写点最近在搞的新单片机。今年十月份才量产的新片,网上资料还不是很完备,所以记录下自己的调试心得,也为后来者提供参考,尽量少走弯路。不多废话,进入正题。本博客中的内容大多是最近在安富莱电子论坛上发的一些个人调试记录的帖子转过来的,网址是http://bbs.armfly.com/u.php。 对于IMX.RT1050芯片的介绍,网上已经有一些了,最近这款芯片这么火的原因是600M的主频,价格却在3美元左右,性能和A7差不多。它的双精度浮点运算单元,高速计算能力,刚好适合写运动控制算法,所以公司开始投入人力搭建这款芯片的软件平台。本文只写技术要点,所以一些基本的MDK和单片机知识都没有提及。 这款单片机有好多种启动方式,SD卡、SPI FLASH、并行NORFLASH、并行NANDFLASH、USB、串口等,下面主要介绍外挂FlexSPI flash加载调试的心得。在介绍这之前先说说CMSIS-DAP调试器的使用注意事项。 一、CMSIS-DAP调试注意事项 NXP官方的评估板,上电使用CMSIS-DAP调试工具调试官方例程helloword,发现CMSIS-DAP调试很不稳定,不断摸索,终于找到原因。一定要认真看官方提供的手册,在MIMXRT1050EVKHUG.pdf文档中,有这么一句话很重要,截图如下:
画红框的这句话意思就是使用CMSIS-DAP在线调试时,一定要把板的boot启动模式切换到串行boot模式 ,下图是boot启动模式的各种管脚配置:
如红框中所示,把板上拨码开关SW7-3和SW7-4跳成01,CMSIS-DAP调试时就稳定了。 二、CMSIS-DAP进入U盘模式把BIN文件烧录到Hyper Flash方法 官方评估板集成了CMSIS-DAP调试工具,该调试工具有三个功能:虚拟串口、在线调试、U盘模式烧录固件到HyperFlash。下面是使用U盘模式烧录固件的方法:
(1)评估板boot模式切换到串行下载模式,即拨码开关SW7-3和SW7-4配置成01;
(2)J27跳线帽跳到1-2脚,USB线供电后按下SW4按键,这样PC上会出现一个U盘符;
(3)官方例程中的helloworld工程选择
(4)编译生成的hello_world.bin文件复制到刚才的U盘中;
(5)把拨码开关SW7-3和SW7-4配置成10,即boot使用HyperFlash启动方式;
(6)按下SW3键复位整板,就可以运行helloworld程序了。 三、评估板下载到HyperFlash调试的方法 HyperFlash加载算法,MDK已经提供了,这里使用官方例程中的Helloworld为例,对MDK的详细配置进行说明,调试器使用评估板自带的CMSIS-DAP,具体方法如下:
(1)使用MDK5.23以上的版本打开官方例程,代码路径为SDK_2.3.0_EVK-MIMXRT1050oardsevkmimxrt1050demo_appshello_worldmdk;
(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了。四、flashloader烧录固件到hyperflash方法 flashloader最终烧录用到的固件是SB格式的镜像文件,下面介绍SB文件生成的方法:
(1)从NXP官网下载Flashloader_i.MXRT1050_1.0_GA.zip工具,可以直接从NXP官网下载Flashloader_i.MXRT1050_1.0_GA.zip
(2)解压文件到当前目录,在doc文件夹下放着关于flashloader的使用手册,这里我们直接看i.MX MCU Manufacturing User's Guide.pdf的7.2.1章节生成SB文件的部分;
(3)用MDK编译器编译出SREC格式的可执行文件,它是用于生成SB文件的原始固件,这里我们以官方例程helloworld为例,用MDK编译出helloworld.srec固件,步骤如下:
1、打开官方例程中的helloworld工程,路径如下SDK_2.3.0_EVK-MIMXRT1050oardsevkmimxrt1050demo_appshello_worldmdk;
2、选择hello_world Flexspi_nor_release目标工程,如下图所示:
3、用fromelf.exe方法生成helloworld.srec固件,SREC格式即常用的S19格式的可执行文件,直接在MDK里配置,如下图红框所示:
fromelf.exe --m32combined --output "$L@L.srec" "#L"
(4)用flashloader里的elftosb.exe工具把helloworld.srec固件生成helloworld.sb烧录文件
1、在DOS命令窗口里用Flashloader_RT1050_1.0Toolselftosbwinelftosb.exe工具把helloworld.srec文件生成helloworld.bin和helloworld_nopadding.bin两个文件,生成过程中需要用到Flashloader_RT1050_1.0Toolsd_fileimx10xximx-flexspinor-normal-unsigned.bd文件,DOS窗 口中输入的命令如下:
elftosb.exe -f imx -V -c ../../bd_file/imx10xx/imx-flexspinor-normal-unsigned.bd -o helloworld.bin ../../../../SDK_2.3.0_EVK-MIMXRT1050/boards/evkmimxrt1050/demo_apps/hello_world/mdk/flexspi_nor_release/hello_world.srec
在elftosb.exe所在的目录下就会生成helloworld.bin和helloworld_nopadding.bin两个文件,DOS命令截图如下所示:
2、继续用elftosb.exe工具把helloworld_nopadding.bin文件生成helloworld.sb文件,生成过程需要用到Flashloader_RT1050_1.0Toolsd_fileimx10xxprogram_flexspinor_image_hyperflash.bd文件,DOS窗口中输入的命令如下:
elftosb.exe -f kinetis -V -c ../../bd_file/imx10xx/program_flexspinor_image_hyperflash.bd -o helloworld.sb helloworld_nopadding.bin
在elftosb.exe所在的目录下就会生成helloworld.sb文件,DOS命令截图如下所示:
(5)烧录helloworld.sb镜像到hyperflash
1、评估板J1跳线帽跳到3/4,USB线接到J9,SW7拨码开关设置为串口下载模式0101,USB线通过USB HUB连接到PC机,打开Flashloader_RT1050_1.0Toolsmfgtools-relMfgTool2.exe,看到如下所示界面:
2、把Flashloader_RT1050_1.0Toolselftosbwinhelloworld.sb拷贝到Flashloader_RT1050_1.0Toolsmfgtools-relProfilesMXRT105XOS Firmware目录下,并把helloworld.sb名字改成boot_image.sb;
3、点击MfgTool2.exe工具的start,开始烧录,烧录完成后如下图所示:
(6)评估板J1跳线帽跳到5/6,USB线接到J28,SW7拨码开关设置为串口下载模式0110,从hyperflash启动,PC上打开串口终端工具,会看到hello world字符串,说明烧录成功。
五、non-xip固件生成步骤 官方评估板的代码一般在hyperflash中直接执行,这种执行方式叫xip,但是hyperflash的运行速度相比于ITCM,还是慢了许多,所以有时候我们希望把固件存放在hyperflash中,但是启动的时候把hyperflash中的固件拷贝到ITCM中再运行,以便提高代码的执行速度,下面开始介绍固件生成步骤:1、修改MDK/Linker中的分散加载文件的中断向量地址,即MIMXRT1052xxxxx_ram.scf文件里的地址修改后如下#define m_interrupts_start 0x00002000 #define m_interrupts_size 0x00000400#define m_text_start 0x00002400
#define m_text_size 0x0001DC00也就是把固件从0x2000地址开始加载,0~0x2000这段地址存放boot的控制信息。2、MDK/Linker中Misc Controls添加 --entry=Reset_Handler,MDK默认生成的入口地址不是我们以为的Reset_Handler,而是__main,初始化RW和ZI段数据等操作后,再跳转到用户定义的main函数。查看Reset_Handler源码可知道,Reset_Handler依次设置了中断向量表,调用SystemInit,之后再调用了__main,所以需要告知BOOT ROM需要从Reset_Handler开始运行。3、用fromelf.exe方法生成*.srec固件,生成方法参看上文的第四章节。4、用flashloader里的elftosb.exe工具把*.srec固件生成*.sb烧录文件,生成方法参看上文的第四章节。这里生成的是non-xip,所以和第四章中使用的工具有不一样的地方,这里说明下:(1)*.srec生成*.bin的时候使用的bd工具是imx-itcm-unsigned.bd,即固件最后是要在ITCM中运行的,由于默认的imx-itcm-unsigned.bd中的地址配置是imx板的,所以我们要打开这个文件,把里面的内容修改为如下地址,options {
flags = 0x00;
startAddress = 0x0;
ivtOffset = 0x1000;
initialLoadSize = 0x2000;
}那么完整的命令格式是elftosb.exe -f imx -V -c ../../bd_file/imx10xx/imx-itcm-unsigned.bd -o interpolation.bin ../../../../../code/project/Objects/interpolation.srec,这样就生成了interpolation.bin 和interpolation_nopadding.bin两个文件(2) *.bin文件生成*.sb文件,完整命令格式是elftosb.exe -f kinetis -V -c ../../bd_file/imx10xx/program_flexspinor_image_hyperflash.bd -o interpolation.sb interpolation_nopadding.bin(3)把*.sb文件用MfgTool2.exe工具烧录到hyperflash中,具体方法参看第四章。