WCH RISC CH32V303RCT6 单片机的SDI Printf 虚拟串口功能 类似RTT打印功能 简单分析

本文主要是介绍WCH RISC CH32V303RCT6 单片机的SDI Printf 虚拟串口功能 类似RTT打印功能 简单分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

参考:
有关于 SDI printf 更多的信息和资料吗?
关于 CH32 系列 MCU SDI 虚拟串口功能的使用
【CH32X035 评估板测评】+ 教你使用 SDI 接口重定向 printf

0.前言

有段时间没有看CH32V单片机的开发了,今天帮新来的同事调试时候看到debug.c里面有新的函数SDI_Printf_Enable
在这里插入图片描述
大概看了下,感觉有点像RTT,去wch官方那个技术社区搜了下果然有相关内容。
在这里插入图片描述
主要看了这篇:关于 CH32 系列 MCU SDI 虚拟串口功能的使用写的很详细了。

在此下载最新的WCH-LinkUtility,解压后Doc文件夹中有WCH-Link使用说明,看来通用MCU的支持的多点,CH582、CH592还没有支持。
在这里插入图片描述

1.试验

1.1 打开SDI_PRINT

这里我使用的是CH32V303RCT6单片机,打开官方EVT中的例程
在这里插入图片描述
默认的Printf是关闭SDI功能、打开串口1的
在这里插入图片描述debug.h中将SDI_PRINT改为SDI_PR_OPEN即可编译。
在这里插入图片描述

1.2 打开串口助手

打开 WCH-LinkE 对应的串口,115200、8N1
在这里插入图片描述

1.3.使用WCH-LinkUtility下载固件并打开SDI 功能

在这里插入图片描述

1.4.下载查看串口信息

wch-linke只连接了SWCLK、SWDIO,没有连接自身的TX、RX,但还是可以看到有数据打印出来。
在这里插入图片描述

2.SDI Printf 虚拟串口功能原理简单推测分析

debug.c中的_write函数可以大概推测下SDI实现的原理:

#define DEBUG_DATA0_ADDRESS  ((volatile uint32_t*)0xE0000380)
#define DEBUG_DATA1_ADDRESS  ((volatile uint32_t*)0xE0000384)__attribute__((used)) int _write(int fd, char *buf, int size)
{int i = 0;#if (SDI_PRINT == SDI_PR_OPEN)int writeSize = size;do{/*** data0  data1 8 bytes* data0 The lowest byte storage length, the maximum is 7**/while( (*(DEBUG_DATA0_ADDRESS) != 0u)){}if(writeSize>7){*(DEBUG_DATA1_ADDRESS) = (*(buf+i+3)) | (*(buf+i+4)<<8) | (*(buf+i+5)<<16) | (*(buf+i+6)<<24);*(DEBUG_DATA0_ADDRESS) = (7u) | (*(buf+i)<<8) | (*(buf+i+1)<<16) | (*(buf+i+2)<<24);i += 7;writeSize -= 7;}else{*(DEBUG_DATA1_ADDRESS) = (*(buf+i+3)) | (*(buf+i+4)<<8) | (*(buf+i+5)<<16) | (*(buf+i+6)<<24);*(DEBUG_DATA0_ADDRESS) = (writeSize) | (*(buf+i)<<8) | (*(buf+i+1)<<16) | (*(buf+i+2)<<24);writeSize = 0;}} while (writeSize);#elsefor(i = 0; i < size; i++){
#if(DEBUG == DEBUG_UART1)while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);USART_SendData(USART1, *buf++);
#elif(DEBUG == DEBUG_UART2)while(USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);USART_SendData(USART2, *buf++);
#elif(DEBUG == DEBUG_UART3)while(USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET);USART_SendData(USART3, *buf++);
#endif}
#endifreturn size;
}
  1. WCH-LinkE调试器在Enable SDI Printf后,会虚拟出来一个串口供上位机串口助手使用,默认波特率115200、8N1
  2. MCU 开启SDI,#define SDI_PRINT SDI_PR_OPEN
  3. MCU程序运行中调用Printf函数,要打印的数据最终通过_write函数不断地写在RAM中的DEBUG_DATA0_ADDRESSDEBUG_DATA1_ADDRESS 地址上,而不是通过硬件串口外设调用USART_SendData发送
  4. WCH-LinkE调试器会不断地查询位于MCU的RAM中上述DEBUG_DATA0/1_ADDRESS两地址的数据,并将该数据打包通过虚拟出来的串口发送给串口上位机
    比较类似于RTT Viewer功能,通过调试器不断快速地访问RAM中的指定范围的数据来实现MCU和调试器到上位机的数据传输。
    只不过WCH的SDI功能目前仅有Printf 打印且RAM缓冲区占用很小,但还没支持双向的数据传输,但也算是很好的提升了,WCH加油啊!

