作者 主题:STM32 Virtual COM端口接收数据(可能是一般C代码问题) (Read 1045 times)

0成员和2位客人正在查看此主题。

离线 幽灵

  • 常规贡献者
  • *
  • 帖子:111
嗨伙计们,我正在研究一个项目,要求我将数据从主机(终端)发送到一个基于STM32F103的设备。为此,我计划使用USB通信设备类,这是一个虚拟COM端口。

首先,我应该说我是这种事情的新手。不是我不'要知道C,它是我真正困难地导航吨的声明,包括在这些项目中包含的许多不同文件中的其他内容。我不'T知道更深层次的意义"interplay"文件之间。如果这个问题太隐身,我也对不起,因为它可能需要一些关于STM32项目结构,图书馆等的一些了解

无论如何,我没有通过函数cdc_transmit_fs()发送数据,但我并不确定如何接收数据。有一个函数cdc_receive_fs(),但从我所能理解的那样,这个函数不应该用于接收数据。从我理解的那样,它是每次收到一些数据时都会运行USB Lib的回调函数。然后将数据存储在同一USBD_CDC_IF_IF文件中声明的userrxbufferfs数组中。我可以验证userrxbufferfs数组是否充满了我在主机上的终端中写入的内容。


静态INT8_T CDC_RECEIVE_FS(UINT8_T * BUF,UINT32_T * LEN)
{
 / *用户代码开始6 * /
 usbd_cdc_setrxbuffer(&hUsbDeviceFS, &Buf[0]);
 usbd_cdc_receivepacket(&hUsbDeviceFS);
  return (USBD_OK);
 / *用户代码结束6 * /
}


现在,我不喜欢什么 't理解是我如何在例如时使用所接收的数据。我的主循环。我可以't只是声明一个变量"myvariable = userrxbufferfs."例如,在我的主循环中,因为编译器将抛出有关userfxbufferfs未被删除的错误。

 我看到大多数人所做的是修改CDC_Receive_FS()函数来处理所接收的数据,但这并不是那么'与我坐下:它似乎创造了不必要的高度复杂性,以便像这样编织文件。基本上,在我的main.c圈中,我'd喜欢使用Switch-case语句来排序通过终端发送到设备发送到设备的所有可能命令。我怎么能避免在CDC_Receive_FS函数内执行此操作?


感谢您的时间 :)
« 上次编辑:2020年12月21日,Pot涉及下午08:58:42 »
 

离线 禁止

  • 贡献者
  • 帖子:23
  • 国家: 我们
Re:STM32 Virtual COM端口接收数据(也许更多的C代码问题)
« 回复#1开: 2020年12月22日,03:17:40»
"Weaving"正是你必须做的。您对CDC_Receive_FS()的理解是正确的,除了它将在64个字节(或更少)块中调用。您通常会做的是将数据复制出USB RX缓冲区("Buf")进入另一个缓冲区并延迟进一步处理,直到中断完成后。如果您的命令是微不足道的(例如,一个字节,但不经常),您可以逃离类似于您的交换机语句的东西。否则你有一点工作要做。

这看起来像St Cubemx代码。你可能想看看像Libopencm3这样的其他库,看看你的喜好是否更加喜欢,但我没有't used them myself.
 
以下用户感谢此帖子: 幽灵

在线的 Langwadt.

  • 超级贡献者
  • ***
  • 帖子:2391
  • 国家: DK.
Re:STM32 Virtual COM端口接收数据(也许更多的C代码问题)
« 回复#2开: 2020年12月22日,04:04:45»
将数据复制到您自己的缓冲区"consume" it as you like,

也许看看这个, //stm32f4-discovery.net/2014/08/library-24-virtual-com-port-vcp-stm32f4xx/
 
以下用户感谢此帖子: 幽灵

离线 幽灵

  • 常规贡献者
  • *
  • 帖子:111
Re:STM32 Virtual COM端口接收数据(也许更多的C代码问题)
« 回复#3开: 2020年12月22日,晚上10:24:03»
"Weaving"正是你必须做的。您对CDC_Receive_FS()的理解是正确的,除了它将在64个字节(或更少)块中调用。您通常会做的是将数据复制出USB RX缓冲区("Buf")进入另一个缓冲区并延迟进一步处理,直到中断完成后。如果您的命令是微不足道的(例如,一个字节,但不经常),您可以逃离类似于您的交换机语句的东西。否则你有一点工作要做。

这看起来像St Cubemx代码。你可能想看看像Libopencm3这样的其他库,看看你的喜好是否更加喜欢,但我没有't used them myself.

感谢您的回复!为什么所有的织布?当我参加编程课程时,我被推动了如何"compartmentalize"函数,不要通过全局变量等来传递价值等。为什么这一实施为什么会鼓励它?
我最终这样做了: //www.openstm32.org/tiki-view_forum_thread.php?forumId=7&comments_parentId=3169&highlight=CDC_Receive_FS%20usb
尤基地说,解决方案是将接收的数据复制到一个单独的缓冲区中,该缓冲区被声明为usbd_cdc_if.c中的全局变量,然后在#include中声明为全局变量"usb_dcd_if.h"在我的主管。它就太丑了。为什么我必须在Main.c中专门包含该文件,当它已被包含在内"usb_device.h",哪个也在我的主管?

如果我的命令是微不足道,你提到这只会工作。这是为什么?我计划做一些类似SCPI的陈述,例如,"output:volt 10", "output:curr 5" or "output on".

是的,它的stm32cubeide,用cubemx生成的代码。

 

离线 禁止

  • 贡献者
  • 帖子:23
  • 国家: 我们
