中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

建設(shè)一個(gè)網(wǎng)站大概費(fèi)用大連seo網(wǎng)站推廣

建設(shè)一個(gè)網(wǎng)站大概費(fèi)用,大連seo網(wǎng)站推廣,dreamweaver網(wǎng)站建設(shè)和維護(hù),建設(shè)銀行河北分行招聘網(wǎng)站USB是很常用的接口,目前大多數(shù)的設(shè)備都是USB接口的,比如鼠標(biāo)、鍵盤、USB攝像 頭等,在實(shí)際開發(fā)中也常常遇到USB接口的設(shè)備,本章就來學(xué)習(xí)一下如何使能Linux內(nèi)核自帶的USB驅(qū)動(dòng)。這里不會(huì)具體學(xué)習(xí)USB的驅(qū)動(dòng)開發(fā)。 USB接口簡(jiǎn)介 什么是…

USB是很常用的接口,目前大多數(shù)的設(shè)備都是USB接口的,比如鼠標(biāo)、鍵盤、USB攝像
頭等,在實(shí)際開發(fā)中也常常遇到USB接口的設(shè)備,本章就來學(xué)習(xí)一下如何使能Linux內(nèi)核自帶的USB驅(qū)動(dòng)。這里不會(huì)具體學(xué)習(xí)USB的驅(qū)動(dòng)開發(fā)。

USB接口簡(jiǎn)介

什么是USB

USB全稱為Universal Serial Bus,翻譯過來就是通用串行總線。由英特爾與眾多電腦公司提出來,用于規(guī)范電腦與外部設(shè)備的連接與通訊。目前USB接口已經(jīng)得到了大范圍的應(yīng)用,已經(jīng)是電腦、手機(jī)等終端設(shè)備的必配接口,甚至取代了大量的其他接口。比如最新的智能手機(jī)均采用USB TypeC取到了傳統(tǒng)的3.5mm耳機(jī)接口,蘋果最新的MacBook只有 USB TypeC接口,至于其他的HDMI、網(wǎng)口等均可以通過USB TypeC擴(kuò)展塢來擴(kuò)展。

按照大版本劃分,USB目前可以劃分為USB1.0、USB2.0、USB3.0以及正在即將到來的USB4.0。

  • USB1.0:USB規(guī)范于1995年第一次發(fā)布,由Inter、IBM、Microsoft等公司組成的USB-IF(USB Implement Forum)組織提出。USB-IF在1996年正式發(fā)布USB1.0,理論速度為1.5Mbps。1998 年USBIF在USB1.0的基礎(chǔ)上提出了USB1.1規(guī)范。
  • USB2.0:USB2.0依舊由Inter、IBM、Microsoft等公司提出并發(fā)布,USB2.0分為兩個(gè)版本:Full-Speed和High-Speed,也就是全速(FS)和高速(HS)。USB2.0 FS的速度為12Mbps,USB2.0 HS速度為480Mbps。目前大多數(shù)單片機(jī)以及低端Cortex-A芯片配置的都是USB2.0接口,比如STM32MP157。USB2.0全面兼容USB1.0標(biāo)準(zhǔn)。
  • USB3.0:USB3.0同樣由Inter等公司發(fā)起的,USB3.0最大理論傳輸速度為5.0Gbps,USB3.0引入了全雙工數(shù)據(jù)傳輸,USB2.0的480Mbps為半雙工。USB3.0中兩根線用于發(fā)送數(shù)據(jù),另外兩根用于接收數(shù)據(jù)。在USB3.0的基礎(chǔ)上又提出了USB3.1、USB3.2等規(guī)范,USB3.1理論傳輸速度提升到了10Gbps,USB3.2理論傳輸速度為20Gbps。為了規(guī)范 USB3.0標(biāo)準(zhǔn)的命名,USB-IF公布了最新的USB命名規(guī)范,原來的USB3.0和USB3.1命名將不會(huì)采用,所有的3.0 版本的USB都命名為 USB3.2,以前的USB3.0、USB3.1和USB3.2分別叫做USB3.2 Gen1、USB3.2 Gen2、USB3.2 Gen 2X2。
  • USB4.0:目前還在標(biāo)準(zhǔn)定制中,目前還沒有設(shè)備搭載,據(jù)說是在Inter的雷電3接口上改進(jìn)而來。USB4.0的速度將提升到了40Gbps,最高支持100W的供電能力,只需要一根線就可以完成數(shù)據(jù)傳輸與供電,極大的簡(jiǎn)化了設(shè)備之間的鏈接線數(shù),期待USB4.0設(shè)備上市

如果按照接口類型劃分的話USB就要分為很多種了,最常見的就是USB A插頭和插座,如下圖所示:

USB A插頭和插座

使用過JLINK調(diào)試器的朋友應(yīng)該還見過USB B插頭和插座,USB B插頭和插座如下圖所示:

USB B插頭和插座

USB插頭在不斷的縮小,由此產(chǎn)生了Mini USB接口,Mini USB插頭和插座如下圖所示:

Mini USB插頭和插座

比Mini USB更小的就是Micro USB接口了,以前的智能手機(jī)基本都是Micro USB接口的,Micro USB插頭和插座如下圖所示:

Micro USB插頭和插座

現(xiàn)在最流行的就是USB Typec了,正點(diǎn)原子的STM32MP1開發(fā)板使用的是USB Typec接口,USB Typec插頭和插座如下圖所示:

USB Typec插頭和插座

USB電氣特性

Mini USB電氣屬性

先以Mini USB為例講解一下USB的基本電氣屬性。Mini USB線一般都是一頭為USB A插頭,一頭為Mini USB插頭。一共有四個(gè)觸點(diǎn),也就是4根線,這四根線的順序如下圖所示:

USB A插頭線序

如上圖所示,USB A插頭從左到右線序依次為 1,2,3,4,第1根線為VBUS,電壓為5V,第2根線為D-,第3根線為D+,第4根線為GND。USB采用差分信號(hào)來傳輸數(shù)據(jù),因此有D-和D+兩根差分信號(hào)線。仔細(xì)觀察的話會(huì)發(fā)現(xiàn)USB A插頭的1和4這兩個(gè)觸點(diǎn)比較
長(zhǎng),2和3這兩個(gè)觸點(diǎn)比較短。1和4分別為VBUS和GND,也就是供電引腳,當(dāng)插入 USB的時(shí)候會(huì)先供電,然后再接通數(shù)據(jù)線。拔出的時(shí)候先斷開數(shù)據(jù)線,然后再斷開電源線

再觀察一下Mini USB插頭,會(huì)發(fā)現(xiàn)Mini USB插頭有5個(gè)觸點(diǎn),也就是5根線,線序
從左往右依次是1-5。第1根線為VCC(5V),第2根線為D-,第3根線為D+,第4根線為ID,第5根線為GND??梢钥闯?strong>Mini USB插頭相比USB A插頭多了一個(gè)ID線,這個(gè)ID線用于
實(shí)現(xiàn)OTG功能,通過ID線來判斷當(dāng)前連接的是主設(shè)備(HOST)還是從設(shè)備(SLAVE)。

USB是一種支持熱插拔的總線接口,使用差分線(D-和 D+)來傳輸數(shù)據(jù),USB支持兩種供電模式:總線供電和自供電,總線供電就是由USB接口為外部設(shè)備供電,在USB2.0下,總線供電最大可以提供500mA的電流。

USB拓補(bǔ)結(jié)構(gòu)

USB是主從結(jié)構(gòu)的,也就是分為主機(jī)和從機(jī)兩部分,一般主機(jī)叫做Host,從機(jī)叫做Device。主機(jī)通過USB A插座來連接外部的設(shè)備,比如電腦作為主機(jī),對(duì)外提供USB A插座,可以通過USB線來連接一些USB設(shè)備,比如聲卡、手機(jī)等。因此電腦帶的USB A插座數(shù)量就決定了能外接多少個(gè)USB設(shè)備,如果不夠用的話可以購(gòu)買USB集線器來擴(kuò)展電腦的USB插口,USB集線器也叫做USB HUB,USB HUB如下圖所示:

USB HUB

上圖是一個(gè)一拖四的USB HUB,也就是將一個(gè)USB接口擴(kuò)展為4個(gè)。主機(jī)一般會(huì)帶幾個(gè)原生的USB主控制器,比如STM32MP1就有兩個(gè)原生的USB主控制器,因此STM32MP1
對(duì)外提供兩個(gè)USB接口
,這兩個(gè)接口肯定不夠用,正點(diǎn)原子的STM32MP1開發(fā)板上有6個(gè)HOST接口,六路都是USB2通過USB HUB芯片擴(kuò)展出來的,稍后會(huì)講解其原理圖。

雖然可以對(duì)原生的USB口數(shù)量進(jìn)行擴(kuò)展,但是不能對(duì)原生USB口的帶寬進(jìn)行擴(kuò)展,比如STM32MP1的兩個(gè)原生USB口都是USB2.0的,帶寬最大為480Mbps,因此接到下面的所有USB設(shè)備總帶寬最大為480Mbps。

USB只能主機(jī)與設(shè)備之間進(jìn)行數(shù)據(jù)通信,USB 主機(jī)與主機(jī)、設(shè)備與設(shè)備之間是不能通信的。因此兩個(gè)正常通信的USB接口之間必定有一個(gè)主機(jī),一個(gè)設(shè)備。為此使用了不同的插頭和插座來區(qū)分主機(jī)與設(shè)備,比如主機(jī)提供 USB A插座,從機(jī)提供Mini USB、Micro USB 等插座。在一個(gè)USB系統(tǒng)中,僅有一個(gè)USB主機(jī),但是可以有多個(gè)USB設(shè)備,包括USB功能設(shè)備和USB HUB,最多支持127個(gè)設(shè)備。一個(gè)USB主控制器支持128個(gè)地址,地址0是默認(rèn)地址,只有在設(shè)備枚舉的時(shí)候才會(huì)使用,地址0不會(huì)分配給任何一個(gè)設(shè)備。所以一個(gè)USB主控制器最多可以分配127個(gè)地址。整個(gè)USB的拓?fù)浣Y(jié)構(gòu)就是一個(gè)分層的金字塔形,如下圖所示:

USB金字塔拓補(bǔ)

上圖中可以看出從Root Hub開始,一共有7層,金字塔頂部是Root Hub,這個(gè)是USB控制器內(nèi)部的。圖中的Hub就是連接的USB集線器,Func就是具體的USB設(shè)備。

