[应用方案] VSF上的USB设备端的声明式开发范式,20行代码实现 -- 已开源

[复制链接]
471|10
 楼主 | 2019-12-27 13:59 | 显示全部楼层 |阅读模式
本帖最后由 vsfopen 于 2019-12-31 15:10 编辑

之前发了第一版USB设备端的简化开发方式,但是。。。代码还是太。。。复杂了,还需要继续简化,第二轮优化大致出来,有望本周更新开源(可能会做一些小调整)先科普一下,声明式的开发范式里,用户需要描述符的只是what,其他的实现细节,自动处理。

还是一样,直接上代码,功能是实现一个USB CDC串口:
  1. #include "vsf.h"

  2. implement_usbd(user_usbd, 0x2348, 0xA7A8, 0x0409, USB_DC_SPEED_HIGH)
  3.     implement_usbd_common_desc(user_usbd, u"VSF-USBD-Simplest", u"SimonQian", u"1.0.0", 64, USB_DESC_CDC_ACM_IAD_LEN, USB_CDC_ACM_IFS_NUM, USB_CONFIG_ATT_WAKEUP, 100)
  4.         implement_cdc_acm_desc(user_usbd, 0, 0, 1, 2, 2, 512, 16)
  5.     implement_usbd_func_desc(user_usbd)
  6.         implement_usbd_func_str_desc(user_usbd, 0, u"VSF-CDC")
  7.     implement_usbd_std_desc_table(user_usbd)
  8.         implement_usbd_func_str_desc_table(user_usbd, 0)
  9.     implement_usbd_device_func(user_usbd)
  10.         implement_cdc_acm_func(user_usbd, 0, 1, 2, 2, NULL, NULL, USB_CDC_ACM_LINECODE(115200, 8, USB_CDC_ACM_PARITY_NONE, USB_CDC_ACM_STOPBIT_1))
  11.     implement_usbd_device_ifs(user_usbd)
  12.         implement_cdc_acm_ifs(user_usbd, 0)
  13. end_implement_usbd(user_usbd, VSF_USB_DC0)

  14. void main(void)
  15. {
  16.     vk_usbd_init(&user_usbd);
  17.     vk_usbd_connect(&user_usbd);
  18. }
复制代码

vsfusbd_cdc1.png

第二轮优化后,用户已经不需要在意数据结构了,只需要在意USB设备的参数,以及实现的功能(func)。
用户实现方式,就是填参数,并且根据功能,调用对应的宏然后继续填入参数即可。

使用特权

评论回复
 楼主 | 2019-12-27 14:07 | 显示全部楼层
本帖最后由 vsfopen 于 2019-12-27 14:33 编辑

基于1楼demo,做简单的修改,实现2路CDC串口,代码和截图如下(红色的是做的修改或者增加):

#include "vsf.h"

implement_usbd(user_usbd, 0x2348, 0xA7A8, 0x0409, USB_DC_SPEED_HIGH)
    implement_usbd_common_desc(user_usbd, u"VSF-USBD-Simplest", u"SimonQian", u"1.0.0", 64, 2 * USB_DESC_CDC_ACM_IAD_LEN, 2 * USB_CDC_ACM_IFS_NUM, USB_CONFIG_ATT_WAKEUP, 100)
        implement_cdc_acm_desc(user_usbd, 0, 0, 1, 2, 2, 512, 16)
        implement_cdc_acm_desc(user_usbd, 1 * USB_CDC_ACM_IFS_NUM, 1, 3, 4, 4, 512, 16)
    implement_usbd_func_desc(user_usbd)
        implement_usbd_func_str_desc(user_usbd, 0, u"VSF-CDC0")
        implement_usbd_func_str_desc(user_usbd, 1, u"VSF-CDC1")
    implement_usbd_std_desc_table(user_usbd)
        implement_usbd_func_str_desc_table(user_usbd, 0)
        implement_usbd_func_str_desc_table(user_usbd, 1)
    implement_usbd_device_func(user_usbd)
        implement_cdc_acm_func(user_usbd, 0, 1, 2, 2, NULL, NULL, USB_CDC_ACM_LINECODE(115200, 8, USB_CDC_ACM_PARITY_NONE, USB_CDC_ACM_STOPBIT_1))
        implement_cdc_acm_func(user_usbd, 1, 3, 4, 4, NULL, NULL, USB_CDC_ACM_LINECODE(115200, 8, USB_CDC_ACM_PARITY_NONE, USB_CDC_ACM_STOPBIT_1))
    implement_usbd_device_ifs(user_usbd)
        implement_cdc_acm_ifs(user_usbd, 0)
        implement_cdc_acm_ifs(user_usbd, 1)
