keil下载程序具体过程3:从jlink的log开始

引言

        本篇文章开始,跟着jlink的log,我们将跟踪镜像文件具体的下载过程。

一、jlink的log

        下面的是keil点击Download按钮输出的log。

FromELF: creating hex file...
".\Objects\Project.axf" - 0 Error(s), 0 Warning(s).
Build Time Elapsed: 00:00:16
Load "MDK-ARM\\Objects\\Project.axf"
Set JLink Project File to "MDK-ARM\JLinkSettings.ini"
* JLink Info: Device "CORTEX-M4" selected.
JLink info:
------------
DLL: V7.22b, compiled Jun 17 2021 17:22:49
Firmware: J-Link ARM-OB STM32 compiled Aug 22 2012 19:52:04
Hardware: V7.00
S/N : 20090937
Feature(s) : RDI,FlashDL,FlashBP,JFlash,GDBFull
* JLink Info: Found SW-DP with ID 0x2BA01477
* JLink Info: DPv0 detected
* JLink Info: Scanning AP map to find all available APs
* JLink Info: AP[1]: Stopped AP scan as end of AP map has been reached
* JLink Info: AP[0]: AHB-AP (IDR: 0x24770011)
* JLink Info: Iterating through AP map to find AHB-AP to use
* JLink Info: AP[0]: Core found
* JLink Info: AP[0]: AHB-AP ROM base: 0xE00FF000
* JLink Info: CPUID register: 0x410FC241. Implementer code: 0x41 (ARM)
* JLink Info: Found Cortex-M4 r0p1, Little endian.
* JLink Info: FPUnit: 6 code (BP) slots and 2 literal slots
* JLink Info: CoreSight components:
* JLink Info: ROMTbl[0] @ E00FF000
* JLink Info: ROMTbl[0][0]: E000E000, CID: B105E00D, PID: 000BB00C SCS-M7
* JLink Info: ROMTbl[0][1]: E0001000, CID: B105E00D, PID: 003BB002 DWT
* JLink Info: ROMTbl[0][2]: E0002000, CID: B105E00D, PID: 002BB003 FPB
* JLink Info: ROMTbl[0][3]: E0000000, CID: B105E00D, PID: 003BB001 ITM
* JLink Info: ROMTbl[0][4]: E0040000, CID: B105900D, PID: 000BB9A1 TPIU
ROMTableAddr = 0xE00FF000
* JLink Info: Reset: Halt core after reset via DEMCR.VC_CORERESET.
* JLink Info: Reset: Reset device via AIRCR.SYSRESETREQ.
Target info:
------------
Device: ARMCM4_FP
VTarget = 3.300V
State of Pins:
TCK: 0, TDI: 0, TDO: 1, TMS: 0, TRES: 1, TRST: 1
Hardware-Breakpoints: 6
Software-Breakpoints: 8192
Watchpoints: 4
JTAG speed: 4000 kHz
Erase Done.
Programming Done.

        这是keil下面的调试窗口显示的log。根据上面的分析,可以看到,JLink第一件事是去加载Project.axf文件,这个是keil生成的工程文件。在keil编译了源代码之后,会生成对应的Project.axf、Project.hex、Project.bin文件。bin文件只有镜像文件,纯二进制,hex文件在bin文件的基础上添加了地址信息,axf在hex文件的基础上再添加了调试信息部分。

出现的这两行log值得注意:
JLink Info: AP[0]: Core found
JLink Info: AP[0]: AHB-AP ROM base: 0xE00FF000

0xE00FF000是什么地址?在《Cortex-M3权威指南》里面搜索下可以看到如下地址排列(截取一部分):

 可以看到,ROM表的地址位于0xE00F_F000–––0xE00F_FFFF这个范围,"AP[0]: AHB-AP ROM
base: 0xE00FF000"说AHB-AP的ROM基地址在0xE00FF000,这里可以引出之前文章的ROM表。

