VSF中的通用USB設備協(xié)議棧:應用部分

VSF中實現(xiàn)了一個相對通用的USB設備端協(xié)議棧,可以通過移植芯片的USB SIE驅(qū)動,來支持不同的MCU。USB設備端協(xié)議棧的實現(xiàn)只用到了最基本的事件驅(qū)動機制,并且,USB的各個中斷響應,沒有實時性要求。VSF的USB代碼都位于vsf/component/usb目錄下,core目錄下的vsfusbd.c是協(xié)議棧主體、dcd(device controller driver設備控制器驅(qū)動)目錄下是USB設備控制芯片的驅(qū)動、class/device目錄下是USB設備類的驅(qū)動。

先從應用角度來看,使用USB設備端協(xié)議棧只需要定義一個vsfusbd_device_t數(shù)據(jù)結(jié)構(gòu),然后調(diào)用vsfusbd_device_init即可,以下是典型的USBD應用代碼:

static void usrapp_usbd_conn(void *p)
{
    struct usrapp_t *app = (struct usrapp_t *)p;

    vsfusbd_device_init(&app->usbd.device);
    app->usbd.device.drv->connect();
    if (app->hwcfg->usbd.pullup.port != VSFHAL_DUMMY_PORT)
        vsfhal_gpio_set(app->hwcfg->usbd.pullup.port, 1 << app->hwcfg->usbd.pullup.pin);
}

void usrapp_srt_init(struct usrapp_t *app)
{
    if (app->hwcfg->usbd.pullup.port != VSFHAL_DUMMY_PORT)
    {
        vsfhal_gpio_init(app->hwcfg->usbd.pullup.port);
        vsfhal_gpio_clear(app->hwcfg->usbd.pullup.port, 1 << app->hwcfg->usbd.pullup.pin);
        vsfhal_gpio_config(app->hwcfg->usbd.pullup.port, app->hwcfg->usbd.pullup.pin, VSFHAL_GPIO_OUTPP);
    }
    app->usbd.device.drv->disconnect();

    vsftimer_create_cb(200, 1, usrapp_usbd_conn, app);
}

應用層定義好app->usbd.device數(shù)據(jù)結(jié)構(gòu)后,代碼上就非常簡單和固化了,在軟實時初始化里,斷開USB上拉,建立一個200ms的定時器,超時后執(zhí)行usrapp_usbd_conn,調(diào)用vsfusbd_device_init、連接USB并且使能上拉。所以應用部分的關(guān)鍵就是在這個vsfusbd_device_t數(shù)據(jù)結(jié)構(gòu)的定義,這個決定了USB實現(xiàn)的功能。

這里,以mscboot的應用代碼作為示例,截取USB設備端數(shù)據(jù)結(jié)構(gòu)的定義:

    .usbd.msc.param.ep_in                   = 1,
    .usbd.msc.param.ep_out                  = 1,
    .usbd.msc.param.scsi_dev                = &usrapp.mal.scsi_dev,
    .usbd.ifaces[0].class_protocol          = (struct vsfusbd_class_protocol_t *)&vsfusbd_MSCBOT_class,
    .usbd.ifaces[0].protocol_param          = &usrapp.usbd.msc.param,
    .usbd.config[0].num_of_ifaces           = dimof(usrapp.usbd.ifaces),
    .usbd.config[0].iface                   = usrapp.usbd.ifaces,
    .usbd.device.num_of_configuration       = dimof(usrapp.usbd.config),
    .usbd.device.config                     = usrapp.usbd.config,
    .usbd.device.desc_filter                = (struct vsfusbd_desc_filter_t *)usrapp_param.usbd.StdDesc,
    .usbd.device.device_class_iface         = 0,
    .usbd.device.drv                        = (struct vsfhal_usbd_t *)&vsfhal_usbd,
    .usbd.device.int_priority               = 0xFF,

device.drv指向一個vsfhal_usbd_t結(jié)構(gòu)的數(shù)據(jù),指定底層的USB設備驅(qū)動。常用的底層設備驅(qū)動有vsfhal_usbd(芯片內(nèi)置的USB設備接口驅(qū)動)、vsfsdcd_usbd(GPIO模擬低速USB的接口驅(qū)動)、vbususbd_drv(虛擬vbus總線上實現(xiàn)的USB設備接口驅(qū)動)等等。device.int_priority定義驅(qū)動使用到的中斷的優(yōu)先級。這些的定義是和硬件有關(guān)的。

其他定義都和硬件無關(guān),只是指定了實現(xiàn)什么樣的USB設備。了解USB的人應該都知道,USB是由configuration、interface、endpoint組成的。一個設備可以有多個configuration,由device.num_of_configuration和device.config指定。上述代碼里,只有一個configuration:

    .usbd.config[0].num_of_ifaces           = dimof(usrapp.usbd.ifaces),
    .usbd.config[0].iface                   = usrapp.usbd.ifaces,

然后,每個configuration可以包含多個interface,上述代碼里,也只有一個interface:

    .usbd.ifaces[0].class_protocol          = (struct vsfusbd_class_protocol_t *)&vsfusbd_MSCBOT_class,
    .usbd.ifaces[0].protocol_param          = &usrapp.usbd.msc.param,

這里的interface是vsfusbd_MSCBOT_class類的,也就是U盤的設備類。這里class_protocol指定了類協(xié)議,protocol_param指定了參數(shù):

    .usbd.msc.param.ep_in                   = 1,
    .usbd.msc.param.ep_out                  = 1,
    .usbd.msc.param.scsi_dev                = &usrapp.mal.scsi_dev,

這個就是MSC類需要設置的參數(shù)。指定了輸入輸出的ep端口號,并且指定了一個scsi設備。

所以,總的來說,vsfusbd_device_t里定義了和硬件相關(guān)的設置、定義了描述符的設置、定義了從configuration到interface的結(jié)構(gòu)、然后再定義各個interface的參數(shù)。有了這些信息,USB設備端協(xié)議棧就可以運行起來了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容