在Rosserial的用法这篇文章中,我们介绍了如何在stm32中通过串口添加ROS的功能和接口,这篇文章接着上篇,介绍如何通过VCP虚拟串口来提升Rosserial的性能。

通过cube添加VCP驱动

首先按网上教程用cube在项目中添加VCP虚拟串口,具体步骤就不详述了,到处都能找到,这里要强调的是,USB FS模式下必须设置48Mhz的时钟。

修改VCP驱动

我们需要修改usbd_cdc_if.c 和usbd_cdc_if.h文件
打开usbd_cdc_if.c ,首先修改CDC_Receive_FS()回调函数,代码如下:

static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
{/* USER CODE BEGIN 6 */WirteRingbuffer(&usb_vcp_ringbuf,Buf,*Len);USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);USBD_CDC_ReceivePacket(&hUsbDeviceFS);return (USBD_OK);/* USER CODE END 6 */
}

其实只添加了WirteRingbuffer(&usb_vcp_ringbuf,Buf,*Len);这一行,usb_vcp_ringbuf是一个环形缓冲区,我们将usb串口接收到的数据暂存到里面。
接下来在usbd_cdc_if.c 中,还是添加三个函数,分别是Vcp_Read、Vcp_Write和Vcp_Available,代码如下:

uint32_t Vcp_Available(void) {return GetRingbufferValidLen(&usb_vcp_ringbuf);
}
//从接收缓冲区中读取
uint8_t Vcp_Read(void) {uint8_t ch = 0;taskENTER_CRITICAL();ReadRingbuffer(&usb_vcp_ringbuf,&ch,1);taskEXIT_CRITICAL();return ch;
}
//通过usb_vcp向外发送
void Vcp_Write(uint8_t *Buf, uint16_t Len) {while (CDC_Transmit_FS(Buf, Len) != HAL_OK) {osDelay(1);};
}

代码也很简单,这里主要强调两点:

  1. VCP接收回调函数CDC_Receive_FS是中断里面执行的,也就是说,对环形缓冲区usb_vcp_ringbuf进行写操作是在中断中完成的,而Vcp_Read中,对环形缓冲区进行读操作是在任务里面完成的,因此最好对读环形缓冲区加一个保护,最简单的方式就是加一个临界区,当然也可以用信号量来实现
  2. Vcp_Write通过VCP发送数据时,由于有个等待发送ok的过程,最好在等待的循环中加一个osDelay(1),以便留给操作系统更多调度时间

最后我们在usbd_cdc_if.h中添加上述三个函数的声明

 /* USER CODE BEGIN EXPORTED_FUNCTIONS */
void Vcp_Write(uint8_t* Buf, uint16_t Len);
uint8_t Vcp_Read(void);
uint32_t Vcp_Available(void);
/* USER CODE END EXPORTED_FUNCTIONS */

修改Rosserial接口

同样的,进入STM32Hardware.h文件,分别实现三个函数:int read()、 void write(uint8_t *data, int length)及unsigned long time()就可以了

class STM32Hardware {protected:
public:STM32Hardware() {}void init() {}int read() {if (Vcp_Available()) {return Vcp_Read();} else {return -1;}}void flush(void) {}void write(uint8_t *data, int length) { Vcp_Write(data, length); }unsigned long time() { return HAL_GetTick(); }protected:
};

其它说明

  1. 改为VCP后,将stm32通过虚拟串口接入上位机,串口识别的名字可能会有变化,默认可能会变成/dev/ttyACM0,另外,使用serial_node.py连接stm32时,波特率的设置是没有意义的,实际传输是按照USB的速度执行。传输速度比普通串口还是要快得多的。
  2. 按默认配置实际使用中,如果通过rosserial收发的消息较多,有可能会收到错误提示:
    Message from device dropped: message larger than buffer.
    这是由于Node Handle中默认定义的输入输出缓冲大小太小造成,我们打开项目的ros.h文件,找到下面的代码。
namespace ros
{typedef NodeHandle_<STM32Hardware, 25, 25, 512, 512> NodeHandle; // default 25, 25, 512, 512
}

这个模板NodeHandle_的定义在ros/node_handle.h里

/* Node Handle */
template<class Hardware,int MAX_SUBSCRIBERS = 25,int MAX_PUBLISHERS = 25,int INPUT_SIZE = 512,int OUTPUT_SIZE = 512>

可以看到这四个数分别表示最大的订阅消息数、最大发送消息数、输入和输出缓冲大小。我们把后面两个数改大即可,在ros.h中修改NodeHandle的声明,根据自己芯片的可用内存大小适当改大两个缓冲区即可。比如我改成了1024

namespace ros
{typedef NodeHandle_<STM32Hardware, 25, 25, 1024, 1024> NodeHandle; // default 25, 25, 512, 512
}

