历史上的今天
返回首页

历史上的今天

今天是:2025年04月19日(星期六)

2020年04月19日 | STM32 使用 Keil MDK 中的软件逻辑分析仪参与硬件调试

2020-04-19 来源:eefocus

这篇文章翻译自 ARM Keil Application Note 230 (1.2版)的前半部分。其中包括 STM32F4 处理器在 Keil MDK 中进行断点调试、变量实时观察,及逻辑分析仪参与硬件调试的实验。

原文使用的是 STM32F4-Discovery 开发板,我这里都改用 NUCLEO-F401RE 实现了。Discovery 板卡在新版本的 Pack Installer 中已没有 Blinky 例程支持,可以用 CMSIS-RTOS Blinky 来做,变量定义的位置等会有变化。

http://www.keil.com/appnotes/docs/apnt_261.asp。

Keil 网站上有 MDK 5 的 Legacy 支持软件,安装之后可以在 MDK 5 中使用 MDK 4 的工程,而不需要任何的 Software Pack。

我们建议使用 MDK 5.10 Software Pack,本文会持续跟进新的版本(译者注:并没有>_<,我在用5.17,如有区别会注明)。

Keil 针对各种 STM32 处理器有许多类似的实验手册,比如 CAN 的使用。详见www.keil.com/st。

这篇文档针对 MDK 5.10 及更新版本。

