Hallo zusammen, ich habe bisher USB dazu genutzt einzelne Steuerbefehle (als ASCII Zeichen) an meinen Microcontroller zu schicken. Hiermit habe ich über ein Visual Studio Programm einzelne Steuerbefehle durchgeführt (Start/Stop/Störung reset etc). Hierzu habe ich immer den FTDI Chip genutzt, der aus RS232 UART macht. Somit konnte ich die Steuerbefehle über den UART Interrupt einlesen was auch an sich sehr zuverlässig funktioniert hat. Nun wird der Chip aber immer teurer und der Platz auf der Platine langsam eng, so dass ich für die nächste Serie gerne die Controller Interne USB Funktionalität nutzen möchte. Nur leider habe ich bisher hierzu keinerlei Informationen zur aAktivierung/Implementierung gefunden. Sämtliche Libraries die ich finde sind nur für das Evaluierungsboard und besitzen ca 200 .c/.h Dateien on denen ich nicht wirklich weis welche zu implementieren sind. Hat jemand Codebeispiele oder Anleitungen für mich. Ich stehe hier wirklich ziemlich bei 0 und weis gar nicht so richtig wie ich anfangen soll. Auch die Dateien die der Konfigurator von Cube ausspuckt sind mir keine große Hilfe. Ich weis nicht, bei UART,SPI und I"C gig das irgendwie alles besser und logischer von Statten P.S. Programmiert wird mittels EM-Bitz Für jede Unterstütung bedanke ich mich schon jetzt.
Ich kenne den STM32 überhaupt nicht, aber hast du dir die Funktionen eins BluePill Boards schon einmal angesehen? Die verwenden den selben uC und greifen über USB direkt darauf zu. Vermutlich ist da auch deine gewünschte Anforderung implementiert. Habe letzte Woche so ein BluePill bestellt und bin gespannt, wie weit ich damit komme. Möchte die Arduino IDE benutzen.
EM-Bitz kenne ich nicht, ich nehme SW4STM32. In der HAL Lib sind Beispiele für alle Arten von USB Devices drin. Wenn du CubeMX (und damit vermutlich auch HAL?) benutzt und ein CDC Projekt erstellst, hat das schon alles was es braucht. Es wird die Funktion CDC_Receive_FS in der Datei usbd_cdc_if.c bei jedem empfangenen Zeichen aufgerufen. Um die Wirkung zu sehen kannst du in der Funktion CDC_Receive_FS einfach das empfangene Zeichen zurück senden, oder dort die Auswertung vornehmen.
1 | .
|
2 | .
|
3 | CDC_Transmit_FS((uint8_t *)&Buf[0],1); |
4 | return (USBD_OK); |
Im Anhang noch die CubeMX Projektdatei und eine Übersicht der verwendeten Dateien.
Noch etwas: bei den Grundeinstellungen gibt es einige Warnungen was VID/PID betrifft und der F103 wird als F407 CDC Device erkannt. Also evtl. noch anpassen, läuft aber auch so.
Guten Morgen zusammen, vielen Dank für die Antworten bisher. Die Library habe ich schon gesichtet, vermisse dabei aber eine Art Aufrufstruktur. D.h. ich sehe zwar die Beispiele und kann diese halbwegs nachvollziehen aber das Problem ist, dass ich nicht exact weiß welche .c und .h files ich nun wirklich einbinden MUSS, und wie die Aufrufstruktur diesbezüglich aussieht. Da stehe ich wirklich auf dem Schlauch. Das nächste Problem, CUBE betreffend ist, dass mein Projekt (bis auf USB) schon fertig ist. I2C, UART, SPI ist alles am Laufen, aber eben ohne `CUBE erstellt. Wenn ich jetzt die Output Dateien aus CUCE nehme, bin ich irgendwie auch zu blöd um zu differenzieren welche Dateien ich wirklich brauche, und welche Inhalte jetzt bestehende Konfigurationen bei mir sogra überbügeln würden. Im Idealfall bräuchte ich eine Hand voll .c und .h files und eine Aufrufstruktur, und dann ein Interruptbeispiel um Buchstaben lesen zu können. Hat jemand sowas, gibt es sowas, bzw. kann mir jemand das Anhand der Library erklären? Sorry für die dummen Fragen, aber was USB betrifft stehe ich beim STM echt auf dem Schlauch...
Von ST gibt es die USB-FS Lib. Sind 10-20 Dateien. Relativ einfach zu verstehen und funktioniert bei mir relativ gut. http://www.st.com/en/embedded-software/stsw-stm32121.html mfg
Mick >Habe letzte Woche so ein BluePill bestellt und bin gespannt, wie weit >ich damit komme. Möchte die Arduino IDE benutzen. Beim ersten Mal musst Du das BluePill-Board mit einem ST-Link oder einem externen seriellen Adapter flashen. Viele Der BlueBill-Boards haben dann noch das Problem des falsch bestückten USB-Widerstandes von 10K anstatt 1.5K : http://wiki.stm32duino.com/index.php?title=Blue_Pill
Wenn es etwas sparsamer sein soll kann ich die Implementierung von W.S. empfehlen: Beitrag "STM32F103-USB-CDC von W.S." Damit schrumpft die Anzahl beteiligter Dateien beträchtlich und die Abhängigkeit von irgendwelchen STM(HAl)Libs ist raus.
temp schrieb: > Wenn es etwas sparsamer sein soll kann ich die Implementierung von W.S. > empfehlen: Leider nicht so einfach auf dem F103 zu implementieren. Da passte erst mal nichts. Nach einigen Patch Versuchen aufgegeben. Das Angebot von W.S. ist zwar verlockend, jedoch gibt er sich keine Mühe die Anpassungschritte für den F103 anzugeben. Lieber das Original von ST verwenden, da ist der Anpassungs- aufwand am geringsten. Auch wenn es ein paar Dateien mehr sind.
Hallo Temp... hab mir diese beiden Dateien gerade mal angesehen und in mein Projekt implementiert. Compiliert mit 0 Fehlern....freu*** Nun gibt es in der USB.h ja diverse nach außen offene Funktionen. Ich bin aber etwas überfragt wie/wann ich diese aufrufen soll, Zeitgesteuert? Im Interrupt? Was ich lediglich möchte, ist, ein Char welches ich über Visual Studio, oder wegen mir erst mal über Hyperterminal schicke empfangen. Kannst du mir da noch kurz Hilfestellung geben bitte ???
Bzw. was mir noch fehlt sind die SETUP-Parameter. D.h. ich weis nicht, inwiefern ich in meinem Setup (Einstellung von Clock und I/O Parmetern etc.) noch Einstellungen vornehmen muss oder ob diese in der Setup Funktion der USB.c schon enthalten sind...
Den Takt musst du schon auf 72MHz eingestellt haben. Das kannst nur du beurteilen. Ansonsten sind in noch die Pins zu konfigurieren. So z.B.:
1 | int main(void) |
2 | {
|
3 | RCC->APB2ENR |= RCC_APB2ENR_IOPAEN; |
4 | RCC->APB2ENR |= RCC_APB2ENR_IOPBEN; |
5 | RCC->APB2ENR |= RCC_APB2ENR_AFIOEN; |
6 | |
7 | // PA11 und PA12 auf USB stellen
|
8 | GPIOA->CRH &= ~(0x0F<<12); |
9 | GPIOA->CRH |= (0x0B<<12); |
10 | GPIOA->CRH &= ~(0x0F<<16); |
11 | GPIOA->CRH |= (0x0B<<16); |
12 | |
13 | UsbSetup (); |
Ich für meinen Teil benutze den Ringbuffer nicht für das Empfangen da ich nur auf kurze ASCII Zeilen mit \n am Ende reagieren will. In etwa so:
1 | // Wird im Usb Interrupt ausgeführt!
|
2 | volatile int bRx=false; |
3 | volatile int bOverFlow=false; |
4 | uint8_t RxBuf[8]; |
5 | uint32_t nRx=0; |
6 | |
7 | void UsbRxHdl(uint8_t u) |
8 | {
|
9 | if (u=='\r' || bRx) |
10 | return; |
11 | |
12 | if (u=='\n') |
13 | {
|
14 | RxBuf[nRx]=u; |
15 | RxBuf[nRx+1]=0; |
16 | nRx=0; |
17 | if (!bOverFlow) |
18 | bRx=true; |
19 | bOverFlow=false; |
20 | }
|
21 | else
|
22 | {
|
23 | if (nRx >= (sizeof(RxBuf)-1)) |
24 | {
|
25 | bOverFlow=true; |
26 | }
|
27 | else
|
28 | {
|
29 | RxBuf[nRx]=u; |
30 | nRx++; |
31 | }
|
32 | }
|
33 | }
|
dazu wurde in der usb.c die Funktion OnEpBulkOut geändert ohne an der bisherigen Funktionalität etwas zu ändern:
1 | void UsbRxHdl(uint8_t u); |
2 | |
3 | void OnEpBulkOut (void) /* EP2 = Bulk-EP OUT */ |
4 | { int i, n, hdroom, avail; |
5 | long D; |
6 | char c; |
7 | dword* P; |
8 | |
9 | |
10 | /* Bulk EP anwählen und Anzahl der Bytes ermittlen */
|
11 | avail = EpTable[2].RxCount & 0x3FF; |
12 | |
13 | i = rxw - rxr; |
14 | if (i<0) i += rxLen; |
15 | hdroom = rxLen - i; |
16 | if (hdroom <= avail) return; |
17 | |
18 | P = (dword*) EP2RxBBuffer; |
19 | n = 2; |
20 | i = avail; |
21 | D = *P++; /* 2 Byte laden */ |
22 | while (i>0) |
23 | {
|
24 | c = D & 0xFF; /* LSB zuerst */ |
25 | |
26 | UsbRxHdl((uint8_t)c); |
27 | |
28 | UsbRxBuf[rxw] = c; |
29 | rxw = (rxw+1) & (rxLen-1); |
30 | |
31 | D = D >> 8; |
32 | --n; |
33 | if (!n) |
34 | {
|
35 | D = *P++; |
36 | n = 2; |
37 | }
|
38 | --i; |
39 | }
|
40 | ClearBuffer(logEpBulkOut); /* wir haben's gelesen */ |
41 | }
|
Eine Echo-Funktion koennte dann so aussehen:
1 | while (1) |
2 | {
|
3 | if (bRx) |
4 | {
|
5 | // debug_printf("%s", RxBuf);
|
6 | UsbStrOut(RxBuf); |
7 | bRx=false; |
8 | }
|
9 | }
|
Hanna schrieb: > ... so dass ich für die nächste Serie gerne die > Controller Interne USB Funktionalität nutzen möchte. Nur leider habe ich > bisher hierzu keinerlei Informationen zur aAktivierung/Implementierung > gefunden. Fällt mir schwer zu glauben...mit Suchmaschinen kennst Du Dich aus? Sei's drum, FTDI und EM-Bitz sagen mir wenig bzw. gar nix, Cube kenne ich als Fahrradmarke ;) Ich empfehle Dir das Projekt STM32duino. Es setzt zwar auf der Arduino-IDE auf (kann Dir wurscht sein) und fußt auf dem Leaflabs Maple Projekt - STM32 für Arduino. Interessant für Dich dürfte die Bootloader-Implementation sein, auch im Hinblick auf die Kunstgriffe, um nicht USB-konforme Miniaturentwicklungsplatinen (Bluepills) in die unterschiedlichen Modi zu versetzen. Zum rumspielen empfehle ich einen Maple Mini Klon, gibt es für ca. 3€ beim Ali, USB funzt damit prächtig. Den Hersteller Baite kann ich wegen unterdurchschnittlicher PCB-Quali allerdings nicht empfehlen. Die günstigste Variante sind die "BLUEPILLS", gibt es für <2$. Mit der Einschränkung, dass die USB-Beschaltung nicht normgerecht ist und einige USB Controller damit rumzicken. Neu auf dem Markt sind schwarze Miniboards von Robotdyn mit offensichtlich korrekten Widerständen. Ich habe zwar keine solchen, meine Robotdyn-Arduinos sind jedenfalls von herausragender Qualität. Für Grafikspielerein ist der Maple Klon von Itead interessant, dort lassen sich die günstigen 8bit-parallel Displays von mcufriends aufstecken und laufen auf Anhieb prima mit der lib mcufriends_kbv. Die Iteadmaples kosten derzeit ca. 5-6$.
Hanna schrieb: > Bzw. was mir noch fehlt sind die SETUP-Parameter. D.h. ich weis nicht, > inwiefern ich in meinem Setup (Einstellung von Clock und I/O Parmetern > etc.) noch Einstellungen vornehmen muss oder ob diese in der Setup > Funktion der USB.c schon enthalten sind... temp schrieb: > Den Takt musst du schon auf 72MHz eingestellt haben. Das kannst nur du > beurteilen. Noch so als Hinweis: Wichtig ist ja vor allem, das USB mit 48MHz getaktet wird. Im Reset-Zustand ist der Teiler für den USB-Takt schon auf 1,5 eingestellt (USBPRE Bit im RCC_CFGR == 0), d.h. mit 72MHz Systemtakt läuft der USB automatisch mit 48MHz. Ansonsten muss man das System ebenfalls mit 48MHz takten und das USBPRE Bit setzen, dann ist USB-Takt gleich Systemtakt.
:
Bearbeitet durch User
STM Apprentice schrieb: > Leider nicht so einfach auf dem F103 zu implementieren. Da > passte erst mal nichts. Nach einigen Patch Versuchen > aufgegeben. Das Angebot von W.S. ist zwar verlockend, jedoch > gibt er sich keine Mühe die Anpassungschritte für den F103 > anzugeben. Was soll da nicht so einfach sein, bzw. welche Problem hast du damit?
Hallo nochmal, jetzt habe ich alles implementiert und den Cotroller neu geflasht. Erst mal rufe ich noch keine Kommunikationsfunktionen auf, sondern in der main vor der while(1) nur die UsbSetup(); Problem ist aber, dass das Gerät von Windows nicht erkannt wird. (Popup zeigt an uSB Gerät funktioniert nicht richtig...) Jetzt bin ich über folgendes Kommentar in der UsbSetup(); gestolpert. /************ USB-Setup **********************************/ /* Die Pins müssen bereits richtig gesetzt sein */ /* ebenso Clock ein und Powerdown aus. */ /* Interrupt 20 ist USB-IRQ (USB_LP_CAN1_RX0_IRQHandler) */ /**********************************************************/ Meine Setup Datei ist soweit fertig, Clocks für SPI UART ADC PORTS etc läuft alles. Der Prozessor wird mit 72MHz getaktet. Die Pins habe cih auch für USB gesetzt mittels //************************************************* //*** USB-Konfiguration //************************************************* GPIOA->CRH &= ~(0x0F<<12); GPIOA->CRH |= (0x0B<<12); GPIOA->CRH &= ~(0x0F<<16); GPIOA->CRH |= (0x0B<<16); Frage: Muss ich noch weitere "Clocks" aktivieren, was ist "Powerdown aus". Ich denke mir fehlen nur ein paar Zielen aber ...hmmmm...
hast du den Thread und die Kommentare zur Nop() Funktion gelesen und das in der usb.c geändert?
Hanna schrieb: > Ich denke mir fehlen nur ein paar Zielen aber Also erst mal eines: Das Aufsetzen von Clocks, Versorgungen und Pinout ist bei mir grundsätzlich in einer separaten Quelle untergebracht, eben weil sich so etwas ja von Projekt zu Projekt ändert. Deshalb findet sich das eben NICHT in den einzelnen Gerätetreibern. Dort hat man allenfalls wenige eher spezielle Dinge wie hier z.B. den Port, über den bei manchen Projekten der 1k5 für den USB aktiviert werden soll. Ich poste dir hier nochmal ne Beispielquelle. Vor dem USB-Setup solltest du also folgendes sichergestellt haben: 1. Namensgleichheit des USB-Interruphandlers mit dem irgendwo vorhandenen Placebo [WEAK] Handler, so daß der Linker den richtigen Handler in die Vektortafel einbaut 2. Powerdown-Optionen (AHB.., APBx.. Resets usw.) für die benötigten Peripherie-Units aus_ und Taktversorgungen _ein. Das betrifft auch die GPIO-Cores. Solange die keinen Takt kriegen oder im Reset kleben, kannst du draufschreiben was du willst - ohne Erfolg. 3. richtige Zuweisung der Pins zu den gewünschten Funktionen 4. richtiger Takt (48 MHz) für den USB Guck dazu einfach in config.c hinein. Wenn das erledigt ist, dann rufst du den USB-Setup auf und ab da führt der gesamte USB sein komplett interruptgesteuertes Eigenleben bis hin zu den Ringpuffern für RxD und TxD. Versuche NICHT, in die blockweisen Algorithmen der Treiber-Innereien hineinzugrätschen (wenn du nicht GENAU WEISST was du tust). Nutze stattdessen die zeichenorientierten Funktionen zum Verkehr mit den treiberinternen Ringpuffern. Wenn du ne Kommandozeile brauchst, dann lasse sowas zeichenweise in einen dafür geeigneten Puffer hineinlaufen, bis du ein CR oder LF im Datenstrom siehst oder der Puffer voll ist. Beispiel --> siehe Talk() in cmd.c Und wenn du dich davor ekelst, daß dein Chip als Nuvoton-CDC erkannt wird, dann mußt du eben die Deskriptoren und das .inf entsprechend anpassen. W.S.
da du in dem anderen Thread nicht darauf eingegangen bist, wie siehst du die Sache mit deiner Nop()-Funktion, die eventuell im Keil geht, aber mit einem aktuellen gcc nicht mehr?
Will's nochmal verbessern. Geht nicht ist der falsche Ausdruck. Sie liefert nur nicht die gewünschte Verzögerung.
Das Problem ist doch einfach nur, dass GCC ab -O2 und damit auch bei -Os die Nop()-Funktion einfach wegoptimiert. Ein einfaches asm("nop"); wird aber selbst bei -O3 nicht wegoptimiert.
1 | void Nop (unsigned int count) |
2 | {
|
3 | // damit die Zyklen zumindest noch grob stimmen wird durch zwei geteilt
|
4 | count = count >> 1; |
5 | while (count--) { |
6 | asm("nop"); |
7 | }
|
8 | }
|
Christopher J. schrieb: > Das Problem ist doch einfach nur, dass GCC ab -O2 und damit auch bei -Os > die Nop()-Funktion einfach wegoptimiert. Das Problem ist keines da man selektiv die Optimierung mit Pragmas ausschalten kan.
Aruinoquäler schrieb: > Das Problem ist keines da man selektiv die Optimierung mit > Pragmas ausschalten kan. Natürlich ist es ein Problem, wenn es eben nicht per Pragma ausgeschaltet ist. Gerne kannst du auch ein Pragma nutzen. Ist beides in etwa gleich inkompatibel zwischen verschiedenen Compilern. Kompatibel zwischen Compilern wäre das count einfach volatile zu machen:
1 | void Nop (volatile unsigned int count) |
2 | {
|
3 | while (count--); |
4 | }
|
Lediglich die Zyklenzahl passt dann nicht mehr ganz.
:
Bearbeitet durch User
Alles was ihr schreibt ist völlig klar und richtig. Ich wollte nur nochmal bei W.S. nach haken weil er schon auf die offensichtliche Lücke in seinem Code angesprochen wurde. Trotzdem wird er wieder hier im Thread an Leute empfohlen die ganz offensichtlich mit viel trivialeren Problemen zu kämpfen haben. Aruinoquäler schrieb: > Das Problem ist keines da man selektiv die Optimierung mit > Pragmas ausschalten kan. Ich denke das geht zwar ist aber die schlechteste Lösung von allen. Irgendwann kann der Compiler auch auf die Idee kommen, wenn er sinnloses Zeug entfernt ist das keine Optimierung sondern Normalität. Wie man es für sich macht ist am Ende egal. Auf alle Fälle ist die Abhängigkeit von der wirklichen Laufzeit der Nop() Funktion, sicherlich nur in WriteControlBlock(), schon etwas schwieriger zu finden. Vor allem wenn man USB nur als Mittel zum Zweck benutzt ohne jedes Detail wirklich verinnerlicht zu haben oder wenn es an Messgeräten für die Analyse fehlt. Wichtig ist die Erkenntnis, dass man an diese Stelle bei Problemen genauer untersuchen sollte.
Hallo nochmals, ich bin nun dank temp und W.S. ein gutes Stück weiter. Ich habe nun die clocks aktiviert GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1ENR_USBEN, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; //Firmware/SCKTouch/MOSITouch GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 |GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_5 | GPIO_Pin_7 | GPIO_Pin_9|GPIO_Pin_11|GPIO_Pin_12; // PWM_LEDR,PWM_LEDG,PWM_LEDB,PWM_LEDW,SPI1SCK, SPI1MOSI GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); Danach führe ich das USB_Setup von W.S. aus und der Controller meldet sich nun auch ordnungsgemäß am PC als Vurtual Com Port an. Ich verwende Windows 7 64Bit Problem ist nun aber, selbst wenn ich den Virtual ComPort Treiber von ST installiere, wird für das Gerät im Geräte Manager immer noch angezeigt, dass kein Treiber installiert ist. Was mache ich falsch? Ich bin auch in diversen Foren auf eine .inf Datei gestoßen, mit der ich aber irgendiwe nichts anfangen kann. Entschuldigt bitte die dummen Fragen aber USB am STM ist für mich wirklich absolutes Neuland, ich gebe auch zu, dass mir hier USB-technisch mit Sicherheit einiges an Background fehlt, aber irgendwie muss man ja mal klein Anfangen, SPI, I2C und UART hab ich ja auch ans Laufen bekommen.
Ein wenig Zeit solltest du dir schon nehmen um mal wenigsten rudimentär über die Dateien zu gucken die du verwendest. Dann wäre dir auch aufgefallen, dass in der usb.h eine passende .inf Datei im Kommentar steht.
Christopher J. schrieb: > die Nop()-Funktion einfach wegoptimiert. Ein einfaches asm("nop"); wird > aber selbst bei -O3 nicht wegoptimiert. Extra dafür gäbe es im CMSIS das _NOP() Macro. Denn asm("nop"); wird ohne volatile weg optimiert, da es keine weiteren Abhängigkeiten hat. Klarer Fehler vom Programmierer. Übrigens könnte er die Schleife auch unrollen, und damit u.U. den Flash sprengen. Für halbwegs vorhersagbare Zyklenzahlen sollte man auf eine Assembler Lösung setzen. Halbwegs deshalb weil ja Interrupt Zyklen nicht gezählt werden.
Hallo temp, vielen Dank für deine Antwort. Ich habe diese Kommentarzeilen sehr wohl gesehen und auch daraus eine .inf Datei gemact die ich unter Windows/Sxstem32/Drivers abgelegt habe, ebenso wie die usbser.inf Datei. Wenn ich nun bei Treiber installieren jedoch diesen Ordner als Zielordner auswähle sagt Windows "Kein passender Treiber gefunden". Ich bin auch wirklich nicht Sattelfest was ich sonst mit dieser .inf Datei machen soll, bzw eine Internetrecherche bringt mich hier auch leider nicht weiter. Bin ich einfach zu blond oder was mache ich falsch?
Die inf-Datei brauchst du nur in ein beliebiges Verzeichnis packen und beim Treiber installieren dort suchen. Hab's eben mal in einer VM unter W7 probiert und es geht. Hast du kein W10 oder Linux mit dem du erst mal feststellen kannst ob das Ding überhaupt geht?
W.S. schrieb: > Ich poste dir hier nochmal ne Beispielquelle. Danke dafür, habe ich schon in einem anderen Thema gesehen. Dieses Beispielprojekt läuft direkt auf den 3€-Chinaboards, ohne es selbst compiliert zu haben. Zum Testen einfach das bin-File draufgeschrieben und er erkennt das Teil:
1 | [ 2608.325890] usb 1-1.4: new full-speed USB device number 3 using ehci-pci |
2 | [ 2608.406320] usb 1-1.4: New USB device found, idVendor=0416, idProduct=5011 |
3 | [ 2608.406323] usb 1-1.4: New USB device strings: Mfr=1, Product=2, SerialNumber=3 |
4 | [ 2608.406325] usb 1-1.4: Product: USB Virtual COM |
5 | [ 2608.406326] usb 1-1.4: Manufacturer: Nuvoton |
6 | [ 2608.406328] usb 1-1.4: SerialNumber: NT2009101400 |
7 | |
8 | |
9 | Bus 001 Device 003: ID 0416:5011 Winbond Electronics Corp. Virtual Com Port |
Jim M. schrieb: > Extra dafür gäbe es im CMSIS das _NOP() Macro. Denn asm("nop"); wird > ohne volatile weg optimiert, da es keine weiteren Abhängigkeiten hat. > Klarer Fehler vom Programmierer. > > Übrigens könnte er die Schleife auch unrollen, und damit u.U. den Flash > sprengen. Für halbwegs vorhersagbare Zyklenzahlen sollte man auf eine > Assembler Lösung setzen. Halbwegs deshalb weil ja Interrupt Zyklen nicht > gezählt werden. Das mit dem ausrollen ist ein guter Einwand. Bei count < 18 und -O3 packt er einen Haufen nop's ins Flash. Uups :D Wegoptimiert wird bei mir asm("nop") aber nicht, auch wenn es nicht volatile ist aber vermutlich hast du Recht und es ist besser so wie in dem CMSIS-Macro (was ja von Haus aus schon Compiler-unabhängig ist). Aber um mal halbwegs beim Thema zu bleiben: temp schrieb: > Auf alle Fälle ist die > Abhängigkeit von der wirklichen Laufzeit der Nop() Funktion, sicherlich > nur in WriteControlBlock(), schon etwas schwieriger zu finden. Wie viele Mikrosekunden muss das denn genau haben?
Christopher J. schrieb: > Wie viele Mikrosekunden muss das denn genau haben? Das kann ich auch nicht sagen, ich hab das nicht entwickelt. Denke das gibt nur Probleme wenn die Zeit zu kurz ist. Ob es auch ein Problem dabei gibt wenn das Delay zu groß ist habe ich nicht pobiert. Insbesondere in Hinblick auf Interrupts mit höherer Priorität könnte das eine spannende Untersuchung werden. Hatte ja gehofft W.S. würde sich mal dazu äußern. Oder er kann es nicht weil der Code irgendwo anders her stammt.
Hallo Zusammen, ich habe heute Nacht die USB Kommunikation ans Laufen gebracht. Ich kann jetzt mittels der einzelnen Funktionen von W.S. mit meinem PC Kommunizieren. Habe Buchstaben über HTERM ausgetauscht und das sah soweit wirklich toll aus. Ich möchte mich nochmals bei allen Beteiligten für die, doch oft recht anstrengende Hilfestellung bedanken. Die restlichen Elemente sollte ich jetzt alleine hinkriegen. Wenn man die NOP 0 Diskussion noch abschliessen könnte wäre das natürlich genial, aus dem Grund heraus, dass es bei mir mittels der von W.S. zur Verfügung gestellten USB.c und USB.h Datei zwar enwandfrei funktioniert, ich aber jetzt natürlich verunsichert bin wie lange das nach eventuellem Compilertausch noch funktionieren wird.
Du kannst das CMSIS Makro _NOP() nutzen oder die Funktion mit volatile versehen. http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0497a/CIHCAEJD.html
Hanna schrieb: > Wenn man die NOP 0 Diskussion noch abschliessen könnte wäre das > natürlich genial, aus dem Grund heraus, dass es bei mir mittels der von > W.S. zur Verfügung gestellten USB.c und USB.h Datei zwar enwandfrei > funktioniert, ich aber jetzt natürlich verunsichert bin wie lange das > nach eventuellem Compilertausch noch funktionieren wird. Ich denke, du musst nicht mal den Compiler tauschen. Es reicht beim Compiler Optimierungen einzuschalten, also z.B. für Speichergröße (-Os) oder Geschwindigkeit (-O2 bzw. -O3). Oft gibt es in IDEs schon ein "Release"-Target, bei dem dann eine der drei Optimierungen eingeschaltet ist. Keine Ahnung wie das bei Embitz ist. Dann schaust du einfach mal ins Assembler-Listing was aus deiner NOP()-Funktion geworden ist. Ich wette sie ist verschwunden, d.h. wegoptimiert, weil sie (aus Compiler-Sicht) unnützige Zyklen frisst. Packst du wie von Jim oder Nils vorgeschlagen das __NOP()-Makro in die Schleife der NOP()-Funktion wird sie nicht mehr wegoptimiert.
:
Bearbeitet durch User
Ich möchte das Thema nochmal aufgreifen da ich auch ratlos vor diesem bereits erwähnten Nuvoton-Treiber-Problem stehe: Hanna schrieb: > Ich habe diese Kommentarzeilen sehr wohl gesehen und auch daraus eine > .inf Datei gemact die ich unter Windows/Sxstem32/Drivers abgelegt habe, > ebenso wie die usbser.inf Datei. > > Wenn ich nun bei Treiber installieren jedoch diesen Ordner als > Zielordner auswähle sagt Windows "Kein passender Treiber gefunden". Ich > bin auch wirklich nicht Sattelfest was ich sonst mit dieser .inf Datei > machen soll, bzw eine Internetrecherche bringt mich hier auch leider > nicht weiter. > > Bin ich einfach zu blond oder was mache ich falsch? Meine Erfahrung lautet: Unter Windows 7 Prof 64 Bit gelingt das Installieren eines USB Treibers mittels *.inf Datei problemlos. Das ganz gleiche Vorgehen scheitert jedoch unter einem Windows 7 Prof 32 Bit. Weiss jemand was zu tun ist damit es auch unter 32 Bit "läuft"? Ach ja, natülich kann ich den USB Code von W.S. auch tatsächlich nutzen wenn der Treiber korrekt installiert ist ... Danke an W.S. für das kompakte USB-Code-Teil.
Christopher J. schrieb: > Packst du wie von Jim oder Nils vorgeschlagen das __NOP()-Makro in die > Schleife der NOP()-Funktion wird sie nicht mehr wegoptimiert. Nun, die ganze Sache ist mittlerweile schon recht lang her. Mir scheint, daß dieses ruppige Wegoptimieren eine Spezialität des GCC ist. Ich hab sowas beim Keil noch nicht beobachtet - und der macht trotzdem einen kompakteren Code als der GCC. Mir wäre es auch eine geradezu unverschämte Eigenmächtigkeit eines Compilers, den Code, den ich explizit hingeschrieben habe, ersatzlos zu entfernen, bloß weil die Compiler-Programmierer den Sinn nicht haben einsehen wollen. Optimierung heißt eigentlich, den Willen des Programmierers auf optimale Weise in Maschinencode zu transformieren - aber es heißt nicht, dem Programmierer über's Maul zu fahren. Wer also den GCC benutzt, schreib sich einfach void Nop (volatile dword count) { while (count) --count; } hin. Das 'volatile' sollte mMn das GCC-Problem lösen. Selber ausprobiert hab ich das aber nicht, denn den GCC hatte ich zuletzt als 'yagarto' bei der Lernbetty mal benutzt - und das ist nun schon viele Jahre her. W.S.
W.S. schrieb: > Mir wäre es auch eine geradezu unverschämte Eigenmächtigkeit eines > Compilers, den Code, den ich explizit hingeschrieben habe, ersatzlos zu > entfernen, bloß weil die Compiler-Programmierer den Sinn nicht haben > einsehen wollen. Das sehe ich anders. Ein einfaches Beispiel: Du nutzt eine portable Lib (nennen wir sie "SUPERIO", welche für verschiedenste Plattformen zur Verfügung steht. Da kann schon mal für Deine Zielplattform eine Preprocessor-Konstante (z.B. SUPERIO_DMA_MAX_SIZE) gleich 0 sein, z.B. weil Dein µC gerade kein DMA unterstützt. Du weisst aber als Anwender dieser Lib überhaupt nicht, ob SUPERIO_DMA_MAX_SIZE gleich 0 oder was anderes ist. Jedenfalls steht in der Dokumentation: "Nullen Sie den Übergabe-Buffer mit der Länge SUPERIO_DMA_MAX_SIZE vor Aufruf der Funktion superio_jetzt_gehts_ab()". Also machst Du brav:
1 | for (i = 0; i < SUPERIO_DMA_MAX_SIZE; i++) |
2 | {
|
3 | mybuf[i] = 0; // oder was anderes, egal |
4 | }
|
Nach Deinem Willen müsste der "dumme Compiler" nun einen Code erzeugen, welcher zur Laufzeit(!) eine Variabe i auf 0 setzt und anschließend mit 0 vergleicht, um dann festzustellen, dass der Code innerhalb der Schleife für diese Plattform gar nicht ausgeführt werden muss. Den Code innerhalb der Schleife muss der "dumme Compiler" auch noch erzeugen, nur weil der Programmierer das so "will". Denn er möchte eine portable Anwendung für Processor A (mit DMA) und B (ohne DMA) schreiben. Folge: Das Programm wird langsamer, weil es zur Laufzeit prüfen muss, was der Compiler schon zur Übersetzungszeit hätte feststellen können. Es wird zudem länger, weil es mit jeder Menge totem Code aufgefüllt wird. Du wirst hier genau diesen Unterschied feststellen: gcc mit -O vs. gcc ohne -O. Lässt Du die Optimierung weg, hast Du in den meisten Fällen genau das, was Du willst. Zu 99% brauchst Du dann zum Beispiel überhaupt keine volatile-Variablen mehr. Denn der Compiler macht ziemlich genau das, was der "Programmierer" will. Nur will das kein Programmierer: Ein großes und grottenlangsames Programm. P.S. Unter http://mikrocontroller.bplaced.net/wordpress/?page_id=142 liest man: "Ich habe Grundsätzlich die Compiler Optimierung AUS = “none” und benutze auch nicht die Hardware-FPU Falls ihr andere Einstellungen benutzt, kann es zu Fehlern kommen, weil z.B. Delay-Schleifen wegoptimiert werden oder zu schnell ablaufen". Und das aus gutem Grund. Der Autor der dort von einer breiten Masse genutzten (und von mir durchaus geschätzten) Libs hat nämlich in seinen Routinen oftmals hier und da das kleine Wörtchen "volatile" in seinem Code "vergessen".
:
Bearbeitet durch Moderator
W.S. schrieb: > Mir wäre es auch eine geradezu unverschämte Eigenmächtigkeit eines > Compilers, den Code, den ich explizit hingeschrieben habe, ersatzlos > zu entfernen, bloß weil die Compiler-Programmierer den Sinn nicht haben > einsehen wollen. Das hat nichts mit "den Sinn nicht einsehen" zu tun, wenn der Compiler Code entfernt, der keinen Effekt hat (außer Laufzeit zu verbraten). Für busy loops gibt es fast immer bessere Alternativen. Oder man spielt dirty und setzt ein volatiles nop in die Schleife.
Den Thread kannt ich noch gar nicht; falls es noch jemanden interessiert, es gibt mittlerweile das USB-Tutorial mit STM32 für genau diesen Controller. Das funktioniert auch mit GCC und Optimierung :-) Um beim Hochfahren einmal 1µs zu warten, wird hier auch __NOP aufgerufen was __asm volatile ("nop") macht. Ein Timer wäre eleganter, aber da der Beispielcode währenddessen ohnehin sonst nichts zu tun hat...
Frank M. schrieb: > Da > kann schon mal für Deine Zielplattform eine Preprocessor-Konstante (z.B. > SUPERIO_DMA_MAX_SIZE) gleich 0 sein, Eben. Kannst du eigentlich den Unterschied erkennen zwischen einem Argument einer Funktion und einem konstanten und zur Compilierzeit bekannten Wert wie diesem: #define SUPERIO_DMA_MAX_SIZE 0 Ich sehe das genau so, wie ich das beschrieben habe. Punkt. Mir kommt da eine Geschichte in den Sinn - wahrscheinlich von Lem - wo ein nicht sonderlich gut programmierter Roboter das Mittagessen in's Klo schüttete, weil es seiner Logik zufolge ja ohnehin dort hinein kommt und man sich auf diese Weise den unnützen Umweg durch den Darm ersparen könnte. W.S.
Wie installiert man die Nuvoton *.inf Datei unter Windows 7 32bit?
Stefanus F. schrieb: > Wie installiert man die Nuvoton *.inf Datei unter Windows 7 32bit? Analog zur Vorgehensweise in der 64-Bit-Version: Im Gerätemanager geht man mit der rechten Maustaste auf das zu installierende "Gerät" und folgt dem Installationsdialog um an geeigneter Stelle auf sein eigenes *.inf File hinzuweisen. Angeblich muss noch eine Kopie des usbser.sys Treibers im Verzeichnis des inf Files vorhanden sein. Das scheitert bei mir auf einem 32-Bit System, mit Windows- typischer, wenig aussagekräftiger Fehlermeldung. Nuvoton Möchtegern schrieb: > Unter Windows 7 Prof 64 Bit gelingt das Installieren eines > USB Treibers mittels *.inf Datei problemlos. Das ganz gleiche > Vorgehen scheitert jedoch unter einem Windows 7 Prof 32 Bit. Am usbser.sys kann es ja nicht liegen, der wird ja bei anderen USB Geräten auch verwendet und funktioniert, also muss es entweder eine fehlende/falsche Einstellung/Angabe im inf File sein oder der USB Code im Nuvoton Treiber (seitens des STM32F103) erfüllt irgendeine Anforderung der Windows Treiberkommunikation nicht. Lieber W.S., vielleicht kannst du dich (bitte) mit der Problematik noch ein wenig auseinandersetzen? Leider fehlen mir Mittel und Möglichkeiten mich als USB-Spezialist zu etablieren ...
Einfach Windows 10 installieren, da werden Standard-Klassen inklusive CDC-ACM direkt ohne .inf-Datei erkannt (endlich!!) :-)
Niklas G. schrieb: > Einfach Windows 10 installieren Auf diesen Tip hab ich gewartet (endlich!!). Dass ich da nicht selbst draufgekommen bin .... Besteht noch die klitzekleine Chance dass Nuvoton Möchtegern schrieb: > der USB Code im Nuvoton Treiber (seitens des STM32F103) erfüllt > irgendeine Anforderung der Windows Treiberkommunikation nicht. Dann hilft der beste Win10-Super-Duper-Automatik-Installer nix. Für die die es nicht wissen: es gibt auch eine 32 Bit-Version von Win10. Und es gibt Gründe eine 32-Bit Windows Version zu verwenden. Es gibt aber auch genügend Gründe Win10 überhaupt zu vermeiden.
Nuvoton Möchtegern schrieb: > der USB Code im Nuvoton Treiber (seitens des STM32F103) erfüllt > irgendeine Anforderung der Windows Treiberkommunikation nicht. Du meinst jetzt aber schon W.S.' Firmware für den STM32F103, welche einfach nur das USB CDC-ACM Protokoll spricht und absolut nichts mit Nuvoton zu tun hat, oder? Diese sollte, wenn sie CDC korrekt umsetzt, unter Windows 10 32- und 64bit direkt ohne irgendwelche Treiber-Installation funktionieren; mit Nuvoton hat man dann absolut nichts mehr am Hut. Tut sie das nicht, liegt hier ein Fehler in W.S.' Firmware vor; probiere doch mal testweise meine: https://github.com/Erlkoenig90/f1usb/releases Wenn die unter Win10 32bit auch nicht geht, haben W.S. und ich beide wohl was falsch verstanden. Wenn sie unter Win7 32bit mit der Nuvoton .inf -Datei geht, ist W.S. schuld; wenn nicht stimmt wohl mit der .inf Datei was nicht. Versuche alternativ einfach mal den Treiber von ST: https://www.st.com/en/development-tools/stsw-stm32102.html Der enthält auch nur eine .inf die einfach nur die usbser.sys lädt. Dazu muss man im Code die VID auf 0483 und die PID auf 5740 setzen. Es müsste eine Möglichkeit geben (mit dpinst.exe oder so) den usbser.sys Treiber direkt ohne .inf-Datei zu laden, aber damit habe ich mich nicht mehr auseinander gesetzt, weil Win7 eh bald obsolet sein dürfte.
Niklas G. schrieb: > Du meinst jetzt aber schon W.S.' Firmware für den STM32F103, welche > einfach nur das USB CDC-ACM Protokoll spricht und absolut nichts mit > Nuvoton zu tun hat, oder? Ja ganz richtig. Niklas G. schrieb: > Versuche alternativ einfach mal den Treiber von ST: > https://www.st.com/en/development-tools/stsw-stm32102.html > Der enthält auch nur eine .inf die einfach nur die usbser.sys lädt. Dazu > muss man im Code die VID auf 0483 und die PID auf 5740 setzen. Das ist doch mal ein sehr nützlicher Hinweis. Für USB Dumpfbacken wie mich. Ausdrücklichen Dank dafür! Wenn es nur an VID und PID liegt dann ändere ich das gerne bzw mache den Versuch .... Wie bereits erwähnt funktioniert ja die Implementierung von ST auch unter Win 32-Bit. Niklas G. schrieb: > probiere doch mal testweise meine: Erkenne jetzt auf die Schnelle aus dem Zusammenhang nicht ob das Binary für den F103 gedacht ist .... Wenn ja werde ich das auch versuchen.
Nuvoton Möchtegern schrieb: > Wenn es nur an VID und PID liegt dann ändere ich das gerne bzw > mache den Versuch .... VID&PID der Firmware müssen halt zur .inf -Datei passen. Nuvoton Möchtegern schrieb: > Wie bereits erwähnt funktioniert ja die Implementierung von ST > auch unter Win 32-Bit. Auch mit der Nuvoton-.inf? Nuvoton Möchtegern schrieb: > Erkenne jetzt auf die Schnelle aus dem Zusammenhang nicht ob das > Binary für den F103 gedacht ist .... Ist für den STM32F103RBT6. Für den C8T6 lässt sich das mit minimalen Änderungen auch kompilieren (Flash-Größe, ggf. Pin für Pullup). Hmm, mir fällt gerade ein dass das ein Composite-Gerät für 3x-Serial ist - kann sein dass das doch nicht geht und man da einen anderen Treiber für laden muss (geht unter Win10 automatisch, daher nicht ausprobiert). Weil ST den CDC-Treiber gut versteckt, mal die Essenz des Ganzen im Anhang. Es ist letztendlich nur eine .inf + .cat (Signatur) um die usbser.sys für Geräte mit VID=0483 und PID=5740 zu laden. Interessanterweise sind die 32bit und 64bit-Versionen absolut identisch, die beiden Installer enthalten exakt die gleichen Dateien. Lediglich zwischen der Win7 und der Win8-Version gibt es einen minimalen Unterschied.
:
Bearbeitet durch User
Niklas G. schrieb: > Auch mit der Nuvoton-.inf? Gute Frage. Gilt es auszutesten ... Niklas G. schrieb: > VID&PID der Firmware müssen halt zur .inf -Datei passen. Das war mir schon klar ... trotz USB-Dumpfbacken-Qualifikation.
Nuvoton Möchtegern schrieb: > USB-Dumpfbacken-Qualifikation. Da kann ich nur das USB-Tutorial mit STM32 als Dumpfbacken-Entqualifikation empfehlen :P
Niklas G. schrieb: > Weil ST den CDC-Treiber gut versteckt, mal die Essenz des Ganzen im > Anhang. Danke auch dafür. Die Win7-Versionen sind vom Jahr 2010, hat sich da seitdem nichts mehr geändert?
Nuvoton Möchtegern schrieb: > Danke auch dafür. Die Win7-Versionen sind vom Jahr 2010, > hat sich da seitdem nichts mehr geändert? Sieht nicht so aus. Was soll sich da auch groß ändern; schau dir die .inf Dateien einfach mal an, das ist kaum mehr als eine Anweisung, die usbser.sys zu laden. Daher ist das ja auch kein echter Treiber; den hat Microsoft mit der .sys Datei schon erstellt. Das Problem ist nur, dass man, um den zu laden, erstmal Geld für ein Zertifikat der .inf-Datei abdrücken muss. Die Signatur lässt sich zwar umgehen, aber seit Win10 ist das ganze ja wie gesagt zum Glück gar nicht mehr nötig.
:
Bearbeitet durch User
Niklas G. schrieb: > Da kann ich nur das USB-Tutorial mit STM32 als > Dumpfbacken-Entqualifikation empfehlen :P Halte ich für eine hervorragende Quelle zum Lernen. Habe auch schon sparsame Blicke hineingeworfen. Nuvoton Möchtegern schrieb: > Leider fehlen mir Mittel und Möglichkeiten mich als USB-Spezialist > zu etablieren ... Also es liegt nicht am Lehrmaterial.
Niklas G. schrieb: > Versuche alternativ einfach mal den Treiber von ST: > https://www.st.com/en/development-tools/stsw-stm32102.html > Der enthält auch nur eine .inf die einfach nur die usbser.sys lädt. Dazu > muss man im Code die VID auf 0483 und die PID auf 5740 setzen. Also das war jetzt wirklich einfach. VID und PID in W.S.' Code ersetzt, neu compiliert und geflasht. Und funktioniert. Der W.S.-Code mit ST IDs meldet sich jetzt als "STMicroelectronic Virtual COM Port" Wunder der Technik! Dieser Bericht hier aus der Arbeit, unter Windows 7 64 Bit. Am Abend kommt dann der "Härtetest" unter Windows 7 32 Bit auf dem Heimrechner.
... liebe Leute ... hab diesen Text mit einem gewissen Schmunzeln gelesen ... ... aber was soll ich als WinXP Benutzer machen ... um einen USB CDC Treiber zum laufen zu bringen ? ... eine Datei mit usbser.sys kann ich nicht finden ... ... und ist es überhaupt Notwendig die Pins PA11 PA12 als "alternat functions" zu initialisieren ... denn im RM0008 auf Seite 167 steht ... das wenn USB enabled wird - diese Pins automatisch mit dem USB Phy verbinden wird ... als können PA11 PA12 in ihren reset-Werten verbleiben ...
Willi S. schrieb: > eine Datei mit usbser.sys kann ich > nicht finden ... Die musst du auch nicht selbst finden. Die sollte bei WinXP aber dabei sein. Hast du die Installation des "Treibers" von ST mal probiert? Das soll angeblich unter XP gehen.
Willi S. schrieb: > ... aber was soll ich als WinXP Benutzer machen ... um einen USB CDC > Treiber zum laufen zu bringen ? ... eine Datei mit usbser.sys kann ich > nicht finden ... Nimm das was dir STM anbietet, das funktioniert auf jeden Fall auch unter Win XP. STM hat ja auch einen USB Treiber für seine USB-Controller.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.