软件仿真和硬件仿真什么区别?软件仿真就是没有硬件参与的仿真,完全是模拟实现的。硬件仿真是将程序下载到控制芯片的FLASH或RAM中,直接在硬件上实现仿真。【有什么问题欢迎联系讨论,一起解决问题】

仿真这种东西,因为涉及到信任问题,用的好觉得好用,用不好可能会徒增麻烦——“还不如直接在硬件上调试靠谱”。但是总体上,仿真还是比较有用的,比如在排查软件问题(寄存器配置等)的时候,使用软件仿真是非常靠谱的。而如果涉及到硬件的问题(比如你的板子代码需要读取外部信号,或者输出信号等),可能需要用到硬件仿真,或者说在线仿真。关于仿真,网上的资料说的还是挺全的,这里只做总结。


目录

一、软件仿真

1.1 仿真配置

1.2 操作方法

逻辑分析窗口

Watch窗口

堆栈局部变量窗口

Peripherals窗口

二、硬件/在线仿真

2.1 仿真器通信协议/接口

JTAG协议/接口

SWD协议/接口

RDI协议/接口

2.2 常见仿真器

Jlink

STlink

ULINK

2.3 Jlink的Keil5仿真配置

2.4 硬件仿真操作方法


一、软件仿真

1.1 仿真配置

首先确定仿真的硬件环境。点击魔术棒,,在Target项确认一下仿真的芯片型号无误,然后选择外部时钟源频率(因为STM32一般使用外部时钟),一般是8MHz。

然后按照如下勾选,这里使用软件仿真就勾选Use Simulator。勾选Run to main(),表示仿真时跳过汇编代码,直接跳转到 main 函数开始仿真。然后Dialog DLL和Parameter分别按照自己的型号进行修改,比如如果你是用的是STM32F103ZE××,就把-pSTM32F103VB改为-pSTM32F103ZE便可,这里是设置支持所选型号的芯片的软硬件仿真,设置好后仿真的时候就可以通过 Peripherals 选择对应外设的对话框观察仿真结果(非常实用,后边详述)。

1.2 操作方法

点击开始仿真。

这里的DEBUG工具条是比较常用,其中作为一般的使用者或者说入门的使用者来说,最常使用的还是下面加黑的几个。

  • 复位:其功能等同于硬件上按复位按钮。相当于实现了一次硬复位。按下该按钮之后,代码会重新从头开始执行。
  • 执行到断点处:该按钮用来快速执行到断点处,有时候你并不需要观看每步是怎么执行的,而是想快速的执行到程序的某个地方看结果,这个按钮就可以实现这样的功能,前提是你在查看的地方设置了断点。
  • 挂起:此按钮在程序一直执行的时候会变为有效,通过按该按钮,就可以使程序停止下来,进入到单步调试状态。
  • 执行进去:该按钮用来实现执行到某个函数里面去的功能,在没有函数的情况下,是等同于执行过去按钮的。
  • 执行过去:在碰到有函数的地方,通过该按钮就可以单步执行过这个函数,而不进入这个函数单步执行。
  • 执行出去:该按钮是在进入了函数单步调试的时候,有时候你可能不必再执行该函数的剩余部分了,通过该按钮就直接一步执行完函数余下的部分,并跳出函数,回到函数被调用的位置。
  • 执行到光标处:该按钮可以迅速的使程序运行到光标处,其实是挺像执行到断点处按钮功能,但是两者是有区别的,断点可以有多个,但是光标所在处只有一个。
  • 汇编窗口:通过该按钮,就可以查看汇编代码,这对分析程序很有用。
  • 堆栈局部变量窗口:该按钮按下,会弹出一个显示变量的窗口,在里面可以查看各种你想要看的变量值,也是很常用的一个调试窗口。
  • Watch窗口:可以用来查看全局变量。
  • 串口打印窗口:该按钮按下,会弹出一个类似串口调试助手界面的窗口,用来显示从串口打印出来的内容。需要注意的是在硬件调试时无法使用,只能从硬件上获取串口信息。
  • 内存查看窗口:该按钮按下,会弹出一个内存查看窗口,可以在里面输入你要查看的内存地址,然后观察这一片内存的变化情况。是很常用的一个调试窗口。
  • 性能分析窗口(没标的那个):按下该按钮,会弹出一个观看各个函数执行时间和所占百分比的窗口,用来分析函数的性能是比较有用的。
  • 逻辑分析窗口:按下该按钮会弹出一个逻辑分析窗口,通过 SETUP 按钮新建一些 IO 口,就可以观察这些 IO 口的电平变化情况,以多种形式显示出来,比较直观。

关于执行到某处以及设置/清除断点等这些常规操作不在赘述。