除此之外,VCP本身还有个缓冲区大小,在usbd_cdc_if.h中,有两个宏定义,分别是APP_RX_DATA_SIZE和APP_TX_DATA_SIZE ,如果stm32内存比较充裕,这个也可以尽量大点,我一般设为2048

#define APP_RX_DATA_SIZE  2048
#define APP_TX_DATA_SIZE  2048

基于VCP虚拟串口的Rosserial接口教程相关推荐

  1. STM32 USB复合设备(VCP虚拟串口+HID键盘)详解

    USB复合设备 介绍 USB复合设备与组合设备区别 USB描述符修改 修改CustomHID_Reset 修改CustomHID_Data_Setup 介绍 本次使用的是Keil 5+STM32F10 ...

  2. USB VCP虚拟串口通讯详细配置步骤(STM32H732)

    USB VCP虚拟串口通讯详细配置步骤(STM32H732) 一.软件版本 二.CodeMX配置 1.使能外部高速时钟. 2.开启USB外设,选择USB Device功能,速度为默认全速USB设备12 ...

  3. 单片机-stm32-使用cdc类实现vcp(虚拟串口)

    本文所述内容基于STM32 HAL库完成 安装stm32CubeMx(ver4.26.0) 新建工程,选择stm32f412zg tx 配置RCC->HSE->crystal/Cerami ...

  4. stm32 usb 虚拟串口 相同_RTThread STM32 虚拟串口代码级移植

    背景介绍: 关于"虚拟串口" Sugar 发过一篇<RT-Thread 使用 CubeMX 的 VCP(虚拟串口)> <软件架构训练计划>选择 CubeMX ...

  5. 关于虚拟串口驱动专业版 Eltima Virtual Serial Port Driver Pro 最新版本 V10.0.979

    关于虚拟串口驱动专业版 Eltima Virtual Serial Port Driver Pro 最新版本 V10.0.979 Virtual Serial Port Driver PRO 是基于「 ...

  6. Jlink v9虚拟串口功能,不用再单独购买串口线了

    前言 买来JLINK之后除了调试之外,也没用过其他什么功能,由于最近需要用到串口功能,看到jlink有虚拟串口功能,便试了试,发现还挺好用,特地分享一下. 一.如何打开虚拟串口功能? 安装完jlink ...

  7. STM32 USB使用记录:使用CDC类虚拟串口(VCP)进行通讯

    文章目录 目的 基础说明 使用STM32CubeIDE配置生成代码 用户代码分析 回环测试 串口参数设置 USB HS使用与演示 通讯速率测试 测试代码 USB FS测试 USB HS测试 影响速度的 ...

  8. STM32F407 CUBEMX RT-Thread USB虚拟串口(VCP)

    STM32F407 CUBEMX RT-Thread USB虚拟串口(VCP) 记录一下STM32平台下使用RT-Thread使用VCP 首先确定HAL_Drivers下是否有RT-Thread提供的 ...

  9. linux系统串口透传,基于CC2540的USB虚拟串口透传方案

    1.USB虚拟串口代替物理串口的可行性 首先,越来越多带USB接口的器件涌现出来,如带USB接口的单片机,或独立的USB接口器件,而且这些器件的成本已经很接近于使用RS232电平转换芯片所带来的成本. ...

最新文章

  1. sort (STL)
  2. 整数划分问题(续)(非递归法)
  3. JS关于时间的一些计算与获取
  4. php+spl+栈,PHP SPL标准库之数据结构栈(SplStack)介绍
  5. sgu 175 Encoding
  6. 关于WinCE6.0补丁包的一点说明
  7. 手动编辑文件解决冲突_4.2.1 git am patch手动解决冲突的办法
  8. 水体专题图和土地利用专题图制作
  9. PowerPoint优点全体验
  10. 项目管理软件浮出水面(转)
  11. 问卷星全自动填写脚本浅尝
  12. 行式 Excel 文件比对
  13. 漫谈TCP-AIMD/BBR的公平性以及buffer bloat
  14. Hash算法及数字签名【六】
  15. Windows MSDOS的批处理文件命令
  16. 大数据hadoop讲解
  17. 毕业生见习期考核鉴定表(单位考核意见)
  18. 橡胶支座抗压弹性模量计算公式_橡胶支座计算
  19. 微信云开发-后端-快速上手
  20. matlab把图像进行网格化,或者是在图像中画网格

热门文章

  1. 排列与组合中的递归策略(as3.0)
  2. 服务器生成微信sign,签名生成方法
  3. 哪款蓝牙耳机的音质好?四款音质最好的蓝牙耳机测评
  4. css3简单实现页面中出现雪花飘落效果
  5. 有一种蓝叫 APEC 蓝
  6. python正则表达式编译_用Python编译正则表达式
  7. 尚硅谷前端视频总结(二)
  8. 汕尾市海陆丰民间开胃小食摘录
  9. Oracle数据库学习的第二天(Oracle的简单操作)
  10. 腾讯云数据库联手宇信科技发布联合方案,全面助力金融科技安全可控