JLink Info: ROMTbl[0][0]: E000E000, CID: B105E00D, PID: 000BB00C SCS-M7
JLink Info: ROMTbl[0][1]: E0001000, CID: B105E00D, PID: 003BB002 DWT
JLink Info: ROMTbl[0][2]: E0002000, CID: B105E00D, PID: 002BB003 FPB
JLink Info: ROMTbl[0][3]: E0000000, CID: B105E00D, PID: 003BB001 ITM
JLink Info: ROMTbl[0][4]: E0040000, CID: B105900D, PID: 000BB9A1 TPIU

        这5行log就是ROM表的内容,从上往下分别是:SCS-M7、DWT、FPB、ITM、TPIU
从上面的表中可以看到,DWT、FPB、ITM、TPIU都在里面,这几个单元具体什么意思,请参考博主之前的文章:Cortext-M3系列:调试组件(9)_紫川宁520的博客-CSDN博客

        可以看到这5个单元的地址也不是默认的。各家芯片厂商可以根据自己的需求自定义端口的地址。(扯得有点远了)

        后面紧接着是将JLink的配置信息写入到JLinkSettings.ini中。可以看到ini文件中的信息(我也不太懂里面具体啥意思,以后搞明白了再更新这个部分)。

 

        在”JLink info:“部分,我们可以在开头看到JLink相关的信息。随后的 "JLink Info: Found SW-DP with ID 0x2BA01477"和上面的信息,跟我们在keil的配置中设置的一样。SWD为0x2BA01477,SN为20090937。

在keil的工程下面还有一个jlink的log,这个才是真正的jlink日志文件,下面放其中的一部分。

T47A4 000:231.035 JLINK_SetWarnOutHandler(...)

T47A4 000:231.057 JLINK_OpenEx(...)

T47A4 000:237.253 Feature(s): RDI,FlashDL,FlashBP,JFlash,GDBFull

T47A4 000:239.217 TELNET listener socket opened on port 19021

T47A4 000:239.360 WEBSRV Starting webserver

T47A4 000:239.463 WEBSRV Webserver running on local port 19080 T47A4 000:239.487 JLINK_SetErrorOutHandler(...)

T47A4 000:239.513 JLINK_ExecCommand("ProjectFile = "MDK-ARM\JLinkSettings.ini"", ... ).

T47A4 000:248.435 Ref file found at: C:\Keil_v5\ARM\Segger\JLinkDevices.ref

T47A4 000:248.537 XML referenced by ref file: C:\Program Files (x86)\SEGGER\JLink\JLinkDevices.xml

T47A4 000:249.085 C:\Program Files (x86)\SEGGER\JLink\JLinkDevices.xml evaluated successfully.

T47A4 000:267.144 JLINK_ExecCommand("Device = ARMCM4_FP", ...).

T47A4 000:267.466 JLINK_GetHardwareVersion()

......

T47A4 000:267.544 JLINK_GetOEMString(...)

T47A4 000:267.549 JLINK_TIF_Select(JLINKARM_TIF_SWD)

T47A4 000:269.794 JLINK_SetResetType(JLINKARM_RESET_TYPE_NORMAL)

T47A4 000:271.663 Found SW-DP with ID 0x2BA01477

T47A4 000:280.994 Old FW that does not support reading DPIDR via DAP jobs

T47A4 000:289.582 DPv0 detected

T47A4 000:289.615 Scanning AP map to find all available APs

T47A4 000:295.659 AP[1]: Stopped AP scan as end of AP map has been reached

T47A4 000:295.699 AP[0]: AHB-AP (IDR: 0x24770011)

T47A4 000:295.705 Iterating through AP map to find AHB-AP to use

T47A4 000:305.475 AP[0]: Core found

T47A4 000:305.499 AP[0]: AHB-AP ROM base: 0xE00FF000

T47A4 000:310.516 CPUID register: 0x410FC241. Implementer code: 0x41 (ARM)

T47A4 000:310.536 Found Cortex-M4 r0p1, Little endian.

T47A4 000:412.248 -- Max. mem block: 0x00002C18

T47A4 000:412.697 CPU_ReadMem(4 bytes @ 0xE000EDF0)

T47A4 000:413.283 CPU_WriteMem(4 bytes @ 0xE000EDF0)

