STM32中重定向printf到SWO口[通俗易懂]

STM32中重定向printf到SWO口[通俗易懂]Keil中调试:用SWO功能替代printf引用网址:http://blog.csdn.net/xiaolei05/article/details/8526021嵌入式软件开发中的一个基本需求就是能通过终端来输出调试信息,一般可通过2种方式实现:一种是使用串口线连接板上的UART和PC上的COM口,通过PC上的超级终端来查看调试信息;另一种则是采用半主机机制,但有可能不被

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

Keil中调试 : 用 SWO 功能替代 printf

引用网址:http://blog.csdn.net/xiaolei05/article/details/8526021

keil官方Guide: http://www.keil.com/support/man/docs/jlink/jlink_trace_itm_viewer.htm

嵌入式软件开发中的一个基本需求就是能通过终端来输出调试信息,一般可通过2种方式实现:一种是使用串口线连接板上的UARTPC上的COM口,通过PC上的超级终端来查看调试信息;另一种则是采用半主机机制,但有可能不被所用的工具链支持。基于Cortex-M3核的软件调试突破了这样的限制,Cortex-M3内核提供了一个ITM(Instrumentation TraceMacrocell)接口,通过SWV(Serial Wire Viewer)可调试由SWO引脚接收到的ITM数据。ITM实现了32个通用的数据通道,基于这样的实现,CMSIS规定用通道0作为终端来输出调试信息,通道31用于操作系统的输出调试(特权模式访问)。在core_cm3.h中定义了ITM_SendChar()函数,因此可通过调用该函数来重写fputc,以在应用程序中通过printf打印调试信息,并可通过ITM Viewer查看这些调试信息。有了这样的实现,嵌入式软件开发者就可以在不配置串口和使用终端调试软件的情况下输出调试信息,在一定程度上减少了工作量

基本概念:

SWD
The J-Link and J-Trace support ARMs Serial WireDebug (SWD). SWD replaces the 5-pin JTAG port with a clock (SWDCLK)and a single bi-directional data pin (SWDIO), providing all thenormal JTAG debug and testfunctionality. 
Pin 13 of SWD:
SWO – Serial Wire Output trace port. (Optional,not required for SWD communication.)

SWO
J-Link can be used with devices that supportSerial Wire Output (SWO). Serial Wire Output (SWO) support meanssupport for a single pin output signal from the core. It iscurrently tested with Cortex-M3 only.

SWV
The Instrumentation Trace Macrocell (ITM) andSerial Wire Output (SWO) can be used to form a Serial Wire Viewer(SWV). The Serial Wire Viewer provides a low cost method ofobtaining information from inside the MCU. The SWO can output tracedata in two output formats, but only one output mechanism is validat any one time. The 2 defined encodings are UART and Manchester.The current J-Link implementation only supports UART encoding.Serial Wire Viewer uses the SWO pin to transmit different packetsfor different types of information. The three sources in theCortex-M3 core which can output information via this pinare:
– Instrumentation Trace Macrocell (ITM) forapplication-driven trace source that supports printf-styledebugging. It supports 32 different channels, which allow it to beused for other purposes such as real-time kernel information aswell.
– Data Watchpoint and Trace (DWT) for real-timevariable monitoring and PC-sampling, which can in turn be used toperiodically output the PC or various CPU-internal counters, whichcan be used to obtain profiling information from thetarget.
– Timestamping. Timestamps are emitted relative topackets.

LPC177x/178x debug support
– A JTAG debug interface is included.
– Serial Wire Debug is included. Serial Wire Debugallows debug operations using only 2 wires, simple trace functionscan be added with a third wire.
– The Embedded Trace Macrocell (ETM) is included.The ETM provides instruction trace capabilities.
– The Data Watchpoint and Trace (DWT) unit isincluded. The DWT allows data address or data value matches to betrace information or trigger other events. The DWT includes 4comparators and counters for certain internal events.
– An Instrumentation Trace Macrocell (ITM) isincluded. Software can write to the ITM in order to send messagesto the trace port.
– The Trace Port Interface Unit (TPIU) isincluded. The TPIU encodes and provides trace information to theoutside world. This can be on the Serial Wire Viewer pin or the4-bit parallel trace port.
– A Flash Patch and Breakpoint (FPB) is included.The FPB can generate hardware breakpoints and remap specificaddresses in code space to SRAM as a temporary method of alteringnon-volatile code. The FPB includes 2 literal comparators and 6instruction comparators.

http://www.keil.com/support/docs/3051.htmhttp://www.keil.com/support/man/do

 

Debug (printf) Viewer

Home » µVision Windows » Debug (printf) Viewer

