minimum_read0.c endet immer im Timeout

Dies ist das deutsche Forum für alle Themen um den IO-Warrior. Beiträge bitte nur in Deutsch.

Moderator: Guido Körber

Post Reply
regenbiegen
Posts: 8
Joined: Thu Jun 19, 2008 4:06 pm

minimum_read0.c endet immer im Timeout

Post by regenbiegen »

Moin moin,

minimum_read0 endet immer mit einem Timeout, egal wie oft ich die Taste drücke.
Auf dem Oszi sehe ich das sobald ich die Taste drücke der Pegel an P6.0 von High (+5V) auf Low (0V) geht. Ansonsten funktioniert z.B. minimum_write0 oder get_io_status_direct einwandfrei. Je nachdem ob man die Taste gedrückt hält liefert get_io_status_direct das entsprechende Ergebnis.

Was hat das select() in minimum_read0 für ein Problem das es immer im Timeout endet ??

Gruß,
Bernd

Die Hardware ist das IOW56 StarterKit und das System ist eine Kubuntu 8.04 x86-64 mit SDK 1.5.
wayoda
Posts: 362
Joined: Fri Dec 19, 2003 12:00 pm
Location: Wuppertal/Germany

Post by wayoda »

Hallo,
das gleiche Phänomen tritt auch bei mir auf. Ich habe den Iow56 in letzter Zeit nur mit den SpecialModes benutzt, die aber keine Probleme machen (soweit ich das sehen kann).

Ich habe mir gerade noch mal kubuntu 7.10 runtergeladen um zu sehen ob es unter diesem Kernel (denn da wird der Knackpunkt sein) auch schon diese Probleme gab.

Eberhard
regenbiegen
Posts: 8
Joined: Thu Jun 19, 2008 4:06 pm

Post by regenbiegen »

Hallo,

wenn ich einmal iowkittest (das Beispiel für die Library Programmierung) laufen lassen dann reagiert danach auch minimum_read0 auf den Taster.
Das funktioniert solange bis ich den IOW56 vom USB trenne und wieder verbinde, denn dann hat minimum_read0 wieder das Problem. Abhilfe schafft dann wieder iowkittest.
Ich habe mir den Quellcode von iowkit.c (das ist ein Teil der Library) angesehen um mal zu schauen was die Library anders macht als minimum_read0. Bis jetzt habe ich aber nichts auffäliges gesehen.

Gruß,
Bernd
wayoda
Posts: 362
Joined: Fri Dec 19, 2003 12:00 pm
Location: Wuppertal/Germany

Post by wayoda »

Hallo Bernd,
ich kenne zwar die Ursache für das Problem noch nicht, habe aber zumindest eine Lösung parat.

Wie Du wahrscheinlich schon weißt, werden bei Linux das IO-Pin Interface und das SpecialMode-Interface als zwei verschiedene Geräte erzeugt (z.B. iowarrior0 und iowarrior1).

Bei dem Iow24 und Iow40 sind beide Geräte auch tatsächlich völlig unabhängig voneinander. Das von Dir beschriebene Problem existiert bei ihnen nicht. Beim Iow56 ist das (aus bisher unbekannten Gründen) anders.

Der Fehler verschwindet beim IOW56 sobald man in einem Programm beide Geräte-Dateien geöffnmet hat. (Das macht die IowKit-Lib intern genaus so, darum funktioniert der Iow56 nach einmaligem Aufruf von iowkittest).

Folgender Code (basierend auf minimum_read0.c ) sollte daher funktionieren

Code: Select all


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include<sys/time.h>
#include <linux/types.h>
#include "iowarrior.h"

#define USB_VENDOR_ID_CODEMERCS	1984
/* low speed iowarrior */
#define USB_DEVICE_ID_CODEMERCS_IOW40	0x1500
#define USB_DEVICE_ID_CODEMERCS_IOW24	0x1501
#define USB_DEVICE_ID_CODEMERCS_IOWPV1	0x1511
#define USB_DEVICE_ID_CODEMERCS_IOWPV2	0x1512
/* full speed iowarrior */
#define USB_DEVICE_ID_CODEMERCS_IOW56	0x1503