USB主機(jī)和從機(jī)之間的通信通過管道(Pipe)來完成,管道是一個(gè)邏輯概念,任何一個(gè)USB設(shè)備一旦上電就會(huì)存在一個(gè)管道,也就是默認(rèn)管道,USB主機(jī)通過管道來獲取從機(jī)的描述符、配置等信息。在主機(jī)端管道其實(shí)就是一組緩沖區(qū),用來存放主機(jī)數(shù)據(jù),在設(shè)備端管道對(duì)應(yīng)一個(gè)特定的端點(diǎn)。

USB OTG

USB分為HOST(主機(jī))和從機(jī)(或DEVICE),有些設(shè)備可能有時(shí)候需要做HOST,有時(shí)候又需要做DEVICE,配兩個(gè)USB口當(dāng)然可以實(shí)現(xiàn),但是太浪費(fèi)資源了。如果一個(gè)USB接口既可以做HOST又可以做DEVICE那就太好了,使用起來就方便很多。為此,USB OTG 應(yīng)運(yùn)而生,OTG是On-The-Go的縮寫,支持USB OTG功能的USB接口既可以做HOST,也可以做DEVICE。為了區(qū)分當(dāng)前的工作狀態(tài),這里就引入了ID線這個(gè)概念,前面講解USB電氣屬性的時(shí)候已經(jīng)說過了,Mini USB插頭有5根線,其中一條就是ID線。ID線的高低電平表示USB口工作在HOST還是DEVICE模式

  • ID=1:OTG設(shè)備工作在從機(jī)模式。
  • ID=0:OTG設(shè)備工作在主機(jī)模式。

支持OTG模式的USB接口一般都是Mini USB、Micro USB 等這些帶有ID線的接口。正點(diǎn)原子的STM32MP1開發(fā)板OTG模式是使用USB Type C做接口,沒有ID線USB Type C有自己的識(shí)別方法,稍后會(huì)講解TypeC接口電氣屬性。正點(diǎn)原子的STM32MP157開發(fā)板USB_OTG連接到了STM32MP1的USB1接口上。如果要使用OTG的主機(jī)模式,那么就需要一根OTG線,TypeC接口的OTG線如下圖所示:

Typec OTG線

可以看出,TypeC OTG線一頭是USB A插座,一頭是Typec插頭,將TypeC插頭插入機(jī)器的TypeC口上,需要連接的USB設(shè)備插到另一端的USB A插座上,比如U盤。TypeC的CC引腳檢查到USB設(shè)備已經(jīng)接入,就會(huì)建立USB設(shè)備為主模式,機(jī)器就知道自己要做為一個(gè)主機(jī),用來連接外部的從機(jī)設(shè)備(U 盤)。

STM32MP1 USB接口簡(jiǎn)介

STM32MP157提供了兩個(gè)USB2.0接口,這兩個(gè)USB接口都是支持高速模式,也就是480Mbit/S,這兩個(gè)USB接口都內(nèi)置了高速PHY。其中USB2支持OTG功能,正點(diǎn)原子STM32MP157開發(fā)板上的USB OTG接口就是鏈接到USB2接口上的。USB1接口連接了一個(gè)HUB芯片,實(shí)現(xiàn)了USB Host接口擴(kuò)展。

STM32MP1內(nèi)部集成了三個(gè)跟USB相關(guān)的控制器名字分別為:USB OTG控制器、USB Host控制器和USB HS PHY控制器,提供一個(gè)簡(jiǎn)稱方便書寫:OTG、USBH和PHY。接著分析一下這三個(gè)控制器是如何工作的。

PHY控制器

PHY(英語:Port Physical Layer),中文可稱之為端口物理層,是一個(gè)對(duì)OSI模型物理層的共同簡(jiǎn)稱。PHY控制器主要是提供兩個(gè)端口,端口1已經(jīng)規(guī)定分配給USB Host控制器,端口2可以分配給USB OTG和USB Host。

OTG控制器

此控制器是支持OTG功能,它的內(nèi)部特性如下所示:

  1. 此控制器有一個(gè)獨(dú)立的內(nèi)核USB OTG HS。
  2. 該控制器支持HS、FS和LS模式,不管是主機(jī)還是從機(jī)模式都支持HS/FS/LS,硬件支持OTG信號(hào)、會(huì)話請(qǐng)求協(xié)議和主機(jī)協(xié)商協(xié)議,支持8個(gè)雙向端點(diǎn),還支持PHY接口。
  3. 內(nèi)嵌一個(gè)DMA。
  4. 支持片上全速PHY、連接外部全速PHY的I2C接口和連接外部高速PHY的ULPL接口。
  5. 具有采用高級(jí)FIFO控制的4 KB專用RAM。

OTG控制器有兩個(gè)模式:正常模式(normal mode)和低功耗模式(low power mode)。OTG控制器都可以運(yùn)行在高速模式(HS 480Mbps)、全速模式(LS 12Mbps)和低速模式(1.5Mbps)。正常模式下每個(gè)OTG控制器都可以工作在主機(jī)(HOST)或從機(jī)(DEVICE)模式下,每個(gè)USB控制器都有其對(duì)應(yīng)的接口。低功耗模式顧名思義就是為了節(jié)省功耗,USB2.0 協(xié)議中要求,設(shè)備在上行端口檢測(cè)到空閑狀態(tài)以后就可以進(jìn)入掛起狀態(tài)。在從機(jī)(DEVICE)模式下,端口停止活動(dòng)3ms以后OTG控制器內(nèi)核進(jìn)入掛起狀態(tài)。在主機(jī)(HOST)模式下,OTG控制器內(nèi)核不會(huì)自動(dòng)進(jìn)入掛起狀態(tài),但是可以通過軟件設(shè)置。不管是本地還是遠(yuǎn)端的USB主從機(jī)都可以通過產(chǎn)生喚醒序列來重新開始USB通信。

USBH控制器

USBH控制器這是一個(gè)主機(jī)控制器,此控制器由EHCI控制器和OHCI控制器組成。USBH控制器只能做主機(jī)模式

這里簡(jiǎn)單提一下OHCI、UHCI、EHCI和xHCI,這四個(gè)是用來描述USB控制器規(guī)格
的,區(qū)別如下:

  • OHCI:全稱為Open Host Controller Interface,這是一種USB控制器標(biāo)準(zhǔn),廠商在設(shè)計(jì)USB控制器的時(shí)候需要遵循此標(biāo)準(zhǔn),用于USB1.1標(biāo)準(zhǔn)。OHCI不僅僅用于USB,也支持一些其他的接口,比如蘋果的Firewire等,OHCI由于硬件比較難,所以軟件要求就降低了,軟件相對(duì)來說比較簡(jiǎn)單。OHCI主要用于非X86的USB,比如擴(kuò)展卡、嵌入式USB控制器。
  • UHCI:全稱是Universal Host Controller Interface,UHCI是Inter主導(dǎo)的一個(gè)用于USB1.0/1.1的標(biāo)準(zhǔn),與OHCI不兼容。與OHCI相比UHCI硬件要求低,但是軟件要求相應(yīng)就高了,因此硬件成本上就比較低。
  • EHCI:全稱是Enhanced Host Controller Interface,是Inter主導(dǎo)的一個(gè)用于USB2.0的USB控制器標(biāo)準(zhǔn)。EHCI僅提供USB2.0的高速功能,至于全速和低速功能就由OHCI或UHCI來提供。
  • xHCI:全稱是eXtensible Host Controller Interface,是目前最流行的USB3.0控制器標(biāo)準(zhǔn),在速度、能效和虛擬化等方面比前三個(gè)都有較大的提高。xHCI支持所有速度種類的USB設(shè)備,xHCI出現(xiàn)的目的就是為了替換前面三個(gè)。

通俗來講,OHCI就是FS模式,也就是低速模式,EHCI是HS模式,也就是高速模式

USB Typec電氣屬性

USB TypeC接口引腳定義

STM32MP157有兩個(gè)USB2接口,所以可以直接使用Mini USB或者M(jìn)icro USB。但是目前USB TypeC接口非常普及,為了方便使用,正點(diǎn)原子STM32MP157開發(fā)板上的USB接口采用了TypeC。

接下來就看一下USB TypeC接口(根據(jù)USB協(xié)議,也叫做USB3.1接口)電氣屬性,由于TypeC功能比較復(fù)雜,比如支持PD充電、顯示、音頻等,這里只講解一下TypeC的數(shù)據(jù)
通信部分
。首先來看一下TypeC的接口定義,這里只看母頭的引腳定義,如下圖所示:

標(biāo)準(zhǔn)USB TypeC母頭引腳

從上圖中可以看出,標(biāo)準(zhǔn)的USB TypeC有24根線,分為上下兩部分,明顯比前面講的Mini USB要多不少引腳,這些引腳按照功能分類:

  • A1、A12、B1、B12:這4個(gè)引腳為GND。
  • A2、A3、B2、B3:這4個(gè)引腳是USB3.1特有的,為超高速差分發(fā)送信號(hào)線,這個(gè)是USB2.0和USB1.0所沒有的。
  • A10、A11、B10、B11:這4個(gè)引腳也是USB3.1特有的,為超高速差分接收信號(hào)線,這個(gè)也是USB2.0和USB1.0所沒有的。
  • A4、A9、B4、B9:VBUS引腳,這個(gè)USB2.0也有。
  • A5、B5:CC1和CC2這2個(gè)引腳為USB3.1特有的配置通道引腳。Type-C的插座中有兩個(gè)CC腳,USB通信中的角色檢測(cè)都是通過CC腳進(jìn)行的。對(duì)于TypeC插頭或者線纜正常只有一個(gè)CC引腳,兩個(gè)端口連接在一起之后,只存在一個(gè)CC引腳連接,通過檢測(cè)哪一個(gè)CC有連接,就可以判斷連接的方向。如果USB線纜中有需供電的器件,其中一個(gè)CC引腳將作為VCONN供電。
    對(duì)于正點(diǎn)原子linux驅(qū)動(dòng)教程里的USB章節(jié)來說,主要使用CC1和CC2引腳來實(shí)現(xiàn)USB OTG功能。
  • A8、B8:SBU1和SBU2引腳,這兩個(gè)并不是USB信號(hào),而是用作其他功能的,比如TypeC作為DP接口使用的時(shí)候SBU用作音頻傳輸通道。
  • A6、A7、B6、B7:這4個(gè)引腳就是USB2.0的D+和D-,因?yàn)閁SB3.1要兼容USB2.0和USB1.0接口,所以必須要有D+和D-。

