ARM Coresight DS-5 系列 4 - ARM Cortex-M DS-5 加载 ELF 文件运行

文章目录

      • 1.1.1 DS-5 工程创建
      • 1.1.2 DS-5 加载 ELF 脚本创建
      • 1.1.3 DS-5 脚本读写 Memory
      • 1.1.4 DS-5 扫描脚本

上篇文章:ARM Coresight DS-5 系列 3 - DS-5 断点设置及常用Debug 命令

1.1.1 DS-5 工程创建

在使用ARM DS-5 连接 board(或者PFGA)之前首先需要能够扫描到相应的硬件信息,比如对应的cpu的相关信息:coresight 相关组件信息,Cache信息等。

创建好工程项目后按照下图黄线的指示进行扫描操作(通常是完成扫描后才会去执行 “build platform”):
ARM Coresight DS-5 系列 4 - ARM Cortex-M DS-5 加载 ELF 文件运行_第1张图片

如果更换平台之后,最好先进行 clean platfom 操作,然后再重新 build platform 操作。

在扫描完成后在DS-5的console中会打印相关的信息,扫描完成后的操作是进行连接操作(见图 1-1)。

1.1.2 DS-5 加载 ELF 脚本创建

通常我们会使用uart或者SPI来烧写镜像到flash,然后再从flash启动,这个过程在实际的debug场景中比较耗时,尤其是当串行时钟比较低的时候。所以我们可以直接使用DS-5通过JTAG接口来烧写镜像到对应的 memory 中,然后再配置好 PC 指针,直接跳转过去既可以启动对应的固件。
ARM Coresight DS-5 系列 4 - ARM Cortex-M DS-5 加载 ELF 文件运行_第2张图片

图 1-1

上图 1-1 中对应的脚本代码如下:

# Filename: load_rtos_schan.py
 
import sys
import os
import time
from arm_ds.debugger_v1 import Debugger
from arm_ds.debugger_v1 import DebugException
 
debugger = Debugger()
ec = debugger.getCurrentExecutionContext()
#value = ec.getRegisterService().getValue('PC')
#print("The PC is %s" %value)

 # 下面是对对板子做reset 操作
os.system("D:\\demo\\USBRelay\\CommandApp_USBRelay.exe QAAMZ open 1")
os.system   ("D:\\demo\\USBRelay\\CommandApp_USBRelay.exe QAAMZ close 1")
time.sleep(1)
print ec.executeDSCommand('stop')
 
print ec.executeDSCommand("load X:\\demo_soc\\rtos\\rt-thread\\rt-thread\\bsp\\\\demo_soc\\demo_soc_fpga\\rtthread.elf")
print ec.executeDSCommand('run')

创建 rtos 加载脚本时需要注意以下几点:
1)需要先固件启动汇编部分的 data 段的 copy 部分 注释掉,因为 DS-5 去加载 elf 文件时会自动根据 elf 符号表data 段加载到对应的地址,例如我们当前是将 data 段放到 DTCM中的,再加载 elf 时 DS-5 会将 data 段数据 load 到对应的 DTCM 地址,所以再编译的时候就需要将启动汇编阶段的 data 段的 copy操作去掉。

2)为了保证硬件内容的 “干净”, 在执行 DS-5 脚本的时候会先进行SoC reset 操作,reset之后系统会自动从bootrom重启,DS-5接入,然后执行 stop 命令,再 load elf(会自动解析 entry point) ,然后再执行 run 命令即可。

bootrom中的代码主要时做循环检测外部接入信号

1.1.3 DS-5 脚本读写 Memory

以写读 0x48000000 地址为例,如下代码:

# Filename: load_rtos_schan.py
  
import sys
import os
import time
from arm_ds.debugger_v1 import Debugger
from arm_ds.debugger_v1 import DebugException
  
debugger = Debugger()
ec = debugger.getCurrentExecutionContext()
#value = ec.getRegisterService().getValue('PC')
#print("The PC is %s" %value)
  
os.system("D:\\demo\\USBRelay\\CommandApp_USBRelay.exe QAAMZ open 1")
os.system   ("D:\\demo\\USBRelay\\CommandApp_USBRelay.exe QAAMZ close 1")
time.sleep(1)
print ec.executeDSCommand('stop')
#ec.getExecutionService().stop()
 
  
print ec.executeDSCommand("load X:\\demo_soc\\rtos\\rt-thread\\rt-thread\\bsp\\demo\\demo_soc\\demo_soc_fpga\\rtthread.elf")
print ec.executeDSCommand('run')
#ec.getExecutionService().resetTarget()
 
print "######## read and write memory test #######"
#base_adr = 0x56020000
base_adr = 0x48000000
 