int main (int argc, char **argv) {
    /* for device information */
    struct iowarrior_info info;
    /* A buffer for reading the data, suitable for all IOWarrior-Products */
    unsigned char in_buffer[8];
    /* The file-descriptor for the IO-Pins of our device */
    int fdIO = -1;
    /* The file-descriptor for the SpecialModes of our device */
    int fdSM = -1;
    
    /* A result for the operations */
    int result=-1;	//result of read and select operations
    /* the read-set for select */
    fd_set rfds;	
    /* the timeout for select */
    struct timeval tv;	
    int i=0;

    /* we try to open the device attached to /dev/usb/iowarrior0 */
    if(( fdIO = open( "/dev/usb/iowarrior0", O_RDWR)) < 0 ) {
    	perror( "iowarrior io-pins open failed" );
	goto exit;
    }
    if(( fdSM = open( "/dev/usb/iowarrior1", O_RDWR)) < 0 ) {
    	perror( "iowarrior special modes open failed" );
	goto exit;
    }
    
    /* lets see what product we have */
    if( ioctl( fdIO, IOW_GETINFO, &info)){
	perror( "Unable to retrieve device info" );
	goto exit;
    }
    
    /* print the device information */
    printf("The device attached to /dev/usb/iowarrior0\n");
    printf("VendorId=%04x\n",info.vendor);
    printf("ProductId=%04x ",info.product);
    if(info.product==USB_DEVICE_ID_CODEMERCS_IOW40)
	printf("(IOWarrior40)\n");
    else if(info.product==USB_DEVICE_ID_CODEMERCS_IOW24)
	printf("(IOWarrior24)\n");
    else if(info.product==USB_DEVICE_ID_CODEMERCS_IOW56) {
      printf("(IOWarrior56)\n");
    }
    else
	printf("(Ooops, unknown device!)\n");
    printf("Serial=0x%s\nRevision=0x%04x\n",info.serial, info.revision); 
    printf("Speed=");
    if(info.speed==1)
	printf("Low Speed (USB 1.1)\n");
    else if(info.speed==2)
	printf("Full Speed (USB 1.1)\n");
    else if(info.speed==3)
	printf("High Speed (USB 2.0)\n");
    else
	printf("Ooops, speed is unknown!\n");
    printf("Power=%dmA\nPacketSize=%d\n",info.power, info.report_size); 
    /* checking for the IO-PIN interface */
    if(info.if_num!=0) {
	printf("Opps, this is not the IO-PIN interface\n");
	printf("Can't go on\n");
	goto exit;
    }    
    
    tv.tv_sec=20;	//timeout is set to 10 seconds 
    tv.tv_usec=0;
    FD_ZERO(&rfds);	//clear the read-descriptors for select
    FD_SET(fdIO, &rfds);	
    printf("We wait for up to 10 seconds... ");
    result=select(fdIO+1,&rfds,NULL,NULL,&tv);
    if(result==-1) {
	//error in select
	perror("Error in select");
	goto exit;
    }
    else if(result==0) {
	//select returned 0, no new data to be read
	printf("Timeout in read, so we exit\n");
    }
    else {
	if(FD_ISSET(fdIO,&rfds)) {
	    memset(&in_buffer,0,sizeof(in_buffer));
	    //We got here, so there should be new data available
	    
	    result = read(fdIO,in_buffer,info.report_size);
	    if(result!=info.report_size) {
		//well thats not what we expected...
		int errcode=errno;
		if(errcode==ENODEV) 
		    printf("Hey, you pulled the plug!\n");
		else
		    perror("Error in reading!");
	    }
	    else {
		//buffer now contains the io-status
		printf("ok, here's the IO-Status:\n");
		for(i=0;i<info.report_size;i++)
		    printf( "Port%d=%02x\n",i,in_buffer[i]);
	    }
 	}
    }
 exit:
    close( fdIO );
    close( fdSM );
    exit( 0 );
}
Eberhard
regenbiegen
Posts: 8
Joined: Thu Jun 19, 2008 4:06 pm

Post by regenbiegen »

Hallo Eberhard,

vielen Dank. Darauf muss man auch erstmal kommen.
Ich hab mal versucht ob das ganze auch per Linux AIO funtkioniert, aber das mag noch nicht so recht.

Kompilieren mit gcc read_aio.c -o read_aio -laio

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/time.h>
#include <linux/types.h>
#include "iowarrior.h"
#include <libaio.h>

#define USB_VENDOR_ID_CODEMERCS 1984
/* low speed iowarrior */
#define USB_DEVICE_ID_CODEMERCS_IOW40 0x1500
#define USB_DEVICE_ID_CODEMERCS_IOW24 0x1501
#define USB_DEVICE_ID_CODEMERCS_IOWPV1 0x1511
#define USB_DEVICE_ID_CODEMERCS_IOWPV2 0x1512
/* full speed iowarrior */
#define USB_DEVICE_ID_CODEMERCS_IOW56 0x1503