仔細(xì)看上圖可看出,上下兩排引腳是對(duì)應(yīng)的,比如(A1,B1)、(A2,B2)等,一直到(A12,B12)。這是因?yàn)閁SB3.1要有能夠正反插,因此上下兩排引腳肯定要是一樣的,這樣才能在正反插的時(shí)候都能正常工作。

上圖是TypeC接口標(biāo)準(zhǔn)的24P母頭引腳,在進(jìn)行TypeC母頭選型的時(shí)候會(huì)發(fā)現(xiàn)也有16P甚至6P封裝的接口。比如正點(diǎn)原子STM32MP157開發(fā)板上使用的就是16P的TypeC母座,16P 的母座引腳結(jié)構(gòu)如下圖所示:

16PTypeC引腳示意圖

上圖就是16P的TypeC引腳示意圖,從左到右依次是1-16 腳,注意1,2 腳、3,4 腳、13,14 腳和15,16腳離得很近,看起來像是一個(gè)引腳,其實(shí)他們是兩個(gè)引腳。16P對(duì)應(yīng)的引腳功能如下圖所示:

16P母座引腳定義

可以看出,相比于標(biāo)準(zhǔn)24P引腳定義,16P的母座少了8根USB3.1高速差分收發(fā)數(shù)據(jù)線。

USB TypeC的Data Role

USB2.0根據(jù)數(shù)據(jù)傳輸方向定義了HOST/Device/OTG這三種類型的設(shè)備角色,其中OTG既可以做HOST也可以做Device,USB2.0的OTG設(shè)備接口通過ID線來區(qū)分HOST還是Device。在TypeC領(lǐng)域,也有類似的概念,但是名字變了:

  1. DFP:DFP全稱是Downstream Facing Port,也就是下行端口,可以理解為HOST,DFP提供VBUS、VCONN,可以接收數(shù)據(jù)。
  2. UFP:UFP全稱是Upstream Facing Port,也就是上行端口,可以理解為Device,UFP 從VBUS中取電源,UFP設(shè)備也可以傳輸數(shù)據(jù),比如U盤,鍵盤鼠標(biāo)等。
  3. DRP:DRP全稱是Dual Role Port,也就是雙角色端口,可以理解為OTG,DRP既可以做DFP,也可以做UFP。也可以在DFP和UFP之間進(jìn)行動(dòng)態(tài)切換。這個(gè)切換過程就用到了CC引腳,具體識(shí)別過程比較復(fù)雜,這里就不講解了。如果要在USB TypeC接口上實(shí)現(xiàn)DRP功能,那么就需要使用到外置的TypeC芯片!正點(diǎn)原子STM32MP157開發(fā)板使用了STUSB1600或FUSB302MPX這兩種TypeC芯片。這兩種芯片都有一個(gè)IIC配置接口,也就是需要編寫驅(qū)動(dòng)程序,否則的話DRP功能無法實(shí)現(xiàn)。

硬件原理圖分析

正點(diǎn)原子的STM32MP1開發(fā)板USB部分原理圖可以分為兩部分:USB HUB以及USB OTG

USB TypeC本來是給USB3.1準(zhǔn)備的,單位了方便使用,所以正點(diǎn)原子STM32MP157開發(fā)板也使用了TypeC接口,但是本質(zhì)上還是USB2.0協(xié)議,所以不要看到TypeC就以為支持USB3.0!

另外,使用TypeC接口實(shí)現(xiàn)OTG功能的話就需要外界TypeC芯片!通過專用的TypeC芯片來控制CC引腳實(shí)現(xiàn)USB的主從切換。V1.3版本以前的底板使用STUSB1600這顆TypeC芯片,V1.5版本以后的底板都使用FUSB302MPX。

依次來看一下這兩部分的硬件原理圖。

USB HUB原理圖分析

首先來看一下USB HUB原理圖,STM32MP1使用FE2.1這個(gè)HUB芯片將STM32MP1的USB2擴(kuò)展成了7路HOST接口,其中一路供4G模塊使用,因此就剩下了6個(gè)通用的USB A插座,原理圖如下圖所示:

USB HUB原理圖

上圖中U21就是USB HUB芯片F(xiàn)E2.1,FE2.1是一款符合USB2.0標(biāo)準(zhǔn)的USB HUB芯片,支持一拖七擴(kuò)展,可以將一路USB擴(kuò)展為7路USB HOST接口。這里將STM32MP1的USB1擴(kuò)展出了7路USB HOST接口,分別為HUB_DP1/DM1、HUB_DP2/DM2、HUB_DP3/DM3、HUB_DP4/DM4、HUB_DP5/DM5、HUB_DP6/DM6和HUB_DP7/DM7。其中HUB_DP7/DM7用于4G模塊,因此對(duì)外提供的只有六個(gè)USB HOST接口,這三個(gè)USB HOST接口如下圖所示:

擴(kuò)展的USB HOST

注意,使用FE2.1擴(kuò)展出來的7路USB接口只能用作HOST!

USB OTG原理圖分析

正點(diǎn)原子的STM32MP1開發(fā)板上還有一路USB OTG接口,使用STM32MP1的USB OTG接口。此路USB OTG既可以作為主機(jī)(HOST),也可以作為從機(jī)(DEVICE),從而實(shí)現(xiàn)完整的OTG功能。V1.4版本以前的底板上TypeC芯片使用STUSB1600,V1.5及以后版本的底板使用FUSB302MPX這顆芯片。

現(xiàn)在購(gòu)買的話都是V1.5以后的版本了,開發(fā)板的USB OTG是使用FUSB302MPX做控制。原理圖如下圖所示:

FUSB302MPX

FUSB302PMX也是負(fù)責(zé)控制切換主機(jī)和從機(jī)模式的,MT9700HT5是負(fù)載開關(guān),用來控制VBUS輸出,當(dāng)OTG_PWR_CTRL輸出高電平的時(shí)候OUT引腳就輸出5V電壓,也就是VBUS變?yōu)?V。當(dāng)OTG_PWR_CTRL輸出低電平的時(shí)候OUT輸出0V,相當(dāng)于VBUS關(guān)閉。

所以當(dāng)開發(fā)板上的TypeC接口作為主設(shè)備的時(shí)候,OTG_PWR_CTRL要輸出高電平,VBUS輸出5V,為外部USB設(shè)備供電。當(dāng)TypeC接口作為從設(shè)備的時(shí)候,OTG_PWR_CTRL輸出低電平OTG_PWR_CTRL對(duì)應(yīng)的GPIO 引腳為PZ6。

USB協(xié)議簡(jiǎn)介

USB描述符

USB描述符就是用來描述USB信息的,描述符就是一串按照一定規(guī)則構(gòu)建的字符串,USB設(shè)備使用描述符來向主機(jī)報(bào)告自己的相關(guān)屬性信息,常用的描述符如下圖所示:

USB設(shè)備常用描述符

依次來看一下上圖中這5個(gè)描述符的含義。

設(shè)備描述符

設(shè)備描述符用于描述USB設(shè)備的一般信息,USB設(shè)備只有一個(gè)設(shè)備描述符。設(shè)備描述符里面記錄了設(shè)備的USB版本號(hào)、設(shè)備類型、VID(廠商 ID)、PID(產(chǎn)品 ID)、設(shè)備序列號(hào)等。設(shè)備描述符結(jié)構(gòu)如下圖所示:

設(shè)備描述符結(jié)構(gòu)

配置描述符

設(shè)備描述符的bNumConfigurations域定義了一個(gè)USB設(shè)備的配置描述符數(shù)量,一個(gè)USB設(shè)備至少有一個(gè)配置描述符。配置描述符描述了設(shè)備可提供的接口(Interface)數(shù)量、配置編號(hào)、供電信息等,配置描述符結(jié)構(gòu)如下圖所示:

配置描述符結(jié)構(gòu)

字符串描述符

字符串描述符是可選的,字符串描述符用于描述一些方便閱讀的信息,比如制造商、設(shè)備名稱等。如果一個(gè)設(shè)備沒有字符串描述符,那么其他描述符中和字符串有關(guān)的索引值都必須為0,字符串描述符結(jié)構(gòu)如下圖所示:

字符串描述符結(jié)構(gòu)

wLANGID[0]~wLANGID[x]指明了設(shè)備支持的語言 , 具體含義要查閱文檔《USB_LANGIDs.pdf》。

主機(jī)會(huì)再次根據(jù)自己所需的語言向設(shè)備請(qǐng)求字符串描述符,這次主機(jī)會(huì)指明要得到的字符串索引值和語言。設(shè)備返回Unicode編碼的字符串描述符,結(jié)構(gòu)如下圖所示:

Unicode編碼的字符串描述符結(jié)構(gòu)

接口描述符

配置描述符中指定了該配置下的接口數(shù)量,配置可以提供一個(gè)或多個(gè)接口,接口描述符用于描述接口屬性。接口描述符中一般記錄接口編號(hào)、接口對(duì)應(yīng)的端點(diǎn)數(shù)量、接口所述的類等,接口描述符結(jié)構(gòu)如下圖所示:

接口描述符結(jié)構(gòu)

端口描述符

接口描述符定義了其端點(diǎn)數(shù)量,端點(diǎn)是設(shè)備與主機(jī)之間進(jìn)行數(shù)據(jù)傳輸?shù)倪壿嫿涌?#xff0c;除了端點(diǎn)0是雙向端口,其他的端口都是單向的。端點(diǎn)描述符描述了樹傳輸類型、方向、數(shù)據(jù)包大小、端點(diǎn)號(hào)等信息,端點(diǎn)描述符結(jié)構(gòu)如下圖所示:

端點(diǎn)描述符結(jié)構(gòu)

USB數(shù)據(jù)包類型

USB是串行通信,需要一位一位的去傳輸數(shù)據(jù),USB傳輸?shù)臅r(shí)候先將原始數(shù)據(jù)進(jìn)行打包,所以USB中傳輸?shù)幕締卧褪菙?shù)據(jù)包。根據(jù)用途的不同,USB協(xié)議定義了4種不同的包結(jié)構(gòu):令牌(Token)包、數(shù)據(jù)(Data)包、握手(Handshake)包和特殊(Special)包。這四種包通過包標(biāo)識(shí)符PID來區(qū)分,PID共有8位,USB協(xié)議使用低4位PID3-PID0,另外的高四位PID7-PID4是PID3-PID0的取反,傳輸順序是PID0、PID1、PID2、PID3…PID7。令牌包的PID1-0為01,數(shù)據(jù)包的PID1-0 為11,握手包的PID1-0為10,特殊包的PID1-0為00。每種類型的包又有多種具體的包,如下圖所示:

數(shù)據(jù)包結(jié)構(gòu)

一個(gè)完整的包分為多個(gè)域,所有的數(shù)據(jù)包都是以同步域(SYNC)開始,后面緊跟著包標(biāo)識(shí)符(PID),最終都以包結(jié)束(EOP)信號(hào)結(jié)束。不同的數(shù)據(jù)包中間位域不同,一般有包目標(biāo)地址(ADDR)、包目標(biāo)端點(diǎn)(ENDP)、數(shù)據(jù)、幀索引、CRC等,這個(gè)要具體數(shù)據(jù)包具體分析。接下來簡(jiǎn)單看一下這些數(shù)據(jù)包的結(jié)構(gòu)。

令牌包

令牌包結(jié)構(gòu)如下圖所示:

SETUP令牌包

上圖是一個(gè)SETUP令牌包結(jié)構(gòu),首先是SYNC同步域,包同步域?yàn)?0000001,也就是連續(xù)7個(gè)0,后面跟一個(gè)1,如果是高速設(shè)備的話就是31個(gè)0后面跟一個(gè)1。緊跟著是PID,這里是SETUP包,為0XB4,是0XB4的原因如下:

  1. ETUP包的PID3-PID0 為1101,因此對(duì)應(yīng)的PID7~PID4就是0010。
  2. PID傳輸順序?yàn)镻ID0、PID1、PID2…PID7,因此按照傳輸順序排列的話此處的PID就是10110100=0XB4,并不是0X2D。

PID后面跟著地址域(ADDR)和端點(diǎn)(ENDP),為目標(biāo)設(shè)備的地址和端點(diǎn)號(hào)。CRC5域是5位CRC值,是ADDR和ENDP這兩個(gè)域的校驗(yàn)值。最后就是包結(jié)束域(EOP),標(biāo)記本數(shù)據(jù)包結(jié)束。其他令牌包的結(jié)構(gòu)和SETUP基本類似,只是SOF令包中間沒有ADDR和ENDP這兩個(gè)域,而是只有一個(gè)11位的幀號(hào)域。

數(shù)據(jù)包

數(shù)據(jù)包結(jié)構(gòu)如下圖所示:

數(shù)據(jù)包

數(shù)據(jù)包比較簡(jiǎn)單,同樣的,數(shù)據(jù)包從SYNC同步域開始,然后緊跟著是PID,這里就是DATA0,PID值為0XC3。接下來就是具體的數(shù)據(jù),數(shù)據(jù)完了以后就是16位的CRC校驗(yàn)值,最后是EOP。

握手包

握手包結(jié)構(gòu)如下圖所示:

ACK握手包

上圖是ACK握手包,很簡(jiǎn)單,首先是SYNC同步域,然后就是ACK包的PID,為0X4B,最后就是EOP。其他的NAK、STALL、NYET和ERR握手包結(jié)構(gòu)都是一樣的,只是其中的PID不同而已。

USB傳輸類型

在端點(diǎn)描述符中bmAttributes指定了端點(diǎn)的傳輸類型,一共有4種,本節(jié)來看一下這四種傳輸類型的區(qū)別。

控制傳輸

控制傳輸一般用于特定的請(qǐng)求,比如枚舉過程就是全部由控制傳輸來完成的,比如獲取描述符、設(shè)置地址、設(shè)置配置等。控制傳輸分為三個(gè)階段:建立階段(SETUP)、數(shù)據(jù)階(DATA)和狀態(tài)階段(STATUS),其中數(shù)據(jù)階段是可選的。建立階段使用SETUP令牌包,SETUP使用DATA0包。數(shù)據(jù)階段是 0 個(gè)、1個(gè)或多個(gè)輸入(IN)/輸出(OUT)事務(wù),數(shù)據(jù)階段的所有輸入事務(wù)必須是同一個(gè)方向的,比如都為IN或都為OUT。數(shù)據(jù)階段的第一個(gè)數(shù)據(jù)包必須是DATA1,每次正確傳輸以后就在DATA0和DATA1之間進(jìn)行切換。數(shù)據(jù)階段完成以后就是狀態(tài)階段,狀態(tài)階段的傳輸方向要和數(shù)據(jù)階段相反,比如數(shù)據(jù)階段為IN的話狀態(tài)階段就要為OUT,狀態(tài)階段使用DATA1包。比如一個(gè)讀控制傳輸格式如下圖所示:

讀控制傳輸階段

同步傳輸

同步傳輸用于周期性、低時(shí)延、數(shù)據(jù)量大的場(chǎng)合,比如音視頻傳輸,這些場(chǎng)合對(duì)于時(shí)延要求很高,但是不要求數(shù)據(jù)100%正確,允許有少量的錯(cuò)誤。因此,同步傳輸沒有握手階段,即使數(shù)據(jù)傳輸出錯(cuò)了也不會(huì)重傳。

批量傳輸

批量傳輸就是用于大批量傳輸大塊數(shù)據(jù)的,這些數(shù)據(jù)對(duì)實(shí)時(shí)性沒有要求,比如MSD類設(shè)備(存儲(chǔ)設(shè)備),U盤之類的。批量傳輸分為批量讀(輸入)和批量寫(輸出),如果是批量讀的話第一階段就是IN令牌包,如果是批量寫那么第一階段就是OUT令牌包

就以批量寫為例簡(jiǎn)單介紹一下批量傳輸過程:

  1. 主機(jī)發(fā)出OUT令牌包,令牌包里面包含了設(shè)備地址、端點(diǎn)等信息。
  2. 如果OUT令牌包正確的話,也就是設(shè)備地址和端點(diǎn)號(hào)匹配,主機(jī)就會(huì)向設(shè)備發(fā)送一個(gè)數(shù)據(jù)(DATA)包,發(fā)送完成以后主機(jī)進(jìn)入接收模式,等待設(shè)備返回握手包,一切都正確的話設(shè)備就會(huì)向主機(jī)返回一個(gè)ACK握手信號(hào)。

批量讀的過程剛好相反:

  1. 主機(jī)發(fā)出IN令牌包,令牌包里面包含了設(shè)備地址、端點(diǎn)等信息。發(fā)送完成以后主機(jī)就進(jìn)入到數(shù)據(jù)接收狀態(tài),等待設(shè)備返回?cái)?shù)據(jù)。
  2. 如果IN令牌包正確的話,設(shè)備就會(huì)將一個(gè)DATA包放到總線上發(fā)送給主機(jī)。主機(jī)收到這個(gè)DATA包以后就會(huì)向設(shè)備發(fā)送一個(gè)ACK握手信號(hào)。

中斷傳輸

這里的中斷傳輸并不是傳統(tǒng)意義上的硬件中斷,而是一種保持一定頻率的傳輸,中斷傳輸適用于傳輸數(shù)據(jù)量小、具有周期性并且要求響應(yīng)速度快的數(shù)據(jù),比如鍵盤、鼠標(biāo)等。中斷的端點(diǎn)會(huì)在端點(diǎn)描述符中報(bào)告自己的查詢時(shí)間間隔,對(duì)于時(shí)間要求嚴(yán)格的設(shè)備可以采用中斷傳輸。

USB枚舉

當(dāng)USB設(shè)備與USB主機(jī)連接以后主機(jī)就會(huì)對(duì)USB設(shè)備進(jìn)行枚舉,通過枚舉來獲取設(shè)備的
描述符信息,主機(jī)得到這些信息以后就知道該加載什么樣的驅(qū)動(dòng)、如何進(jìn)行通信等
。USB 枚舉過程如下:

  1. 第一回合,當(dāng)USB主機(jī)檢測(cè)到USB設(shè)備插入以后機(jī)會(huì)發(fā)出總線復(fù)位信號(hào)來復(fù)位設(shè)備。USB設(shè)備復(fù)位完成以后地址為0,主機(jī)向地址0的端點(diǎn)0發(fā)送數(shù)據(jù),請(qǐng)求設(shè)備的描述符。設(shè)備得到請(qǐng)求以后就會(huì)按照主機(jī)的要求將設(shè)備描述符發(fā)送給主機(jī),主機(jī)得到設(shè)備發(fā)送過來的設(shè)備描述符以后,如果確認(rèn)無誤就會(huì)向設(shè)備返回一個(gè)確認(rèn)數(shù)據(jù)包(ACK)。
  2. 第二回合,主機(jī)再次復(fù)位設(shè)備,進(jìn)入地址設(shè)置階段。主機(jī)向地址0的端點(diǎn)0發(fā)送設(shè)置地址請(qǐng)求數(shù)據(jù)包,新的設(shè)備地址就包含在這個(gè)數(shù)據(jù)包中,因此沒有數(shù)據(jù)過程。設(shè)備進(jìn)入狀態(tài)過程,等待主機(jī)請(qǐng)求狀態(tài)返回,收到以后設(shè)備就會(huì)向主機(jī)發(fā)送一個(gè)0字節(jié)狀態(tài)數(shù)據(jù)包,表明設(shè)備已經(jīng)設(shè)置好地址了,主機(jī)收到這個(gè)0字節(jié)狀態(tài)數(shù)據(jù)包以后會(huì)返回一個(gè)確認(rèn)包(ACK)。設(shè)備收到主機(jī)發(fā)送的ACK包以后就會(huì)使用這個(gè)新的設(shè)備地址,至此設(shè)備就得到了一個(gè)唯一的地址。
  3. 第三回合,主機(jī)向新的設(shè)備地址端點(diǎn)0發(fā)送請(qǐng)求設(shè)備描述符數(shù)據(jù)包,這一次主機(jī)要獲取整個(gè)設(shè)備描述符,一共是18個(gè)字節(jié)。
  4. 和第3步類似,接下來依次獲取配置描述符、配置集合、字符串描述符等等。

STM32MP1 USB HOST驅(qū)動(dòng)編寫