逻辑分析窗口

点击选择逻辑分析仪(Logic Analyzer),

点击左上角SETUP

然后输入要查看的引脚,选择显示类型为Bit,最后Close(另外显示颜色可以自由选择)。这里的引脚名有一定的格式,比如这个是表示GPIOC13引脚,PORTC这里可以理解为GPIOC引脚状态寄存器,(PORTC & 0x00002000)表示取其GPIOC13的状态(bit),然后右移13位是把该值移到最低位(可以简记为pin号是几就右移几位)。

如果不知道怎么确定“&”的数应该是多少,可以参考下面各pin号的值:

#define GPIO_Pin_0                 ((uint16_t)0x0001)  /*!< Pin 0 selected */
#define GPIO_Pin_1                 ((uint16_t)0x0002)  /*!< Pin 1 selected */
#define GPIO_Pin_2                 ((uint16_t)0x0004)  /*!< Pin 2 selected */
#define GPIO_Pin_3                 ((uint16_t)0x0008)  /*!< Pin 3 selected */
#define GPIO_Pin_4                 ((uint16_t)0x0010)  /*!< Pin 4 selected */
#define GPIO_Pin_5                 ((uint16_t)0x0020)  /*!< Pin 5 selected */
#define GPIO_Pin_6                 ((uint16_t)0x0040)  /*!< Pin 6 selected */
#define GPIO_Pin_7                 ((uint16_t)0x0080)  /*!< Pin 7 selected */
#define GPIO_Pin_8                 ((uint16_t)0x0100)  /*!< Pin 8 selected */
#define GPIO_Pin_9                 ((uint16_t)0x0200)  /*!< Pin 9 selected */
#define GPIO_Pin_10                ((uint16_t)0x0400)  /*!< Pin 10 selected */
#define GPIO_Pin_11                ((uint16_t)0x0800)  /*!< Pin 11 selected */
#define GPIO_Pin_12                ((uint16_t)0x1000)  /*!< Pin 12 selected */
#define GPIO_Pin_13                ((uint16_t)0x2000)  /*!< Pin 13 selected */
#define GPIO_Pin_14                ((uint16_t)0x4000)  /*!< Pin 14 selected */
#define GPIO_Pin_15                ((uint16_t)0x8000)  /*!< Pin 15 selected */

比如,如果你需要查看PA11的引脚,就写为(PORTA & 0x00000800)>> 11(0x00000800可以写为0x0800)。因为为PA11,所以写PORTA,从上宏定义可知,因为11脚对应的是0x0800,所以就&0x0800,因为是11脚就右移11位。

设置好引脚之后,在View下勾选上更新窗口,这样的话仿真时各种数据会实时更新,逻辑分析仪也就可以看到实时波形。

设置好之后点击运行,就可以在逻辑分析仪窗口看到该引脚的状态实时波形。

Watch窗口

Watch创口可以用来观察全局变量,只要将需要观察的全局变量复制到下面的窗口中,运行之后就可以看到数据的变化。

比如这里是观察一个结构体数组变量的情况,那个数据的值是多少、是什么类型一目了然。

当然,这里没法看局部变量,要看局部变量的话还是要用堆栈局部变量窗口。

堆栈局部变量窗口

你可能会问,什么是堆、栈?点这!

什么是堆栈?
内存分配方式有三种:
[1]从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。
[2]在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
[3]从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由程序员决定,使用非常灵活,但如果在堆上分配了空间,就有责任回收它,否则运行的程序会出现内存泄漏,频繁地分配和释放不同大小的堆空间将会产生堆内碎块。

简言之,我们可以通过这个串口观察申请在堆栈区的变量,另外实测发现静态变量也是可以看的。总之,通过Watch窗口和堆栈窗口我们可以查看几乎所有的变量。

Peripherals窗口

它是用来仿真时观察和修改芯片的在外设寄存器用的,第一个System Viewer可以通过箭头所指的地方直接查看。

            

但是! 这是一个通用的选项,即涵盖了所有的外设,这上边可以查看的外设在我们的芯片型号上不一定有。比如我选用的是STM32VBT6只有3个串口,而这里可以看5个串口!而SyetemViwer下边的是外设是根据前文配置仿真时配置的Dialog DLL和Parameter决定的,所以要使用这个功能,必须要把Dialog DLL和Parameter配置为你要仿真的芯片型号。

另外两者的界面也有一些差别,看一哈

    

左图是System Viwer的界面,直接显示了改外设的所有寄存器极其每个位的值。右图是另一个界面,可以相对前者比较直观一些。

二、硬件/在线仿真

2.1 仿真器通信协议/接口

