2. 使用断点进行程序暂停与单步执行

任务定义

在CCS(Code Composer Studio)中对C2000系列DSP程序实施断点调试,实现程序在指定位置暂停、随后以单步方式逐指令执行,并观察CPU寄存器与局部变量在每一步的变化。本案例以TI官方例程blinky为基础工程,在LED翻转语句处设置断点,验证暂停与单步功能。

调试原理与观测点

C2000内核(C28x)支持硬件断点,通过CCS调试接口写入断点地址。程序运行到断点地址时,CPU暂停并进入调试状态,此时可读取寄存器、内存与变量。单步执行分为汇编级单步(每次执行一条指令)与源码级单步(每次执行一行C语句)。本案例使用源码级单步,观测ledCounter变量与PC(程序计数器)寄存器。

断点暂停与单步执行调试流程 CCS调试器 C28x CPU JTAG/cJTAG ① 设置断点 (blinky.c: 第42行) ② 点击 Resume (F8) 运行至断点 ③ 点击 Step Over (F6) 单步执行C语句 ④ 观察变量/寄存器 ledCounter, PC, SP 程序暂停 PC = 断点地址 执行LED翻转 GPIO32 电平变化 执行ledCounter++ 变量值+1 等待下一条指令 PC 指向下一行 验证点:每次单步后ledCounter递增1

工程准备与代码

在CCS中导入C2000Ware的blinky例程(路径:C2000Ware_x_xx_xx_xx/device_support/f28004x/examples/blinky),编译生成.out文件。核心代码如下:

// blinky.c — 断点调试目标代码(节选)
#include "F28004x_Device.h"
#include "F28004x_Examples.h"

volatile uint32_t ledCounter = 0;   // 全局变量,用于观测

void main(void)
{
    // 初始化设备与GPIO(略,保持例程原样)
    InitSysCtrl();
    InitGpio();
    GPIO_SetupPinMux(32, GPIO_MUX_CPU1, 0);
    GPIO_SetupPinOptions(32, GPIO_OUTPUT, GPIO_PUSH_PULL);

    while(1)
    {
        GPIO_WritePin(32, 1);        // 行A:LED亮
        ledCounter++;                // 行B:计数器+1
        DEVICE_DELAY_US(500000);     // 延时500ms
        GPIO_WritePin(32, 0);        // 行C:LED灭
        ledCounter++;                // 行D:计数器+1
        DEVICE_DELAY_US(500000);
    }
}

断点设置与单步操作步骤

  1. 设置断点:在CCS编辑器中,双击GPIO_WritePin(32, 1);所在行的左侧灰色边栏,出现蓝色圆点即断点已启用。
  2. 启动调试会话:点击Debug按钮(或按F11),CCS将程序下载至目标板并停在main()入口。
  3. 运行至断点:按F8(Resume),程序全速运行,遇到断点后暂停,当前行高亮显示。
  4. 单步执行:按F6(Step Over)执行当前行,每按一次执行一条C语句,高亮行移至下一行。
  5. 观测变量:在Expressions窗口中添加ledCounter与PC寄存器,每次单步后记录其值变化。

验证方法与判定标准

按以下步骤验证调试功能正常:

  • 断点暂停验证:程序运行后应停在断点行(GPIO_WritePin(32, 1);),此时PC寄存器指向该行对应的程序地址,LED保持当前状态不变。
  • 单步执行验证:连续按F6四次,观察ledCounter变量。预期每次执行ledCounter++后变量值增加1,且LED状态在GPIO_WritePin行执行后发生翻转(可通过开发板LED灯或CCS的GPIO寄存器视图确认)。
  • 判定标准:若程序能在断点处稳定暂停,且每按一次F6仅执行一条C语句、ledCounter按预期递增,则判定断点与单步功能验证通过。

预期观测结果

假设初始ledCounter = 0,断点位于GPIO_WritePin(32, 1)行。按F8运行至断点后,按F6单步,观测序列如下:

步骤    执行行                     ledCounter值    PC指向
初始    停在断点(GPIO_WritePin)    0              blinky.c:42
F6#1    GPIO_WritePin(32,1)       0              blinky.c:43
F6#2    ledCounter++               1              blinky.c:44
F6#3    DEVICE_DELAY_US(500000)    1              blinky.c:45
F6#4    GPIO_WritePin(32,0)        1              blinky.c:46
F6#5    ledCounter++               2              blinky.c:47

以上为基于代码逻辑的预期值,实际调试时以CCS观测窗口显示为准。