Re:STM32 Virtual COM端口接收数据(也许更多的C代码问题)
« 回复#4开: 2020年12月22日,晚上11:45:04»
如果我的命令是微不足道,你提到这只会工作。这是为什么?我计划做一些类似SCPI的陈述,例如,"output:volt 10", "output:curr 5" or "output on".
由于USB的64字节数据包。如果您发送的命令长于此,则将在多个回调中拆分。或者,如果您在时间非常接近地发送两条消息,则它们可能会将其组合成F103结束的单个回调。如果发件人感觉就像它一样,即使是小命令也可能跨越多个回调。或者如果新命令进入之前的饰面之前等等。我的版本"trivial"是所有这些问题都被认为是。你必须考虑自己的案例。

这种类型的东西,特别是在与(Async)物理世界互动时,有一种不同的问题和策略,肯定。但它没有't have to be "ugly". You shouldn't从cubemx代码中取出太多线索,其更典范而不是理想。
« 上次编辑:2020年12月22日,PM PM Bugnate 11:49:50 »
 
以下用户感谢此帖子: 幽灵

离线 幽灵

  • 常规贡献者
  • *
  • 帖子:111
Re:STM32 Virtual COM端口接收数据(也许更多的C代码问题)
« 回复#5: 2020年12月22日,晚上11:53:22»
如果我的命令是微不足道,你提到这只会工作。这是为什么?我计划做一些类似SCPI的陈述,例如,"output:volt 10", "output:curr 5" or "output on".
由于USB的64字节数据包。如果您发送的命令长于此,则将在多个回调中拆分。或者,如果您在时间非常接近地发送两条消息,则它们可能会将其组合成F103结束的单个回调。如果发件人感觉就像它一样,即使是小命令也可能跨越多个回调。或者如果新命令进入之前的饰面之前等等。我的版本"trivial"是所有这些问题都被认为是。你必须考虑自己的案例。

这种类型的东西,特别是在与(Async)物理世界互动时,有一种不同的问题和策略,肯定。但它没有't have to be "ugly". You shouldn't从cubemx代码中取出太多线索,其更典范而不是理想。

感谢回复!

为什么内部缓冲区设置为1000字符'默认情况下,如果USB数据包长64个字节?无论如何,似乎"trivial"这意味着我应该将我的命令限制为64个字符(减去a \ n,我猜),这应该足够,对吧?
 

在线的 Langwadt.

  • 超级贡献者
  • ***
  • 帖子:2391
  • 国家: DK.
Re:STM32 Virtual COM端口接收数据(也许更多的C代码问题)
« 回复#6开启: 2020年12月23日,上午12:07:56»
如果我的命令是微不足道,你提到这只会工作。这是为什么?我计划做一些类似SCPI的陈述,例如,"output:volt 10", "output:curr 5" or "output on".
由于USB的64字节数据包。如果您发送的命令长于此,则将在多个回调中拆分。或者,如果您在时间非常接近地发送两条消息,则它们可能会将其组合成F103结束的单个回调。如果发件人感觉就像它一样,即使是小命令也可能跨越多个回调。或者如果新命令进入之前的饰面之前等等。我的版本"trivial"是所有这些问题都被认为是。你必须考虑自己的案例。

这种类型的东西,特别是在与(Async)物理世界互动时,有一种不同的问题和策略,肯定。但它没有't have to be "ugly". You shouldn't从cubemx代码中取出太多线索,其更典范而不是理想。

感谢回复!

为什么内部缓冲区设置为1000字符'默认情况下,如果USB数据包长64个字节?无论如何,似乎"trivial"这意味着我应该将我的命令限制为64个字符(减去a \ n,我猜),这应该足够,对吧?

64字节是最大值,无法保证您将在一个数据包中获取整个命令。

 
以下用户感谢此帖子: 幽灵

离线 禁止

  • 贡献者
  • 帖子:23
  • 国家: 我们
Re:STM32 Virtual COM端口接收数据(也许更多的C代码问题)
« 回复#7: 2020年12月23日,02:14:24»
为什么内部缓冲区设置为1000字符'默认情况下,如果USB数据包长64个字节?

是的,我不'得到它,也很确定这是一个错误。与cubemx一起使用的一部分是为了让您的代码实际上vs."hints that compile"给你一个小的东西。

如果你不'关心膨胀,一个选项是将CDC_Receive_FS()加入_read()(但仍在使用第二个缓冲区等)。这将允许您使用读取(),一切都会再次看起来像典型的CS 123代码。
« 上次编辑:2020年12月23日,02:20:17 AM Butnate »
 

离线 Tagli.

  • 贡献者
  • 帖子:17
  • 国家: TR.
Re:STM32 Virtual COM端口接收数据(也许更多的C代码问题)
« 回复#8开: 2020年12月23日,晚上12:51:25»
为什么内部缓冲区设置为1000字符'默认情况下,如果USB数据包长64个字节?
USB传输可以由多个USB数据包组成。例如,主机PC可以通过单个传输发送1000个字节,单个系统调用(函数调用)。 USB硬件将其划分为64个字节数据包。

F4系列上的OTG_FS硬件可以在其RX缓冲区中存储多个数据包,只要分配的内存就足够了。 F1系列上的FS_DEVICE硬件较低,并且可以在双缓冲模式下存储最大2个数据包(如果我记得正确)。当UC中的硬件缓冲区耗尽时,UC USB硬件将NAK响应到传入数据包。这不是错误/失败。 USB主机继续尝试发送其余传输,直到它命中超时限制(当然,超时表示故障)。理想情况下,在超时发生之前,UC固件从硬件缓冲区移动数据,因此端点可以再次开始接受新数据包,并且传输正常继续。
Gokce taglioglu.
 


分享我

掘客  Facebook  诽谤  可口的  Technorati.  推特  谷歌  雅虎
SMF.