衡阳派盒市场营销有限公司

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

基于DWC2的USB驅動開發-0x0C 驅動框架設計

嵌入式USB開發 ? 來源: 嵌入式USB開發 ? 作者: 嵌入式USB開發 ? 2023-06-05 17:15 ? 次閱讀

本文轉自公眾號,歡迎關注

基于DWC2的USB驅動開發-0x0C 驅動框架設計 (qq.com)

一. 驅動架構

1.1 前言

前面我們介紹了DWC2的控制器相關的寄存器,驅動的編寫本質上就是進行寄存器的配置。為了代碼的健壯性,可移植性,可調試性等我們必須設計一個比較好的架構。對于驅動編程來說輸入就是各個寄存器,如果使用的都是DWC2的話甚至來說寄存器都是一樣的輸入就只需要寄存器基地址,即如果都是使用該IP的驅動甚至只要修改寄存器基地址,然后移植中斷等一些和SOC相關的內容即可復用。

1.2 架構框圖

圖片

整體的設計思想如下:

借鑒面向對象的設計的依賴倒置原則:

面向接口編程,不依賴具體實現編程,應用層不直接依賴具體實現而是依賴接口,上層調用接口底層實現接口,接口是硬件隔離的橋梁.

接口即對應上圖的HAL層。

硬件: 對于使用DWC2控制器的則還可以復用HW層本身的內容,只需要修改寄存器的基地址即可,因為DWC2控制器寄存器都是一樣的。另外需要修改一些和SOC相關的內容,比如中斷的設置。對于不同的控制器和SOC平臺的則需要根據具體的平臺進行封裝。理論上也可以直接依賴硬件實現HAL層,而不需要HW層的封裝,但是這樣的話直接在HAL層操作寄存器代碼的閱讀性上不佳。

HW層:即對頭文件中寄存器的操作進行封裝,主要采用宏的方式封裝,目的是為了可閱讀性。同時對于一些聯系緊密的操作放在一起進行封裝,比如初始化等,提供比如結構體參數等,進行相應的參數配置。這一層對于使用同樣的DWC2控制器的也完全可復用。

HAL層:這是硬件和上層隔離的一層,定義了一系列接口,協議棧調用該接口進行硬件操作,而HAL調用HW層實現上述的接口。對于不使用DWC2控制器的,則需要重新實現HAL層,而同使用DWC2控制器的則本層也通用。本層的設計原則是接口個數盡可能少和簡單但是要足夠滿足協議棧層的需要。符合面向對象設計的最少知道原則。

協議棧層:依賴HAL接口,實現USB規格書規定的協議。

協議棧和HAL層以及以下的層次,盡可能不進行資源分配(比如內存)等預留相應的接口,資源分配由應用層實現,這樣設計的目的是在嵌入式開發環境資源往往受限,資源的分配往往需要應用層來把控,應用層來負責。底層盡可能少的依賴資源,盡可能保持確定性,避免過多動態行為。

應用層:調用協議棧實現具體的應用功能。

考慮到通用性和可移植性,我們要支持OS和無OS的實現,所以非必要不依賴OS相關的API,如果不可避免則盡可能少依賴,且實現需要依賴的API的OS和NONE-OS版本,將依賴抽離出來作為需要移植實現的部分,使得在不同OS和裸機下都能運行,這里會涉及到協議棧基于中斷驅動的處理方式和基于事件驅動的處理方式兩種實現,后面到協議棧設計部分再說。

1.3 調試方案

調試手段是驅動開發中需要重點考慮的一環,沒有合適的調試手段,遇到問題,會兩眼一抹黑完全無從下手。進行USB開發,硬件上示波器和協議分析儀是必須的。另外軟件上也需要一些手段配合調試。以下是幾種常見的方式。

1.3.1 仿真器

這是嵌入式開發必須的,尤其是驅動開發階段,需要跟蹤代碼流,寄存器的配置,變量的值等等。仿真器調試有個問題就是需要中斷正常的程序流.USB是一個有著嚴格時序要求,且高速的協議,程序中斷會導致USB的處理過程由于超時等導致異常,所以很多時候不能通過仿真器打斷點等方式進行調試。

1.3.2 IO