T47A4 000:414.297 CPU_ReadMem(4 bytes @ 0xE0002000)

T47A4 000:415.240 FPUnit: 6 code (BP) slots and 2 literal slots

T47A4 000:415.247 CPU_ReadMem(4 bytes @ 0xE000EDFC)

T47A4 000:416.032 CPU_WriteMem(4 bytes @ 0xE000EDFC)

T47A4 000:416.778 CPU_ReadMem(4 bytes @ 0xE0001000)

T47A4 000:417.627 CPU_WriteMem(4 bytes @ 0xE0001000)

T47A4 000:418.364 CPU_ReadMem(4 bytes @ 0xE000ED88)

T47A4 000:419.092 CPU_WriteMem(4 bytes @ 0xE000ED88)

T47A4 000:420.015 CPU_ReadMem(4 bytes @ 0xE000ED88)

T47A4 000:421.009 CPU_WriteMem(4 bytes @ 0xE000ED88)

T47A4 000:421.923 CoreSight components:

T47A4 000:421.997 ROMTbl[0] @ E00FF000

T47A4 000:422.003 CPU_ReadMem(64 bytes @ 0xE00FF000)

T47A4 000:423.384 CPU_ReadMem(32 bytes @ 0xE000EFE0)

T47A4 000:424.420 ROMTbl0: E000E000, CID: B105E00D, PID: 000BB00C SCS-M7 T47A4 000:424.425 CPU_ReadMem(32 bytes @ 0xE0001FE0)

T47A4 000:425.456 ROMTbl0: E0001000, CID: B105E00D, PID: 003BB002 DWT

T47A4 000:425.471 CPU_ReadMem(32 bytes @ 0xE0002FE0)

T47A4 000:426.420 ROMTbl0: E0002000, CID: B105E00D, PID: 002BB003 FPB

T47A4 000:426.428 CPU_ReadMem(32 bytes @ 0xE0000FE0)

T47A4 000:427.597 ROMTbl0: E0000000, CID: B105E00D, PID: 003BB001 ITM

T47A4 000:427.662 CPU_ReadMem(32 bytes @ 0xE0040FE0)

T47A4 000:428.759 ROMTbl0: E0040000, CID: B105900D, PID: 000BB9A1 TPIU

T47A4 000:428.868 CPU is running

T47A4 000:428.875 CPU_WriteMem(4 bytes @ 0xE000EDF0)

T47A4 000:429.654 CPU is running

T47A4 000:429.709 CPU_WriteMem(4 bytes @ 0xE000EDFC)

T47A4 000:430.525 Reset: Halt core after reset via DEMCR.VC_CORERESET.

T47A4 000:431.541 Reset: Reset device via AIRCR.SYSRESETREQ.

T47A4 000:431.560 CPU is running

T47A4 000:431.571 CPU_WriteMem(4 bytes @ 0xE000ED0C)

T47A4 000:486.058 CPU_ReadMem(4 bytes @ 0xE000EDF0)

T47A4 000:486.763 CPU_ReadMem(4 bytes @ 0xE000EDF0)

T47A4 000:487.567 CPU is running

T47A4 000:487.577 CPU_WriteMem(4 bytes @ 0xE000EDF0)

T47A4 000:488.278 CPU is running

T47A4 000:488.290 CPU_WriteMem(4 bytes @ 0xE000EDFC)

T47A4 000:495.055 CPU_ReadMem(4 bytes @ 0xE000EDF0)

T47A4 000:499.878 CPU_WriteMem(4 bytes @ 0xE0002000)

T47A4 000:500.818 CPU_ReadMem(4 bytes @ 0xE000EDFC)

T47A4 000:501.757 CPU_ReadMem(4 bytes @ 0xE0001000)

T47A4 000:502.559 - 232.763ms

T47A4 000:502.573 JLINK_GetId()

T47A4 000:503.581 - 1.010ms returns 0x2BA01477 T47A4 000:508.670 JLINK_GetFirmwareString(...) T47A4 000:508.688 - 0.019ms T47A4 058:935.486 JLINK_SWO_Control(JLINKARM_SWO_CMD_GET_SPEED_INFO, ...)

