发新帖本帖赏金 80.00元(功能说明)我要提问
返回列表
打印
[开发工具]

如何使用串口和SWD口对MCU进行数据的监控?我来抛砖引玉

[复制链接]
16680|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 yang377156216 于 2023-2-8 15:53 编辑
#申请原创#  @21小跑堂
整体概览
嵌入式软硬件的开发工作包含了大量的测试以及调试过程,这就需要开发者在工作中找到合适和高效的方法让自己做到事半功倍。前阵子工作中因为要大量地进行 ADC 采样测试来验证结果的精确度和稳定性,所以就自然而然地会考虑这么些问题:该如何将结果准确地呈现出来?除了直接以文本的方式输出是否还能通过虚拟示波器工具以图形展示?在 ADC 采样过程中是否还能够实时地根据一些命令去切换采样模式?一方面是数据的上行输出,另一方面是数据的下行输入,我们都能通过串口或者SWD口作为接口来完成数据的监控,另外再配备一些常用上位机工具即可达成目标,与串口/shell相关的工具在我之前的分享中已经汇总了很多,可以回顾一下:有哪些嵌入式 shell 适合用于单片机上?在这选一个吧,地址:https://bbs.21ic.com/icview-3226456-1-1.html 与 SWD 相关的工具有 freemaster 、segger rtt view/ j-scope 等。而我选用的一个是山外多功能调试助手-虚拟示波器,另一个是借用 GitHub 网友 XIVN1987  开源之作小改而来的一款工具(自己命名DataMonitor)。本次我会将内容主要分为以下几个部分:
  • HC32F460 上传数据到山外多功能调试助手-虚拟示波器
  • 搭建 DataMonitor 工具的开发环境
  • 在 HC32L0136 和 HC32F460 开发板上使用 DAP-Link 与 DataMonitor 通讯
  • 附件内容

一、HC32F460 上传数据到山外多功能调试助手-虚拟示波器
在山外多功能调试助手中嵌入了虚拟示波器这一项功能,用它可以实时地观察来自串口的数据更新变化情况,像示波器一般更为直观。它有以下一些特点:
  • 支持8个通道,且通道可隐藏,通道名称可修改
  • 支持多种通道数据类型,从8位到32位可选
  • 界面可缩放和移动
  • 可追踪最新数据

  • 可归零y轴数据

它与串口终端间的通信协议格式为:[CMD] [~ CMD] [数据1,数据2,……,数据8] [~ CMD] [CMD],虚拟示波器的 CMD 为 3 ,即一次图像传输的通信协议为 :[0x03] [0xFC] [数据1,…… ,数据8] [0xFC] [0x03] 是一次的波形。不同的波形数量和数据类型,数据的长度就不相同。假设是 5 个通道, uint8_t 类型( unsigned char ),那么数据就是 5 个字节,从左往右是波形 1 到波形 5 的波形数据。下位机发送一次波形 时,先发送帧头: 0x03 0xFC ,接着发送全部波形的数据,最后发送帧尾:0xFC 0x03 完成一 次波形发送。
在实际应用中,我测试的数据为 HC32F460 的一个 ADC 通道采样结果,为 16位的一个数组,那么需要选择数据类型为 uint_16 ,且需要注意是先发送低八位,再发送高八位,其他的数据类型也是如此,由低八位到高八位发送数据。以下为具体的串口以及发送1-8个uint_16  类型数据的接口函数实现代码:
void UART_PutChar(uint8_t ch)
{
    M4_USART3->DR = ch;
    while (0ul == M4_USART3->SR_f.TC)
    {
        ;
    }
}

void UART_PutBuff(uint8_t *array, uint16_t len)
{
    uint16_t i;

    for (i = 0; i < len; i++)
    {
        UART_PutChar(array[i]);
    }
}

///< 向上位机发送一个变量的数据一次
void virtual_Osc_send_data(uint16_t value)
{
    uint8_t value_h, value_l;

    uint8_t cmdf[2] = {0x03, 0xFC};
    uint8_t cmdr[2] = {0xFC, 0x03};

    UART_PutBuff(cmdf, sizeof(cmdf));
    value_h = value / 256;
    value_l = value % 256;
    UART_PutChar(value_l);
    UART_PutChar(value_h);
    UART_PutBuff(cmdr, sizeof(cmdr));
}