USB由于其嚴格的時序要求,且高速的處理,很多時候我們需要測試相應的處理時間,使用定時器進行計時并打印時間是一種方法,但是對于高精度計時定時器的處理代碼本身需要時間會帶來誤差。這時使用IO翻轉,來指示某種狀態的變化非常有用,比如測試SOF之間的時間,可以在SOF中斷中翻轉IO,使用示波器或者邏輯分析儀測量波形即可。翻轉IO往往一條指令即可,這使得代碼帶來的誤差減小。

更重要的是可以通過多個IO關聯多個事件,看到多個事件之間的關聯關系,尤其是使用示波器和邏輯分析儀查看時。曲線會非常直觀。這是使用定時器打印所不具備的。

IO翻轉的調試方法是嵌入式實時分析中重要的手段。

1.3.3 串口打印

USB的處理流程對應著狀態的流轉,實際對于軟件來說過是各種中斷的進入與退出。使用仿真器跟蹤會破壞USB的處理流程導致超時等,所以需要一個非中斷方式的跟蹤事件的方式。常見的方式是使用串口打印,這里要注意串口打印不能使用阻塞方式,否則同樣的會導致USB處理流的異常。一般采用緩沖區的方式,打印接口將數據寫入緩沖區,主循環或者其他線程中將緩沖區的數據通過串口發送。

當然除了串口打印還有很多其他類似的方式比如 Jlink提供的rtt等性能更高,也可以使用網口等接口,根據具體平臺而定。

串口打印可是設置為宏的方式,debug版本使能,release版本可不使能,打印輸出也可以設置等級和類別,這樣通過等級和類別控制輸出,避免一次打印過多干擾分析,也可以使用CLI動態配置等級可列別的控制。

如下是一個簡單的示例,依賴printf,假設printf已經實現是一個非阻塞的版本(即寫入緩沖區),其他地方再真正的發送數據。可以通過宏配置不同等級的LOG,且打印信息對應不同的顏色。

頭文件中

#define USB_HAL_DEBUG 1
#define USB_HAL_LOG_LEVEL_ERROR 1
#define USB_HAL_LOG_LEVEL_WARN 1
#define USB_HAL_LOG_LEVEL_INFO 1


/** Debug levels */
typedef enum 
{
    USB_HAL_DEBUG_ERROR = 0,
    USB_HAL_DEBUG_WARN  = 1,
    USB_HAL_DEBUG_INFO  = 2,
}USB_HAL_DEBUG_e;


#define USB_HAL_DEBUG_COLOR_MASK_COLOR  0x0F
#define USB_HAL_DEBUG_COLOR_MASK_MODIFIER   0xF0


typedef enum {
    /* Colors */
    USB_HAL_DEBUG_COLOR_RESET       = 0xF0,
    USB_HAL_DEBUG_COLOR_BLACK       = 0x01,
    USB_HAL_DEBUG_COLOR_RED     = 0x02,
    USB_HAL_DEBUG_COLOR_GREEN       = 0x03,
    USB_HAL_DEBUG_COLOR_YELLOW  = 0x04,
    USB_HAL_DEBUG_COLOR_BLUE        = 0x05,
    USB_HAL_DEBUG_COLOR_MAGENTA = 0x06,
    USB_HAL_DEBUG_COLOR_CYAN        = 0x07,
    USB_HAL_DEBUG_COLOR_WHITE       = 0x08,
    /* Modifiers */
    USB_HAL_DEBUG_COLOR_NORMAL  = 0x0F,
    USB_HAL_DEBUG_COLOR_BOLD        = 0x10,
    USB_HAL_DEBUG_COLOR_UNDERLINE   = 0x20,
    USB_HAL_DEBUG_COLOR_BLINK       = 0x30,
    USB_HAL_DEBUG_COLOR_HIDE        = 0x40,
} USB_HAL_DEBUG_COLOR_e;


void usb_hal_do_debug(USB_HAL_DEBUG_e level, const char *format, ...);


#ifdef USB_HAL_DEBUG
    #define usb_hal_debug(level, format, ...) do { usb_hal_do_debug(level, format, ##__VA_ARGS__); } while(0)
#else
    #define usb_hal_debug(...) do {} while (0)
#endif


#ifdef USB_HAL_LOG_LEVEL_ERROR
    #define usb_hal_error(format, ...) usb_hal_debug(USB_HAL_DEBUG_ERROR, format, ##__VA_ARGS__)