for i in range(0, 5):
    print('i=%d, addr=0x%x, default value:0x%x'  %(i, base_adr + i*4, ec.getMemoryService().readMemory32(base_adr + i*4, {})))
     
    if base_adr == 0x56020000: #ipcm source register
        value = 0x1
    else:
        value = i * 4
    ec.getMemoryService().writeMemory32(base_adr + i*4, value, {'width': 32, 'verify': 0})
    print('i=%d, addr=0x%x, write value:0x%x'  %(i, base_adr + i*4, ec.getMemoryService().readMemory32(base_adr + i*4, {})))
    #print ec.getMemoryService().readMemory32(base_adr + i*4, {})
    #ec.getExecutionService().resume()

对于 write only 外设寄存器地址需要加上 flag “verify=0” ,命令行的话可以使用 “memory set :0x46020004 32 1”

TIPS: "alt+/ " 调出 commands 栏 help命令说明
ARM Coresight DS-5 系列 4 - ARM Cortex-M DS-5 加载 ELF 文件运行_第3张图片

1.1.4 DS-5 扫描脚本

通常芯片回来后软件同学需要做的第一件事就是完成寄存器扫描,保证系统及各个IP的寄存器可以正常写读,通常会按照各个Subsystem进行扫描,一般情况下每个 IP 都少扫描1-2个寄存器,按照先写再读的方式进行扫描。
扫描脚本首先需要保证以下几点:

  • 各个模块供电正常;
  • 各个模块 clk 正常;
  • 在扫描过程中如果出现有的寄存器有问题可以先跳过。

下面给出了一个简单的DEMO, 该demo 使用的是Python 脚本完成的。

# Filename: DS5_Reg_Scan.py
    
import sys
import os
import time
from arm_ds.debugger_v1 import Debugger
from arm_ds.debugger_v1 import DebugException
    
debugger = Debugger()
ec = debugger.getCurrentExecutionContext()
#value = ec.getRegisterService().getValue('PC')
#print("The PC is %s" %value)
# TO DO: reset SoC     
time.sleep(1) # wait bootrom start
ec.executeDSCommand('stop')
  
def read32(addr):
    return ec.getMemoryService().readMemory32(addr)
  
def write32(addr, val):
     return ec.getMemoryService().writeMemory32(addr, val, {'width': 32, 'verify': 0})
  
demo_aon_subsystem = [
#       reg_adr         write_val       ip name
        0x66004000,     0x55,           "hrtimer0",
        0x66004014,     0x55,           "hrtimer1",
        0x66004028,     0x55,           "hrtimer2",
        ]
peri_subsys = [
#       reg_adr          write_val      ip name
        0x6c002004,      0xdf,          "uart0",
        0x60011010,      0x1,           "uar1",
        0x60009004,      0x11,          "spi1",
        0x60008000,      0x55,          "spi2",
        0x60008014,      0x55,          "spi3",
        0x60008028,      0x55,          "spi4",
        ]
        
def demo_subsys_scan(subsys, subsys_name, mode):
    ret = 0xdeadbeef
    list_len = len(subsys) / 3
    print("Total Registers:%d in %s" %(list_len, subsys_name))
     
    for i in range(0, int(list_len)):
        addr = subsys[i*3]
        val = subsys[i*3 + 1]
        name = subsys[i*3 + 2]
         
        try:
            write32(addr, val)
            if mode == 0: # write-only registers no check return value
                ret = read32(addr)
                if ret != val:
                    print("DS-5 Scan %s reg:0x%x failed!!!, read:0x%x" %(name, addr, ret))
                    if subsys_name == "demo_peri_subsystem" or subsys_name == "demo_aon_subsystem":
                        continue
                    else:
                        return -1
                # else if mode == 1:
                 
        except DebugException, e:
            print("Excetpion: DS-5 Scan %s reg:0x%x failed!!!, read:0x%x" %(name, addr, ret))
            if subsys_name == "demo_peri_subsystem" or subsys_name == "demo_aon_subsystem":
                continue
            else:
                return -1
  
    return 0
 
# demo_aon_subsystem scan
ret = demo_subsys_scan(demo_aon_subsystem, "demo_aon_subsystem", 0)
if ret == 0:
    print("#######  demo_aon_subsystem scan test finished ######\n")
else:
    print("demo_aon_subsystem scan failed !!!\n")
  
# peri_subsys scan
ret = demo_subsys_scan(peri_subsys, "demo_peri_subsystem", 0)
if ret == 0:
    print("#######  peri_subsys scan test finished ######\n")
else:
    print("demo_peri_subsystem scan failed !!!\n")

上篇文章:ARM Coresight DS-5 系列 3 - DS-5 断点设置及常用Debug 命令

你可能感兴趣的:(#,ARM,Coresight,DS-5,系列,arm开发,DS-5,DS5)