⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.tex

📁 usbport-sl811usb主控器芯片usb程序实现
💻 TEX
📖 第 1 页 / 共 2 页
字号:
{   	/* device address */	u8 address;	/* endpoint address */	u8 endpoint;	/* Interrupt on complete */	u8 ioc;	/* PID setup,out or in */	u8 pid;	/* if packet is isochronous */	u8 iso;	/* Togl Bit select DATA0 or DATA1 */	u8 togl;	/* buffer */	char *buf;	/* buffer length */	u16 buflen;};\end{lstlisting}Die Funktion usb\_submit\_urb wandelt URBsin die entsprechenden Transfer Deskriptoren um.Daf"ur muss die Nachricht aus dem URB in Endpunkt grosseSt"uecke Zerlegt werden. Beim Aufteilen muss das Togl Bit in den einzelnen Transfer Deskriporen gleichrichtig gesetzt werden.Wenn es sich um ein Setup Paket handelt, mussdas erste Paket speziell mit der PID Setup makiert werden.Bei einem  UHCI Controller kann man ein spezielles Flag Interrupt on Complete setzen. Welches dann daf"ursorgt das erst bei einem ensprechenden Paket ein Interrupt ausgel"ost wird. Ich will versuchendieses Konzept zu "ubernehmen. Das heisst man kann bei einem Standard Request z.B.GetDeviceDescriptor alle 5 Transferdeskriporen absenden.Der UHCI Controller w"urde jetzt direkt die Puffermit den Antwort Bytes f黮len und erst beim letzten TD signalisierendas er fertig ist.Der UHCI braucht daf"ur keinen extra Speicher, da er direktim Arbeitsspeicher des Computers arbeitet.Bei Embedded USB Host Controller ist dies leider aber nicht immer m"oglich. Der SL811 hat daf"ur zwar 240 Byte Speicher, nur gibt es viele Bausteine die "uber so einen internen Speicher nicht verf"ugen.Das heisst das sammeln der Pakete wird im Host Treiber geschehen.Dann kann man individuell auf den Baustein eingehen.Es wird dann zu der Funktion usb\_hcd\_transfer eine benoetigt,die die Antwort der letzten n TDs abholt. Dazu wird ein zaehler benoetigtwie oft das Interrupt on Complete Flag nicht gesetzt war.Wie kommen die Daten jetzt wieder in den Stack zur"uck?Normalerweise werden im Single Modus die TDs direkt mit den Daten bef"ullt.Im Queue Modus ohne der oben genannten Idee wuerde man ebenfalls die Datendirekt in die TDs wieder schreiben.Die Funktion die die letzten n TDs abholt muss die Daten auf die zugehoerigen TDs verteilen.Woher weiss man welche TDs zu welcher URB gehoeren?Eventuell sollte man eine TD Liste im URB speichern.Gibt es ein System mit den man eindeutige IDs ueber einen besimmten Zeitraum verteilen kann?Wie kann man merken das eine Grenze uberschritten wird und eine Zahl doppelt hergenommen wird?Und das ganze sollte mit einem Byte funktionieren.Warum das Ganze?Der USB Stack w"urde sonst nahezu 100 Prozent der Prozessorzeit durch warten verbraten.Auf dem USB Bus wird jede Millisekunde eine SOF generiert. Nach diesem koennen Daten versendet werden.Das heisst zwischen zwei SOFs kann der USB Baustein selbst"andig arbeiten und mankann diese Zeit sinnvoll im eigenen Programm nutzen.\subsubsection{usb\_submit\_urb - im Single oder Queue Modus}Der Single Modus ist f"ur Umgebungen mit extrem wenig Arbeitsspeicher.In diesem Modus werden die Nachrichten sofort nacheinanderabgearbeitet. Eigentlich verfolgt ein USB Stack die Strategie,die verf"ugbare Datenrate fair auf alle Ger"ate am Bus zu verteilen.So ist z.B. in der USB Spezifikation definiert das f"ur Isochronous- und InterruptTransfer bis zu 90 Prozent der Gesamtdatenrate reserviert sind.Daf"ur braucht man aber entsprechende Warteschlangen um ein fairesaufteilen der Datenrate zu erm"oglichen. Und auf dieses Feature verzichtetman im Single Modus. Wenn man aber genug Speicherplatz zur Verf"ugung hatkann man den Queue Modus w"ahlen und hat die eben erw"ahnten Vorteile.\newline\newline\noindentIm Queue Modus werden die Transferdeskriptoren in USB Kern gesammelt.Parallel dazu werden immer entsprechend zusammen passende Transferdeskriptorenf"ur ein Frame gesammelt um so effektiv die Transferrate nutzen zu k"onnen.\newline\newline\noindentIm Single Modus werden die erzeugen Transferdeskriptoren sofort anden Host Controller zur "Ubertragung auf dem USB Bus "ubergeben.\subsubsection{usb\_submit\_urb - Algorithmus}{\bf Allgemein}\newline\begin{enumerate}\item Pr"ufe ob es sich um ein Setup Request handelt -> if urb->setup==1\item Falls Setup -> goto Setup Transfer Deskriptor\item sonst -> pruefe 7. Bit in Endpoint Adresse ob es sich um eine IN oder OUT Pipe handelt\item Teile Gesamtanzahl der zu "ubertragenden Bytes durch Endpunkt FIFO Gr"oesse\item Genererie n TDs mit entsprechend gesetztem Togl Bit und if urb->iso makiere TD\end{enumerate}\noindent\newline{\bf Setup Transfer Deskriptor}\begin{enumerate}\item Generiere Setup TD\item Falls keine Antwort erwartet wird (7. Bit im 8. Byte des Descr) -> PID IN zero data1\item Sonst Anzahl der zu "ubertragenden Bytes durch Endpunkt FIFO Gr"oesse\item Genererie n TDs mit entsprechend gesetztem Togl Bit\item Als Abschluss muss ein OUT zero data1 oder data0 Packet gesendet werden\end{enumerate}\noindent\newlineNach jedem nicht isochronen Packet muss ein ACK vom Ger"at kommen.Falls ein NACK kommt, muss das letzte Packet nochmal gesendet werden.\newpage\subsection{USB Host Controller Treiber}\subsubsection{USB Host Controller Treiber API}Der Host Controller Treiber muss f"ur den USB Kern die folgenden Funktionen anbieten:\begin{figure}[h]\begin{center}\begin{tabular}{|l|l|}\hlineFunktion & Beschreibung\\ \hlineusb\_hcd\_init() & mitte\\ \hlineusb\_hcd\_event() & mitte\\ \hlineusb\_hcd\_transfer() & mitte\\ \hline\end{tabular}\end{center}\caption{USB Host Controller API}\end{figure}\subsubsection{Kommunikation "uber Transfer Deskriptoren}Die Aufgabe des Host Controllers umfasst die "Ubertragungvon Daten auf dem USB Bus. Die Auftr"age bekommt der Controller"uber Transfer Deskriptoren. Die Transfer Deskriptoren stellenDatenstrukturen da, die folgende Informationen beinhalten:\begin{itemize}\item Adresse des angesprochenen USB Ger"ats\item Endpoint\item ISO (Handelt es sich um ein isochrones Packet?) \item PID des Packets (SETUP,IN oder OUT)\item Toggl Bit\item Interrupt on complete \item Pufferspeicher Adresse\item Nachrichten L"ange\end{itemize}\newpage\subsubsection{Events vom Host Controller}Der USB Host Controller Treiber signalisiert dem USB Kern "uberEvents, wenn etwas auf dem Host Controller passiert ist.\begin{figure}[h]\begin{center}\begin{tabular}{|l|l|}\hlineEreignisse & Beschreibung\\ \hlineHCD\_EVENT\_NONE & mitte\\ \hlineHCD\_EVENT\_DEVICEFOUND & Neues Ger"at am Host gefunden\\ \hlineHCD\_EVENT\_DEVICEREMOVED & Das Ger"at wurde von Host entfernt\\ \hlineHCD\_EVENT\_NACK & NACK Signal von USB Ger"at empfangen\\ \hlineHCD\_EVENT\_ACK & ACK Signal von USB Ger"at empfangen\\ \hlineHCD\_EVENT\_ISO & Host hat ein isochrones Packet empfangen\\ \hlineHCD\_EVENT\_READY & Controller ist bereit f"ur neue Transaktionen\\ \hline\end{tabular}\end{center}\caption{USB Host Controller Ereignisse} \end{figure}\noindentDiese Ereignisse sind nur f"ur Ger"ate die direkt am Host Controllerh"angen. Falls mehrer Ger"ate an einem USB Bus betrieben werden sollen,muss ein USB Hub dazwischen geschaltet werden. Der USB Hub Treiber ist dannselbst"andig f"ur die Verwaltung der Ger"ate an seinen Ports zust"andig.\subsubsection{Interrupt Leitung}Oft haben USB Host Bausteine eine Interrupt Leitung, an der signalisiertwird wenn sich ein Ereignis im Baustein ereignet hat. In der Interruptroutinemuss das Ereignis am Controller abgefragt werden und danach die Funktionusb\_core\_process aufgerufen werden.\lstset{language=C}\begin{lstlisting}uint8_t event;event = usb_hcd_event();core.hcd_event=event;/* execute event at once*/usb_core_process((struct usbcore*)&core);\end{lstlisting}\newpage\section{USB Hub Treiber}\section{USB Treiber selber schreiben}\section{Beispiel: Erkennung eines neuen USB Ger"ats}Das Ger"at wird direkt am USB Host Controller eingesteckt. Nachdem das Ger"at erkannt wordenist beginnt der USB Kern mit der Enumeration.\newline\newlineHCD = Host Controller Drivder\newlineHC = Host Controller\newlineCORE = USB Kern\newlineDRIVERAPI = Treiber API\newlineTD = Transfer Deskriptor\begin{enumerate}\item Ger"at wird angesteckt\item HC l"ost Interrupt aus\item Interrupt Routine holt Event und meldet es dem Kern\item CORE usb\_core\_process startet Enumeration\item DRIVERAPI GetDeviceDescriptor Request wird erzeugt\item CORE Request wird abgesendet (usb\_urb\_submit)\item CORE erzeugt aus dem Requests einzelne Transfer Deskriptoren\item CORE f"ugt neue TDs in Frame Liste ein\item HCD erstes TD wird versendet und makiert (SETUP DATA0)	(TD1)\item HC l"ost Interrupt aus\item HC meldet das er wieder Betriebsbereit ist\item HCD zweiter TD wird versendet und makiert (IN DATA1)		(TD2)\item HC l"ost Interrupt aus\item HC meldet das er wieder Betriebsbereit ist\item HCD stoppt Request in dem ein leeres OUT Packet gesendet wird (OUT ZERO DATA0) (TD3)\item DRIVERAPI SetAddress Request wird erzeugt\item CORE Request wird abgesendet (usb\_urb\_submit)\item CORE erzeugt aus dem Requests einzelne Transfer Deskriptoren (TD)\item CORE f"ugt neue TDs in Frame Liste ein\item HCD erstes TD wird versendet und makiert (SETUP DATA0)	(TD1)\item \end{enumerate}\end{document}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -