全球最实用的IT互联网信息网站!

AI人工智能P2P分享&下载搜索网页发布信息网站地图

当前位置:诺佳网 > 电子/半导体 > 控制/MCU >

关键指南针-NXP USB CDC_VCOM虚拟串口例程

时间:2024-07-25 09:17

人气:

作者:admin

标签: NXP  指南针  USB  虚拟串口 

导读:最近有小伙伴反应USB中的 usb_examples/usb_device_cdc_vcom 例程(USB虚拟串口VCOM)中的一些使用问题,今天集中来说说使用example的必知要点~ 实验平台和软件版本说明 本篇文章的实验平台为:SD...

最近有小伙伴反应USB中的 usb_examples/usb_device_cdc_vcom 例程(USB虚拟串口VCOM)中的一些使用问题,今天集中来说说使用example的必知要点~

实验平台和软件版本说明

本篇文章的实验平台为:SDK_2_5_0_LPC54605J512oardslpcxpresso54608usb_examplesusb_device_cdc_vcom但实际上本篇文章适用于NXP大部分的硬件平台,因为usb_device_cdc_vcom(以下简称vcom)这部分例程代码和硬件关系并不大,属于USB Stack之上的应用部分,另外这部分代码在SDK的各个版本上变化也不是很大,所以如果您使用的新版本的SDK,本篇文章也同样适用。

40bba49a-4a20-11ef-b8af-92fbcf53809c.png

目标读者

关于vcom的一些基础环境搭建/编译下载等基础问题这篇文章不再赘述,具体可以参考example文件夹下的readme.pdf. 这里假设读者:

有一定的USB基础知识

已经成功跑过这个vcom例程,大概浏览过源代码,并且准备使用vcom的代码作为参考开发自己的项目产品

重要概念解释

首先一个最基本的概念:USB所有传输都是主机发起的,从机只是被动的响应主机发来的请求

USB OUT 传输: 即 USB Host(如PC)向USB Device(如MCU)下发数据, 对应vcom 例程中事件kUSB_DeviceCdcEventRecvResponse. 这个很好理解:对于vcom例子,就是虚拟串口上有数据发到了MCU(比如PC端有一个上位机软件,打开了虚拟串口,并且向虚拟串口写入数据)。每当MCU收到数据,都会进入kUSB_DeviceCdcEventRecvResponse.在kUSB_DeviceCdcEventRecvResponse事件中,需要MCU这边尽快的调用USB_DeviceCdcAcmRecv API将USB中的数据读取出来,然后USB Stack会和USB硬件一起准备好下次USB OUT事件接收工作。(类似串口的DMA接收机制)

从下图的CallStack可以看出,kUSB_DeviceCdcEventRecvResponse本质就是BulkOut中断回调上来的:

40d4e3c4-4a20-11ef-b8af-92fbcf53809c.png

USB IN传输:即USB Host(PC) 向USB Device(如MCU)索要数据, 比OUT传输稍微难理解一些:在vcom这个例程中,由于vcom属于buck传输。每当从机响应上一个IN token之后,就会进入kUSB_DeviceCdcEventSendResponse 事件,从下图的CallStack也可以看到, kUSB_DeviceCdcEventSendResponse事件本质就是 USB Buck In 中断回调上来的:

40df8c7a-4a20-11ef-b8af-92fbcf53809c.png

所以每当进入到kUSB_DeviceCdcEventSendResponse的时候,都说明USB IN传输已经完成(或取消)。那么从机如何向主机发送数据呢?调用USB_DeviceCdcAcmSend 这个API。但是调用这个API你需要注意,每次调用这个API,你都需要等待发送完成事件(kUSB_DeviceCdcEventSendResponse) 或超时(第一次除外)。在任何时候,你都不能在代码里连续调用USB_DeviceCdcAcmSend 多次。这个机制类似于串口DMA发送,即:每次调用串口DMA发送的时候,你都要确保上一次串口DMA发送已经完成。 总结如下:

40e5ce3c-4a20-11ef-b8af-92fbcf53809c.png



实际上,vcom例程实现的东西很简单,就是自发自收(echo),把虚拟串口接到的数据再原封不动的发回而已。所涉及的数据传输过程中的事件也只有:kUSB_DeviceCdcEventSendResponse 和kUSB_DeviceCdcEventRecvResponse. 其他的USB Class回调事件实际上多半是有关一些配置,控制 (波特率,打开,关闭虚拟串口)等,这部分内容暂不展开,需自学。

usb_device_cdc_vcom的问题 这个例程不太方便的地方就是代码里把发送和接收是耦合在一起的,对于新手且对USB不熟悉的用户,都不知道怎么解耦。实际应用中,串口的发送和接收应该是独立的,没有太大关系的,但是很可惜,这个example设计的时候硬生生的把发送和接收”粘”在一起,让新手不太容易剥离开。

这里给出一个简单的改造方案,把VCOM的发送和接收拆开:

1. 首先对于USB_IN: 注释掉之前的 USB_DeviceCDCAcmRecv部分,USB IN 传输和USB OUT之间没有必然关系。另外在kUSB_DeviceCdcEventSendResponse中,定义一个标志is_cdc_in_compelte (类比于串口的发送完成中断,或者DMA发送完成中断):

40f6a978-4a20-11ef-b8af-92fbcf53809c.png

2. 对于USB OUT: 将之前的代码替换为下图,在收到Host下发的数据后,第一时间调用USB_DeviceCDCAcmRecv,把数据接下来,然后通过一个消息队列(你可以用你自己实现的一个消息队列) 发送给应用层。不要在DeviceCdcEventSendResponse中做过多的应用层处理:

4128ef82-4a20-11ef-b8af-92fbcf53809c.png

3. 其他的有关原demo中的一些变量,比如s_recvSize, s_sendSize 之类的,删掉处理。在while(1)主循环中,处理USB中断回调发出来的消息队列:

412d9960-4a20-11ef-b8af-92fbcf53809c.png

通过解耦VCOM的Tx(发送)与Rx(接收),代码不仅变得清晰简洁,还提升了模块间的独立性和可维护性。这种设计促进了代码的复用性和可扩展性,为未来的功能升级或定制开发奠定了坚实基础。无论是对于初次接触的开发者还是资深工程师,都能从中受益,享受更流畅的编程体验。希望本期分享对大家有所帮助!

恩智浦致力于打造安全的连接和基础设施解决方案,为智慧生活保驾护航。

温馨提示:以上内容整理于网络,仅供参考,如果对您有帮助,留下您的阅读感言吧!
相关阅读
本类排行
相关标签
本类推荐

CPU | 内存 | 硬盘 | 显卡 | 显示器 | 主板 | 电源 | 键鼠 | 网站地图

Copyright © 2025-2035 诺佳网 版权所有 备案号:赣ICP备2025066733号
本站资料均来源互联网收集整理,作品版权归作者所有,如果侵犯了您的版权,请跟我们联系。

关注微信