www.keil.com/mdk5/install Download MDK-Core

  • 将 MDK 安装到默认路径。安装到其他路径也是可以的,本教程会以默认路径为例:C:Keil_v5。

  • 本教程使用C:MDK做为例程目录,建议同样使用这个默认路径。

  • 如果 MDK 安装在其他路径,实验中需要做对应的路径修改。

  • (译者注:原文没有5,P.S. 上面这一段真贫)

  • Keil 网站上可以找到 DSP5 例程。

  • 这个实验可以用评估版本(MDK-Lite)来完成,不需要购买授权。

  • 不需要额外的调试器,只需准备 NUCLEO-F401RE 开发板、USB 线,以及在电脑上安装 MDK 5.10 就可以了(译者注:原文使用的是 STM32F4-Discovery 开发板)。

  • http://www.keil.com/appnotes/docs/apnt_230.asp。

    http://www.keil.com/mdk5/。

    http://www.keil.com/appnotes/docs/apnt_230.asp 上获得例程的 zip 文件。

  • 解压缩到 C:MDKBoardsSTSTM32F4-Discovery。(译者注:这个程序是对 Discovery 开发板的。)

  • 7) 测试 ST-Link V2 的连接

    1. 用 USB 线将 NUCLEO 开发板连接到电脑上。

    2. 如果 ST-Link USB 驱动程序安装正确,应该可以听到正常的 USB 设备连接的系统声音。否则需要根据下一章的指示,手动安装驱动程序。

    3. 两个红色 LED 应该点亮:LD1 (COM)和 LD3(PWR)。

    4. 启动 μVision Keil图标 并选择 Project/Open Project。

    5. 选择 Blinky 工程 C:MDKBoardsSTNUCLEO-F401REBlinkyBlinky.uvprojx。

    6. 在这个地方选择 STM32F401 Flash:Project Option

    7. 点击 Target Options Target Options 或者按 ALT+F7,并选择 Debug 选项卡:
      Debugger Selection

    8. 点击 Settings,会出现下面所示的窗口。如果显示出了 IDCODE 和 Device Name,说明 ST-Link 工作良好,可以继续下面的教程。点击两次 OK 返回 μVision 主界面。
      Target Setup

    9. 上图中 Serial Number 框里出现一串数字说明 ST-Link 调试器已经连接到了 μVision。

    10. 如果 SW Device 框中没有显示,或者显示 error,这个问题在继续本教程之前必须要解决。请参照下一节内容:安装 ST-Link USB 驱动程序。

    11. 如果已经显示正常,ST-Link USB 驱动程序安装良好。点击两次 OK 退出 Target Options 窗口并从第9章继续。

    提示:在上图 Port 框中选择 JTAG,然后在选回 SW,可以刷新 SW Device 框的显示。也可以关闭再重新打开这个窗口。

    提示:ST-Link V2 和 ST-Link 的主要区别是添加了 Serial Wire Viewer (SWV) 跟踪功能。

    8) 安装 ST-Link USB 驱动程序

    如果上面的测试没有问题,则不需要进行这一步。

    安装 ST-Link USB 驱动程序:(当上面的测试没有通过时)

    1. 先断开 NUCLEO 开发板和电脑之间的 USB 连接。

    2. 需要手动运行 stlink_winusb_install.bat 来安装 USB 驱动,这个文件存放在 C:Keil_v5ARMSTLinkUSBDriver 中。找到这个文件并双击来安装驱动程序。

    3. 连接 NUCLEO 的 USB,USB 驱动程序应该会以正常的方式安装完毕。

    重要提示:ST-Link V2 固件升级程序 ST-LinkUpgrade.exe 存放在 C:Keil_v5ARMSTLink。如果要更新 ST-Link 固件,找到并双击这个程序,操作还是比较简单的,程序会检查并报告当前的固件版本。请注意我们需要使用 V2.J16.S0 或更高的版本来支持 SWV 操作。另外不要使用 V2.J19.S0,这一版本与最新版驱动程序不兼容。
    (译者注:V2.J19.S0 不兼容估计是个历史问题,我已经在用 MDK 5.17 和 V2.J24.M11 版本了。)

    COM LED LD1 的含义:

    LED 红色闪烁:电脑开始 USB 枚举,但还未完成。
    LED 红色:电脑和 ST-LINK/V2 之间已经建立连接(枚举结束),但 μVision 还没有连接到 ST-Link (比如 Debug 模式)。
    LED 绿色:μVision 以 Debug 模式连接到 ST-Link,上一个通信是成功的。
    LED 红色、绿色间隔闪烁:μVision 和目标之间正在交换数据。
    LED 熄灭,但当进入 Debug 模式或点击 RUN 时闪烁一下:μVision 的 SWV 跟踪已启动。
    LED 熄灭:ST-LINK/V2 与目标 MCU 或 μVision 之间的连接失败,需要重新连接电源以重启开发板。

    9) 使用 NUCLEO 开发板运行 Blinky 例程

    我们将使用板载 ST-Link V2 调试器连接 Keil MDK 开发平台和真实的目标硬件。

    1. 点击桌面图标 Keil图标 启动 μVision,用 USB 线将 NUCLEO 开发板的 CN1 连接到电脑上。

    2. 选择 Project/Open Project,打开文件 C:MDKBoardsSTNUCLEO-F401REBlinkyBlinky.uvprojx。

    3. ST-Link 会默认被选择。第一次运行 μVision 和 NUCLEO 开发板的时候,可能需要安装 USB 驱动程序,详见上面章节。

    4. 点击 Rebuild 图标 Rebuild 编译源文件。也可以用旁边的 Build 图标 Build

    5. 点击 Load 图标 Load 对 STM32 的 flash 进行编程。Output 窗口中会显示这个过程。

    6. 点击 Debug 图标 Debug 进入 Debug 模式,如果出现 Evaluation Mode 对话框,点击 OK。
      注意: 当下载到 flash 时才需要使用 Load 图标,如果选择的是 RAM 运行则不需要。

    7. 点击 RUN 图标 RUN。注意:点击 STOP 图标 STOP 可以停止程序运行。

    NUCLEO 开发板上的绿色 LED 会开始闪烁。
    按下开发板上蓝色的 USER 按键会暂停闪烁。

    至此你已经了解如何编译工程、下载到 STM32 处理器的 flash 中、运行并停止程序!

    注意: Blinky 程序已经永久的烧写到 flash 中了,开发板可以独立运行这个程序,直到下一次被烧写。

    10) 硬件断点

    STM32F4 共有六个硬件断点,可以在程序运行过程中随时设置或取消。

    1. 在 Blinky 程序运行过程中,打开 Blinky.c 文件,点击 main() 函数中 for 循环里的某一行左侧边缘深灰色区域。

    2. 会出现一个红色的圆形标志,程序会停止运行。

    3. 请注意断点同时显示在源代码窗口和反汇编窗口,如下图。
      断点

    4. 不论是反汇编窗口还是源代码窗口,左侧边缘显示深灰色方形的区域表示这些代码行存在汇编指令,可以在这里设置断点。

    5. 每次点击 RUN 图标 RUN,程序会运行到下一次遇到断点。

    6. 可以尝试点击 Single Step(Step In)Step In 、Step OverStep Over 和 Step OutStep Out 。

    提示: 如果单步调试(Step In)不工作,点击 Disassembly 窗口使它成为焦点,可能需要点击一行反汇编代码。这样操作表示想要汇编级别的单步运行,而不是 C 语言代码级别。

    提示: ARM CoreSight 的断点是 no-skid 的,硬件断点发生在被设置断点的指令执行之前(译者注:有 skid 的断点的意思是,程序停止在断点设置的指令甚至后面几个指令执行之后)。另外 flash 中烧写的指令不会被替代或修改,这的特性对于高效率软件开发有重要意义。

    完成这个实验后,再次点击这些断点以删除它们,为后面的实验做准备。

    提示: 可以通过点击断点,或者选择 Debug/Breakpoints(或按 Ctrl+B)并选择 Kill All 来删除。

    提示: 可以通过选择 Debug/Breakpoints 或按 Ctrl+B 来查看所有断点的设置。

    11) Call Stack + Locals 窗口

    局部变量

    Call Stack + Locals 窗口被合并在一个集成窗口中,每当程序停止时会显示调用栈和当前函数的所有局部变量。

    如果可能,局部变量的值会显示,否则显示 < not in scope >。菜单中的 View/Call Stack Window 用来切换 Call Stack + Locals 窗口显示或隐藏。

    1. 运行并停止 Blinky,点击 Call Stack + Locals 选项卡。

    2. 下图展示了Call Stack + Locals 窗口。
      Call Stack + Locals
      窗口中显示了当前活动函数的名称和局部变量列表。随同每个函数的名字会显示它被哪个函数或中断/异常调用。
      当函数退出时,会从列表上移除。
      最早调用的函数会出现在列表的底端。
      这个列表只有在程序停止运行时有效。

    3. 点击 Step In 图标 Step In 或按 F11 键。

    4. 当单步运行到不同的函数时,观察它们在窗口上显示的变化。如果陷入到 Delay 函数的循环当中,可以用 Step Out Step Out 或 Ctrl+F11 键快速退出。

    5. 点击几次 Step In,观察其他函数。

    6. 右键点击一个函数名,尝试 Show Callee Code 和 Show Caller Code 选项。
      Right Click Function Name

    7. 点击 Step Out 图标 Step Out 退出所有函数,返回 main()。

    提示: 如果单步调试(Step In)不工作,点击 Disassembly 窗口使它成为焦点,可能需要点击一行反汇编代码来执行汇编级别的单步运行。如果焦点在源代码窗口上,则是执行 C 语言代码级别的单步运行。

    提示: 可以在程序停止运行时,通过 Call Stack + Locals 窗口来修改变量的值。

    提示: 上述是标准的“Stop and Go”调试过程。ARM Coresight 调试技术还可以做很多更强大的事情,比如在程序运行中显示并实时更新全局或静态变量,而不需要修改程序。由于局部变量通常存储在 CPU 寄存器中,不能在程序运行时实时显示,需要转换成全局或静态变量使得作用域不会消失。

    如果借助 ULINK pro 和 ETM 跟踪,可以记录所有指令的执行情况。Disassambly 和 Source 窗口是按编写的顺序显示代码的,而 ETM 跟踪可以按执行的顺序显示。另外 ETM 还提供 Code Coverage、Performance Analysis 及 Execution Profiling 等功能。

    把局部变量转换成全局或静态变量通常意味着把它从 CPU 寄存器移动到 RAM 上,CoreSight 在程序运行中可以观察 RAM,但不能观察 CPU 寄存器。

    调用栈

    如上面可以看到的,当程序停止运行时,函数按栈的方式显示在列表中。当想要了解栈中有哪些函数被调用、存储的返回值是什么的时候,这个功能就很有用。

    提示: 可以在程序停止运行时,通修改局部变量的值。

    提示: 点击菜单 Debug/Breakpoints 或按 Ctrl+B 键可以查看 Hardware Breakpoint 列表,同时这也是配置 Watchpoint (观察点,也叫 Access Point)的地方。在这个列表里可以临时屏蔽某些项目。点击 Debug/Kill All Breakpoints 会删除断点,但不会删除观察点。

    12) Watch 和 Memory 窗口及其使用方法

    Watch 和 Memory 窗口实时显示变量的值,这是通过 ARM CoreSight 调试技术实现的,这项技术是包含在 Cortex-M 处理器中的一部分。同时,也可以在这些存储器地址上实时地“put”或插入数值。这两个窗口都可以通过拖拽变量名,或者手动输入来添加变量。

    Watch 窗口

    添加全局变量: 除非程序停止在局部变量所在的函数,否则 Watch 和 Memory 窗口不能观察局部变量。

    1. 停止运行处理器 STOP 并退出 Debug 模式 Debug

    2. 在 Blinky.c 的第24行左右,声明一个全局变量(这里变量名叫做 value):unsigned int value = 0;。

    3. 在第104行左右添加语句 value++; 和 if (value > 0x10) value = 0;,如图:
      value Codes

    4. 选择菜单 File/Save All 或点击 Save All 。

    5. 点击 Rebuild Rebuild ,点击 Load Load 下载到 flash。

    6. 进入 Debug 模式 Debug ,点击 RUN RUN ,提示:可以在程序运行中设置 Watch 和 Memory 窗口。

    7. 在 Blinky.c 中,右键点击变量 value 并选择 Add value to … 及 Watch 1,Watch 1 窗口会打开并显示 value 如下图。

    8. value会实时增加到0x10。
      Watch 1
      提示: 也可以框选 value,单击并拖拽到 Watch 或 Memory 窗口。
      提示: 请确认菜单 View/Periodic Window Update 在选中状态。

    9. 也可以在 Name 下面区域双击或按 F2,再手动输入或复制粘贴变量名。或是打开菜单 View/Symbols Window 来输入变量。
      提示: 如果要拖拽到一个非活动的选项卡,选中变量按住鼠标并移动至希望打开的选项卡名字上,等待其打开并拖拽鼠标到窗口内释放。

    Memory 窗口

    1. 右键点击 value 并选择添加到 Memory 1,或手动添加 value 到 Memory 1。如果需要的话,选择菜单 View/Memory 来打开 Memory 1 窗口。

    2. 注意 value 被当作了一个指针,其值做为地址显示在了 Memory 1 上。这个操作在想要看一个指针指向的地址的时候很有用,但不是我们现在想看到的。

    3. 在变量名前面加一个“&”符号并按回车键,改为显示变量的物理地址(0x2000000C)。

    4. 右键点击 Memory 1 窗口并选择 Unsigned/Int。

    5. value 的值现在以32位的形式显示了。

    6. Watch 和 Memory 窗口都是实时更新的。

    7. 在 Memory 窗口中,鼠标移动到数据区域右键点击,选择 Modify Memory,可以修改对应地址的值。
      Memory

    提示: 这些操作通常不会占用 CPU 周期。关于 DAP 是如何运行的,详见下一章“原理”。

    提示: 在 Debug 模式中选择菜单 View/Symbol Window,可以打开 Symbol 窗口查看变量和各自的位置。

    上面展示的 Memory 和 Watch 窗口的操作并不需要配置 Serial Wire Viewer (SWV),这些机制使用的是 SWV 之外的另一个 CoreSight 特性。CoreSight Debug Access Port (DAP)通过 Serial Wire Debug (SWD)或 JTAG 连接来处理读写操作,从而实现实时在线的存储器访问。

    13) 如何在 Watch 和 Memory 窗口中观察局部变量

    (译者注:由于板卡的区别,这一部分和原文略有不同。)

    1. 运行 Blinky.c 程序。我们将使用 main() 中的局部变量 num。

    2. 在 Blinky.c 的第87行附近,main 函数的开头,找到声明这个局部变量的地方。

    3. 右键点击这个变量,把它输入到 Watch 1 窗口中。注意由于局部变量的值可能存放在 CPU 寄存器内,μVision 不能在程序运行时访问,因此会显示 < not in scope >。如果 μVision 显示无法添加变量,请尝试停止再开始 Blinky 程序。
      Watch Local Variables

    4. 在 Blinky.c 的主循环里添加一个断点,会使程序停止,这时会出现当前变量的值。

    5. 删除这个断点。

    6. 局部变量或自动变量可能存放在 CPU 寄存器内,μVision 不能在程序运行时访问。局部变量 num 只有在 main 函数运行时才会存在,在其他函数或中断/异常处理程序中是不存在的,因此 μVision 无法确定这个变量的值。

    7. 停止运行处理器 STOP 并退出 Debug 模式 Debug 。

    如何实时更新局部变量:

    只需把 num 改为全局变量定义在 Blinky.c 中。

    1. 把 num 的声明移动到 main() 的外面、Blinky.c 的最前面,把它改为全局变量:

    unsigned int value = 0;
    int32_t num = 0;12

    提示: 也可以定义成静态变量,如: static int32_t num = 0; 。
    提示: 在编辑模式和 Debug 模式都可以编辑文件,但编译只能在编辑模式进行。

    推荐阅读

    史海拾趣

    Galaxy Microelectronics公司的发展小趣事

    江苏飞翼智能科技有限公司在无人机航模领域也有着深厚的积累。公司不仅自己购买零件组装各类航模,还积极参与国内航模比赛,凭借良好的飞机性能和一流的操控技术取得了不俗的成绩。尤其是涡喷航模,作为中高级的航模产品,其高难度的特技动作展示了飞翼智能在无人机技术方面的深厚功底。这些经验积累和技术创新为飞翼智能向无人机应用型企业转型奠定了坚实基础。

    DURAKOOL公司的发展小趣事

    面对日益激烈的市场竞争和不断变化的客户需求,DURAKOOL公司始终保持着对创新的追求。公司不断投入研发资源,推动产品升级和技术进步。同时,公司也关注行业趋势和未来发展,积极探索新的业务领域和市场机会。展望未来,DURAKOOL将继续致力于成为全球电子行业的领先者。

    请注意,以上故事均为虚构,旨在提供与DURAKOOL公司发展相关的故事概要。如需了解更多关于DURAKOOL公司的详细信息,建议查阅相关报道或公司官方资料。

    Grand Halo Technology Co Ltd公司的发展小趣事

    随着技术的不断进步,DURAKOOL公司不断投入研发,推出了一系列创新产品,如Durakool接触器和电流互感器。这些产品凭借其高可靠性和稳定性,在电力监控和智能计量等领域得到了广泛应用。公司也逐渐扩大了市场覆盖范围,不仅在美国本土取得了成功,还逐步进入国际市场。

    CSR plc(剑桥硅晶无线电)公司的发展小趣事

    2009年,CSR plc以1.36亿美元成功收购了SiRF技术控股公司。这一收购为CSR plc带来了GPS和A-GPS的知识产权组合、航位推算和位置中心平台等重要技术资源,使其在世界无晶圆半导体厂商中的地位得到了进一步巩固。此次收购也让CSR plc的客户群体得到了极大的扩展,包括世界排名前七位的手机制造商中的六家,以及世界前五位的个人导航设备制造商等。

    固驰(GUERTE)公司的发展小趣事

    固驰电子深知产品质量是企业生存之本,因此始终将品质控制放在首位。公司不仅建立了完善的质量管理体系,还通过了ISO9001:2015质量管理体系认证和美国UL产品认证,这标志着固驰电子的产品质量达到了国际先进水平。此外,公司还积极申请专利,目前已拥有50项国家专利,进一步巩固了其在行业内的技术领先地位。

    绿索超容(GreenSource)公司的发展小趣事

    随着产品质量的不断提升和技术的持续创新,固驰电子开始积极拓展国内外市场。公司产品不仅畅销国内市场,为美的、格力、艾美特等知名企业配套,还大量出口至韩国、俄罗斯、美国、加拿大、德国等国家和地区。这一过程中,固驰电子凭借其优良的品质、满意的价格和完善的服务赢得了国内外客户的一致好评,品牌影响力显著提升。

    问答坊 | AI 解惑

    开关电源中几种过流保护方式的比较

                                       开关电源中几种过流保护方 ...…

    查看全部问答>

    供应麦肯MDT单片机,PIC单片机,Freescale传感器,单片机,单片机开发

    广州远景微电子有限公司从1999年至今专业从事麦肯MDT单片机,十速TENX单片机,美国MEAS传感器,Freescale单片机、传感器,自产IC的销售及产品方案单片机开发设计。公司技术力量雄厚,拥有专业的工程师队伍,专业承接各类单片机的开发与设计,坚持以 ...…

    查看全部问答>

    高手请进!

    深圳知名通信企业,高薪诚聘底层软件设计师、工程师, 本科2年以上,硕士1年半以上嵌入式系统开发设计经验; 熟悉PowerPC/mips/ARM/X86至少一种或以上处理器架构; 熟悉CPU的多核、多线程、cache、MMU等常用硬件技术,深入了解嵌入式OS(VXWORKS ...…

    查看全部问答>

    高手帮我找个编译错误吧.

    我用的是CE6.0 。 系统定制时编译出现一个错误,只能找到最后说 ; Build for Windows CE (Release 601) (Built on Aug 17 2006 15:18:52) File names: Build.log Build.wrn Build.err Build.dat CEBUILD: Running sysgen -p script preproc St ...…

    查看全部问答>

    三星6410/Wince6.0 环境下,Directshow显示

    三星6410/Wince6.0 环境下,Directshow 的范例一般在什么目录下? 我想用Directshow 显示 Byte *pBuf(pBuf 是一个指向RGB数据 的指针) 中的数据应可以吧?…

    查看全部问答>

    关于编程控制电机转动的问题

    我现在在学C++,想设计代码通过电脑远程控制电机的转动,可是脑子里连个概念都没有,希望各位大虾能详细指教一下该怎么实现,不是求代码,是想求得一个详细可行的方法以及实现的过程,我现在就是个程序设计初学者,对于串口之类还没有认识,希望您 ...…

    查看全部问答>

    Modesim错误

    编译完,启动仿真后就出现这种错误。# Reading C:/altera/10.0/modelsim_ase/tcl/vsim/pref.tcl # do vga_nios_run_msim_rtl_vhdl.do # if {[file exists rtl_work]} {#         vdel -lib rtl_work -all# }# vlib r ...…

    查看全部问答>

    【原创】请教各位,F149有时候不能下载,有时可以,是什么原因?

    能下和找不到没有任何规律。我看斑竹只顶的帖子说有可能是内、外部  电源冲突,不知道具体是什么意思?…

    查看全部问答>

    PSPICE仿真一个RC震荡电路的问题请教。

    各位老大好,今天用PSPICE仿真一个RC震荡电路。有个问题没有想明白,请教各位高手,有劳指点一下。电路很简单,就是一个RC振荡电路。输入是一个1V的正弦波,输入是下面图中最右边的电容。见下。我首先是进行AC扫描,频率从80k到150k,得到的输出如 ...…

    查看全部问答>

    急救!!!!哪位大大帮看看我的HS9148红外解码程序哪儿除了问题?

    这是源代码。//使用12M晶振 适用于HS9148芯片#include<reg52.h>#include<stdio.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intsbit led=P1^1;sbit in=P3^2;//红外接口标志uchar const tab[]={0x3f,0x06,0 ...…

    查看全部问答>