The Debug (printf) Viewer window displays data streams that are transmitted sequentially through the ITM Stimulus Port 0. Enable ITM Stimulus Port 0.
STM32中重定向printf到SWO口[通俗易懂]

Debug Viewer Window

To use the Debug (printf) Viewer for tracing:

   1. Add ITM Port register definitions to your source code.

    #define ITM_Port8(n)    (*((volatile unsigned char *)(0xE0000000+4*n)))
    #define ITM_Port16(n)   (*((volatile unsigned short*)(0xE0000000+4*n)))
    #define ITM_Port32(n)   (*((volatile unsigned long *)(0xE0000000+4*n)))

    #define DEMCR           (*((volatile unsigned long *)(0xE000EDFC)))
    #define TRCENA          0x01000000

   2. Add an fputc function to your source code that writes to the ITM Port 0 register. The fputc function enables printf to output messages.

    struct __FILE { int handle; /* Add whatever you need here */ };
    FILE __stdout;
    FILE __stdin;

    int fputc(int ch, FILE *f) {

      if (DEMCR & TRCENA) {

        while (ITM_Port32(0) == 0);
        ITM_Port8(0) = ch;
      }
      return(ch);
    }

    3.Add your debugging trace messages to your source code using printf.

    printf(“AD value = 0x%04X\r\n”, AD_value);

    4.Set the ITM Port 0 to capture the information. Clear the Port 7..0 privilege bit to access ITM Port 0 from User mode.
STM32中重定向printf到SWO口[通俗易懂]
    ITM Stimulus Port 0
    Open the View – Serial Windows – Debug (printf) Viewer window.

Note

    ITM Stimulus Ports can be monitored in the Instruction Trace Window, where ITM Port 0 is shown as well.
    Consult Configure Cortex-M Target of the MDK-Primer for information on how to retarget the output.

GCC工具链下调试:
 用 SWO 功能替代 printf

引用自:http://bbs.elecfans.com/forum.php?mod=viewthread&tid=466474&extra=

printf在命令行编程的时候是非常常用的,虽然是个老函数,但是功能强大,经久不衰
51等8位
单片机由于RAM比较小,栈就比较小,跑printf比较吃力,
但是STM32这种32位单片机跑printf就很容易了,而作为一种调试手段,printf十分方便、直观。
比较常见的方法是把printf重定向到串口,不过这需要外接一个串口线,比较麻烦。
其实STM32自带的SWO口是能够异步输出数据的,而且不需要外接什么设备,
ST-LINK/J-Link等带SWO口的调试器都支持。
下面以STM32F4Discovery开发板+GCC为例说明。
根据这里的方法,也可以把printf定位到其他外设。
PS:IAR在编译选项里自带了printf via SWO的功能,就不需要外加设置了。
http://community.silabs.com/t5/Microcontroller-How-to-Guides/SWO-printf-in-IAR/td-p/98257
首先来说说怎么把信息输出到SWO口,一句话搞定。
ITM_SendChar(ch);
这是在core_cm4.h(如果是F1系列的那就是core_cm3.h)中定义的内联函数。
不过不需要特意去include这个头文件,通过#include “stm32f4xx.h”就间接地将core_cm4.h包含进来。
不过说起来,ITM这个东西其实严格来说是Cortex-M提供的一个特性,而不是STM32。
利用这个函数把信息输出到SWO口之后再打开St-Link Utility,
在菜单里找到ST-LINK→Printf via SWO Viewer就会弹出一个窗口,
设置System Clock为单片机内核频率,点Start就能看到输出的信息了。
接下来就是把printf函数输出的字符串重定向过去了。
由于单片机的外设功能是根据需求变化的,编译器不可能确定printf需要用到的外设资源,
于是乎它就干脆留了个接口,也就是_write函数,
当然除了_write函数之外还有_read等其他函数,不过这里我们用不到。
其声明为 int _write(int fd, char* ptr, int len);
关于_write函数,说简单点,就是所有涉及到输出字符串的函数,
比如printf和putchar(),最终都会跑到_write函数,这里fd是文件标识符,说开来就比较复杂了,
这里我们用得到的就只有STDOUT_FILENO跟STDERR_FILENO,
其中前一个是标准输出的文件标识符的预定义变量,后一个是错误输出的文件标识符预定义变量。
第二个变量ptr是需要输出的字符串首地址,len就是输出长度。
当我们调用printf函数后,C运行库会把输入变量转换为最终需要输出的字符串,
然后调用_write函数,将结果输出。我们的工作就是实现一个_write函数。
新建一个_write.c文件,内容如下:
  1. #include <stdio.h>
  2. #include <unistd.h>

  3. #include “stm32f10x.h”

  4. #ifdef _DEBUG

  5. int _write(int fd, char* ptr, int len)
  6. {

  7. if (fd == STDOUT_FILENO || fd == STDERR_FILENO)
  8. {

  9. int i = 0;
  10. while(i<len)
  11. ITM_SendChar(ptr[i++]);
  12. }
  13. return len;
  14. }

  15. #endif