///< 向上位机发送多个变量(最多8个)的数据一次
void virtual_Osc_send_array(uint16_t *array, uint16_t len)
{
    uint8_t value_h[8], value_l[8];
    uint16_t i;
    uint8_t cmdf[2] = {0x03, 0xFC};
    uint8_t cmdr[2] = {0xFC, 0x03};

    UART_PutBuff(cmdf, sizeof(cmdf));
    for (i = 0; i < len; i++)
    {
        value_h[i] = array[i] / 256;
        value_l[i] = array[i] % 256;
        UART_PutChar(value_l[i]);
        UART_PutChar(value_h[i]);
    }
    UART_PutBuff(cmdr, sizeof(cmdr));
}

/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
*******************************************************************************
** \brief  Main function.
**
** \param  None.
**
** \retval int32_t return value, if needed.
**
******************************************************************************/
int32_t main(void)
{
    /***************** Configuration end, application start **************/
    while (1u)
    {
        /* PB7 falling edge will trigger ADC1 sequence A conversion. */
        if (m_u32AdcIrqFlag & ADC1_SA_IRQ_BIT)
        {
            m_u32AdcIrqFlag &= ~ADC1_SA_IRQ_BIT;
            // TODO: YOUR CODE.
            m_au16AdcValue[us_AdcValueIndex ++] = M4_ADC1->DR4; ///< adc1_ch4
            if (us_AdcValueIndex >= ADC_LEN)
            {
                us_AdcValueIndex = 0;

                for (uint16_t i = 0; i < ADC_LEN ; i++)
                {
                    virtual_Osc_send_data(m_au16AdcValue[i]);///<发送一个通道的 ADC 采样结果共 ADC_LEN 个数据
                }
            }
        }
    }
}
在虚拟示波器工具上显示 ADC 单通道数据的效果图如下:

二、搭建 DataMonitor 工具的开发环境
源工程请到 GitHub 仓库下载,地址为:https://github.com/XIVN1987/RTTView它实际上是一个基于 SEGGER-RTT 组件和 J-Link / Dap-Link 的调试工具,基于 python 做的开发,所以前提是得搭建好必要的开发运行环境,这里约定装好以下版本资源: python 3.6 、 pyqt5 、 pyqtchart 、pyusb 、 pywinusb 。先下载安装 python 3.6.x ,这个版本必须有限定为 3.6 不然运行起来会有很多问题;然后使用 pip3 将其它几个 lib 包全部安装好来即可,在下载安装过程中如遇到不成功的问题可以切换到国内的源再次尝试。当然后面需要打包的话还可以将 pyinstaller 也安装好,需要更改设计页面的话需要将 PyQt5Designer 装好,具体操作细节不作过多描述,大家可以自行尝试。
搭建好了开发环境,可以对相应的 .ui 和 .py 文件按照自己定义的名称去做修改,这里全部改成了 DataMonitor,使用 python DataMonitor.py 命令即可将工具运行起来了,打包的话可以使用
pyinstaller -F -w -i Image/monitor.ico DataMonitor.py 命令生产 .exe 工具,但是由于未将 DataMonitor.ui 一同打包进去,所以必须得将其拷贝到 DataMonitor.exe 同目录下才能正常运行。