.....

JLINK_SWO_Control(JLINKARM_SWO_CMD_GET_SPEED_INFO, ...)

T47A4 080:629.020 - 0.498ms returns 0x00 T47A4 083:195.488 JLINK_Close()

T47A4 083:196.154 CPU_ReadMem(4 bytes @ 0xE0001000)

T47A4 083:197.087 CPU_WriteMem(4 bytes @ 0xE0001000)

T47A4 083:197.834 CPU_WriteMem(4 bytes @ 0xE0001004)

T47A4 000:239.217 :可以看到JLink支持网络调试的。
T47A4 000:239.513:就是刚才将JLink信息写入到ini的那个文件。
T47A4 000:248.435:打开JLinkDevices.ref就是如下所示。

 C:\Keil_v5\ARM\Segger\JLinkDevices.ref是keil安装的JLink相关的部分,”C:\Program Files
(x86)\SEGGER\JLink\“是电脑上安装的JLink驱动的位置。这部分的内容就是配置好jlink的驱动,使用其下载镜像文件。

T47A4 000:248.537:是一个xml文件,打开之后会看到很多芯片的设置,我这里取一个stm32的芯片为例。

 打开之后是一堆设备标签。看名字就行了,很好理解,我们看看Loader指向的文件。打开文件夹,

 里面有一个Readme.txt文件,内容:

         各个elf文件其实根据Reame.txt的内容看,是QSPI FLASH的下载算法。JLink有一个JFlashSPI.exe的工具,猜测应该使用这个算法给SPI Flash下载程序的,elf文件是jlink的下载算法。

T47A4 000:267.466:从这里开始的一些之类就是获取各种信息了。
T47A4 000:271.663:获取了SW-DP的ID,这里已经能和芯片的SW-DP接口通信了。
T47A4 000:289.615:扫描各个AP接口。
T47A4 000:295.699:找到AHB-AP接口,这个就是用于和AHB总线通信的AP接口。
T47A4 000:305.499:这里显示AHB-AP ROM 的地址是0xE00FF000。这个地址前文说过,是ROM表的起始地址,用于检测调试系统有哪些哪些组件。
T47A4 000:412.697 :从这里开始,连续读写地址。0xE000EDF0搜索《M3权威指南》之后,是调试停机控制及状态寄存器。0xE0002000是FPB的基址。0xE000EDFC是调试监视器的地址,调试监视器用于断点,数据观察点,或者是外部调试请求。0xE0001000是DWT的基址。0xE000ED88未找到相关信息。
T47A4 000:422.003:从0xE00FF000地址读取了64个Byte的数据,刚好是ROMTbl的大小(4×4×4Byte = 64B)

我们分析下这个数据,取TPIU为例。将前文的图放到这里,方面查看。

TPIU相关的信息是:

T47A4 000:427.662 CPU_ReadMem(32 bytes @ 0xE0040FE0)
T47A4 000:428.759 ROMTbl[0][4]: E0040000, CID: B105900D, PID: 000BB9A1 TPIU

         从0xE0040FE0地址读取32B,读取到的内容第一个字(4B)就是E0040000,这个就是TPIU的地址。TPIU中文名是跟踪端口接口单元,用于将ITM, DWT和ETM的跟踪数据汇聚到TPIU处。TPIU用于把这些跟踪数据格式化并输出到片外,以供跟踪端口分析仪之类的设备接收使用。跟前文所述:ROM表记录调试相关组件信息相一致。

T47A4 000:428.875:0xE000EDF0地址在T47A4 000:412.697 已经说过了。
T47A4 000:431.571:0xE000ED0C是复位控制,是应用程序中断及复位控制寄存器的地址。之后的0xE0002000、0xE000EDFC、0xE0001000在前面都已经论述了。
T47A4 000:502.573:从这里开始就是SWD相关的了,获取SWD速度信息。
 

下面放的是跟下载镜像有关系日志,与上面的日志并不是同一次的,二者无关,博主写文章的时候,多次下载,有些没保存,这里特地说明下。

 T5324 000:386.354 JLINK_WriteMem(0xE0001000, 0x1C Bytes, ...)