接下來就開始編寫USB HOST的驅(qū)動(dòng)。USB子系統(tǒng)是一個(gè)標(biāo)準(zhǔn)和復(fù)雜的接口,所以驅(qū)動(dòng)基本不用寫,都是內(nèi)核里有現(xiàn)成的,只需要在設(shè)備樹提供對(duì)應(yīng)的設(shè)備節(jié)點(diǎn)即可

之前的學(xué)習(xí)有說到USBH是只能主機(jī)模式,要編寫USB HOST就用USBH控制器即可。ST官方的STM3MP157C-DK2開發(fā)板已經(jīng)配置好了USBH的節(jié)點(diǎn)信息,所以直接參考此節(jié)點(diǎn)即可,這樣開發(fā)板就能夠使用 USB Host 模式。

USBH控制器節(jié)點(diǎn)信息

打開“stm32mp151.dtsi”文件,找到USBH兩個(gè)控制器的節(jié)點(diǎn)信息,名字分別為“usbh_ohci”和“usbh_ehci”。如下示例代碼所示:

示例代碼 50.4.1 USBH 下兩個(gè)控制器節(jié)點(diǎn)信息
1  usbh_ohci: usbh-ohci@5800c000 {
2      compatible = "generic-ohci";
3      reg = <0x5800c000 0x1000>;
4      clocks = <&rcc USBH>;
5      resets = <&rcc USBH_R>;
6      interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
7      status = "disabled";
8  };
9
10 usbh_ehci: usbh-ehci@5800d000 {
11     compatible = "generic-ehci";
12     reg = <0x5800d000 0x1000>;
13     clocks = <&rcc USBH>;
14     resets = <&rcc USBH_R>;
15     interrupts-extended = <&exti 43 IRQ_TYPE_LEVEL_HIGH>;
16     companion = <&usbh_ohci>;
17     power-domains = <&pd_core>;
18     wakeup-source;
19     status = "disabled";
20 };

從上面的代碼可以知道USBH是支持USB2.0和USB1.1的。使用USB2.0就要配置usbh_ehci節(jié)點(diǎn),使用USB1.1就要配置usbh_ohci 節(jié)點(diǎn)。這兩個(gè)節(jié)點(diǎn)的信息是不需要修改的,這是STM32MP1一些通用配置信息。需要做的就是在stm32mp157d-atk.dts文件中追加對(duì)應(yīng)屬性信息,然后status屬性值改為“okay”,還要配置USBH使用哪個(gè)PHY端口。根據(jù)兩個(gè)節(jié)點(diǎn)的compatible屬性找到對(duì)應(yīng)的驅(qū)動(dòng)路徑為:drivers/usb/host/ohci-platform.c和drivers/usb/host/ehci-platform.c。

配置PHY控制器

先了解一下PHY控制器,一些通用配置,打開 stm32mp151.dtsi文件,找的如下內(nèi)容所示:

示例代碼 50.4.2 usbphyc 控制器節(jié)點(diǎn)信息
1  usbphyc: usbphyc@5a006000 {
2      #address-cells = <1>;
3      #size-cells = <0>;
4      #clock-cells = <0>;
5      compatible = "st,stm32mp1-usbphyc";
6      reg = <0x5a006000 0x1000>;
7      clocks = <&rcc USBPHY_K>;
8      resets = <&rcc USBPHY_R>;
9      vdda1v1-supply = <&reg11>;
10     vdda1v8-supply = <&reg18>;
11     status = "disabled";
12
13     usbphyc_port0: usb-phy@0 {
14         #phy-cells = <0>;
15         reg = <0>;
16     };
17
18     usbphyc_port1: usb-phy@1 {
19         #phy-cells = <1>;
20         reg = <1>;
21     };
22 };

示例代碼50.4.1.2 usbphyc節(jié)點(diǎn)就是STM32MP1的USB PHY。已經(jīng)知道PHY控制器有兩個(gè)端口,剛好usbphyc節(jié)點(diǎn)里有兩個(gè)子節(jié)點(diǎn)名字分別為:usbphyc_port0和usbphyc_port1,這兩個(gè)子節(jié)點(diǎn)就是PHY控制器的兩個(gè)端口,其中usbphyc_port0只能分配給USB Host。注意:“#phy-cells”屬性和“#gpio-cells”屬性作用是一樣的,如果#phy-cells為1,表示一個(gè)cell,此cell表示端口做USBH的PHY端口還是OTG的PHY端口,0表示做OTG的PHY端口,1表示做USBH的PHY端口。

打開“stm32mp15xx-dkx.dtsi”文件找到“usb_phy_tuning”節(jié)點(diǎn),把此節(jié)點(diǎn)的內(nèi)容拷貝到stm32mp157d-atk.dts的根目錄下,拷貝內(nèi)容如下所示:

示例代碼 50.4.3 添加的 usb_phy_tuning 節(jié)點(diǎn)信息
1  usb_phy_tuning: usb-phy-tuning {
2      st,hs-dc-level = <2>;
3      st,fs-rftime-tuning;
4      st,hs-rftime-reduction;
5      st,hs-current-trim = <15>;
6      st,hs-impedance-trim = <1>;
7      st,squelch-level = <3>;
8      st,hs-rx-offset = <2>;
9      st,no-lsfs-sc;
10 };

usb_phy_tuning此節(jié)點(diǎn)負(fù)責(zé)調(diào)整PHY的配置,對(duì)于此節(jié)點(diǎn)的屬性內(nèi)容感興趣的可以去看Documentation/devicetree/bindings/phy/phy-stm32-usbphyc.yaml文件 。 接著還是在stm32mp157d-atk.dts文件中使能usbphyc以及向usbphyc_port0節(jié)點(diǎn)追加的內(nèi)容,要修改的如下所示:

示例代碼 50.4.4 使能 usbphyc 和追加 usbphyc_port0 的內(nèi)容
1 &usbphyc {
2     status = "okay";
3 };
4
5 &usbphyc_port0 {
6     phy-supply = <&v3v3>;
7     st,phy-tuning = <&usb_phy_tuning>;
8 };

第2行,這里把usbphyc的status屬性修改為“okay”,使能usbphyc。

第6行,給usbphyc_port0節(jié)點(diǎn)追加phy-supply屬性,添加一個(gè)電源管理屬性。

第7行,把要修改的PHY配置,添加到usbphyc_port0節(jié)點(diǎn)里。

配置usbh_ehci

最后在stm32mp157d-atk.dts文件,使能usbh_ehci和指定PHY端口。

示例代碼 50.4.5 追加 usbh_ehci 節(jié)點(diǎn)內(nèi)容
1 &usbh_ehci {
2     phys = <&usbphyc_port0>;
3     status = "okay";
4 };

這里的內(nèi)容很簡(jiǎn)單,就是修改status屬性為“okay”和指定使用usbphyc_port0端口。修改完就重新編譯設(shè)備樹,使用新的stm32mp157d-atk.dtb設(shè)備樹重新啟動(dòng)開發(fā)板。就會(huì)有以下輸出所示:

usbh-echi打印信息
如果有上圖這些輸出信息,說明usb host驅(qū)動(dòng)加載到內(nèi)核了。

Linux內(nèi)核自帶Host實(shí)驗(yàn)

USB鼠標(biāo)鍵盤測(cè)試

首先做一下USB HOST試驗(yàn),也就是正點(diǎn)原子的STM32MP1開發(fā)板做USB主機(jī),然后外接USB設(shè)備,比如USB鼠標(biāo)鍵盤、USB 轉(zhuǎn)TTL串口線、U盤等設(shè)備。Linux內(nèi)核已經(jīng)集成了大量的USB設(shè)備驅(qū)動(dòng),尤其是常見的USB鼠標(biāo)鍵盤、U盤等,本節(jié)就來學(xué)習(xí)一下如何使能Linux內(nèi)核常見的USB設(shè)備驅(qū)動(dòng)。

USB鼠標(biāo)鍵盤驅(qū)動(dòng)使能

USB鼠標(biāo)鍵盤屬于HID設(shè)備,內(nèi)核已經(jīng)集成了相應(yīng)的驅(qū)動(dòng),ST官方提供的linux內(nèi)核默認(rèn)已經(jīng)使能了USB鼠標(biāo)鍵盤驅(qū)動(dòng),但是還要學(xué)習(xí)一下如何手動(dòng)使能這些驅(qū)動(dòng)。輸入“make
menuconfig”,打開linux內(nèi)核配置界面,首先打開HID驅(qū)動(dòng),按照如下路徑到相應(yīng)的配置項(xiàng)目:

-> Device Drivers
-> HID support
-> HID bus support
-> <*> Generic HID driver //使能通用 HID 驅(qū)動(dòng)

使能后結(jié)果如下圖所示:

使能HID驅(qū)動(dòng)

接下來需要使能USB鍵盤和鼠標(biāo)驅(qū)動(dòng),配置路徑如下:

-> Device Drivers
-> HID support
-> USB HID support
-> <*> USB HID transport layer //USB 鍵盤鼠標(biāo)等 HID 設(shè)備驅(qū)動(dòng)

使能后如下圖所示:

使能USB鼠標(biāo)鍵盤驅(qū)動(dòng)

可以將光標(biāo)放到上圖中“USB HID Transport layer”這一行,然后按下“?”鍵打開對(duì)應(yīng)的幫助信息就可以看到對(duì)于這個(gè)配置項(xiàng)的描述,簡(jiǎn)單總結(jié)一下:

此選項(xiàng)對(duì)應(yīng)配置項(xiàng)就是CONFIG_USB_HID,也就是USB接口的HID設(shè)備。如果要使用USB接口的keyboards(鍵盤)、mice(鼠標(biāo))、joysticks(搖桿)、graphic tablets(繪圖板)等其他的HID設(shè)備,那么就需要選中“USB HID Transport layer”。但是要注意一點(diǎn),此驅(qū)動(dòng)和HIDBP(Boot Protocol)鍵盤、鼠標(biāo)的驅(qū)動(dòng)不能一起使用!所以要是在網(wǎng)上查閱linux內(nèi)核USB鍵盤鼠標(biāo)驅(qū)動(dòng)的時(shí)候,發(fā)現(xiàn)推薦使用“USB HIDBP Keyboard (simple Boot) support”和“USB HIDBP Mouse (simple Boot) support”這兩個(gè)配置項(xiàng)的時(shí)候也不要覺得教程這里寫錯(cuò)了。

測(cè)試USB鼠標(biāo)和鍵盤

