Autor |
Beitrag |
oOXTCOo
      
Beiträge: 141
Windows XP Prof. 3
Delphi 7
|
Verfasst: Do 25.11.10 21:46
hi!
ich brauche mal wieder von euch hilfe.
ich habe mir eine unit gebastelt (möchte meine eigene schreiben und keine fertige verwenden) die die kommunikation mit usb geräten übernimmt.
es klappt alles wunderbar, das gerät wird sofort erkannt nach dem verbinden, daten werden gesendet und empfangen, alles läuft perfekt bis auf:
.) wenn das usb gerät einen fehler hat und einmal nichts zurück sendet wo ich aber eine bestimmte anzahl an bytes erwarte, friert mir das programm ein bis ich das gerät vom usb wieder abstecke, erst dann läuft es weiter.
das problem tritt bei readfile auf.
Delphi-Quelltext 1: 2: 3: 4: 5:
| if ReadFile(USBPORT, d, sizeof(d), BytesRead, nil) = false then begin ADDLine('[ERROR] - Unable to read from USB!'); exit; end; |
ich suche wie verrückt, finde aber keine lösung...
ich habe es auch schon mit einem timeout versucht, da alles einfriert klappt das nicht.
kann mir jemand einen tipp geben?
|
|
bummi
      
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: Do 25.11.10 22:23
ich bin hier gar nicht sattelfest, aber kannst Du vorher nicht ein GetFileSize absetzen?
_________________ Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
|
|
jaenicke
      
Beiträge: 19312
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Do 25.11.10 22:28
Du übergibst als letzten Parameter ja auch nil. Damit gibst du doch an, dass du keine überlappende Operation möchtest, also blockiert der Aufruf.
|
|
oOXTCOo 
      
Beiträge: 141
Windows XP Prof. 3
Delphi 7
|
Verfasst: Do 25.11.10 23:19
aha.. ich habs wo gelesen aber ignoriert.
schaue ich mir gleich mal an.
dann müsste das hier funktionieren:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| Function _USBReadPointerA(bp : pointer; SizeToRead : dWord; timeout: cardinal) : Cardinal; var Ovr : TOverlapped; begin Result := 0; FillChar(Ovr, SizeOf(TOverlapped), 0); Ovr.hEvent := CreateEvent(nil, true, FALSE, nil); if not ReadFile(USBPORT, bp^, SizeToRead, Result, @ovr) then if GetLastError=Error_IO_Pending then if WaitForSingleObject(ovr.hEvent, timeout) = WAIT_OBJECT_0 then GetOverlappedResult(USBPORT, ovr, Result, false) else CancelIo(USBPORT); CloseHandle(Ovr.hEvent); end; |
Zuletzt bearbeitet von oOXTCOo am Do 25.11.10 23:24, insgesamt 2-mal bearbeitet
|
|
oOXTCOo 
      
Beiträge: 141
Windows XP Prof. 3
Delphi 7
|
Verfasst: Do 25.11.10 23:23
alles klar, jetzt klappt es!
danke für den tipp...
man muss overlapped auch beim "openfile" befehl angeben...
darum hat es bei meinem readfile aufruf nicht geklappt.
|
|
jaenicke
      
Beiträge: 19312
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 26.11.10 02:17
Du kannst auch WaitForMultipleObjects benutzen, wenn du möchtest.
Dann kannst du zusätzlich noch auf ein Abbruchevent warten und musst nicht unbedingt auf ein Timeout warten bzw. kannst vor dessen Ablauf abbrechen (indem du das Abbruchevent von außen mit SetEvent auslöst).
|
|
oOXTCOo 
      