目前主流的协议是JTAG协议和SWD协议,一般常用的仿真器也是同时支持这两种协议/接口的。

JTAG协议/接口

JTAG(Joint Test Action Group,联合测试行动小组)是一种国际标准测试协议(IEEE 1149.1兼容),主要用于芯片内部测试。现在多数的高级器件都支持JTAG协议,如ARM、DSP、FPGA器件等。JTAG的工作原理可以归结为:在器件内部定义一个TAP(Test Access Port,测试访问口),通过专用的JTAG测试工具对内部节点进行测试和调试。一个含有JTAG Debug接口模块的CPU,只要时钟正常,就可以通过JTAG接口访问CPU的内部寄存器、挂在CPU总线上的设备以及内置模块的寄存器。

JTAG有5根线与目标CPU相连,TMS、TCK、TDI、TDO、NTRST:

  • TMS:测试模式选择,TMS用来设置JTAG接口处于某种特定的测试模式;
  • TCK:测试时钟输入;
  • TDI:测试数据输入,数据通过TDI引脚输入JTAG接口;
  • TDO:测试数据输出,数据通过TDO引 脚从JTAG接口输出;
  • NTRST:JTAG模块复位

其中在引脚紧缺的时候NTRST复位引脚可以不用。

SWD协议/接口

SWD全称Serial Wire Debug,是ARM为嵌入式设备推出的一种简单的调试接口,这种接口通过一条双向数据线和一条时钟线实现对于ARM核心的调试。

SWD需要3根线与目标MCU相连,SWDIO,SWDCLK和GND。

  • SWDIO 为双向Data口,主机到目标的数据传送。
  • SWDCLK 为时钟口,主机驱动。
  • GND  GND脚。

关于SWD的协议的具体内容,可以参考这位篇文章。还不满足的话可以参考这篇硕士论《WD协议的研究及ARM程序下载器的设计》。

RDI协议/接口

远程调试接口(Remote Debug Interface),是ARM公司提出的标准调试接口,主要用于ARM芯片的仿真,由于各个IDE厂商使用的调试接口各自独立,硬件无法进行跨平台的调试。现在众多的IDE厂家都逐步采用标准RDI作为ARM仿真器的调试接口,因此使跨平台的硬件调试成为可能。EasyJTAG由于使用标准RDI调试接口,因此在任何使用标准RDI接口的IDE调试环境中都可以使用,例如ARM公司的ADS1.2/IAR公司的EWARM 3.30 。

2.2 常见仿真器

Jlink

J-Link是德国SEGGER公司推出基于JTAG的仿真器。简单地说,是一个JTAG协议转换盒,即一个小型USB到JTAG的转换盒,其连接到计算机用的是USB接口,而到目标板内部用的还是jtag协议。它完成了USB接口和JTAG接口的转换工作。JLINK是一个通用的开发工具,可以用于KEIL、IAR、ADS 等平台。速度,效率,功能都很好,据说是众多仿真器里最强悍的。

STlink

ST-LINK是专门针对意法半导体STM8和STM32系列芯片的仿真器。ST-LINK /V2指定的SWIM标准接口和JTAG / SWD标准接口。

ULINK

ULINK是ARM/KEIL公司推出的仿真器,专用于KEIL平台下使用,ADS、IAR下不能使用。

2.3 Jlink的Keil5仿真配置

首先确认所选用的芯片支持哪种仿真通信协议,STM32F103支持 JTAG 和 SWD。并且PA13、PA14、PA15、PB3、PB4默认功能为调试引脚,如果要使用这些引脚,要Remap为普通IO

魔术棒的DEBUG选项下选用使用仿真器以及所使用的仿真器的型号。

点击setting,选择接口类型(SW或JTAG),速度建议选4M,过高的话也行,只是有时候擦写flash会失败。

下载的时候使用的仿真器,所以要在这里勾选使用仿真器

最后,这里根据所选型号flash大小选择合适的下载算法。如果不知道怎么选,看一下STM32芯片的命名规则,或点这里。

2.4 硬件仿真操作方法

仿真操作方法与软件操作相同,不同的是,硬件/在线仿真是在硬件上跑的,可以向硬件输入数据或者由硬件输出数据,比如做按键仿真的时候,只能通过硬件/在线仿真才能测试出芯片有没有正确地处理按键信息等。

