Hallo
ich möchte per USB auf einen PIC 18F4550 Prozessor zugreifen. Über ein Hilfsprogramm in Delphi (Marke Sprut) funktioniert das auch. Sobald ich dieses Programm als Formular in meine Anwendung einbinde passiert merkwürdiges. Die Funktion SendReceivePacket haut mir lokale Variablen in der aufrufenden onclick Prozedur kaputt. Ich kann nur vermuten, daß auf dem Stack irgendetwas schiefläuft und mir die Variablen überschreibt, weil irgendetwas inkompatibel deklariert ist.
Nach 2 intensiven Debuggertagen bis in die Maschinenebene weiß ich nicht mehr weiter. Vielleicht hat jemand eine Idee dazu....
Im vorliegenden Fall hat nach Aufruf die Variable Selection den Wert 34 , das entspricht den gelesenen Datenbytes. Zufall oder Anhaltspunkt? Je nach Variablenkonstellation kann auch die self Variable überschrieben werden.
Nachtrag:
Mir ist aufgefallen, daß die DLL Funktionen ihre Parameter auf den Stack geschrieben bekommen, wie es sein soll, nach der externen Funktion steht der Stackpointer aber noch auf der Position hinter den gepushten Parametern. Es scheint als bereinige die externe Funktion den Stackpointer nicht von den Parametern, was dann zu der Verschiebung der lokalen Variablen führt. Warum das passiert, weiß ich noch nicht.
Hier die aufrufende onclick Prozedur:
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:
| procedure Tusbdlg.Button16Click(Sender: TObject); var selection : LONGWORD; send_buf : PBYTE; receive_buf : PBYTE; RecvLength : LONGWORD; CurrentCMD : BYTE; i,j : integer; s: string; begin selection:=0;
For selection:=0 to MAX_NUM_MPUSB_DEV-1 Do Begin myOutPipe:= _MPUSBOpen(selection,vid_pid,out_pipe,MP_WRITE,0); if(myoutpipe <> INVALID_HANDLE_VALUE) then break; end; myInPipe:= _MPUSBOpen(selection,vid_pid,out_pipe,MP_READ,0);
if ((myOutPipe = INVALID_HANDLE_VALUE) or (myInPipe = INVALID_HANDLE_VALUE)) then begin Memo1.lines.add('USB Error, no pipes'); exit; end;
s:=''; send_buf[0]:=Read_Block32; send_buf[2]:=0; send_buf[3]:=$3C; RecvLength:=34;
if(SendReceivePacket(send_buf,4,receive_buf,RecvLength,100,100) = 1) then begin if(receive_buf[0] = READ_Block32) then begin for i:=0 to 31 do begin s:=s+intToHex(receive_buf[i+2],2)+' '; end; Memo1.lines.add(intTostr(selection)+' '+s); end; end else begin Memo1.lines.add('USB Error'); exit; end;
_MPUSBClose(myOutPipe); _MPUSBClose(myInPipe); myInPipe:= INVALID_HANDLE_VALUE; myOutPipe:=INVALID_HANDLE_VALUE;
end; |
Hier die DLL dazu:
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:
| unit usbdll;
interface
uses Windows, Dialogs, Sysutils;
Const MAXSIZE = 64; MPUSB_FAIL = 0; MPUSB_SUCCESS = 1; MP_WRITE:DWORD = 0; MP_READ:DWORD = 1; MAX_NUM_MPUSB_DEV = 127;
READ_VERSION = $00;
READ_FLASH = $01; WRITE_FLASH = $02; ERASE_FLASH = $03; READ_EEDATA = $04; WRITE_EEDATA = $05; READ_CONFIG = $06; WRITE_CONFIG = $07;
READ_BLOCK32 = $10; READ_16VALUES = $11; WRITE_BLOCK32 = $15; ERASE_BLOCK64 = $1F; UPDATE_LED = $32; RESET_DEVICE = $FF; LED_ONOFF = $31; READ_SWITCH = $32; RD_POT = $37; RESET = $FF;
type DWORD = LongWORD; PCHAR8 = array[0..MAXSIZE] of char; PBYTE = array[0..MAXSIZE] of BYTE; PDWORD = array[0..MAXSIZE] of DWORD; PVOID = Pointer; UINT = Cardinal;
var vid_pid : PCHAR8 = 'vid_04d8&pid_000c'; out_pipe : PCHAR8 = '\MCHP_EP1'; in_pipe : PCHAR8 = '\MCHP_EP1'; myOutPipe : THANDLE; myInPipe : THANDLE; isConnected : boolean;
function _MPUSBGetDLLVersion():DWORD; stdcall;external 'mpusbapi.dll';
function _MPUSBGetDeviceCount(pVID_PID:PCHAR8):DWORD; stdcall;external 'mpusbapi.dll';
function _MPUSBOpen(instance:DWORD;pVID_PID:PCHAR8; pEP:PCHAR8;dwDir:DWORD;dwReserved:DWORD): THANDLE;stdcall;external 'mpusbapi.dll';
function _MPUSBClose(handle:THANDLE):DWORD; stdcall;external 'mpusbapi.dll';
function _MPUSBRead(handle:THANDLE;var pData:PBYTE; dwLen:LONGWORD;var pLength:LONGWORD; dwMilliseconds:LONGWORD):LONGWORD;stdcall; external 'mpusbapi.dll';
function _MPUSBReadInt(handle:THANDLE; var pData:PBYTE;dwLen:DWORD; var pLength:PDWORD; dwMilliseconds:DWORD):DWORD; stdcall;external 'mpusbapi.dll';
function _MPUSBWrite(handle:THANDLE;pData:PBYTE; dwLen:LONGWORD; var pLength:LONGWORD; dwMilliseconds:LONGWORD):LONGWORD; stdcall;external 'mpusbapi.dll';
function SendReceivePacket(SendData:PBYTE;SendLength:LONGWORD;var ReceiveData:PBYTE; var ReceiveLength:LONGWORD;SendDelay:LONGWORD;ReceiveDelay:LONGWORD):LONGWORD; stdcall;
implementation
procedure CheckInvalidHandle(); begin if(GetLastError=ERROR_INVALID_HANDLE) then begin _MPUSBClose(myOutPipe); _MPUSBClose(myInPipe);
myInPipe:=INVALID_HANDLE_VALUE; myOutPipe:=INVALID_HANDLE_VALUE; end else ShowMessage('Error Code :'+inttostr(GetLastError())); end;
function SendReceivePacket(SendData:PBYTE;SendLength:LONGWORD;var ReceiveData:PBYTE; var ReceiveLength:LONGWORD;SendDelay:LONGWORD;ReceiveDelay:LONGWORD):LONGWORD; stdcall; var SentDataLength:LONGWORD ; ExpectedReceiveLength:LONGWORD;
begin result:=100; ExpectedReceiveLength:= ReceiveLength;
if((myOutPipe <> INVALID_HANDLE_VALUE) and (myInPipe <> INVALID_HANDLE_VALUE)) then begin if(_MPUSBWrite(myOutPipe,SendData,SendLength,SentDataLength,SendDelay)<>0) then if(_MPUSBRead(myInPipe,ReceiveData,ExpectedReceiveLength,Receivelength,ReceiveDelay)<>0)then begin if(ReceiveLength = ExpectedReceiveLength) then begin Result:=1; exit; end else if(ReceiveLength < ExpectedReceiveLength) then begin Result:=2; exit; end end else CheckInvalidHandle() else CheckInvalidHandle() end else begin Result:=0; end; end; initialization end. |
Die Deklarationen der DLL in C lauten hierzu
C#-Quelltext
1: 2: 3:
| DWORD MPUSBWrite (HANDLE handle, PVOID pData, DWORD dwLen, PDWORD pLength, DWORD dwMilliseconds)
DWORD MPUSBRead (HANDLE handle, PVOID pData, DWORD dwLen, PDWORD pLength, DWORD dwMilliseconds) |