三、在 HC32L0136 和 HC32F460 开发板上使用 DAP-Link 与 DataMonitor 通讯
由于  DataMonitor 工具是基于 SEGGER RTT 组件的,所以必须在 mcu 端将该组件移植进来,类似实现在 j-link rtt view 工具中对 mcu 进行数据的监测和控制,这里也不展开具体的移植步骤,可以参考这篇博文来完成: https://blog.51cto.com/u_15244533/2862656
完成移植后在 rtt view 中使用 jlink 先连上测试,能够实现数据的上行和下行了:
具体测试代码放在了附件中,接着使用 HC32L0136 和 HC32F460 开发板板载的 Dap-Link 连上 DataMonitor 工具来测试,工具使用很简单,只要插上调试器并且正确选择、填写好 RTT Block 的 RAM 地址后开启连接,连接正常时会看到输出界面会有数据打印出来,对 mcu 发送字符 'c' 后会有每秒 +1的数据流打印出来。这里需要注意 HC32F460 的 RAM 地址并非为 0x20000000 , 需要在 .map 文件中找到对应的 RTT 控制块所在 RAM 地址,整个工具工作的原理可以理解为:rtt 控制块在 RAM 存放了数据,dap 或者 jlink 通过 SWD 接口实时扫描 RAM 地址,找到 rtt 控制块存放的内容后读取打印出来或者将设置的数据再存放进去。
下面是实际连接测试的效果图:
这里可以看到预留了一个波形监测的复选框,勾选上后可以使用本工具的虚拟示波器功能,它对输出数据格式的要求如下:
  • 1 个数据波形 : 11, 22, 33,
  • 2 个数据波形 : 11 22, 33 44, 55 66,
  • 3 个数据波形 : 11 22 33, 44 55 66, 77 88 99,
  • 4 个数据波形 : 11 22 33 44, 55 66 77 88, 99 11 22 33,

下面是波形显示效果图:
到这里已经可以很方便地进行数据的监测和控制了,基于此工具可以延伸开发,实现类似凌鸥的电机调试工具 lksviewer ,用作调机工具,再配上隔离型的 CMSIS-DAPLink 就可以愉快地玩转 BLDC 了。

四、附件内容附件资源包中有以下内容可供参考下载:
链接:https://pan.baidu.com/s/1pHkMKzuqm9W8Y22VJwluUQ?pwd=bgwk 提取码:bgwk

使用特权

评论回复

打赏榜单

21小跑堂 打赏了 80.00 元 2023-02-10
理由:恭喜通过原创审核!期待您更多的原创作品~

评论
21小跑堂 2023-2-10 11:07 回复TA
数据监控方法很多,常用的串口输出加串口助手,如果有这种虚拟示波器功能是最好的,山外和纸飞机都是不错的选择,DataMonitor 的使用则是更灵活的延伸了监控方法,可自行配置需要的部分功能,数据显示更为灵活直观。 
沙发
weifeng90| | 2023-2-8 18:44 | 只看该作者
这个调试方法确实方便,学到了。

使用特权

评论回复
板凳
icecut| | 2023-2-8 20:27 | 只看该作者
rtt viewer 是为了节约串口资源的.  这和串口其实是一样的方案.

这个方法的确比较新奇. 不过是个新思路. 值得推进一下.感觉写的这么复杂很多人搞不定啊.

使用特权

评论回复
地板
汽车电子| | 2023-2-25 23:08 | 只看该作者
我的串口通,10年就这么做了。还有一个网友的CommBox,支持串口、以太网、USB,还支持C语言脚本,可以绘图,你想做什么都可以。

使用特权

评论回复
5
qbwww| | 2023-2-28 12:41 | 只看该作者
嵌入式软硬件的开发工作包含了大量的测试以及调试过程,这就需要开发者在工作中找到合适和高效的方法让自己做到事半功倍。

-------------

使用特权

评论回复
6
lvanping| | 2023-3-2 15:05 | 只看该作者
太复杂了,简单点就好了

使用特权

评论回复
7
tpgf| | 2023-3-3 14:11 | 只看该作者
以前从来都不知道swd口还可以 用来监控数据

使用特权

评论回复
8
nawu| | 2023-3-3 14:25 | 只看该作者
之前用过串口 但是我觉得 也不是那么太可靠

使用特权

评论回复
9
aoyi| | 2023-3-3 14:36 | 只看该作者
这种情况是不是必须要外接显示设备了啊

使用特权

评论回复
10
zljiu| | 2023-3-3 14:54 | 只看该作者
这两种方式都可以看到比较丰富的数据内容

使用特权

评论回复
11
gwsan| | 2023-3-3 15:11 | 只看该作者
有些办法用起来还是比较麻烦的 不到万不得已很少用

使用特权

评论回复
12
tfqi| | 2023-3-3 15:25 | 只看该作者
如果程序死机了 是不是就不能进行监控了啊

使用特权

评论回复
发新帖 本帖赏金 80.00元(功能说明)我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

35

主题

204

帖子

10

粉丝