完成以后重新編譯linux內(nèi)核并且使用得到的 uImage啟動(dòng)開發(fā)板。啟動(dòng)以后插入U(xiǎn)SB鼠標(biāo),會(huì)有如下圖所示的提示信息:

USB鼠標(biāo)log信息

從上圖可以看出,系統(tǒng)檢測(cè)到了鼠標(biāo),如果成功驅(qū)動(dòng)的話就會(huì)在/dev/input目錄下生成一個(gè)名為eventX(X=0,1,2,3…)的文件,這個(gè)就是前面講的輸入子系統(tǒng),鼠標(biāo)和鍵盤都是作為輸入子系統(tǒng)設(shè)備的。教程中這里對(duì)應(yīng)的就是/dev/input/event1這個(gè)設(shè)備,使用如下命令查看鼠標(biāo)的原始輸入值,結(jié)果如下圖:

鼠標(biāo)原始輸入值

上圖就是鼠標(biāo)作為輸入子系統(tǒng)設(shè)備的原始輸入值,這里就不去分析了,在移植GUI圖形庫(kù)以后就可以直接使用鼠標(biāo),比如QT等。

最后再來測(cè)試一下USB鍵盤,屏幕已經(jīng)驅(qū)動(dòng)起來了,所以可以直接將屏幕作為終端,然后接上鍵盤直接輸入命令來進(jìn)行各種操作。首先將屏幕設(shè)置為控制臺(tái),打開開發(fā)板根文件系統(tǒng)中的/etc/inittab文件,然后在里面加入下面這一行:

tty1::askfirst:-/bin/sh

完成以后重啟開發(fā)板,此時(shí)屏幕就會(huì)作為終端控制臺(tái),會(huì)有“Please press Enter to activate
this console.”這樣提示,如下圖所示:

LCD屏幕作為終端

接上鍵盤,然后根據(jù)上圖中的提示,按下鍵盤上的Enter(回車)鍵即可使能LCD屏幕控制臺(tái),然后就可以輸入各種命令來執(zhí)行相應(yīng)的操作,如下圖所示:

鍵盤操作終端

U盤實(shí)驗(yàn)

ST提供的Linux內(nèi)核默認(rèn)也已經(jīng)使能了U盤驅(qū)動(dòng),因此可以直接插上去使用。但是還是需要學(xué)習(xí)一下如何手動(dòng)配置Linux內(nèi)核,使能U盤驅(qū)動(dòng)。

使能U盤驅(qū)動(dòng)

U盤使用SCSI協(xié)議,因此要先使能Linux內(nèi)核中的SCSI協(xié)議,配置路徑如下:

-> Device Drivers
-> SCSI device support
-> <*> SCSI disk support //選中此選項(xiàng)

結(jié)果如下圖所示:

使能SCSI

還需要使能USB Mass Storage,也就是USB 接口的大容量存儲(chǔ)設(shè)備,配置路徑如下:

-> Device Drivers
-> USB support
-> USB Gadget Support
-> USB Gadget functions configurable through configfs
-> [*] Mass storage //選中

結(jié)果如下圖所示:

使能USB大容量存儲(chǔ)設(shè)備

U盤測(cè)試

準(zhǔn)備好一個(gè)U盤,注意U盤要為FAT32格式的!NTFS和exFAT由于版權(quán)問題所以在Linux下支持的不完善,操作的話可能會(huì)有問題,比如只能讀,不能寫或者無法識(shí)別等。準(zhǔn)備好以后將U盤插入到開發(fā)板USB HUB擴(kuò)展出來的HOST接口上,此時(shí)會(huì)輸出如下圖所示信息:

U盤log信息

從上圖可以看出,系統(tǒng)檢測(cè)到U盤插入,大小為16GB對(duì)應(yīng)的設(shè)備文件為/dev/sda和/dev/sda1,可以查看一下/dev目錄下有沒有sda和sda1這兩個(gè)文件。/dev/sda是整個(gè)U盤,/dev/sda1是U盤的第一個(gè)分區(qū),一般使用U盤的時(shí)候都是只有一個(gè)分區(qū)。要想訪問U盤需要先對(duì)U盤進(jìn)行掛載,理論上掛載到任意一個(gè)目錄下都可以,這里可以創(chuàng)建一個(gè)/mnt/usb_disk目錄,然后將U盤掛到/mnt/usb_disk目錄下,命令如下:

mkdir /mnt/usb_disk -p //創(chuàng)建目錄
mount /dev/sda1 /mnt/usb_disk/ -t vfat -o iocharset=utf8 //掛載

-t指定掛載所使用的文件系統(tǒng)類型,這里設(shè)置為vfat,也就是FAT文件系統(tǒng),“-o iocharset”
設(shè)置硬盤編碼格式為utf8,否則的話U盤里面的中文會(huì)顯示亂碼!

掛載成功以后進(jìn)入到/mnt/usb_disk目錄下,輸入ls命令查看U盤文件,如下圖所示:

U盤文件

至此U盤就能正常讀寫操作了,直接對(duì)/mnt/usb_disk目錄進(jìn)行操作就行了。如果要拔出U盤要執(zhí)行一個(gè)sync命令進(jìn)行同步,然后在使用unmount進(jìn)行U盤卸載,命令如下所示:

sync //同步
cd / //如果處于/mnt/usb_disk 目錄的話先退出來,否則卸載的時(shí)候提示設(shè)//備忙,導(dǎo)致卸載失敗,切記!
umount /mnt/usb_disk //卸載

Linux內(nèi)核自帶USB OTG實(shí)驗(yàn)

STUSB1600設(shè)備樹編寫

STUSB1600是ST出的一款TypeC 芯片,也是ST官方開發(fā)板搭配STM32MP1的。STUSB1600的驅(qū)動(dòng)設(shè)備樹編寫參考文檔“Documentation/devicetree/bindings/usb/st,typec-stusb.txt”。此文檔描述了STUSB1600 設(shè)備相關(guān)信息。

USB OTG控制器節(jié)點(diǎn)信息

進(jìn)入到Linux內(nèi)核源碼目錄,打開arch/arm/boot/dts/stm32mp151.dtsi 設(shè)備樹文件,在這個(gè)設(shè)備樹文件有一個(gè)usbotg_hs節(jié)點(diǎn),此節(jié)點(diǎn)就是USB OTG控制器節(jié)點(diǎn),內(nèi)容如下:

示例代碼 50.6.1.1 usbotg_hs 控制器
1  usbotg_hs: usb-otg@49000000 {
2      compatible = "st,stm32mp1-hsotg", "snps,dwc2";
3      reg = <0x49000000 0x10000>;
4      clocks = <&rcc USBO_K>;
5      clock-names = "otg";
6      resets = <&rcc USBO_R>;
7      reset-names = "dwc2";
8      interrupts-extended = <&exti 44 IRQ_TYPE_LEVEL_HIGH>;
9      g-rx-fifo-size = <512>;
10     g-np-tx-fifo-size = <32>;
11     g-tx-fifo-size = <256 16 16 16 16 16 16 16>;
12     dr_mode = "otg";
13     usb33d-supply = <&usb33>;
14     power-domains = <&pd_core>;
15     wakeup-source;
16     status = "disabled";
17 };

示例代碼50.6.1.1中的usbotg_hs節(jié)點(diǎn)不需要修改,這里只是查看一下usbotg_hs完整節(jié)點(diǎn)信息。根據(jù)第2行的compatible屬性就是可以找到STM32MP1的usbotg_hs驅(qū)動(dòng)源文件,驅(qū)動(dòng)文件名為drivers/usb/dwc2/params.c。第12行,dr_mode屬性用來配置控制器做otg功能還是host功能,不配置此屬性默認(rèn)為otg功能。第16行的status屬性為disabled,所以u(píng)sbotg_hs默認(rèn)關(guān)閉的,如果要使能就是要修改status屬性為 okay、配置一個(gè)PHY端口和設(shè)置使用那個(gè)控制器去控制usbotg_hs。

使能usbotg_hs節(jié)點(diǎn)

首先先去配置PHY接口,在stm32mp157d-atk.dts文件中追加usbphyc_port1節(jié)點(diǎn),內(nèi)容如下所示:

示例代碼 50.6.1.2 usbphyc_port1 節(jié)點(diǎn)配置
1 &usbphyc_port1 {
2     phy-supply = <&vdd_usb>;
3     st,phy-tuning = <&usb_phy_tuning>;
4 };

注意:要先使能usbphyc節(jié)點(diǎn),這里在USB HOST實(shí)驗(yàn)已經(jīng)使能就不用配置。

接著去追加usbotg_hs的相關(guān)屬性信息。追加的內(nèi)容如下所示:

示例代碼 50.6.1.3 usbotg_hs 節(jié)點(diǎn)內(nèi)容
1  &usbotg_hs {
2      phys = <&usbphyc_port1 0>;
3      phy-names = "usb2-phy";
4      usb-role-switch;
5      status = "okay";
6
7      port {
8      usbotg_hs_ep: endpoint {
9          remote-endpoint = <&con_usbotg_hs_ep>;
10         };
11     };
12 };

第2行,配置usbotg_hs的PHY接口,這里0表示為OTG USB的PHY端口。

第5行,把status屬性改為okay,使能usbotg_hs。

第7-11行,添加了一個(gè)port節(jié)點(diǎn),第9行指定usbotg_hs 節(jié)點(diǎn)使用con_usbotg_hs_ep做控制器,con_usbotg_hs_ep會(huì)在STUSB1600節(jié)點(diǎn)里創(chuàng)建。

最后還需要添加vdd_usb電源節(jié)點(diǎn),因?yàn)槭纠a50.6.1.2中的usbphyc_port1節(jié)點(diǎn)需要用到vdd_usb節(jié)點(diǎn),在stm32mp157d-atk.dts中添加vdd_usb電源節(jié)點(diǎn),在根節(jié)點(diǎn)下添加內(nèi)容如下

示例代碼 50.6.1.4 vdd_usb 電源節(jié)點(diǎn)
1 vdd_usb: regulator-vdd-usb {
2     compatible = "regulator-fixed";
3     regulator-name = "vdd_usb";
4     regulator-min-microvolt = <3300000>;
5     regulator-max-microvolt = <3300000>;
6     regulator-always-on;
7     regulator-boot-on;
8 };

使能I2C1節(jié)點(diǎn)

