> 文章列表 > 【ARM Cortex-M7 使用 Python 脚本通过 J-link 烧录 bin 文件 】

【ARM Cortex-M7 使用 Python 脚本通过 J-link 烧录 bin 文件 】

【ARM Cortex-M7 使用 Python 脚本通过 J-link 烧录 bin 文件 】

文章目录

    • 简介
      • 1.1.1 J-link 信息扫描
      • 1.1.2 j-link 烧写脚本

简介

固件烧录有很多方式,比如 uart, usb, spi等,这里主要介绍的是 Cortex-M7 的J-link的烧写方式,J-link debuger 通过 DAP 可以访问 SoC 中 memory-maped 地址,所以可以通过 j-link 读写 SoC 中的地址来完成镜像的烧写。

一般的烧写都是烧写 xxx.img(rt-thread.bin) 固件,通常来说 img 固件是在 二进制 bin 文件的基础上加了一个 header 而已,这个 header 里面包含了一些信息,比如 固件的大小,固件运行的平台架构(ARM/X86/Power PC)及 OS(RTOS/Linux...),固件的 load 地址运行地址等。

bin 文件的产生是来自于 elf 文件,通常使用 gcc 编译出来最原始的可执行文件是 elf 文件,由于 elf 文件里包含了需要 debug 信息及一些 基本上用不到的信息,所以会将 elf 文件通过 一些命令将(objcopy)进行删减,删减之后剩余的部分就是 bin文件了。

通常 elf 文件到 bin 再到 img 文件都是在编译脚本里做好的,有时还会对 img 进行加密操作,用来做安全启动使用。

1.1.1 J-link 信息扫描

J-link 自带 loadbin 命令,也即直接 load 二进制文件,在执行下图中的"USB" 命令之前需要先把板子上电然后连接上 j-link, 连上 j-link 之后执行 usb 命令可以自动完成对 cortex-m7 的扫描,从下面打印的信息可以看到扫描出来的内容主要是 Coresight 中的一些组件,比如 DWT/FPB/ITM/ETM/CTI等,还有 Cache 的信息。
在这里插入图片描述

1.1.2 j-link 烧写脚本

import os
import time
# import subprocesscmd= 'C:\\\\Users\\\\admin\\\\Desktop\\\\USBRelay\\\\CommandApp_USBRelay.exe QAAMZ open  1'
p=os.popen(cmd)
time.sleep(1)
cmd= 'C:\\\\Users\\\\admin\\\\Desktop\\\\USBRelay\\\\CommandApp_USBRelay.exe QAAMZ close  1'
p=os.popen(cmd)# read rtthread.bin and get the entry point
img_path=r"X:\\demo_test\\rtos\\rt-thread\\rt-thread\\bsp\\demo\\demo_test\\demo_test_fpga\\rtthread.bin"
with open(img_path, 'rb') as f:f.seek(4,0)   # seek entry point positionfirstline = f.read(4)#print(firstline)#print('entry point: %x%x%x%x' %(firstline[3],firstline[2],firstline[1],firstline[0]))ep_int=int(firstline[3])<<24 | int(firstline[2])<<16 | int(firstline[1])<<8 | int(firstline[0])ep_hex=hex(ep_int)print(ep_hex)f.close()# create jlink download script
current_path = os.getcwd()
with open(current_path + '/' + 'rtos_download.jlink', 'w', encoding='utf-8') as f:f.write('r'+'\\n') # reset socf.write('h'+'\\n') # stop cpuf.write('power off mpu'+'\\n') # disable mpuf.write('speed 50000'+'\\n') #check jtag speedf.write('loadbin X:\\\\demo_test\\\\rtos\\\\rt-thread\\\\rt-thread\\\\bsp\\\\demo\\\\demo_test\\\\demo_test_fpga\\\\rtthread.bin, 0x0'+'\\n')f.write('setpc ' + ep_hex +'\\n')f.write('g'+'\\n')f.write('exit'+'\\n')f.close# run jlink download script    
time.sleep(1)
cmd="jlink.exe D:\\\\zhushiqiang\\\\jlink_download\\\\rtos_download.jlink"
p=os.popen(cmd)
#print("p.read(): {}\\n".format(p.read()))

上面python脚本主要包含以下内容:

  • 对板子进行reset 操作,这里使用的是工具 CommandApp_USBRelay 来通过继电器来对 板子机型 reset操作,也可以通过写 SoC 的reset 寄存器来进行reset 操作, 这里做 reset 的作用主要是保证一个干净的环境;
  • 通过python脚本获取编译出来的镜像的 entry_point 的值,后面通过设置PC的值为 entry_point的值即可启动 rtos 镜像;
  • 通过python创建 烧写脚本 rtos_download.jlink, 该脚本中的主要内容包含:
    • 使用 jlink “r” 命令来 reset cpu;
    • 使用 jlink “h” 命令来stop cpu(halt cpu);
    • 关掉 mpu,因为有时 在bootloader 阶段会对使用 MPU 来限制某些内存的访问,这样有可能导致 cpu 无法从从被限制的内存中获取所要执行的code 或者数据,需要注意的是 “power off mpu” 这条命令有可能无效,这个时候需要单独使用 “w4” 来写 mpu 的寄存器disable mpu功能;
    • 配置 j-link的传输速率;
    • 使用 loadbin 命令将 rt-thread.bin load到 0x0 地址处,具体 load 到哪个位置还需要根据链接脚本中的配置来配置;
    • 配置 PC的值为 entry_point的值;
    • 执行 go 命令 开始 run。

在 j-link 脚本开发好后,就可以执行该脚本进行烧录来运行 rtos了。