#else
    #define usb_hal_error(...) do {} while (0)
#endif


#ifdef USB_HAL_LOG_LEVEL_WARN
    #define usb_hal_warn(format, ...) usb_hal_debug(USB_HAL_DEBUG_WARN, format, ##__VA_ARGS__)
#else
    #define usb_hal_warn(...) do {} while (0)
#endif


#ifdef USB_HAL_LOG_LEVEL_INFO
    #define usb_hal_info(format, ...) usb_hal_debug(USB_HAL_DEBUG_INFO, format, ##__VA_ARGS__)
#else
    #define usb_hal_info(...) do {} while (0)
#endif

c文件中

static void usb_hal_set_color(uint32_t color) 
{


    unsigned int color_code, modifier_code;
    switch (color & USB_HAL_DEBUG_COLOR_MASK_COLOR) 
    {
        case USB_HAL_DEBUG_COLOR_BLACK:
            color_code = 30; break;
        case USB_HAL_DEBUG_COLOR_RED:
            color_code = 31; break;
        case USB_HAL_DEBUG_COLOR_GREEN:
            color_code = 32; break;
        case USB_HAL_DEBUG_COLOR_YELLOW:
            color_code = 33; break;
        case USB_HAL_DEBUG_COLOR_BLUE:
            color_code = 34; break;
        case USB_HAL_DEBUG_COLOR_MAGENTA:
            color_code = 35; break;
        case USB_HAL_DEBUG_COLOR_CYAN:
            color_code = 36; break;
        case USB_HAL_DEBUG_COLOR_WHITE:
            color_code = 37; break;
        case USB_HAL_DEBUG_COLOR_RESET:
        default:
            color_code = 0; break;
    }
    
    switch (color & USB_HAL_DEBUG_COLOR_MASK_MODIFIER) 
    {
        case USB_HAL_DEBUG_COLOR_BOLD:
            modifier_code = 1; break;
        case USB_HAL_DEBUG_COLOR_UNDERLINE:
            modifier_code = 2; break;
        case USB_HAL_DEBUG_COLOR_BLINK:
            modifier_code = 3; break;
        case USB_HAL_DEBUG_COLOR_HIDE:
            modifier_code = 4; break;
        case USB_HAL_DEBUG_COLOR_NORMAL:
        default:
            modifier_code = 0; break;
    }


    printf("\\\\033[%u;%um", modifier_code, color_code);
}


void usb_hal_do_debug(USB_HAL_DEBUG_e level, const char *format, ...)
{
    uint32_t color = USB_HAL_DEBUG_COLOR_RESET;
    va_list args;


    switch(level) 
    {
    case USB_HAL_DEBUG_INFO:
        color = USB_HAL_DEBUG_COLOR_GREEN | USB_HAL_DEBUG_COLOR_BOLD;
        break;
    case USB_HAL_DEBUG_ERROR:
        color = USB_HAL_DEBUG_COLOR_RED | USB_HAL_DEBUG_COLOR_BOLD;
        break;
    case USB_HAL_DEBUG_WARN:
        color = USB_HAL_DEBUG_COLOR_YELLOW | USB_HAL_DEBUG_COLOR_BOLD;
        break;
    default:
        return;
    }
    va_start(args, format);
    usb_hal_set_color(color);


    vprintf(format, args);


    //printf("\\\\r\\\\n");
    usb_hal_set_color(USB_HAL_DEBUG_COLOR_RESET);


    va_end(args);
}

1.4 總結

以上從整體上設計了整個的驅動框架,重點考慮可移植性,可維護性等原則,借鑒面向對象的一些設計思想和原則。同時提供了一些調試方案供參考。前面磨刀已經磨了很久了,后面我們就開始正式進入編程階段了。

審核編輯 黃宇

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • usb
    usb
    +關注

    關注

    60

    文章

    7980

    瀏覽量

    266095
  • USB驅動
    +關注

    關注

    1

    文章

    137

    瀏覽量

    20275
  • 驅動開發
    +關注

    關注

    0

    文章

    130

    瀏覽量

    12110
  • 驅動框架
    +關注

    關注

    0

    文章

    14

    瀏覽量

    4074
  • DWC2
    +關注

    關注

    0

    文章

    35

    瀏覽量

    151