Beiträge: 141
Windows XP Prof. 3
Delphi 7
|
Verfasst: Fr 26.11.10 02:25
also wenn ihr noch verbesserungs vorschläge habt und vorallem für leute die die unit auch brauchen können, poste ich sie hier:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246:
| unit USB;
interface Uses SysUtils, Forms, Windows;
type TSetofChars = Set of Char;
Function USBOpenDriver:boolean; Function USBCloseDriver:boolean; function USBReadText(BytesRead: cardinal; timeout: cardinal = 500): string; function USBReadHEX(BytesRead: cardinal; timeout: cardinal = 500): string; function RWUSB(frame: string; readLen:integer = 0; ReadTimeout: integer = 500; Typ : String = 'HEX') : string; procedure USBWriteHEX(frame: string);
implementation
var USBPORT:Thandle = INVALID_HANDLE_VALUE;
{$HINTS OFF}
Function USBOpenDriver:boolean; begin USBPORT:= CreateFile('\\?\USB1', GENERIC_WRITE or GENERIC_READ, FILE_SHARE_WRITE or FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_FLAG_OVERLAPPED OR FILE_ATTRIBUTE_NORMAL, 0); USBOpenDriver:= USBPORT <> INVALID_HANDLE_VALUE; if USBPORT = INVALID_HANDLE_VALUE then begin result:=false; end else result:=true; end; {$HINTS ON}
Function USBCloseDriver:boolean; begin USBCloseDriver := CloseHandle(USBPORT); USBPORT := INVALID_HANDLE_VALUE; end;
function NurBestimmteZeichen (const aValue : String; aChars : TSetofChars) : String; var i: Integer; newString : string; begin newString := ''; for i := 0 to Length(aValue) do begin if aValue[i] in aChars then begin newString := newString + aValue[i]; end; end; result := newString; end;
Function HexToStr(s: String): String; Var i : Integer; Begin Result:=''; i:=1; While i<Length(s) Do Begin Result:=Result+Chr(StrToIntDef('$'+Copy(s,i,2),0)); Inc(i,2); End; End;
Function StrToHex(s: String): String; Var i : Integer; Begin Result:=''; If Length(s)>0 Then For i:=1 To Length(s) Do Result:=Result+IntToHex(Ord(s[i]),2); End;
Function USBReadTEXT(BytesRead : dWord; timeout: cardinal = 500) : string; var d: array[0..10000] of byte; s, buffer: string; i, Tmp: Integer; Ovr : TOverlapped; count :cardinal; begin Result := ''; count:=0; Fillchar( d, sizeof(d), 0 ); FillChar(Ovr, SizeOf(TOverlapped), 0); Ovr.hEvent := CreateEvent(nil, true, FALSE, nil); if not ReadFile(USBPORT, d, BytesRead, count, @ovr) then if GetLastError=Error_IO_Pending then if WaitForSingleObject(ovr.hEvent, timeout) = WAIT_OBJECT_0 then GetOverlappedResult(USBPORT, ovr, count, false) else CancelIo(USBPORT); CloseHandle(Ovr.hEvent); s := ''; for i := 0 to count-1 do begin Tmp:=ord(d[i]); s := s + Char(Tmp); end; s := strtohex(s); buffer:=''; for i:=1 to length(s) do begin if Odd(i) then begin buffer := ''; buffer := hextostr(s[i] + s[i+1]); buffer := NurBestimmteZeichen(buffer,['0'..'9','a'..'z','A'..'Z','.'..':',' '..'?']); result := result+buffer; end; end; end;
Function USBReadHEX(BytesRead : dWord; timeout: cardinal = 500) : string; var d: array[0..10000] of byte; s: string; i, Tmp: Integer; Ovr : TOverlapped; count :cardinal; begin Result := ''; count:=0; Fillchar( d, sizeof(d), 0 ); FillChar(Ovr, SizeOf(TOverlapped), 0); Ovr.hEvent := CreateEvent(nil, true, FALSE, nil); if not ReadFile(USBPORT, d, BytesRead, count, @ovr) then if GetLastError=Error_IO_Pending then if WaitForSingleObject(ovr.hEvent, timeout) = WAIT_OBJECT_0 then GetOverlappedResult(USBPORT, ovr, count, false) else CancelIo(USBPORT); CloseHandle(Ovr.hEvent); s := ''; for i := 0 to count-1 do begin Tmp:=ord(d[i]); s := s + Char(Tmp); end; Result := strtohex(s); end;
Function _USBWritePointerA(bp : Pointer; SizeToSend : DWord; timeout: integer) : Cardinal; var Ovr : TOverlapped; begin Result := 0; FillChar(Ovr, SizeOf(TOverlapped), 0); Ovr.hEvent := CreateEvent(nil, true, FALSE, nil); if not WriteFile(USBPort, bp^, SizeToSend, Result, @ovr) then if GetLastError=Error_IO_Pending then if WaitForSingleObject(ovr.hEvent, timeout) = WAIT_OBJECT_0 then GetOverlappedResult(USBPORT, ovr, Result, false) else CancelIo(USBPORT); CloseHandle(Ovr.hEvent); end;
procedure USBWriteHEX(frame: string); var BytesWritten: DWord; begin while Pos(' ', FRAME) > 0 do Delete(FRAME,Pos(' ', FRAME),1); frame:=hextostr(frame); WriteFile(USBPORT, (Pchar(frame))^, SizeOf(frame), BytesWritten, nil); end;
Function USBWritePointerA(bp : Pointer; SizeToSend : DWord) : boolean; begin Result := _USBWritePointerA(bp, SizeToSend, $688) = SizeToSend; end;
Function USBWriteStringA(SendString : String) : boolean; var StrSize : Word; begin StrSize := Length(SendString); Result := _USBWritePointerA(@SendString[1], StrSize, $688) = StrSize; end;
function RWUSB(frame: string; readLen:integer = 0; ReadTimeout: integer = 500; Typ : String = 'HEX') : string; begin while Pos(' ', FRAME) > 0 do Delete(FRAME,Pos(' ', FRAME),1); if length(frame) >0 then USBWriteStringA(hextostr(frame)); Application.ProcessMessages; sleep(ReadTimeout); if (ReadLen >0) and (Typ='HEX') then result:=USBReadHEX(readLen, ReadTimeout); if (ReadLen >0) and (Typ='STRING') then result:=USBReadText(readLen, ReadTimeout); end;
end. |
diese unit ist sicher nicht perfekt geschrieben und es gibt sicher noch einiges zu verbessern, aber für meine anforderungen läuft diese jetzt perfekt 
Zuletzt bearbeitet von oOXTCOo am Fr 26.11.10 02:39, insgesamt 2-mal bearbeitet
|
|
jaenicke
      
Beiträge: 19312
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 26.11.10 02:35
Warum deklarierst du das Handle als Konstante? Es ist doch nun einmal keine.
Mach einfach ein var draus, dann muss man nicht die Einstellung ändern, außerdem ist es ja wohl passender.
|
|
oOXTCOo 
      
Beiträge: 141
Windows XP Prof. 3
Delphi 7
|
Verfasst: Fr 26.11.10 02:39
weis ich nicht  funktioniert auch danke!
ich habe es korregiert...
|
|
|