3.WCH-LinkUtility的问题

WCH-LinkUtility在菜单栏 Target下拉可以随时控制SDI的开关,但是下图这里的开关不是即时发生的,实测只有在下载程序时会生效。(2024-04-25)
在这里插入图片描述
请添加图片描述

这篇关于WCH RISC CH32V303RCT6 单片机的SDI Printf 虚拟串口功能 类似RTT打印功能 简单分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/936665

相关文章

Python yield与yield from的简单使用方式

《Pythonyield与yieldfrom的简单使用方式》生成器通过yield定义,可在处理I/O时暂停执行并返回部分结果,待其他任务完成后继续,yieldfrom用于将一个生成器的值传递给另一... 目录python yield与yield from的使用代码结构总结Python yield与yield

python使用Akshare与Streamlit实现股票估值分析教程(图文代码)

《python使用Akshare与Streamlit实现股票估值分析教程(图文代码)》入职测试中的一道题,要求:从Akshare下载某一个股票近十年的财务报表包括,资产负债表,利润表,现金流量表,保存... 目录一、前言二、核心知识点梳理1、Akshare数据获取2、Pandas数据处理3、Matplotl

Java使用Thumbnailator库实现图片处理与压缩功能

《Java使用Thumbnailator库实现图片处理与压缩功能》Thumbnailator是高性能Java图像处理库,支持缩放、旋转、水印添加、裁剪及格式转换,提供易用API和性能优化,适合Web应... 目录1. 图片处理库Thumbnailator介绍2. 基本和指定大小图片缩放功能2.1 图片缩放的

python panda库从基础到高级操作分析

《pythonpanda库从基础到高级操作分析》本文介绍了Pandas库的核心功能,包括处理结构化数据的Series和DataFrame数据结构,数据读取、清洗、分组聚合、合并、时间序列分析及大数据... 目录1. Pandas 概述2. 基本操作:数据读取与查看3. 索引操作:精准定位数据4. Group

深度解析Spring Security 中的 SecurityFilterChain核心功能

《深度解析SpringSecurity中的SecurityFilterChain核心功能》SecurityFilterChain通过组件化配置、类型安全路径匹配、多链协同三大特性,重构了Spri... 目录Spring Security 中的SecurityFilterChain深度解析一、Security

MySQL中EXISTS与IN用法使用与对比分析

《MySQL中EXISTS与IN用法使用与对比分析》在MySQL中,EXISTS和IN都用于子查询中根据另一个查询的结果来过滤主查询的记录,本文将基于工作原理、效率和应用场景进行全面对比... 目录一、基本用法详解1. IN 运算符2. EXISTS 运算符二、EXISTS 与 IN 的选择策略三、性能对比

MySQL 内存使用率常用分析语句

《MySQL内存使用率常用分析语句》用户整理了MySQL内存占用过高的分析方法,涵盖操作系统层确认及数据库层bufferpool、内存模块差值、线程状态、performance_schema性能数据... 目录一、 OS层二、 DB层1. 全局情况2. 内存占js用详情最近连续遇到mysql内存占用过高导致

深度解析Nginx日志分析与499状态码问题解决

《深度解析Nginx日志分析与499状态码问题解决》在Web服务器运维和性能优化过程中,Nginx日志是排查问题的重要依据,本文将围绕Nginx日志分析、499状态码的成因、排查方法及解决方案展开讨论... 目录前言1. Nginx日志基础1.1 Nginx日志存放位置1.2 Nginx日志格式2. 499

Java中使用 @Builder 注解的简单示例

《Java中使用@Builder注解的简单示例》@Builder简化构建但存在复杂性,需配合其他注解,导致可变性、抽象类型处理难题,链式编程非最佳实践,适合长期对象,避免与@Data混用,改用@G... 目录一、案例二、不足之处大多数同学使用 @Builder 无非就是为了链式编程,然而 @Builder

Olingo分析和实践之EDM 辅助序列化器详解(最佳实践)

《Olingo分析和实践之EDM辅助序列化器详解(最佳实践)》EDM辅助序列化器是ApacheOlingoOData框架中无需完整EDM模型的智能序列化工具,通过运行时类型推断实现灵活数据转换,适用... 目录概念与定义什么是 EDM 辅助序列化器?核心概念设计目标核心特点1. EDM 信息可选2. 智能类