STM32-Keil软件仿真和硬件仿真/在线仿真相关推荐

  1. 【软件工程师学硬件】之 仿真

    大多数软件工程师对仿真没有概念,因为软件里没有仿真的说法,但是软件开发里原型的说法,这个原型就有些类似于仿真. 仿真,顾名思义,就是乱真,和真的差不多.这只是个说法,要是假的都能成为真的,就不需要真的 ...

  2. STM32 SPI 软件NSS和硬件NSS解读

    [导读] SSM可以控制内部NSS引脚与SSI(一个寄存器,软件模式)相连,还是与NSS外部引脚(真正的STM32引脚,硬件模式)相连.真正作用的是内部NSS引脚(内部NSS引脚才真正连接到SPI通信 ...

  3. STM32 KEIL软件设置程序烧写起始地址选择

    转自  https://blog.csdn.net/alfredseng/article/details/53021583 STM32系列的mcu,这儿以cortex-M4为例,我们在线调试时,一般会 ...

  4. stm32怎么用keil软件进行仿真?(必需掌握的技能)

    在做开发的前几年,基本上都没用仿真,有bug就尝试改程序,一边改一边调试. 甚至都还不知道硬件仿真存在的价值,因为一直都没用过,而且很多芯片也不支持. 直到有一次在做行车记录仪项目的时候,接触到了GR ...

  5. PLC编程安卓版 兼容三菱FX PLC编程指令 软件在线仿真 硬件PLC工控板蓝牙与手机蓝牙在线下载程序 在线仿真

    1 APP功能描述 2 APP下载与安装注册 3 APP介面操作 3.1 主介面介绍 3.2 状态栏 3.3 工件区 3.4 工具栏 3.5 转换成上位机GX Works2文件 1 APP功能描述 F ...

  6. Keil软件仿真STM32时出现“no ‘write‘ permission”,“no ‘read‘ permission ”的错误

    Keil软件仿真STM32时出现"no 'write' permission","no 'read' permission "的错误 在Keil中可以对我们的程 ...

  7. Keil软件仿真步骤

    目录 前言 一.准备工作 二.仿真 1.波形验证 2.变量验证 3.其他 注意事项 前言 在学习STM32的过程中会不可避免的遇到需要仿真的情况,其实大部分时候都是直接使用ST-Link进行硬件仿真, ...

  8. keil软件仿真时,程序不能正常运行解决方法

    在用keil软件调试程序时,有时候手头没有硬件电路板,就需要用到软件仿真功能.但是使用软件仿真时经常出现一个问题,就是开始仿真后,程序就会卡在系统初始化函数中. 程序停在时钟设置这里就不动了,不能进入 ...

  9. keil软件仿真时如何使用逻辑分析仪查看波形

    在调试程序时有时候手头没有示波器,这时候就需要用到软件仿真.在软件仿真时可以通过逻辑分析仪来查看IO口的波形.但是逻辑分析仪对于新手来说不知道怎么用,现在就来说说逻辑分析仪如何设置. 首先用LED灯来 ...

最新文章

  1. java创建主键自增表_oracle创建表时设置自增主键
  2. Spring笔记——2.使用Spring容器
  3. mysql 线上加索引_MySQL加索引都经历了什么?
  4. 本月 Firefox 65 将加入 Flexbox Inspector 开发者工具
  5. 通过Xcode断点集成 reveal(2017-10-20更新)
  6. 【asp.net Core MVC + angular6实战】 - 1. 环境搭建
  7. insert函数的修改,
  8. 设计模式系列 - 原型模式
  9. 数据结构之malloc()函数动态内存分配复习
  10. Redis数据安全与性能保障——redis读书笔记4
  11. unity5 人皮渲染 Skin Shading
  12. 排队 (白雪公主与n个小矮人)
  13. matplotlib 绘制直方图和拟合正态曲线
  14. linux进入bios设置超线程,从BIOS开启超线程的方法
  15. scrapy手工识别验证码登录超星泛雅
  16. html实现网页多人聊天,实现websocket多人聊天,很简单(示例代码)
  17. 一个Python自动提取内容摘要的实践
  18. 什么样的人适合当领导
  19. 自定义波浪View,使头像跟着波浪背景浮动
  20. 一种跳板机的实现思路

热门文章

  1. 前端程序员需要了解的原生微信小程序-基础知识
  2. IK Multimedia T-RackS 5 for Mac 混音和母带处理插件
  3. 校企合作 | 长江师范学院重庆芝诺大数据有限公司大学生实践教育基地校企合作签约授牌仪式...
  4. emlog程序仿小刀娱乐网模板最终版本
  5. Android-自定义心电图控件
  6. NCL 错误 fatal:Loop end must be scalar, can‘t execute loop
  7. 分享哈啰出行小程序架构演进之路
  8. wr885n虚拟服务器设置,tp-link wr885n如何用手机设置
  9. ChatGPT客服系统产品-利用chatgpt训练企业知识开发个性化客服系统
  10. 各行业的英语术语(绝对精华4)--房地产