硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1125|回复: 4
收起左侧

[RL-USB-HS-CDC求助]无法连续发送数据

[复制链接]

5

主题

24

回帖

39

积分

新手上路

积分
39
发表于 2022-2-6 14:27:21 | 显示全部楼层 |阅读模式
1.建立了一个Thread专门去发送数据,没有使用信号量或者事件组,用的全局变量判断是不是已经满了2.如果已满则调用USBD_CDC_ACM_WriteData发送数据

3.osDelay(1000)以上才可以正常发送数据,系统的Keneral Fre 设置的默认值1000,改变核心的频率比如改到100Hz,就可以Delay(100),可以初步判断是需要较长空闲的时间

4.但是这个osDelay的值很神奇,无论是发送16484个长数据还是发送1024个短数据都需要1000以上
5.如果配置FS的CDC反而不需要Delay
6.猜测:是因为USBD_CDC_ACM_WriteData需要一段时间发送,但是无法判断是否发送完毕,正在查看ARM的文档
7.猜测:是因为我的设置有问题,对于RL-USB了解不足
  1. /*
  2. *********************************************************************************************************
  3. *        函 数 名: CDC1_ACM_UART_to_USB_Thread
  4. *        功能说明: USB发送任务
  5. *        形    参: 无
  6. *        返 回 值: 无
  7. * 优 先 级: osPriorityNormal
  8. *********************************************************************************************************
  9. */
  10. #ifdef USB_CMSIS_RTOS2
  11. __NO_RETURN static void CDC1_ACM_UART_to_USB_Thread(void *arg)
  12. {
  13. #else
  14. __NO_RETURN void CDC1_ACM_UART_to_USB_Thread(void const *arg)
  15. {
  16. #endif
  17.         (void)(arg);
  18.        
  19.         osStatus_t status;
  20.        
  21.         for (;;)
  22.         {       
  23.                 if(usb_send_full==1)
  24.                 {
  25.                         usb_send_full=0;
  26.                         USBD_CDC_ACM_WriteData(1U,USBD_HIGHSPEED_CDC_Send_Buf1,USB_SEND_BUFFER_SIZE/2);
  27.                 }
  28.                 else if(usb_send_full==2)
  29.                 {
  30.                         usb_send_full=0;
  31.                         usb_send_cnt=0;
  32.                         USBD_CDC_ACM_WriteData(1U,&USBD_HIGHSPEED_CDC_Send_Buf1[USB_SEND_BUFFER_SIZE/2],USB_SEND_BUFFER_SIZE/2);
  33.                 }
  34.                 osDelay(1000U);
  35.         }
  36. }

  37. #ifdef USB_CMSIS_RTOS2
  38. #ifdef USB_CMSIS_RTOS2_RTX5
  39. /*控制块内存*/
  40. static osRtxThread_t cdc1_acm_uart_to_usb_thread_cb_mem __SECTION(.bss.os.thread.cb);
  41. /*栈内存*/
  42. static uint64_t cdc1_acm_uart_to_usb_thread_stack_mem[512U / 8U] __SECTION(.bss.os.thread.stack);
  43. #endif
  44. /*线程参数设置*/
  45. static const osThreadAttr_t cdc1_acm_uart_to_usb_thread_attr = {
  46.         "CDC1_ACM_USB_Thread",
  47.         0U,
  48. #ifdef USB_CMSIS_RTOS2_RTX5
  49.         &cdc1_acm_uart_to_usb_thread_cb_mem,
  50.         sizeof(osRtxThread_t),
  51.         &cdc1_acm_uart_to_usb_thread_stack_mem[0],
  52. #else
  53.         NULL,
  54.         0U,
  55.         NULL,
  56. #endif
  57.         512U,
  58.         osPriorityAboveNormal,
  59.         0U,
  60.         0U};
  61. #else
  62. extern const osThreadDef_t os_thread_def_CDC0_ACM_UART_to_USB_Thread;
  63. osThreadDef(CDC0_ACM_UART_to_USB_Thread, osPriorityNormal, 1U, 0U);
  64. #endif
复制代码




回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106660
QQ
发表于 2022-2-6 15:02:32 | 显示全部楼层
这个有个虚拟串口的例子,参考下那个回调函数实现,你的MDK安装了STM32F4的软件包就看到了。
回复

使用道具 举报

5

主题

24

回帖

39

积分

新手上路

积分
39
 楼主| 发表于 2022-2-6 16:15:43 | 显示全部楼层
eric2013 发表于 2022-2-6 15:02
这个有个虚拟串口的例子,参考下那个回调函数实现,你的MDK安装了STM32F4的软件包就看到了。

您上次说的也是这个,我是参考他的来的,他的代码里是串口3转我们的虚拟串口嘛,我就是照着他的改的,好像也不行,我再试试
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106660
QQ
发表于 2022-2-8 10:48:55 | 显示全部楼层
winddevil 发表于 2022-2-6 16:15
您上次说的也是这个,我是参考他的来的,他的代码里是串口3转我们的虚拟串口嘛,我就是照着他的改的,好 ...

你可以考虑直接把虚拟串口例子跑通了,再修改,这样好点。
回复

使用道具 举报

20

主题

94

回帖

154

积分

初级会员

积分
154
发表于 2024-2-6 18:07:13 | 显示全部楼层
不知道楼主还来不来,不知道楼主有没有解决这个问题。我遇到的问题应该和楼主是一样的。

使用RTE创建的CDC,采用的默认配置,利用向导生成的USBD_User_CDC_ACM_UART_0.c代码。(RLUSB从RTE中看到的版本是6.16.1)

[C] 纯文本查看 复制代码
// Thread: Sends data received on UART to USB
// \param[in]     arg           not used.
#ifdef USB_CMSIS_RTOS2
__NO_RETURN static void CDC0_ACM_UART_to_USB_Thread (void *arg) {
#else
__NO_RETURN        void CDC0_ACM_UART_to_USB_Thread (void const *arg) {
#endif
  int32_t cnt, cnt_to_wrap;
 
  (void)(arg);
 
  for (;;) {
    // UART - > USB
    if (ptrUART->GetStatus().rx_busy != 0U) {
      cnt  = uart_rx_cnt;
      cnt += (int32_t)ptrUART->GetRxCount();
      cnt -= usb_tx_cnt;
      if (cnt >= UART_BUFFER_SIZE) {
        // Dump data received on UART if USB is not consuming fast enough
        usb_tx_cnt += cnt;
        cnt = 0U;
      }
      if (cnt > 0) {
        cnt_to_wrap = (int32_t)(UART_BUFFER_SIZE - ((uint32_t)usb_tx_cnt & (UART_BUFFER_SIZE - 1)));
        if (cnt > cnt_to_wrap) {
          cnt = cnt_to_wrap;
        }
        cnt = USBD_CDC_ACM_WriteData(0U, (uart_rx_buf + ((uint32_t)usb_tx_cnt & (UART_BUFFER_SIZE - 1))), cnt);
        if (cnt > 0) {
          usb_tx_cnt += cnt;
        }
      }
    }
    (void)osDelay(10U);
  }
}

模板中的代码将UART接收到的数据转发到USB,for(;;)循环中,使用的延时是osDelay(10); 我测试另外用一个串口给这个CDC发数据“1234567890”,定时1ms发送,这个代码可以很好的将UART接收到的数据转发到USB。

然后,我将上面代码,替换成如下精简的代码。
[C] 纯文本查看 复制代码
#ifdef USB_CMSIS_RTOS2
__NO_RETURN static void CDC0_ACM_UART_to_USB_Thread (void *arg) {
#else
__NO_RETURN        void CDC0_ACM_UART_to_USB_Thread (void const *arg) {
#endif
  int32_t cnt, cnt_to_wrap;
 
  
  (void)(arg);
 
	for(int i = 0; i < CDC_BUFFER_SIZE; i++)
	{
		cdc_tx_buf[i] = i;
	}
	
  for (;;) {
    // UART - > USB
    USBD_CDC_ACM_WriteData(0U, cdc_tx_buf, 1);
    (void)osDelay(500U);
  }
}

每次发送固定的数据,osDelay(500),串口助手可以收到CDC发过来的数据。
osDelay改成400,100,10等值测试,都无法收到数据。
每次发送的数据个数从1到4096都没问题(更大的值没有测试了)。

模板代码没看到什么神奇的地方,为啥模板代码可以用osDelay(10),而我这个简单的代码却必须osDelay(500)以上?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-4-29 04:41 , Processed in 0.163960 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表