end_implement_usbd(user_usbd, VSF_USB_DC0)

void main(void)
{
    vk_usbd_init(&user_usbd);
    vk_usbd_connect(&user_usbd);
}

vsfusbd_cdc2.png


使用特权

评论回复
 楼主 | 2019-12-27 14:15 | 显示全部楼层
本帖最后由 vsfopen 于 2019-12-27 14:33 编辑

基于2楼代码,再增加一个MSC试试:

#include "vsf.h"

implement_usbd(user_usbd, 0x2348, 0xA7A8, 0x0409, USB_DC_SPEED_HIGH)
    implement_usbd_common_desc(user_usbd, u"VSF-USBD-Simplest", u"SimonQian", u"1.0.0", 64, 2 * USB_DESC_CDC_ACM_IAD_LEN + USB_DESC_MSCBOT_IAD_LEN, 2 * USB_CDC_ACM_IFS_NUM + USB_MSCBOT_IFS_NUM, USB_CONFIG_ATT_WAKEUP, 100)
        implement_cdc_acm_desc(user_usbd, 0, 0, 1, 2, 2, 512, 16)
        implement_cdc_acm_desc(user_usbd, 1 * USB_CDC_ACM_IFS_NUM, 1, 3, 4, 4, 512, 16)
        implement_msc_desc(    user_usbd, 2 * USB_CDC_ACM_IFS_NUM, 2, 5, 5, 512)
    implement_usbd_func_desc(user_usbd)
        implement_usbd_func_str_desc(user_usbd, 0, u"VSF-CDC0")
        implement_usbd_func_str_desc(user_usbd, 1, u"VSF-CDC1")
        implement_usbd_func_str_desc(user_usbd, 2, u"VSF-MSC0")
    implement_usbd_std_desc_table(user_usbd)
        implement_usbd_func_str_desc_table(user_usbd, 0)
        implement_usbd_func_str_desc_table(user_usbd, 1)
        implement_usbd_func_str_desc_table(user_usbd, 2)
    implement_usbd_device_func(user_usbd)
        implement_cdc_acm_func(user_usbd, 0, 1, 2, 2, NULL, NULL, USB_CDC_ACM_LINECODE(115200, 8, USB_CDC_ACM_PARITY_NONE, USB_CDC_ACM_STOPBIT_1))
        implement_cdc_acm_func(user_usbd, 1, 3, 4, 4, NULL, NULL, USB_CDC_ACM_LINECODE(115200, 8, USB_CDC_ACM_PARITY_NONE, USB_CDC_ACM_STOPBIT_1))
        implement_msc_func(    user_usbd, 2, 5, 5, 0, NULL, NULL)
    implement_usbd_device_ifs(user_usbd)
        implement_cdc_acm_ifs(user_usbd, 0)
        implement_cdc_acm_ifs(user_usbd, 1)
        implement_msc_ifs(user_usbd, 2)
end_implement_usbd(user_usbd, VSF_USB_DC0)

void main(void)
{
    vk_usbd_init(&user_usbd);
    vk_usbd_connect(&user_usbd);
}

这里也都是增量式的开发方式,增加新功能,那就增加新的宏,并且填参数。
这里MSC是跑不起来的,因为MSC不仅仅需要USB,还需要一个SCSI设备(可以用一块内存模拟),目前仅仅有USB部分的代码是没用的

其实,之前的CDC也只是USB部分,并没有实现数据流的代码,这里演示的也只是USB的极简化开发方式

使用特权

评论回复
 楼主 | 2019-12-27 14:31 | 显示全部楼层

代码已经提交

