Forum: PC-Programmierung Treiberprogrammierung READ_PORT_UCHAR WINXP


von Daniel (Gast)


Lesenswert?

Ich habe einen Treiber entwickelt der mir die serielle Schnittstelle als 
I2C-Bus emuliert, nun das Problem: Ich mache anscheinend einen Fehler 
bei den Fuktionen READ-und WRITE_PORT_UCHAR: Der Treiber wird jetzt zu 
Testzwecken mithilfe eines PYTHON - Programms aufgerufen. Laut 
Debugmonitor funktionieren die DeviceIoControl-Funktionen. (wird richtig 
ausgegeben) Nur wenn ich jetzt den Pegel messa am Port tut sich da 
überhaupst nichts. Über Python wird auch die Serielle Schnittstelle 
aktiviert (RTS und DSR auch)
Code:
#include "wdm1.h"

#include "Ioctl.h"

#include <string.h>

#include <wdm.h>



#define DTR 0    //Write Data Bit SDA

#define RTS 1  //SCL

#define CTS 4   //ReadData

#define DSR 0  //SCL


........................................


NTSTATUS Wdm1DeviceControl(  IN PDEVICE_OBJECT fdo,

              IN PIRP Irp)

{



  PUCHAR MCR ;

  PUCHAR MSR ;

  MCR=(PUCHAR)(0x3FC);

  MSR=(PUCHAR)(0x3FE);

  UCHAR BufferREAD;   //Buffer for READ_Register(MSR)

  UCHAR BufferWRITE;  //Buffer for Write_Register(MCR)

  UCHAR BufferUART;   //Buffer for UART

  UCHAR BufferUSER;  //Buffer for USERMODE

  UCHAR GETBuffer;



  PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);

  NTSTATUS status = STATUS_SUCCESS;

  ULONG BytesTxd = 0;



  ULONG ControlCode = 
IrpStack->Parameters.DeviceIoControl.IoControlCode;

  ULONG InputLength = 
IrpStack->Parameters.DeviceIoControl.InputBufferLength;

  ULONG OutputLength = 
IrpStack->Parameters.DeviceIoControl.OutputBufferLength;



  DebugPrint("DeviceIoControl: Control code %x InputLength %d 
OutputLength %d",

        ControlCode, InputLength, OutputLength);



  // Get access to the shared buffer

  KIRQL irql;

  KeAcquireSpinLock(&BufferLock,&irql);

  switch( ControlCode)

  {

  ///////  Zero Buffer





  case IOCTL_WRITE_SCL:

    RtlCopyMemory(&BufferUSER,Irp->AssociatedIrp.SystemBuffer,sizeof(UCHAR)) 
;

    BufferREAD=READ_PORT_UCHAR(MSR);

    BufferWRITE=READ_PORT_UCHAR(MCR);

    if(BufferUSER==1)      //Set SCL

    {

      DebugPrint("SetSCL");

      BufferWRITE|=(1<<RTS);

      BufferREAD|=(1<<DSR);

      DebugPrint("BufferWrite %d BufferRead %d",BufferWRITE,BufferREAD);

      WRITE_PORT_UCHAR(MCR,BufferWRITE);

      WRITE_PORT_UCHAR(MSR,BufferREAD);

    }

    else  //Clear SCL

    {

      DebugPrint("ClearSCL");

      BufferWRITE&=~(1<<RTS);

      BufferREAD&=~(1<<DSR);

      DebugPrint("BufferWrite %d BufferRead %d",BufferWRITE,BufferREAD);

      WRITE_PORT_UCHAR(MCR,BufferWRITE);

      WRITE_PORT_UCHAR(MSR,BufferREAD);

    }



    break;

  case IOCTL_WRITE_SDA:

    RtlCopyMemory(&BufferUSER,Irp->AssociatedIrp.SystemBuffer,sizeof(UCHAR)) 
;

    BufferWRITE=READ_PORT_UCHAR(MCR);

    if(BufferUSER==1)      //Set SDA

    {

      DebugPrint("SetSDA");

      BufferWRITE|=(1<<DTR);

      WRITE_PORT_UCHAR(MCR,BufferWRITE);

    }

    else        //Clear SDA

    {

      DebugPrint("ClearSDA");

      BufferWRITE&=~(1<<DTR);

      WRITE_PORT_UCHAR(MCR,BufferWRITE);

    }

    break;

  case IOCTL_READ_SDA:

    BufferUART=READ_PORT_UCHAR(MSR);

    if (BufferUART & CTS)    //Bit is Set

    {

      GETBuffer=1;

      RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,&GETBuffer,sizeof(UCHAR));

      DebugPrint("ReadHighSDA");

    }

    else        //Bit is Clear

    {

      GETBuffer=0;

      RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,&GETBuffer,sizeof(UCHAR));

      DebugPrint("ReadLowSDA");



    }



  break;

  default:

    status = STATUS_INVALID_DEVICE_REQUEST;

  }

  // Release shared buffer

  KeReleaseSpinLock(&BufferLock,irql);







  // Complete IRP

  return CompleteIrp(Irp,status,BytesTxd);

}
..........................................

