JLink访问双核CPU

我们知道随着半导体水平的进步,嵌入式微处理器(MCU)也在不断进步,人们对于智能化的需求越来越高,各种边缘计算的需求也越来越大,这个对于MCU的计算水平要求也越来越高。就是在这种背景下,MCU的设计也越来越复杂,现在很多厂商都开始退出双核甚至多核CPU了。

与一般ARM A核或者x86的多核架构不同,MCU的多核一般属于异构多核,也就是说MCU的核心属于不同类型的,比如一个Cortex M4核心和一个Cortex M0+核心,两个核心一般一个负责计算,另外一个负责低功耗,二者相辅相成。

伴随着MCU多核的产生,现在各种多核的调试技术也不断升级,比如IAR就有自己的调试器,可以直接支持双核调试,就是软件工具不怎么靠谱,最近总是崩溃,并且版本越新越容易崩溃。好了,就不吐槽这个了,换另外一家吐槽。

作为调试器的霸主,Jlink竟然不支持多核调试,这不得不说是一种遗憾呀。不过呢,研究过Jlink的一些资料之后,我发现,其实Jlink是可以支持多核调试的,只不过现在还是只能支持分时手动复用。下面我们就来看看基于Jlink的多核调试的一个步骤吧。

准备材料

  1. 多核开发板,这个当然是必须的
  2. Jlink调试器,支持正版,虽然巨贵无比,但是公司出钱,管他呢
  3. JLink软件,最好是6.3版本的,版本太低没研究过,版本太高没研究通😭

准备脚本

Jlink的多核试验是通过自定义初始化脚本实现的。我们知道ARM CoreSight调试时通过DP,AP实现的,而在多核设计中,每个核心都有一个对应的AP。Jlink自己初始化的时候也会去搜索AP,当找到一个有效的AP的时候就会直接连接里面的CORE,连接成功之后就不会继续往下寻找新的AP了,所以默认情况下我们只能找到一个主core.

为了干预这个自动寻找的过程,我们就需要自己定义一个脚本去修改,下面就是一个简单的脚本:

void SetupTarget(void)
{
  Report(" Release reset for CM0+");
  MEM_WriteU32(0x4002B094, 0xC0000000); //Enable MUA clk gate
  MEM_WriteU32(0x40025068, 0x00000004); //Set Boot From DFlash, Hold Reset
  MEM_WriteU32(0x40025068, 0x00000000); //Release Reset
}
/*********************************************************************
*
*       InitTarget
*/
void InitTarget(void) {
 
  Report("******************************************************");
  Report("J-Link script: Dual CORE Demo. J-Link script");
  Report("******************************************************");
  
  SetupTarget();
 
  CPU = CORTEX_M0;        // Pre-select that we have a Cortex-M0 connected
  JTAG_AllowTAPReset = 0; // J-Link is allowed to use a TAP reset for JTAG-chain auto-detection
 

  CORESIGHT_AddAP(0, CORESIGHT_AHB_AP);
  CORESIGHT_AddAP(1, CORESIGHT_AHB_AP);
  CORESIGHT_AddAP(2, CORESIGHT_AHB_AP);
  CORESIGHT_IndexAHBAPToUse = 2;    // Use second AP which is the AHB-AP for the core
}

上面就是一个简单的脚本,Jlink的脚本和C语言有些类似,并且支持变量和While循环等待,这个很高端的。脚本里面首先是通过写Memory的方式启动另外一个Cortex M0+的核,然后添加一系列AP,最后一句设置CORESIGHT_IndexAHBAPToUse这个变量非常重要,这个变量会让Jlink使用自定义的AP,比如这里Cortex M0+就是挂在AP2上,所以这里就可以直接通过指定AP2选择Cortex M0+核。

配置脚本

这次试验是在JLink Commander下面完成的,所以首先要打开JLink Commander工具,然后在系统托盘找到Jlink的图标,单击之后打开配置窗口进行设置,具体配置如下图所示:

JLINK配置

注意,这里JLINK的版本最好是选6.3和6.4版本的,版本低的工具没有这个配置选项,版本高一点的配置变成网页配置,还没找到相应的选项,所以还是推荐用图中一样的版本。

连接过程:

JLINK连接

尝试连接

配置完脚本之后,我们在打开的JlinkCommander中直接输入connect,这个时候Jlink就会根据我们自己定义的脚本去选择AP,并连接找到的CORE,比如Demo中我们可以得到如下的log信息:

Connecting to target via SWD
InitTarget() start
******************************************************
J-Link script: Dual CORE Demo. J-Link script
******************************************************
Release CM0
InitTarget() end
Found SW-DP with ID 0x6BA02477
AP map detection skipped. Manually configured AP map found.
AP[0]: AHB-AP (IDR: Not set)
AP[1]: AHB-AP (IDR: Not set)
AP[2]: AHB-AP (IDR: Not set)
AP[3]: AHB-AP (IDR: Not set)
AP[4]: AHB-AP (IDR: Not set)
AP[5]: AHB-AP (IDR: Not set)
AP[6]: AHB-AP (IDR: Not set)
AP[7]: AHB-AP (IDR: Not set)
AP[8]: AHB-AP (IDR: Not set)
AP[9]: AHB-AP (IDR: Not set)
AP[2]: Core found
AP[2]: AHB-AP ROM base: 0xF0002000
CPUID register: 0x410CC601. Implementer code: 0x41 (ARM)
Found Cortex-M0 r0p1, Little endian.
FPUnit: 4 code (BP) slots and 0 literal slots
CoreSight components:
ROMTbl[0] @ F0002000
ROMTbl[0][0]: F0000000, CID: B105900D, PID: 001BB932 MTB-M0+
ROMTbl[0][3]: F0001000, CID: B105900D, PID: 1008E000 MTBDWT
ROMTbl[0][4]: F0006000, CID: B105900D, PID: 000BB9A6 ???
ROMTbl[0][5]: E00FF000, CID: B105100D, PID: 000BB4C0 ROM Table
ROMTbl[1] @ E00FF000
ROMTbl[1][0]: E000E000, CID: B105E00D, PID: 000BB008 SCS
ROMTbl[1][6]: E0001000, CID: B105E00D, PID: 000BB00A DWT
ROMTbl[1][7]: E0002000, CID: B105E00D, PID: 000BB00B FPB
Release CM0
Cortex-M0 identified.
J-Link>

从log上可以看到,我们已经成功的连上了Cortex M0+的CORE了,这个时候就可以通过Loadbin等命令实现程序的下载和调试了,对于和IAR的集成,带我仔细研究过后再说吧。


本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。

相关文章

仅有 1 条评论
  1. njsolo

    请问一下,我看了一些例子,切换核需要使用CORESIGHT_CoreBaseAddr,请问该参数如何获取?为何您的切换方式不需要该参数呢?

    njsolo 回复
发表新评论取消回复