本帖最后由 vsfopen 于 2019-12-29 17:17 编辑

VSF项目的git仓库:https://github.com/vsfteam/vsf

下载之后,使用IAR打开工程,工程位于:vsf/tree/master/source/example/project/iar_8.4

工程需要选择:usbd_demo_simplest
usbd_simplest.png

然后可以直接编译,下载,硬件使用M484,USB设备口接电脑

用户代码只要一个最简配置文件和一个main.c


另外,在上一个echo的demo,红色为改动的地方,这里实现了一个1K的mem_stream流(实际大小可修改,大于一个EP size就行),并且让CDC的收发流都指向这个,就实现了echo功能:
#include "vsf.h"

implement_mem_stream(user_usbd_cdc_acm_stream, 1024)

implement_usbd(user_usbd, 0x2348, 0xA7A8, 0x0409, USB_DC_SPEED_HIGH)
    implement_usbd_common_desc(user_usbd, u"VSF-USBD-Simplest", u"SimonQian", u"1.0.0", 64, USB_DESC_CDC_ACM_IAD_LEN, USB_CDC_ACM_IFS_NUM, USB_CONFIG_ATT_WAKEUP, 100)
        implement_cdc_acm_desc(user_usbd, 0, 0, 1, 2, 2, 512, 16)
    implement_usbd_func_desc(user_usbd)
        implement_usbd_func_str_desc(user_usbd, 0, u"VSF-CDC")
    implement_usbd_std_desc_table(user_usbd)
        implement_usbd_func_str_desc_table(user_usbd, 0)
    implement_usbd_device_func(user_usbd)
        implement_cdc_acm_func(user_usbd, 0, 1, 2, 2, &user_usbd_cdc_acm_stream, &user_usbd_cdc_acm_stream, USB_CDC_ACM_LINECODE(115200, 8, USB_CDC_ACM_PARITY_NONE, USB_CDC_ACM_STOPBIT_1))
    implement_usbd_device_ifs(user_usbd)
        implement_cdc_acm_ifs(user_usbd, 0)
end_implement_usbd(user_usbd, VSF_USB_DC0)

void main(void)
{
    vk_usbd_init(&user_usbd);
    vk_usbd_connect(&user_usbd);
}

使用特权

评论回复
| 2019-12-27 22:16 | 显示全部楼层
谢谢!VSF到底是什么?

使用特权

评论回复
 楼主 | 2019-12-28 13:03 | 显示全部楼层
dyyxp 发表于 2019-12-27 22:16
谢谢!VSF到底是什么?

VSF是我们自己的系统,抢占式事件驱动内核,自己的各个协议栈,文件系统等等。支持一些比较特殊的开发方式,比如都在PC上用visual studio开发调试,然后基本不需要太大修改,在IAR/MDK里编译。还可以直接使用某些linux的应用代码,arduino的应用代码等等。

使用特权

评论回复
| 2019-12-28 15:53 | 显示全部楼层
牛,看起来高大上的

使用特权

评论回复
 楼主 | 2019-12-28 23:43 | 显示全部楼层
刚刚公开了代码,之后再玩啥呢?USB主机口吗?
USB主机可以可以玩的东西很多,不过都不仅仅是USB了,还需要高层的应用
比如,支持USB网卡,就需要tcpip;支持USB蓝牙dongle,就需要蓝牙协议栈;支持U盘,就需要文件系统。
当然,这些我们大部分都搞定了

使用特权

评论回复
| 2019-12-28 23:49 | 显示全部楼层
马上去看看

使用特权

评论回复
 楼主 | 2019-12-29 13:17 | 显示全部楼层
msc的demo也更新了,usbd_demo_msc配置
这个demo里,USB还只是一部分,实现了MSC
还有通过一些数据结构,实现FAT32的文件系统,磁盘大小1M(支持windows,不支持mac,max的fat识别不如windows的,需要改大容量才能识别)

使用特权

评论回复
| 2019-12-31 10:14 | 显示全部楼层

使用特权

评论回复
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

我要发帖 投诉建议 创建版块 申请版主

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式

论坛热帖

在线客服 快速回复 返回顶部 返回列表