Ich finde leider keinen Fehler mehr im Programm, muss ich irgendwas 
bestimmtes beachten. Habe schon so ziemlich alle Möglichkeiten 
gegoogelt, aber leider nichts relevantes gefunden.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Hast Du wirklich allen Ernstes die I/O-Adressen der seriellen 
Schnittstelle in Deinem "Treiber" hartcodiert ?

Hast Du denn dafür gesorgt, daß diese Schnittstelle nicht mehr vom 
Treiber für serielle Schnittstellen angesprochen wird?

Bist Du Dir sicher, daß das der richtige Ansatz ist?

von Christian R. (supachris)


Lesenswert?

Oha, komplizierter gehts wohl kaum. Ein IOWarrior oder ein FT2232 hätte 
dir das ganze ohne schlimme Kernel-Treiber-Programmierung per USB 
standardkonform erledigt.

von Daniel (Gast)


Lesenswert?

Zu Rufus was meinst du mit: " daß diese Schnittstelle nicht mehr vom
Treiber für serielle Schnittstellen angesprochen wird" ich muss ja den 
Treiber akitivieren damit er mit Python geöffnet werden kann.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Es gibt einen Treiber, der die Standard-Schnittstellen anspricht. Dein 
"Treiber" fummelt dem dazwischen, indem er direkt irgendwelche Register 
der seriellen Schnittstelle umprogrammiert.

Das ist Pfusch.

von Tobias P. (hubertus)


Lesenswert?

Hey Daniel,
womit hast du denn deinen Treiber programmiert? Mit dem Windows DDK?
Hast du mir dazu vlt. den Microsoft-Link, wo man das runterladen kann? 
Ich habs nämlich schon mal gesucht, aber nix gefunden :-(

Gruss

von Christian R. (supachris)


Lesenswert?

Das WDK ist meines Wissens nicht kostenlos. Wenn, dann nur für MSDN 
Mitglieder.

von walther trugget (Gast)


Lesenswert?

>Hast du mir dazu vlt. den Microsoft-Link, wo man das runterladen kann?
>Ich habs nämlich schon mal gesucht, aber nix gefunden :-(
Dafür muss man eigentlich auch zahlen (und deswegen kennt das hier auch 
keiner :-).

von Tobias P. (hubertus)


Lesenswert?

Oh.
Ich habe gemeint, das war zumindes mal gratis.
Schade das das DDK heute was kostet, dann wird man es wohl kaum irgendwo 
bekommen :-( Extra eine horrende Summe dafür zahlen, dass ich bisschen 
experimentieren kann, will ich nicht.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Ganz so schlimm scheint es nicht zu sein, man braucht zwar eine 
Windows-Live-ID und muss sich registrieren, aber dann kann man wohl das 
WDK so herunterladen:

http://www.microsoft.com/whdc/devtools/wdk/wdkpkg.mspx

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
Noch kein Account? Hier anmelden.