控制Typec的芯片是STUSB1600,此芯片是使用I2C協(xié)議和CPU進(jìn)行通訊,所以要使能I2C1。把示例代碼50.6.1.4拷貝到stm32mp157d-atk.dts文件里,代碼如下所示:

示例代碼 50.6.1.5 使能 i2c1 節(jié)點(diǎn)
1 &i2c1 {
2     pinctrl-names = "default", "sleep";
3     pinctrl-0 = <&i2c1_pins_b>;
4     pinctrl-1 = <&i2c1_pins_sleep_b>;
5     status = "okay";
6 };

正點(diǎn)原子STM32MP157開發(fā)板I2C1_SCL和I2C1_SDA這兩個(gè)引腳為PF14和PF15。這兩個(gè)引腳的pinctrl配置已經(jīng)在stm32mp15-pinctrl.dtsi文件里面提供了,如果使用的其他引腳需要自行配置。

配置STUSB1600節(jié)點(diǎn)

先配置STUSB1600的中斷引腳電氣屬性和電源管理,STUSB1600中斷引腳為PG2,在stm32mp15-pinctrl.dtsi文件中輸入如下內(nèi)容:

示例代碼 50.6.1.6 stusb1600 中斷電氣屬性
1 stusb1600_pins_b: stusb1600-0 {
2     pins {
3         pinmux = <STM32_PINMUX('G', 2, ANALOG)>;
4         bias-pull-up;
5     };
6 };

把STUSB1600的中斷引腳改為內(nèi)部上拉。因?yàn)閁SB OTG需要5V電源管理,前面沒有此配置,所以要一個(gè)5V的電源配置,在根節(jié)點(diǎn)下添加如下示例代碼所示:

示例代碼 50.6.1.7 5V 的 vin 節(jié)點(diǎn)
1 vin: regulator-vin {
2     compatible = "regulator-fixed";
3     regulator-name = "vin";
4     regulator-min-microvolt = <5000000>;
5     regulator-max-microvolt = <5000000>;
6     regulator-always-on;
7     regulator-boot-on;
8 };

接下來配置STUSB1600節(jié)點(diǎn),此節(jié)點(diǎn)屬于I2C1的子節(jié)點(diǎn)。STUSB1600的配置內(nèi)容如下所示:

示例代碼 50.6.1.8 stusb1600 節(jié)點(diǎn)信息
1  stusb1600@28 {
2      compatible = "st,stusb1600";
3      reg = <0x28>;
4      interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
5      interrupt-parent = <&gpiog>;
6      pinctrl-names = "default";
7      pinctrl-0 = <&stusb1600_pins_b>;
8      status = "okay";
9      vdd-supply = <&vin>;
10
11     connector {
12         compatible = "usb-c-connector";
13         label = "USB-C";
14         power-role = "dual";
15         power-opmode = "default";
16
17         port {
18             con_usbotg_hs_ep: endpoint {
19                 remote-endpoint = <&usbotg_hs_ep>;
20             };
21         };
22     };
23 };

示例代碼50.6.1.7代碼中可以分為兩個(gè)部分:第1-9行屬于控制STUSB1600芯片相關(guān)屬性,第11-22行屬于Typec端口相關(guān)屬性。

第2行,compatible的屬性值為“st,stusb1600”,在Linux源碼目錄下,搜索此屬性值,會(huì)找到stusb1600的驅(qū)動(dòng)源碼為drivers/usb/typec/typec_stusb.c。

第3行,reg屬性值為“0x28”,stusb1600芯片通訊地址為0x28。

第4-5行,設(shè)置中斷相關(guān)配置,中斷觸發(fā)為下降沿觸發(fā)。

第6-7行,設(shè)置中斷的電氣屬性。

第9行,設(shè)置電源配置。

第12-15行,可以查看Documentation/devicetree/bindings/connector/usb-connector.txt 文件。

第17-20行,定義了一個(gè)con_usbotg_hs_ep端口,同時(shí)指定此端口連接到usbotg_hs節(jié)點(diǎn)的usbotg_hs_ep端口。

重新編譯設(shè)備樹,使用新的stm32mp157d-atk.dtb 文件去啟動(dòng)開發(fā)板。

FUSB302驅(qū)動(dòng)移植

在上一小節(jié)已經(jīng)完成了一部分的設(shè)備樹配置,由于只是改了USB TypeC的芯片,所以只需要把STUSB1600相關(guān)的部分改為FUSB302 即可。其實(shí)就是上一小節(jié)前面的1-3小點(diǎn)不用修改,只需要改第4小點(diǎn)。

首先配置FUSB302的中斷電氣屬性,配置如下所示:

示例代碼 50.6.2.1 fusb302 中斷電氣屬性
1 fusb302_pins_a: fusb302-0 {
2     pins {
3         pinmux = <STM32_PINMUX('G', 2, ANALOG)>;
4         bias-pull-up;
5     };
6 };

在 stm32mp157d-atk.dts文件中添加頭文件“dt-bindings/usb/pd.h”,如下圖所示:

添加“dt-bindings/usb/pd.h”頭文件

接著配置FUSB302節(jié)點(diǎn),配置的代碼如下所示:

示例代碼 50.6.2.2 fusb302 節(jié)點(diǎn)信息
1  fusb302@22 {
2      compatible = "fcs,fusb302","fairchild,fusb302";
3      reg = <0x22>;
4      pinctrl-names = "default";
5      pinctrl-0 = <&fusb302_pins_a>;
6      int-n-gpios = <&gpiog 2 GPIO_ACTIVE_HIGH>;
7      vbus-5v-gpios = <&gpioz 6 GPIO_ACTIVE_HIGH>;
8      status = "okay";
9
10     connector {
11         compatible = "usb-c-connector";
12         label = "USB-C";
13         power-role = "dual";
14         power-opmode = "default";
15
16         try-power-role = "sink";
17         source-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
18         sink-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)
19         PDO_VAR(3000, 12000, 3000)
20         PDO_PPS_APDO(3000, 11000, 3000)>;
21         op-sink-microwatt = <10000000>;
22         port {
23             con_usbotg_hs_ep: endpoint {
24                 remote-endpoint = <&usbotg_hs_ep>;
25             };
26         };
27     };
28 };

fusb302的設(shè)備樹沒有使用電源管理,而是用PZ6 引腳去控制電壓。其它的屬性和stusb1600一樣。

最后就是去改驅(qū)動(dòng)了,Linux內(nèi)核提供的fusb302驅(qū)動(dòng)是沒讀取connector相關(guān)的屬性,所以此驅(qū)動(dòng)是不能使用。在github里找到了可用的fusb302驅(qū)動(dòng),改動(dòng)的部分是如何讀取connector節(jié)點(diǎn)和使用PZ6引腳控制電壓。想看如何修改的,可以用文件對(duì)比軟件,就能知道修改了那些內(nèi)容。將25_fusb302目錄的fusb302.c和fusb302.h文件拷貝到linux源碼下的drivers/usb/typec/tcpm目錄里,注意要把原來的fusb302.c覆蓋掉,拷貝結(jié)果如下圖所示:

拷貝fusb302驅(qū)動(dòng)的tcpm目錄

拷貝完成后,進(jìn)入內(nèi)核的配置選項(xiàng)圖形界面,配置路徑如下:

-> Device Drivers
-> USB support
-> USB Type-C Support
-> USB Type-C Port Controller Manager
-> <*> Fairchild FUSB302 Type-C chip driver //選中

如下圖所示:

FUSB302的驅(qū)動(dòng)使能

重新編譯設(shè)備樹和內(nèi)核,使用新的設(shè)備樹stm32mp157d-atk.dtb和內(nèi)核uImage去啟動(dòng)開發(fā)
板,有如下圖打印信息,說明加載驅(qū)動(dòng)成功。如圖所示:

加載FUSB302驅(qū)動(dòng)打印信息

OTG主機(jī)實(shí)驗(yàn)

系統(tǒng)重啟成功以后就可以正常使用USB_OTG接口,OTG既可以做主機(jī),也可以做從機(jī),做主機(jī)的話測(cè)試方法和之前的測(cè)試一模一樣,直接在正點(diǎn)原子的USB_OTG接口上使用Typec OTG線接入鼠標(biāo)鍵盤、U盤等設(shè)備。USB_OTG接口如下所示:

USB_OTG接口

OTG從機(jī)實(shí)驗(yàn)

OTG從機(jī)就是將開發(fā)板作為一個(gè)USB設(shè)備連接到其他的主機(jī)上,這里來做兩個(gè)USB從機(jī)實(shí)驗(yàn):模擬U盤以及USB聲卡。

模擬U盤實(shí)驗(yàn)

模擬U盤實(shí)驗(yàn)就是將開發(fā)板當(dāng)做一個(gè)U盤,可以將開發(fā)板上的U盤或者TF卡掛載到PC上,首先需要配置Linux,配置路徑如下:

-> Device Drivers
-> USB support
-> USB Gadget Support
-> < > USB Gadget functions configurable through configfs //不要編譯進(jìn)內(nèi)核
-> USB Gadget precomposed configurations ( [=m])
-> Mass Storage Gadget //大容量存儲(chǔ)

結(jié)果如下圖所示:

USB Gadget中大容量存儲(chǔ)設(shè)備驅(qū)動(dòng)

這里需要將驅(qū)動(dòng)編譯為模塊!使用的時(shí)候直接輸入命令加載驅(qū)動(dòng)模塊即可。配置好
以后執(zhí)行下面這些命令重新編譯Linux內(nèi)核、編譯模塊:

make uImage LOADADDR=0XC2000040 -j32
make modules -j32

編譯完成后會(huì)得到3個(gè).ko內(nèi)核模塊文件,對(duì)應(yīng)路徑為:

drivers/usb/gadget/libcomposite.ko
drivers/usb/gadget/function/usb_f_mass_storage.ko
drivers/usb/gadget/legacy/g_mass_storage.ko

將上述三個(gè).ko 模塊拷貝到開發(fā)板根文件系統(tǒng)/lib/modules/5.4.31目錄下,如圖所示:

內(nèi)核模塊拷貝到根文件系統(tǒng)

拷貝完成以后使用新編譯出來的uImage啟動(dòng)開發(fā)板,在開發(fā)板上插入一個(gè)U盤,記住這個(gè)U盤對(duì)應(yīng)的設(shè)備文件,比如這里是/dev/sda 和/dev/sda1,以后要將/dev/sda1掛載到PC上,也就是把/dev/sda1作為模擬U盤的存儲(chǔ)區(qū)域。