void leave(int fdio, int fdsm, int error_code)
{
close(fdio);
close(fdsm);
exit(error_code);
}

int main (int argc, char **argv)
{
struct iowarrior_info info; /* for device information */
unsigned char in_buffer[8]; /* A buffer for reading the data, suitable for all IOWarrior-Products */
int fdio = -1; /* The file-descriptor of our device */
int fdsm = -1;

/* A result for the operations */
int result=-1; //result of read and select operations
fd_set rfds; /* the read-set for select */
struct timeval tv; /* the timeout for select */
int i=0;

io_context_t s1_ctxp = NULL;
struct iocb s1_iocb;
struct iocb *s1_iocbs[] = {&s1_iocb};
struct io_event s1_event[1];
struct timespec s1_timeout;
long s1_result = 0LL;

/* we try to open the device attached to /dev/iowarrior0 */
if(( fdio = open( "/dev/iowarrior0", O_RDWR | O_NONBLOCK)) < 0 )
{
perror( "iowarrior open failed" );
exit(1);
}

/* we try to open the device attached to /dev/iowarrior1 */
if(( fdsm = open( "/dev/iowarrior1", O_RDWR | O_NONBLOCK)) < 0 )
{
perror( "iowarrior open failed" );
exit(1);
}

/* lets see what product we have */
if( ioctl( fdio, IOW_GETINFO, &info))
{
perror( "Unable to retrieve device info" );
leave(fdio, fdsm, 1);
}

/* print the device information */
printf("The device attached to /dev/iowarrior0\n");
printf("VendorId=%04x\n",info.vendor);
printf("ProductId=%04x ",info.product);

switch(info.product)
{
case USB_DEVICE_ID_CODEMERCS_IOW40: printf("(IOWarrior40)\n"); break;
case USB_DEVICE_ID_CODEMERCS_IOW24: printf("(IOWarrior24)\n"); break;
case USB_DEVICE_ID_CODEMERCS_IOW56: printf("(IOWarrior56)\n"); break;
default: printf("(Ooops, unknown device!)\n");
}

printf("Serial=0x%s\nRevision=0x%04x\n",info.serial, info.revision);

printf("Speed=");
switch(info.speed)
{
case 1: printf("Low Speed (USB 1.1)\n"); break;
case 2: printf("Full Speed (USB 1.1)\n"); break;
case 3: printf("High Speed (USB 2.0)\n"); break;
default: printf("Ooops, speed is unknown!\n");
}

printf("Power=%dmA\nPacketSize=%d\n",info.power, info.report_size);

/* checking for the IO-PIN interface */
if(info.if_num!=0)
{
printf("Opps, this is not the IO-PIN interface\n");
printf("Can't go on\n");
leave(fdio, fdsm, 1);
}

memset(&in_buffer,0,sizeof(in_buffer));
io_prep_pread(&s1_iocb, fdio, in_buffer, info.report_size, 0);
io_submit(s1_ctxp, 1, s1_iocbs);
s1_timeout.tv_sec=10;
s1_timeout.tv_nsec=0;
s1_result=io_getevents(s1_ctxp, 1, 1, &s1_event[0], &s1_timeout);

if(s1_result<1)
{
perror("timeout");
printf("s1_result=%i\n", s1_result);
leave(fdio, fdsm, 1);
}

if(s1_event[0].res != info.report_size)
{
perror("read failed");
leave(fdio, fdsm, 1);
}

printf("ok, here's the IO-Status:\n");
for(i=0;i<info.report_size;i++)
printf( "Port%d=%02x\n",i,in_buffer);

leave(fdio, fdsm, 0);
}

Gruß,
Bernd
wayoda
Posts: 362
Joined: Fri Dec 19, 2003 12:00 pm
Location: Wuppertal/Germany

Post by wayoda »

Hallo Bernd
regenbiegen wrote:Hallo Eberhard,

vielen Dank. Darauf muss man auch erstmal kommen.
Es war einfach ungewöhnlich, dass es mit der IowKit-Lib funktioniert
auch wenn man nur noch den Befehl IowKit.OpenDevice() ausführt.
Ich hab mal versucht ob das ganze auch per Linux AIO funtkioniert, aber das mag noch nicht so recht.
Da musste ich erst mal nachschauen was AIO ist :-) kann daher also auch nichts dazu sagen.
Ich bin einfach froh das ich irgendwann einmal Multithreading verstanden habe, da ist das ja für mich nicht so interessant.

Falls aber noch weitere Iow unter Linux-Fragen auftauchen sollten meld dich doch ruhig wieder.

Eberhard
Post Reply