收藏 人收藏

    評論

    相關推薦

    基于DWC2USB驅動開發-0x01開篇介紹與新思DWC2 USB2.0控制器簡介

    本文轉自公眾號,歡迎關注 基于DWC2USB驅動開發-0x01開篇介紹與新思DWC2
    的頭像 發表于 05-08 18:10 ?4800次閱讀
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驅動</b><b class='flag-5'>開發</b>-<b class='flag-5'>0x</b>01開篇介紹與新思<b class='flag-5'>DWC2</b> <b class='flag-5'>USB</b>2.0控制器簡介

    基于DWC2USB驅動開發-0x02 DWC2 USB2.0 IP功能特征介紹

    DWC2即新思(Synopsys )的DesignWare? Cores USB 2.0 HiSpeed On-The-Go (OTG)控制器IP,被大量使用。從linux的內核源碼驅動中就帶
    的頭像 發表于 05-09 10:09 ?9847次閱讀
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驅動</b><b class='flag-5'>開發</b>-<b class='flag-5'>0x</b>02 <b class='flag-5'>DWC2</b> <b class='flag-5'>USB</b>2.0 IP功能特征介紹

    基于DWC2USB驅動開發-0x07 DWC2 USB2.0 IP 配置參數

    混淆,IP的配置參數固定之后就不能改了,就決定了IP所具有的能力。對于軟件開發者來說也要了解其具體的配置,因為只有知道當前IP的配置,知道支持哪些功能,哪些是軟件可以配置的哪些是硬件固定了無法配置的,等等這些,后面寫驅動才心中有數。 配置相關
    的頭像 發表于 05-17 09:49 ?2418次閱讀

    基于DWC2USB驅動開發-IAD描述符詳解

    本文轉自公眾號,歡迎關注 基于DWC2USB驅動開發-IAD描述符詳解 (qq.com) 一.? 前言 IAD描述符用于一個設備功能關聯多個接口,可以用于實現組合設備。 二.參考文檔
    的頭像 發表于 06-27 08:45 ?26.4w次閱讀
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驅動</b><b class='flag-5'>開發</b>-IAD描述符詳解

    基于DWC2USB驅動開發-USB復位詳解

    本文轉自公眾號歡迎關注 基于DWC2USB驅動開發-USB復位詳解 (qq.com) 一.前言 ? ? ? ? ?上一篇我們詳細介紹了
    的頭像 發表于 07-07 11:18 ?7.6w次閱讀
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驅動</b><b class='flag-5'>開發</b>-<b class='flag-5'>USB</b>復位詳解

    基于DWC2USB驅動開發-USB連接詳解

    本文轉自公眾號,歡迎關注 基于DWC2USB驅動開發-USB連接詳解 (qq.com) 一.前言 ? 之前一直在閱讀手冊,規格書,練習招式
    的頭像 發表于 07-07 08:46 ?3878次閱讀
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驅動</b><b class='flag-5'>開發</b>-<b class='flag-5'>USB</b>連接詳解

    基于DWC2USB驅動開發-高速設備枚舉為全速設備問題案例分析

    本文轉自公眾號,歡迎關注 基于DWC2USB驅動開發-高速設備枚舉為全速設備問題案例分析 (qq.com) 一.前言 ? 本文分享一個高速設備被枚舉為全速的問題。 ? ? 高速設備速
    的頭像 發表于 07-10 17:12 ?1500次閱讀
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驅動</b><b class='flag-5'>開發</b>-高速設備枚舉為全速設備問題案例分析

    基于DWC2USB驅動開發-設備類驅動框架

    本文轉自公眾號,歡迎關注 基于DWC2USB驅動開發-設備類驅動框架 (qq.com) 一.前
    的頭像 發表于 07-16 15:56 ?1376次閱讀
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驅動</b><b class='flag-5'>開發</b>-設備類<b class='flag-5'>驅動</b><b class='flag-5'>框架</b>

    基于DWC2USB驅動開發-發送相關的寄存器DMA寄存器詳解

    本文轉自公眾號,歡迎關注 基于DWC2USB驅動開發-發送相關的寄存器DMA寄存器詳解 (qq.com) 前言 如下寄存器DIEPxxx,對應IN端點,和發送數據相關,這一篇先介紹和
    的頭像 發表于 07-16 16:42 ?1736次閱讀
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驅動</b><b class='flag-5'>開發</b>-發送相關的寄存器DMA寄存器詳解

    基于DWC2USB驅動開發-USB包詳解

    不管什么通訊協議,比如UART,SPI,USB等等,不管是并口還是串口,不管是同步還是異步,我們從抽象的角度去看,其本質都是一樣的。都是先定義物理信號,物理信號可能是差分,單端,電流驅動電壓驅動等等
    的頭像 發表于 07-23 17:11 ?2733次閱讀
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驅動</b><b class='flag-5'>開發</b>-<b class='flag-5'>USB</b>包詳解

    基于DWC2USB驅動開發-數據不能發送問題分析案例

    本文轉自公眾號歡迎關注 基于DWC2USB驅動開發-數據不能發送問題分析案例 (qq.com) ? 一.前言 ? ? ? ?對于驅動
    的頭像 發表于 08-08 09:43 ?2494次閱讀
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驅動</b><b class='flag-5'>開發</b>-數據不能發送問題分析案例

    新思 DWC2 的參考手冊從哪里可以下載

    最近在學習STM32F4 USB驅動,有看到 dwc2驅動的代碼,但是沒有手冊用來參考,ST手冊上寄存器不全,從網上看到有下面兩個手冊,但是一直找不到下載的資源 《DesignWar
    發表于 01-22 11:32

    如何對基于hal庫的DWC2 USB IP進行調試呢

    背景之前適配 DWC2 USB IP 的時候,主要是基于 st 的 hal 庫來走的,當時我就對他們的 hal 庫代碼不滿,只是無奈,迫于時間就沒重構,果不其然,usb bug 一堆,隨意舉例,這還
    發表于 06-14 15:23

    基于DWC2USB驅動開發-0x0A ULPI接口同步模式介紹

    同步模式是ULPI必須支持的且主要的模式,內容比較多,對于軟件開發人員來說重點關注下總線時序,即數據是如何交互的,這樣必要的的時候可以使用邏輯分析儀進行抓包分析。另外重點關注下各個狀態是如何反應在ULPI的寄存器中的
    的頭像 發表于 06-04 15:35 ?4158次閱讀
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驅動</b><b class='flag-5'>開發</b>-<b class='flag-5'>0x0</b>A ULPI接口同步模式介紹

    基于DWC2USB驅動開發-抽絲剝繭再論切換到狀態階段標志DOEPINTn.StsPhseRcvd

    本文轉自公眾號系列文章,歡迎關注 基于DWC2USB驅動開發-USB包詳解 (qq.com) 一.前言 前面我們對SETUP完成標志DOE
    的頭像 發表于 07-24 18:04 ?1706次閱讀
    基于<b class='flag-5'>DWC2</b>的<b class='flag-5'>USB</b><b class='flag-5'>驅動</b><b class='flag-5'>開發</b>-抽絲剝繭再論切換到狀態階段標志DOEPINTn.StsPhseRcvd
    美国百家乐怎么玩| 百家乐游戏解密| 百家乐群柏拉图软件| 尊龙国际娱乐| 澳门百家乐看路博客| 网络百家乐官网真人游戏| 贵族国际娱乐城| 状元百家乐的玩法技巧和规则| 新干县| 大发888官方爱好| 可以玩百家乐的博彩公司| 香港百家乐官网的玩法技巧和规则| 大三巴百家乐的玩法技巧和规则| 九州百家乐官网的玩法技巧和规则| 百家乐分析网| 24山向方位| 网上百家乐官网网| 大玩家百家乐官网游戏| 百家乐官网长龙有几个| 大发888 没人举报吗| 大家旺百家乐的玩法技巧和规则 | 百家乐官网桌德州扑克桌| 环球国际娱乐| 大发888娱乐城备用网址| KK百家乐娱乐城 | 金花百家乐官网娱乐城| 百家乐官网赌坊| 大发888娱乐城高手| 百家乐赌博分析网| 老k百家乐官网的玩法技巧和规则| 百家乐官网学院教学视频| 大发888城| 大发888城亚洲游戏| 大发888bet娱乐城| 大发888游戏注册| 威尼斯人娱乐场注册| 百家乐翻天超清| 百家乐麻将牌| 真人百家乐试玩账号| 百家乐的视频百家乐| 澳门百家乐技巧经|