Hallo, ist es möglich, mit einem µC einen USB-Speicherstick zu simulieren, der von einem PC als Speichermedium erkannt wird. Hier eine Erklärung über eine mögliche Verwendung. Ich habe einen Server, der NUR !! Dateien an einem angeschlossenen USB-Stick schreiben kann. Anhand des Dateinamens, den der Server auf meinen simulierten USB-Stick schreiben will, soll der µC dann Schaltvorgänge ausführen. Es geht hier also nicht darum, Daten real zu speichern, sondern es muss ein USB-Stick von einem µC simuliert werden und bei einem Zugriff auf den simulierten USB-Stick (anhand von verschiedenen Dateinamen) Ausgänge geschalten werden. Gruß, Michael
NxP LPC17xx können das glaub ich, die haben soweit ich weiss einen integrierten MSD-Treiber. Bin aber nicht ganz sicher, musst du im DB/UM nachschlagen. Ralf
Guck Dir mal die App-Note AVR273 von Atmel an, da müßte eigentlich alles drinstehen, was Du suchst. Peter
Für die MSP430 Mikrocontroller von TI mit USB gibts kostenlose Firmwarebeispiele, damit sich diese als sogenanntes Mass Storage Device, also Speicherstick ausgeben können. Damit solltest Du Deine Anforderungen eigentlich in überschaubarer Zeit implementieren können. Hier ein Propagandadokument von TI zum MSP430 mit USB: http://www.ti.com/lit/wp/slay014/slay014.pdf?DCMP=OTC-MCU_Newsflash&HQS=Other%2bNL%2bmcunf_aug10_msp430_mc5
Moin. das wird so nix. das was du suchst nent sich USB MSC Mass storage class. beispiele gibts von vielen MCU herstellern. somit nichts besonderes. nur MSC ist ein block layer, das erst mal gar nix von dateien weiss. (512Byte blöcke) den rest macht windows. (dateisystem) Problem an der sache ist, du weist nicht wann, wie windows die dateien auf dem Stick aktuallisiert. hängt auch noch von der Windows version ab, und von den einstllungen (sicheres entfernen chaching, ... ) linux kann das schon wieder ganz anders aussehen. auf mcu seite müsstest du somit den MSC stack implementieren, siehe hoben, und ein dateisystem (FAT 12 / 16 32 ntfs / ? ) das bei jedem sektor zugriff kontrolliert, welche datei jetzt wie verändert worden ist. Problem, das das nicht zeitsynchron laufen kann. siehe hoben. ggf lesen die Host OS das auch wieder gegen zum validieren. somit prinzipiell möglich nur nicht die schönste art so was zu implementieren. Solltest du aber jemals auf die idea kommen, informationen vom stick richtung pc zu übertragen. bist du gekniffen. das tut nicht, da der pc dateien ggf cacht, und dadurch werden änderungen an der datei nicht am pc sichtbar werden. Weiter: aufgrund von block layer und dateisystem, gibt das mit absoluter sicherheit dan datensalat. alternativ vorschlag, HID, ist unter linux und windows fast genauso einfach anzusprechen, und bereitet weniger probleme von wegen dateisystem, caching, synchrone zugriffe auf dateisystem von 2 verschiedenen steiten, ... da gibts auch schon vertige ICs, die man an usb anschliesen kann im irgendwelche relais zu steuen. gruss
Ralf schrieb: > NxP LPC17xx können das glaub ich, die haben soweit ich weiss einen > integrierten MSD-Treiber. Bin aber nicht ganz sicher, musst du im DB/UM > nachschlagen. Die LPC13xx haben einen "USB-Stick Modus". Der ist aber nur zum programmieren. Man kann also eine neue Firmware per Drag&Drop auf den Controller spielen. Die LPC17xx können MSD meines wissens nicht direkt.
USB - HID Ic z.B. IOWarior nur als alternative. libs zum ansprechen gibts
Hallo, wie 123 schon ausgeführt hat, das wird garnicht gehen. Auf Seiten deiner Schaltung bekommst du nur einen Befehl der Art "schreibe xx Bytes in Block xy". Hinter welchen dieser Befehle ein Neuanlegen einer Datei steckt (auf jeden Fall mehrere davon), kannst du garnicht entnehmen. Und die Idee auf bestimmte xy zu reagieren kannst du auch gleich vergessen, die sind jedesmal anders und vom User nicht beeinflussbar. Gruss Reinhard
moin das geht prinzipiell schon. nur der PC sagt lies bitte sektor x und folgende (jder 512 Byte gross ) und beim schreiben dann umgekehrt. es können immer nur blöcke a 512 Byte gelesen / geschrieben werden! Bei fat ist das anlegen einer datei in mehreren schritte zu zerlegen. je nach dem wie man es macht ist das dann power fail save (mit beeintächtigungen des dateisystems) oder führt zu totalschäden am dateisystem. 1. den speicher für die datei in der fat reservieren, 2. die reseriverten blöcke mit dem inhalt der datei füllen, 3. die entsprechenden informationen, start fat eintrag, dateiname, datum dateigrösse, ... in den verzeichnis strukturen eintragen. (das sind die wesentlichen schritte, reihenfolge kann durchaus anders sein, ggf können es sogar mehr sein) was auf der stick seite jetzt zu machen ist: auf die sektor schreib / lese zugriffe reagieren, und dann entsprechend reagieren. wobei wie oben schon gesagt: caching könnte da einiges durcheinander bringen. (w2k wird immer mit caching auf den stick zugegriffen. hier wird definitif nicht gehen auser man erzwing den cach flush. bei xp kann mans einstillen, W7 erlaubt nur nach direkt access, linux kommt es auf die mountparameter an) z.B. kurz hintereinander die gleiche datei ändern um z.B. irgend was zum blinken zu bringen, könnte vom caching/ io queue plötzlich zunichte gemacht werden. (OS ich bin doch nicht blöd und änder 2 mal den gleichen speicherbereich. das letzte ist wichtig, der rest ist für die tonne, wird doch sowieso vom 2. auftrag überschrieben) somit währe schreibend möglich. der rückkanal hingegen ist definitif nicht möglich. der PC geht nicht davon aus, das sich dateien / verwaltungs informationen auf einem speichermedium ohne sein zutun verändern könne. was bereits gelesen ist und im cach ist, muss nicht zwingend neu eingelesen werden. somit der dringende rat, geht auf hid, erspart dier sicher einiges an kopfzerbechen und probleme. und ist aus einem c programm fast genauso leicht anzusprechen das anlegen einer datei. codebeispiele gibts genug im netz.
Ich hatte sowas mal auf Basis eines PIC18F4550 gemacht. Von Mikrochip gibt es dafür eine Beispielprojekt, das zusammen mit einem Flashspeicher eine USB-Stick nachbildet. Flash Speicher kann man entfernen, wenn man keine Daten abspeichern will. Und das braucht man eigentlich auch gar nicht. Ich hab es so gemacht: Im PIC war eine Dateistruktur fest im ROM hinterlegt. Mit einer Datei im Root. Etwa so: F:FILE.TXT Diese Datei ist <512 Bytes. und eigentlich leer. PC öffnet diese Datei und ändert den Inhalt zu "1" Dann findet ein Schreibzugiff statt. Den kannst Du abfangen, da er immer noch auf den gleichen Sektor stattfinden wird. Deshalb wird die FAT Tabelle nicht geändert. PIC gibt dann zurück: "Schreiben erfolgreich". PC meint, da würde ne "1" drin stehen. Aber in Wirklichkeit hast Du nichts geschrieben, sondern nur ne LED eingeschaltet. Wenn Du die Datei vom PC öffnest, wird sogar ne "1" drinstehen, weil der PC das im Zwischenspeicher hält. Lesen geht auch. Man muss aber etwas tricksen. Getestet habe ich das unter Windows2000,XP,Vista,Solaris,OSX und Linux.
Vielen Dank für die ganzen Infos... An das Problem mit dem Cachen von den Dateien hab ich nicht gedacht, aber es gibt ja auch positive Erfahrung. Da ich es unter Linux betreibe, habe ich hier etwas mehr einfluss. Als HID-Device geht es leider nicht, da ich nur Daten schreiben/lesen kann. Wenn ich mehr Möglichkeiten hätte, dann würde ich hier gleich den µC per Ethernet anbinden und hätte den ganzen Umweg nicht. Hab mir gerade eine AT90USB.. bestellt und werde dies mal ausprobieren. Gruß, Michael
????? moment unter linux / unix ist ALLES eine datei. vereppeln kann ich mich selber. je nach distrie taucht für dein hid device ein character device im dev verzeichnis auf. auf das du wieder mit file IO zugreifen kannst. du must bei HID nur die richtige zahl an zeichen schreiben dann geht das auch. HID point nummer + anzahl der zeichen die der hid point haben will. zu wenig oder zuviel füren zu keinem ergebniss. ok ggf sind rootrechte notwendig / rechte anzupassen. ggf muss man dazu ein die entsprechneden regeln eintragen / dev nodes anlegen. und je nach distrie must du auch bei Mass Storage hand anlegen ( mount point / mount parameter ) was ggf einfacher gehen würde wenn es umbedingt mass storage sein muss. mach das ganze ohne dateisystem, und greif direkt auf block device ebene zu. dazu gibt es das tool dd. aber vorsicht. braucht glaubich root rechte und damit kann man sich ganz böse das system in jenseitz befördern wenn man was falsches eintipt. (gibts auch wir windows)
Unter Linux kenn ich mich als Root aus - mit dd schon so einiges gemacht. Ich hab hier aber einen Server, der nur über einen FTP oder Dateifreigaba (Samba) verfügt. Ich kann auf diesem Server NICHTS ändern - sonst müsste ich ja nicht diesen umständlichen Weg gehen. ....wollte Dich also nicht "veräppeln" Michael
nabend, was darfst / kannst du nicht an dem server verändern? die sicht nach aussen (firewall netwerkinterfaces ... )? oder auch die configuration module treiber die geladen werden? ggf könnte man so was änliches wie sysfs oder prog fs implementieren und für smb / ftp mounter, der dann als übersetzer dient. ist aber dann warscheinlich kernel programierung mit entsprecheden anpassungen. könnte aber als modul geladen werden. und ohne kernel übersetzung entwickelt werden. ggf beim kernel update sind anpassungen notwendig. was mich an der ganzen sache stört. ist, das auf der einen seite auf sektor ebene zugegriffen wird, und auf der anderen seite, erkannt werden muss, welche datei verändert wird. gibt es unter linux nicht die möglichkeit ein volum / laufwerk als ganze datei zu mounten? damit könntest du gezielt sektoren über ftp / smb manipulieren. was auf device seite das dateisystem eliminieren würde. (komplexe software, fehleranfällig) beispiel. ein 16MB Stick taucht als eine datei mit 16mb im smb auf. es gibt im linux kernel ganz sub syteme wie z.B. LED PIO ... mit einem entsprechenden Kerneltreiber könne man das dann durch eine mount ins prog / sysfs erledigen. (Documentation/gpio.txt) mit entsprechender HW und dem entsprechenden Treiber lassen sich z.B. mit embedded hw leds über die console ein und aussschalten / sogar configureren. gruss
@Michael: Das klingt aber danach, als ob Dein Server ebenfalls unter Linux läuft, und das läßt hoffen, daß er vielleicht soweit hack^H^H^H^Herweiterbar ist, daß er auch andere USB-Geräteklassen unterstützt als die, die der Hersteller ursrprünglich vorgesehen hatte.
Ich würde mal ein paar alte USB Sticks sammeln und aufschrauben/sägen. Wenn Du Glück hast, dann ist der Controller vom RAM schön sauber getrennt und Du kannst den Daten- und Adressbus abgreifen? So bleibt der Stick wirklich absolut kompatibel zum Server und du schreibst halt immer die selbe Datei. Du musst auch garnicht den ganzen Adressbus dekodieren, sondern einfach nur dem Datenbus lauschen: dann wartet Deine CPU auf eine magische Sequenz auf dem Datenbus mit Datenbytes und Checksumme. Mit einem Datenblatt vom RAM und einem Latch am Datenbus, der vom CS oder WE getriggert wird kannst Du sogar mit ner lahmen CPU noch wenigstens Teile vom Datenverkehr abhören. Das wäre natürlich ein heftiger Hack, könnte aber klappen. Rückkanal geht so auch, wenn Du auf dem Stick Leiterbahnen vom Datenbus auftrennen kannst. - Matthias
Eigentlich sollte es mit nem µC als MSD recht einfach gehen. Ich würde sogar sagen in eins/zwei Stunden. Ich hatte sowas ähnliches mal auf PIC Basis gemacht. Flash Speicher brauchst Du keinen. Du erzeugst Dir folgende Verzeichnisstruktur: USB_STICK/FOLDER/ Damit mit:
1 | SDC_Error SectorRead(dword sector_addr, byte* buffer) |
2 | {
|
3 | if ((sector_addr==0)||(sector_addr==0+6)) //BootSektor |
4 | {
|
5 | ...
|
6 | }
|
7 | else if ((sector_addr==1)||(sector_addr==1+6)) //FSInfo |
8 | {
|
9 | ...
|
10 | }
|
11 | else if ((sector_addr==2)||(sector_addr==2+6)||(sector_addr==12)||(sector_addr==12+6)) //3. leerer Cluster mit Signatur |
12 | {
|
13 | ...
|
14 | }
|
15 | else if (sector_fat==0) //FAT (Sektor 1 von 5) |
16 | {
|
17 | ...
|
18 | }
|
19 | else if ((sector_fat>=1)&&(sector_fat<(1+FLASH_FAT_SECTORS))) // Flash FAT |
20 | {
|
21 | ...
|
22 | }
|
23 | |
24 | else if (sector_addr==(RESSECTORS+2*SECPERFAT)) // Root Verzeichnis Einträge |
25 | {
|
26 | setDirEntry(&buffer[0x000],"USB_STICK ",VOLLABEL,0,0); |
27 | setDirEntry(&buffer[0x0C0],"FOLDER ",DIRECTORY,128,0); |
28 | |
29 | }
|
30 | |
31 | ..
|
32 | |
33 | return 0; |
34 | }
|
Und beim Schreiben fängst Du dann eine Sequenz "xxx.." ab:
1 | SDC_Error SectorWrite(dword sector_addr, byte* buffer) |
2 | {
|
3 | int i; |
4 | xsen = 0; |
5 | for (i=0;i<512;i++) |
6 | {
|
7 | // nach Startsequenz "xxx..." suchen
|
8 | if (buffer[i] == 'x') |
9 | {
|
10 | xsen ++; |
11 | }
|
12 | else
|
13 | {
|
14 | //3 x-se gefunden, nächstes Zeichen wird ausgewertet
|
15 | if (xsen >= 3) |
16 | {
|
17 | |
18 | // Ausgänge schalten
|
19 | if (buffer[i] == '0' ) SwitchOff_Output_A(); |
20 | if (buffer[i] == '1' ) SwitchOn_Output_A(); |
21 | if (buffer[i] == '2' ) SwitchOff_Output_B(); |
22 | if (buffer[i] == '3' ) SwitchOn_Output_B(); |
23 | ....
|
24 | }
|
25 | |
26 | xsen = 0; |
27 | }
|
28 | |
29 | }
|
30 | |
31 | return 0; // immer 0 für "Schreiben hat funktioniert" |
32 | }
|
Also xxx wäre die Sequenz, um dein "Ausgang-Setzen" einzuleiten. Das Zeichen nach dem xxx ist dann Dein Steuerzeichen. Die ganze Problematik mit dem Cache kannst Du umgehen, indem Du jedesmal eine neue Datei schreibst. Zum Beispiel mit einem Datumsstempel. so würde also ein Schreiben auf: 2011-08-27_83025_001_xxx3.txt den Ausgang B setzen. Dein Stick würde sagen: "ok, hab ich geschrieben". Das Linux Filesystem glaubt das auch. Aber dein Stick hat eh kein Flash, und kann deshalb auch nie voll werden.
Es gibt ein Buch von Jan Axelson zum Thema Massenspeicher am USB. Ich hab ein wenige geblaettert, und fand das unterliegende Protokoll bildet den SCSI Bus nach. Dh es schaut nach einer Menge Arbeit aus.
So. Ich hab's mal ausprobiert. Und es tut. Plattform ist ein AT90USBKey Board. Passt also zu Deinem AT90USB. Hier der Sourcecode + Binary: http://sebulli.com/download/MSD_Control.zip Projekt hab ich für Linux angepasst. Das Wichtigste steht in MSD_Control/at90usb128/lib_mem/df/df.c 1. (make in: MSD_Control/at90usb128/demo/MSD_Control/gcc) 2. Board in den Bootload Modus setzen (HWB + RES -> HWB) 3. dfu-programmer at90usb1287 erase 4. dfu-programmer at90usb1287 flash MSD_Control.hex (Siehe auch http://www.avrfreaks.net/wiki/index.php/Documentation:Tutorials_AT90UsbKey_under_Linux) Led einschalten, indem zb. die Datei XXXE_Led0_ON.txt per Drag&Drop in den WRITE Ordner kopiert wird
Hallo Gerd, vielen lieben Dank für den Beispiel und Deine Mühen. Werde es gleich ausprobieren, sobald mein µC kommt. Gruß, Michael
Ich hab mir eine AT90USB1287 bestellt und mach gerade dazu eine einfache Platine.
Ok. Auf das Board hättest Du es 1:1 aufspielen können. Ich denke für den Chip alleine müsste man nochmals etwas anpassen. ZB glaube ich, dass die Flash-Bausteine (die ja nicht benutzt werden) zur Zeit noch initialisiert werden. Wenn keine da sind, könnte die Software ewig warten. Dann ist mir noch was zum Cachen aufgefallen: Beim Schreiben einer Datei wird der Dateiname abgelegt. Angenommen, der ist 16 Bytes lang, dann werden nur 16 Bytes des 512 Bytes Block belegt. Wenn man jetzt eine neue Datei anlegt, wird der neue Dateiname dahinter geschrieben. Aber beim Schreiben wird höchstwahrscheinlich der erste Name auch nochmals geschrieben, da ja immer 512 Bytes Blöcke benutzt werden. Deshalb wäre wahrscheinlich sowas besser (falls möglich): Datei XXXA_Led0Off.txt anlegen. Datei XXXB_Led1Off.txt anlegen. Datei XXXC_Led2Off.txt anlegen. Datei XXXD_Led3Off.txt anlegen. Datei XXXA_Led0Off.txt in XXXE_Led0On.txt umbennen zum Einschalten LED0 Datei XXXE_Led0On.txt in XXXA_Led0Off.txt umbennen zum Ausschalten LED0 Dann bräcuhte man auch nicht mehr einen Zeitstempel, es würde immer bei 4 Dateien bleiben. Aber man braucht eine "RENAME". gerd
bei jedem schreibvorgang in eine datei, egal ob die nun existiert oder nicht, wird immer die verwaltungsstruktur für die datei aktuallisiert. Hier steht drin wie die datei heist, kurzer und langer dateinamen, grösse der datei, erster block in der fat tabelle, der zu der datei gehört und das datum für erstellung, änderung und letzter zugriff, Datei oder Verzeichniss, Dateiattribute, ... wie oben schon mal kurz beschrieben. sind für das anlegen einer neuen datei 1. die fat zu aktuallisieren, 2. die veraltungsstrukturen 3. die datei selber mit inhalt zu füllen. das alles ist nur ein grobe abläufe. das kann noch viel komplizierter weden, wenn z.B. die verwaltungsstrukturen in der Fat auch noch speicher anfordern (z.B. bei unterverzeichnissen oder FAT32 ) da das host system linux ist, kann man das caching deaktivieren. ist nur ein mount parameter den man entsprechend angeben muss. die umstände mit immer einer neuen datei könnte man sich hier sparen. (windows ist ja nicht gefordert)
Hallo Gerd, heute kam mein µC und auch die Platine. Board funktioniert schon und er lässt sich auch über FLIP Flashen. Muss jetzt Dein Beispiel im AVR-Studio umsetzten. Melde mich, sobald es funktioniert. Gruß, Michael
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.