RealView Debugger的命令行接口(CLI)是嵌入式开发中调试ARM架构程序的重要工具。与图形界面相比,CLI提供了更高效的调试控制方式,特别适合需要自动化调试脚本或远程调试的场景。通过CLI,开发者可以完成断点设置、寄存器查看、内存修改等典型调试任务。
提示:CLI命令长度限制为4095字符,支持大小写混合输入,但需注意符号名称区分大小写。
每个CLI命令必须遵循特定语法结构:
code复制COMMAND [,qualifier | /flag] [parameter]...
典型命令示例:
bash复制BREAKINSTRUCTION /H main.c#32 ; 在main.c第32行设置半字断点
参数传递规则:
,FULL显示完整帮助/B指定字节操作调试输出可定向到不同窗口或文件,通过编号指定目标位置:
| 编号 | 目标类型 | 说明 |
|---|---|---|
| 1 | 代码窗口 | 默认输出位置,同时写入日志文件 |
| 20 | 标准I/O窗口 | 显示标准输入输出信息 |
| 28 | 日志文件 | 专用日志记录通道 |
| 29 | 日志文件 | 替代日志记录通道 |
| 50+ | 用户自定义窗口/文件 | 需先使用VOPEN命令创建 |
使用示例:
bash复制PRINTF "开始内存测试",20 # 输出到标准I/O窗口
FOPEN "debug_log.txt",50 # 创建自定义日志文件
RealView Debugger支持丰富的表达式类型,这些表达式可以用于条件断点、内存操作等场景:
典型表达式示例:
c复制*(int*)0x20000000 = 0xABCD1234 // 内存地址操作
counter >= 10 && flag == 1 // 条件判断
array[index] + offset // 数组元素访问
特殊符号引用:
@R15或@PC:程序计数器@CPSR_FLG:处理器状态标志位@module:当前模块名@procedure:当前函数名宏是自动化调试的强大工具,其定义语法类似C函数:
c复制DEFINE int memory_test(int base, int size)
{
int errors = 0;
$printf "Testing memory at 0x%x\n", base$;
for(int i=0; i<size; i++) {
char expected = i & 0xFF;
char *addr = (char*)(base + i);
*addr = expected;
if(*addr != expected) errors++;
}
return errors;
}
.
宏定义要点:
高级技巧:
/R选项覆盖已有宏定义$命令$;格式嵌入调试命令BREAKINSTRUCTION命令:
bash复制BREAKINSTRUCTION [qualifiers] address [;macro]
常用限定符:
,WHEN:{condition}:条件断点,MACRO:{macro_name}:触发时执行宏/B、/H、/W:指定断点大小典型应用场景:
bash复制# 在main函数入口设置条件断点
BREAKINSTRUCTION,WHEN:{argc>1} main\@entry
# 访问特定内存时触发断点
BREAKREAD 0x1000..0x1010 /W
FILL命令内存填充示例:
bash复制FILL 0x20000000..0x20001000 0x00 # 填充内存区域
内存查看技巧:
bash复制# 以不同格式查看内存
PRINTVALUE /F float 0x20000000 # 浮点数格式
PRINTVALUE /X 0x20000000 # 十六进制格式
读取和修改寄存器:
bash复制PRINTVALUE @R0 # 查看R0寄存器
@R0 = 0x12345678 # 修改R0值
@CPSR_FLG = 0xF0000000 # 修改状态标志位
特殊寄存器访问:
bash复制# 访问不同模式下的寄存器
PRINTVALUE @R13_IRQ # IRQ模式下的SP
PRINTVALUE @SPSR_SVC # SVC模式的SPSR
问题1:断点无法触发
问题2:符号无法解析
@root\module\symbol@"!unusual_symbol"问题3:宏执行错误
$command$;结合宏和条件断点,可以构建自动化测试框架:
c复制DEFINE int run_test_suite()
{
$load "test.axf"$;
$breakinstruction,macro:{check_result} test_entry$;
$go$;
return @test_status;
}
.
利用周期计数器和断点进行性能分析:
c复制DEFINE void profile_function(char *func_name)
{
$add unsigned long start_cycles, end_cycles$;
$breakinstruction,macro:{start_cycles=@cycle} func_name\@entry$;
$breakinstruction,macro:{end_cycles=@cycle} func_name\@exit$;
$go$;
$printf "Function %s took %d cycles\n", func_name, end_cycles-start_cycles$;
}
.
在实际项目中,我发现将常用调试流程封装成宏可以显著提高效率。例如,内存测试宏可以重复用于不同项目,只需调整基地址和大小参数。对于复杂调试场景,建议将相关宏组织在单独的include文件中,通过INCLUDE命令加载:
bash复制INCLUDE "debug_utils.inc"
调试ARM架构程序时,理解处理器状态寄存器(CPSR)的各个标志位至关重要。通过@CPSR_FLG可以快速检查或修改NZCV标志,这在调试条件执行指令时特别有用。此外,不同处理器模式下的寄存器组访问(如@R13_IRQ)是调试中断处理程序的关键。