打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
使用SWO来替代串口实现Printf打印功能
不知道有多少人跟我一样不喜欢用断点仿真器什么的,长期以来我唯一的调试工具就是串口打印信息,
但串口打印有以下几个问题:
1:占用串口,这个,完全无解...
2:速度慢,真的很慢....
2:串口输出一般都是用中断方式发送,而经常调试的时候就是需要在中断中观察某些信息,中断的嵌套容易出问题,尤其是在RTOS环境下.
3:RTOS环境下还要考虑Thread Safe,这个倒是可以搞定,驱动上把互斥量用好就行了.

其实STM32之类的Cortex芯片都支持SWO输出,而我们用串口调试很多时候也只是使用TX输出而已,完全可以把Printf的串口TX Retarget到SWO这个脚上,直接使用ST-Link就可以查看打印信息了.
SWO的优势是什么呢?
1:速度快,ARM官方描述的速度:高性能数据速率 - 4 M 字节/秒 @ 50 MHz
2:不占用串口
 ,其实如果你是用JTAG口的,改成SWD调试,一个脚都不会多占用.
3:因为速度快,所以基本上只需要用Block方式输出,没有中断问题
4:还是因为是Block输出,资源互斥的问题也一起被解决了

硬件条件:你得把芯片的SWO脚接到调试口上,按JTAG接线的话,这个默认已经接上了,不过很多人可能自己只用SWD的两根线,这个就没接了.

代码条件:你得把Printf的输出函数,替换成SWO输出函数,其实这个函数在CMSIS库里已经提供了,就在core_cm4.h里面,如下:
  1. /** \brief  ITM Send Character

  2.     This function transmits a character via the ITM channel 0.
  3.     It just returns when no debugger is connected that has booked the output.
  4.     It is blocking when a debugger is connected, but the previous character send is not transmitted.

  5.     \param [in]     ch  Character to transmit
  6.     \return             Character to transmit
  7. */
  8. static __INLINE uint32_t ITM_SendChar (uint32_t ch)
  9. {
  10.   if ((CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk)  &&      /* Trace enabled */
  11.       (ITM->TCR & ITM_TCR_ITMENA_Msk)                  &&      /* ITM enabled */
  12.       (ITM->TER & (1UL << 0)        )                    )     /* ITM Port #0 enabled */
  13.   {
  14.     while (ITM->PORT[0].u32 == 0);
  15.     ITM->PORT[0].u8 = (uint8_t) ch;
  16.   }
  17.   return (ch);
  18. }
复制代码
这个会通过ITM 通道0(具体是啥我也没研究
 )输出一个字符,很多人用Keil的话,Printf的都是把一个Putchar函数改成了USART的输出字符的函数吧,改成这个就行了.
我的printf以前是自己写的,代码如下:

  1. /** 
  2. * @brief Use Serial Debug Wire SWO Pin to send out the 

  3. * @param pcBuff
  4. * @param length

  5. * @return int
  6. */
  7. int SwdWrite(char * pcBuff,unsigned long length)
  8. {
  9.         int xBytesSent=0;
  10.         while (length)
  11.         {
  12.                 ITM_SendChar((uint32_t)(*pcBuff));
  13.                 length--;
  14.                 pcBuff++;
  15.                 xBytesSent++;
  16.         }
  17.         return xBytesSent++;
  18. }

  19. /** 
  20. * @brief private impleted printf function,this would save a lot
  21. *            of rom&ram space compare to the built in printf
  22. *            function in the C newlib.Carefully use it inside a
  23. *            interrupt service routine.
  24. * @param fmt

  25. * @return int
  26. */
  27. int printf(const char * fmt, ...)
  28. {


  29.         int length=0;
  30.         va_list va;

  31.         char pcBuff[200];

  32.         va_start(va, fmt);
  33.         ts_formatstring(pcBuff, fmt, va);
  34.         va_end(va);

  35.         #ifdef SERIAL_DEBUG
  36.         length = CONSOLE_UART.ulWrite(pcBuff,strlen(pcBuff));
  37.         #endif
  38.         #ifdef SWD_DEBUG
  39.         length = SwdWrite(pcBuff,strlen(pcBuff));
  40.         #endif

  41.         return (length);
  42. }
复制代码
怎么用:
PC上安装最新版的ST-Link Utility,从菜单的ST_LINK那项下面,选择Printf via SWO,就可以打开SWO查看器了

填写正确的芯片速度,后的的Port就是前面的0,如果你先用别的Port,自己查一下对应的寄存器应该怎么改吧,点Start就可以看到SWO的Printf数据了
这里可以看到SWO的速度是2Mbps(说好的4M byte呢
 ),已经很快了,凑合着用吧,要什么自行车啊!
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
浅谈工程师的调试法宝(三)---SWO引脚的巧妙应用
printf系列教程05
基于STM32的多种printf用法,你都知道吗?
嵌入式开发输出调试和日志信息的几种方法
avr单片机 串口实现printf(使用变参函数)
将printf重定向到ITM[图解]
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服