使用TypeC數(shù)據(jù)線將開發(fā)板和電腦連接,連接好以后依次加載libcomposite.ko、usb_f_mass_storage.ko和g_mass_storage.ko這三個(gè)驅(qū)動(dòng)文件,順序不能錯(cuò)了!命令如下:

depmod
modprobe libcomposite.ko
modprobe usb_f_mass_storage.ko
modprobe g_mass_storage.ko file=/dev/sda1 removable=1

加載g_mass_storage.ko的時(shí)候使用file參數(shù)指定使用的大容量存儲(chǔ)設(shè)備,這里使用U盤對(duì)應(yīng)的/dev/sda1。如果加載成功的話電腦就會(huì)出現(xiàn)一個(gè)U盤,這個(gè)U盤就是開發(fā)板模擬的,可以直接在電腦上對(duì)這個(gè)U盤進(jìn)行讀寫,實(shí)際上就是操作插在開發(fā)板上的U盤。操作完成后要退出需要執(zhí)行如下命令:

rmmod g_mass_storage.ko
rmmod usb_f_mass_storage.ko
rmmod libcomposite.ko

注意!不要將開發(fā)板上的EMMC或者NAND作為模擬U盤的存儲(chǔ)區(qū)域,因?yàn)閘inux下EMMC和NAND使用的文件系統(tǒng)一般都是EXT3/EXT4和UBIFS,這些文件系統(tǒng)類型和windows下的不兼容,如果掛載的話就會(huì)在windows下提示要格式化U盤!

USB聲卡實(shí)驗(yàn)

USB聲卡就是USB接口的外置聲卡,一般電腦內(nèi)部都自帶了聲卡,但是內(nèi)部自帶的聲卡效果相對(duì)來說比較差,不能滿足很多HIFI玩家的需求。USB聲卡通過USB接口來傳遞音頻數(shù)據(jù),具體的ADC和DAC過程由聲卡完成,擺脫了電腦主板體積的限制,外置USB聲卡就可以做的很好。STM32MP1開發(fā)板板載了音頻解碼芯片,因此可以將STM32MP1開發(fā)板作為一個(gè)外置USB聲卡,配置Linux內(nèi)核,配置路徑如下:

-> Device Drivers
-> USB suppor
-> USB Gadget Support
-> USB Gadget precomposed configurations
-> Audio Gadget //選中音頻,編譯為模塊
-> UAC 1.0 //選中
-> [*] UAC 1.0 (Legacy) //選中 UAC

配置如下圖所示:

使能USB Gadget下的音頻驅(qū)動(dòng)

注意,這里也是編譯為驅(qū)動(dòng)模塊,配置完成以后重新編譯內(nèi)核、編譯模塊,會(huì)得到3個(gè)驅(qū)動(dòng)模塊文件,模塊文件路徑如下:

drivers/usb/gadget/libcomposite.ko
drivers/usb/gadget/function/usb_f_uac1_legacy.ko
drivers/usb/gadget/legacy/g_audio.ko

將上述三個(gè).ko模塊文件拷貝到開發(fā)板根文件系統(tǒng)/lib/modules/5.4.31目錄下,拷貝完成以后使用新編譯出來的uImage啟動(dòng)開發(fā)板,首先要按照之前學(xué)習(xí)的音頻驅(qū)動(dòng)的方法配置STM32MP1的聲卡,保證聲卡播放正常!使用Typec數(shù)據(jù)線將開發(fā)板與電腦連接起來,最后依次加載 libcomposite.ko、usb_f_uac1_legacy.ko和g_audio.ko這三個(gè)驅(qū)動(dòng)模塊,命令如下:

depmod
modprobe libcomposite.ko
modprobe usb_f_uac1_legacy.ko
modprobe g_audio.ko

加載完成以后稍等一會(huì)虛擬出一個(gè)USB聲卡,打開電腦的設(shè)備管理器,選擇“聲音、視頻和游戲控制器”,會(huì)發(fā)現(xiàn)有一個(gè)名為“AC Interface”設(shè)備,如下圖所示:

模擬的USB聲卡

上圖中的“AC Interface”就是開發(fā)板模擬出來的USB聲卡,設(shè)置Windows,選擇音頻輸出使用“AC Interface”,Windows10設(shè)置如下圖所示:

聲卡輸出設(shè)置為AC Interface

一切設(shè)置好以后就可以從開發(fā)板上聽到電腦輸出的聲音,此時(shí)開發(fā)板就完全是一個(gè)USB聲
卡設(shè)備了。

關(guān)于USB驅(qū)動(dòng)就講解到這里,本章并沒有深入到USB驅(qū)動(dòng)具體編寫方式,只是對(duì)USB的協(xié)議做了簡(jiǎn)單的介紹,后面講解了一下Linux內(nèi)核自帶的USB HOST和DEVICE驅(qū)動(dòng)的使用,Linux 內(nèi)核已經(jīng)集成了大量的USB設(shè)備驅(qū)動(dòng),至于其他特殊的就需要具體情況具體分析了。

總結(jié)

本章的學(xué)習(xí)重點(diǎn),主要就是對(duì)USB設(shè)備做了一個(gè)大致的了解,然后對(duì)USB的傳輸協(xié)議大致做了介紹,這一部分可以多看看,如果之后想做項(xiàng)目有要用到USB設(shè)備的話這一部分要多琢磨一下。

然后就是具體的STM32MP157開發(fā)板的USB驅(qū)動(dòng)的使用。

對(duì)于USB HOST來說,這一部分需要在設(shè)備樹中(.dts),在根節(jié)點(diǎn)下添加usb_phy_tuning節(jié)點(diǎn)(可以直接從stm32mp15xx-dkx.dtsi復(fù)制),然后在設(shè)備樹中添加usbphyc和usbphyc_port0的節(jié)點(diǎn),之后在添加usbh_ehci節(jié)點(diǎn)。

以上就配置完成了,之后要具體使用USB驅(qū)動(dòng)設(shè)備的話,就進(jìn)入Linux內(nèi)核里面取使能對(duì)應(yīng)設(shè)備就可以了。

至于USB OTG的驅(qū)動(dòng),因?yàn)槲疫@邊新買的肯定是最新的,就是FUSB302芯片。在設(shè)備樹里面追加usbphyc_port1節(jié)點(diǎn),然后再加一個(gè)usbotg_hs節(jié)點(diǎn),然后在根節(jié)點(diǎn)加上usbphyc_port1所需要的vdd_usb節(jié)點(diǎn);之后添加i2c1節(jié)點(diǎn)并使能;最后配置fusb302的電氣屬性,在i2c1節(jié)點(diǎn)下添加fusb302節(jié)點(diǎn)。最后再修改一下驅(qū)動(dòng),把提供的驅(qū)動(dòng)文件拷貝到drivers/usb/typec/tcpm目錄里面,最后進(jìn)入內(nèi)核配置使能FUSB302配置就可以了。

OTG主機(jī)實(shí)驗(yàn)和HOST是一樣的;從機(jī)就需要先進(jìn)入內(nèi)核配置使能,然后需要“make modules”并按照前面寫的復(fù)制.ko到/lib/modules/5.4.31然后按照順序來modprobe,最后不用了就rmmod就可以了。

http://www.risenshineclean.com/news/29881.html

相關(guān)文章:

  • 高端企業(yè)網(wǎng)站建設(shè)注意問題谷歌瀏覽器搜索入口
  • 福建省建設(shè)執(zhí)業(yè)繼續(xù)教育網(wǎng)站吉林seo排名公司
  • 浙江融興建設(shè)有限公司網(wǎng)站網(wǎng)站建設(shè)公司推薦
  • 大學(xué)生網(wǎng)站建設(shè)方案世界球隊(duì)最新排名
  • 網(wǎng)站建設(shè)有增值稅發(fā)票嗎seo個(gè)人優(yōu)化方案案例
  • 夏天做啥網(wǎng)站能致富sem優(yōu)化師
  • 網(wǎng)站制作網(wǎng)站建設(shè)需要多少錢網(wǎng)站銷售怎么推廣
  • 教做家庭菜的網(wǎng)站怎么做推廣比較成功
  • 樂清做網(wǎng)站價(jià)格推廣的軟件
  • 彈幕網(wǎng)站是怎么做的發(fā)布軟文平臺(tái)
  • seo網(wǎng)站建設(shè)價(jià)格自己怎么創(chuàng)建網(wǎng)站
  • 商貿(mào)網(wǎng)站管理培訓(xùn)機(jī)構(gòu)
  • ftp是專門提供文件傳輸?shù)木W(wǎng)站百度注冊(cè)新賬號(hào)
  • 品牌seo公司焦作關(guān)鍵詞優(yōu)化排名
  • 建網(wǎng)站的服務(wù)器學(xué)電商出來一般干什么工作
  • 創(chuàng)意個(gè)人網(wǎng)站設(shè)計(jì)大冶seo網(wǎng)站優(yōu)化排名推薦
  • 律師網(wǎng)站深圳網(wǎng)站設(shè)計(jì)百度app在哪里找
  • 黔東南網(wǎng)頁設(shè)計(jì)seo搜索引擎優(yōu)化人員
  • wordpress掃碼收款seo網(wǎng)絡(luò)營(yíng)銷課程
  • 公司做的網(wǎng)站賬務(wù)處理淘寶關(guān)鍵詞搜索量查詢
  • 開發(fā)公司人效比seo排名培訓(xùn)學(xué)校
  • 做網(wǎng)站彩票代理犯法嗎我是站長(zhǎng)網(wǎng)
  • php做網(wǎng)站網(wǎng)絡(luò)營(yíng)銷有什么崗位
  • 國(guó)內(nèi)可以做的國(guó)外兼職網(wǎng)站海外營(yíng)銷方案
  • 專門做微信推送的網(wǎng)站搜索引擎優(yōu)化要考慮哪些方面?
  • 海北高端網(wǎng)站建設(shè)哪家好網(wǎng)站推廣途徑和推廣要點(diǎn)
  • 網(wǎng)站建設(shè)方案書深圳關(guān)鍵詞推廣優(yōu)化
  • 東營(yíng)本地網(wǎng)站制作公司可以入侵的網(wǎng)站
  • 公司網(wǎng)站維護(hù)該誰來做全網(wǎng)營(yíng)銷外包
  • java可以做微信網(wǎng)站么站長(zhǎng)統(tǒng)計(jì)工具