复制代码


加了个#ifdef _DEBUG 的效果是未加 _DEBUG 定义的时候就忽略下面的东西,
因为这东西主要是用在调试阶段,RELEASE版本里面都用不到了,而且多少还是会影响速度。
其他东西就很简单了- -不需要多说明了吧。
直接编译能通过,但是链接会报错,提示无法找到_read之类的一堆函数。
在链接脚本的下面libgcc.a ( * )后面加上libnosys.a ( * ),就不会报错了。
具体原因涉及到Cortex-M3使用的newlib库的实现,就不具体展开了。
好吧好吧,其实我也不知道。
如果想把信息定位到串口,可以直接把ITM_SendChar改成相应的串口函数,
也可以利用DMA,先把数据拷贝到DMA缓冲区,让DMA自动传数据,提高响应速度。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/234566.html原文链接:https://javaforall.net

(0)
上一篇 2025年6月1日 上午11:22
下一篇 2025年6月1日 下午12:01


相关推荐

  • 通俗理解运行时异常和非运行时异常(一般异常)[通俗易懂]

    通俗理解运行时异常和非运行时异常(一般异常)[通俗易懂]一,异常的概念Java异常类层次结构图:Throwable:有两个重要的子类:Exception(异常)和Error(错误),二者都是Java异常处理的重要子类,各自都包含大量子类。Error(错误):是程序无法处理的错误,表示运行应用程序中较严重问题。大多数错误与代码编写者执行的操作无关,而表示代码运行时JVM(Java虚拟机)出现的问题。例如,Java虚拟机运行错误

    2022年9月30日
    7
  • 百度快照更新周期、百度收录更新时间[通俗易懂]

    百度快照更新周期、百度收录更新时间[通俗易懂]很多做SEO的都不清楚百度快照的更新周期,所以很多时候都不能有针对性的对网站进行操作,错过了很多机会。百度收录的更新日期一般是每个月的11号和26号,特别是26号,更新最大,但K站也是最多的。另外百度也有一个小的更新的日期,即每周四凌晨4点左右,对网站的访问量没有什么效果,只有到了中午的日期,百度对网站关键字的搜索停止重新调整之后,才会有访问量上的大的变化,有升有降。总体上来说是大致为一个

    2026年4月15日
    3
  • 字符串之字符串压缩

    字符串之字符串压缩字符串压缩利用字符重复出现的次数 编写一种方法 实现基本的字符串压缩功能 比如 字符串 aabcccccaaa 会变为 a2b1c5a3 若 压缩 后的字符串没有变短 则返回原先的字符串 你可以假设字符串中只包含大小写英文字母 a 至 z 示例 1 输入 aabcccccaaa 输出 a2b1c5a3 示例 2 输入 abbccd 输出 abbccd 解释 abbccd 压缩后为 a1b2c2d1 比原字符串长度更长 这个题可以直接按照题的意思去写 依次从前往后遍历 初始化字母次数为 1

    2026年3月19日
    3
  • mysql子查询和连接查询(大数据联合计算)

    大圣网络2017-01-3109:19连接查询连接查询:将多张表(>=2)进行记录的连接(按照某个指定的条件进行数据拼接)。连接查询的意义:在用户查看数据的时候,需要显示的数据来自多张表.连接查询:join,使用方式:左表join右表;左表:在join关键字左边的表;右表:在join关键字右边的表连接查询分类:SQL中将连接查询分成

    2022年4月15日
    39
  • 你的工资能“养龙虾”吗 AI助手的成本与价值(3)

    你的工资能“养龙虾”吗 AI助手的成本与价值(3)

    2026年3月12日
    2
  • Qt多线程实例与connect第五个参数[通俗易懂]

    Qt是一个GUI框架,在GUI程序中,主线程也叫GUI线程,因为它是唯一被允许执行GUI相关操作的线程。对于一些耗时的操作,如果放在主线程中,就是出现界面无法响应的问题。解决方法一:在处理耗时操作中频繁调用QApplication::processEvents()。这个函数告诉Qt去处理那些还没有被处理的各类事件,然后再把控制权返还给调用者。QElapsedTimeret;…

    2022年4月8日
    87

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号