T5324 000:386.358 Data: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ...
T5324 000:386.372 CPU_WriteMem(28 bytes @ 0xE0001000)
T5324 000:390.509 JLINK_WriteMem(0x20000000, 0x670 Bytes, ...)
T5324 000:390.517 Data: 00 BE 0A E0 0D 78 2D 06 68 40 08 24 40 00 00 D3 ...
T5324 000:390.720 CPU_WriteMem(1648 bytes @ 0x20000000)
T5324 000:527.583 JLINK_WriteMem(0x20000000, 0x670 Bytes, ...)
T5324 000:527.598 Data: 00 BE 0A E0 0D 78 2D 06 68 40 08 24 40 00 00 D3 ...
T5324 000:527.622 CPU_WriteMem(1648 bytes @ 0x20000000)
T5324 000:563.095 JLINK_WriteMem(0x20000670, 0x200 Bytes, ...)
T5324 000:563.106 Data: 88 08 00 20 D5 01 00 10 8B 0A 00 10 65 0A 00 10 ...
T5324 000:563.126 CPU_WriteMem(512 bytes @ 0x20000670)
.....
T5324 000:695.612 JLINK_WriteMem(0x20000670, 0x200 Bytes, ...)
T5324 000:695.618 Data: 72 74 20 0A 00 00 00 00 4F F0 40 70 E1 EE 10 0A ...
T5324 000:695.628 CPU_WriteMem(512 bytes @ 0x20000670)
T1A34 000:768.192 JLINK_WriteMem(0x20000000, 0x670 Bytes, ...)
T1A34 000:768.209 Data: 00 BE 0A E0 0D 78 2D 06 68 40 08 24 40 00 00 D3 ...
T1A34 000:768.232 CPU_WriteMem(1648 bytes @ 0x20000000)

T1A34 000:884.512 JLINK_WriteMem(0x20000000, 0x2 Bytes, ...)
T1A34 000:884.533 Data: FE E7
T1A34 000:884.552 CPU_WriteMem(2 bytes @ 0x20000000)

T5324 000:563.095:开始写入bin文件,按照512Byte写入(下面的图是使用二进制查看bin文件的)

可以看到,T5324 000:563.106 Data: 88 08 00 20 D5 01 00 10 8B 0A 00 10 65 0A 00 10 ...
Data数据刚好对应bin文件的开始16Byte。

T5324 000:695.612:写入bin文件的最后一个块(以512B为单位,不足512B的补0)

 查看MCU芯片手册的时候,发现上面对flash记载的是:以扇区为单位组织,每扇区512B,这里对上了。

T5324 000:695.618 Data: 72 74 20 0A 00 00 00 00 4F F0 40 70 E1 EE 10 0A ...中,对应最后一个扇区(C00行),很明显是不够512B的,进行补0操作。在keil中已经设置了擦除扇区,写不写0其实都不是很大的问题(猜测)。

 T5324 000:386.354 JLINK_WriteMem(0xE0001000, 0x1C Bytes, ...)
T5324 000:386.358 Data: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ...
T5324 000:386.372 CPU_WriteMem(28 bytes @ 0xE0001000)
T5324 000:390.509 JLINK_WriteMem(0x20000000, 0x670 Bytes, ...)
T5324 000:390.517 Data: 00 BE 0A E0 0D 78 2D 06 68 40 08 24 40 00 00 D3 ...
T5324 000:390.720 CPU_WriteMem(1648 bytes @ 0x20000000)

第一次写入28B,第二次写入1648B。这部分的日志是什么意思?第一次写入内容告诉芯片要开始写入程序了(猜测),第二次写入的就是flash算法文件,如下图。

至于flash下载文件是个什么东西,放到后面的文章介绍。

了解完JLink下载的过程之后,还有问题:JLink是如何知道该往哪里写入bin文件已经如何写入?
往哪里写很容易知道,在keil里面设置的有。

如何写入的过程我们放到下一篇文章中介绍。

猜你喜欢

转载自blog.csdn.net/zichuanning520/article/details/132252738