【ARM Trace32(劳特巴赫) 使用介绍 2.1 -- TRACE32 Practice 脚本 cmm 脚本学习】

请阅读【ARM Coresight SoC-400/SoC-600 专栏导读】

上篇文章【ARM Trace32(劳特巴赫) 使用介绍 2 - Veloce 环境中使用trace32 连接 Cortex-M33】
下篇文章【ARM Trace32(劳特巴赫) 使用介绍 2.2 -- TRACE32 进阶命令之 DIAG 弹框命令】

文章目录

  • [1. TRACE32 Practice 语法](#1. TRACE32 Practice 语法)
    • [1.1 脚本变量申明](#1.1 脚本变量申明)
      • [1.1.1 本地变量申明:](#1.1.1 本地变量申明:)
      • [1.1.2 全局变量申明:](#1.1.2 全局变量申明:)
      • [1.1.3 常量](#1.1.3 常量)
    • [1.2 Trace32 循环语句](#1.2 Trace32 循环语句)
      • [1.2.1 While](#1.2.1 While)
      • [1.2.2 Repeat](#1.2.2 Repeat)
      • [1.2.3 Repeat While](#1.2.3 Repeat While)
    • [1.2 Trace32 条件判断](#1.2 Trace32 条件判断)
      • [1.3.1 IF ELSE 条件判断](#1.3.1 IF ELSE 条件判断)
    • [1.4 Trace32 跳转语句](#1.4 Trace32 跳转语句)
      • [1.4.1 GOTO](#1.4.1 GOTO)
      • [1.4.2 JUMPTO](#1.4.2 JUMPTO)

1. TRACE32 Practice 语法

Practice脚本是Lauterbach公司提供的一种脚本语言,运用于其TRACE32软件当中,非常容易上手、并且功能强大。其运用的主要领域包含:

  • 自动化测试
  • 创建图形化界面的工具
  • 初始化和配置TRACE32软件
  • 控制Lauterbach硬件

1.1 脚本变量申明

Practice脚本中的变量(Variable)被称为(Marco),其本质就是存储于内存中的字符串,与C语言中的宏不同,Practice脚本中的宏随时可以被创建和修改。且根据作用域的不同,其又被进一步分为三类: 本地宏,私有宏,全局宏:

  • 本地宏 (Local Marco)
    在代码块(block)中存在,离开代码块时被擦除。本地宏在它的代码块、子代码块、子函数、子脚本中可见。
  • 私有宏 (Private Marco)
    仅在声明它的代码块和子代码块中可见。
  • 全局宏 (Global Marco)
    全局可见,并且声明它的代码块终止后也不会被擦除。

1.1.1 本地变量申明:

csharp 复制代码
 LOCAL &a &b &c //关健字为LOCAL, 变量以 "&" 开头
 ENTRY &a &b
 &c=&a*&b
 RETURN &c

1.1.2 全局变量申明:

cpp 复制代码
 GLOBAL &State &Level //关健字为 GLOBAL,变量以"&"开头

1.1.3 常量

Practice脚本中支持多种常量类型:

十进制 128.

浮点型 128.0369.36

十六进制 0xA5A5

二进制 0b0010

比特掩码 0y10xx0

布尔型 TRUE()FALSE()

字符串 "hello world"

字符 'z'

地址 P:0x100

带段信息的地址 P:0x02:0x100

地址范围 P:0x100--0x1ffP:0x100++0x0f

高级语言的符号表 'main'

声明、初始化宏都很简单,下面是个简单的例子,先声明,再初始化。注意在初始化宏的时候,宏名称和等号之间不能有空格,等号后面允许有空格。

csharp 复制代码
GLOBAL  &ChipVersion
LOCAL  &msg1
PRIVATE &val1 &val2

&ChipVersion= "ES1"
&msg1=  "Hello World!"
&val1=  0xAA55
&val2=  128.

1.2 Trace32 循环语句

在 practice 脚本中,常见的循环有while、repeat、以及这两种的组合。

1.2.1 While

在限定条件下,重复执行一个代码段

c 复制代码
WHILE <condition>		Execute <block> while <condition> is true.
(
	<block>				<condition> has to be specified in TRACE32 syntax.
)
csharp 复制代码
AREA.view
PRIVATE &i
&i=0.
WHILE &i<10. ;Loop while &i is smaller 10
(
    PRINT "Count: " &i
    &i=&i+1.
)
ENDDO

执行结果

1.2.2 Repeat

按照给定的次数,重复执行一个代码段。

语法1

cpp 复制代码
RePeaT <count> <command> 		Repeat <command> <count>-times.

示例1

csharp 复制代码
;Example 1
;Print the character X 5 times
AREA.view
RePeaT 5. PRINT "hello world"

执行结果

语法 2

c++ 复制代码
RePeaT <count>					Repeat <block> <count>-times.
(
	<block>
)

示例1

每 200ms 打印一个"*"

cpp 复制代码
;Example 2
AREA.view
RePeaT 10.
(
	PRINT %CONTinue "*"
	WAIT 200.ms
)

结果如下

示例2

csharp 复制代码
;Example 2
Var.Break.Set flags /Write 		//Set a Write breakpoint to array
								//flags
;Repeat the following 10 times
;Start the program and wait until the target halts at the breakpoint.
;Then export the contents of array flags to file flags_export.csv in CSV
;format.
RePeaT 10.
(
	Go
	WAIT !STATE.RUN()
	Var.EXPORT "flags_export.csv" flags /Append
)

1.2.3 Repeat While

类似 C 语言中的 do-while 循环

csharp 复制代码
;Example 3
;Read a line from my_strings.txt
;Write not-empty lines to file my_strings_noempty.txt

PRIVATE &CurrentLine &RightLine
OPEN #1 my_strings.txt /Read
OPEN #2 my_strings_noempty.txt /Create
AREA.view
RePeaT
(
	READ #1 %LINE &CurrentLine
	IF (!FILE.EOFLASTREAD()&&("&CurrentLine"!=""))
	WRITE #2 "&CurrentLine"
)
WHILE !FILE.EOFLASTREAD()
CLOSE #1
CLOSE #2

1.2 Trace32 条件判断

1.3.1 IF ELSE 条件判断

Practice 脚本中的条件判断是依赖 IF ELSE 语句来完成的。

  • IF ELSE 和其后的条件语句之间要有至少一个空格;
  • 条件语句本身可以用圆括号包裹,也可不用;
  • IF ELSE 所条件执行的代码段必须使用圆括号包裹,注意这时圆括号必须位于独立的一行。

语法如下

clike 复制代码
IF <condition>
(
	<if_block>
)
ELSE
(
	<else_block>
)

示例1

Trace32 关健字不区分大小写,也可以是 if else

csharp 复制代码
AREA.view
PRINT "IF ELSE Ttest"

IF "a"=="a"
(
  PRINT "true"
)
ELSE IF "a"=="b"
(
  PRINT "false"
)
ELSE
(
  PRINT "这里不会运行(test)"
)

运行结果

Trace32 里面没有 then 关健字,多行语句请使用括号"()"括起来。

示例 2

cpp 复制代码
// Script double_if.cmm
PRIVATE &testfunc &correct_result
OPEN #1 "func_test.txt" /READ

WHILE TRUE()
(
	READ #1 &testfunc &correct_result
	IF "&testfunc"!=""
	(
		IF Var.VALUE(&testfunc)==&correct_result
		(
			APPEND "test_protocol.txt"\
			FORMAT.STRing("&testfunc=&correct_result",50.,' ')\
			FORMAT.UnixTime("c",DATE.UnixTime(),DATE.utcOffSet())
		)
		ELSE
		(
			PRIVATE &result
			&result=CONVert.HEXTOINT(Var.VALUE(&testfunc))
			APPEND "test_protocol.txt"\
			FORMAT.STRing("&testfunc failed with &result (&correct_result)",50.,' ')\
			FORMAT.UnixTime("c",DATE.UnixTime(),DATE.utcOffSet())
		)
	)
	ELSE
	(
		CLOSE #1
		ENDDO
	)
)
ENDDO

如果一行字符太长可以使用换行符 "\"。

1.4 Trace32 跳转语句

利用GOSUB、GOTO和JUMPTO指令可以完成脚本内的跳转。

1.4.1 GOTO

语法:

csharp 复制代码
GOTO <label> 					Continue PRACTICE script at <label>.
								<label> must be part of the currently executing script.

示例

csharp 复制代码
GOTO 88. 				 ;跳转至当前脚本文件第88行
csharp 复制代码
AREA.view
GOTO print_hello

print_hello:
	PRINT "hello world !"
ENDDO

运行结果

1.4.2 JUMPTO

csharp 复制代码
JUMPTO <label> 			Continue PRACTICE script at <label>.
						<label> must be part of a script that is currently located on the
						PRACTICE stack. <label> must not be located in a block.

示例

csharp 复制代码
AREA.view

PRINT "test start..."
GOTO jumpto_test

PRINT "jumpto test failed!"

jumpto_test:
	PRINT "jumpto test success!"
ENDDO

运行结果

上篇文章【ARM Trace32(劳特巴赫) 使用介绍 2 - Veloce 环境中使用trace32 连接 Cortex-M33】
下篇文章【ARM Trace32(劳特巴赫) 使用介绍 2.2 -- TRACE32 进阶命令之 DIAG 弹框命令】

推荐阅读
https://blog.csdn.net/thanklife/article/details/119608383
https://blog.csdn.net/goodlinux/article/details/6736418
https://zhuanlan.zhihu.com/p/37827150