>Note that those 6 us is the pure time on the cable and does not include >any hardware and (foremost) software related delays. If you want some >real numbers of typical round trip times, switch off RTmac/TDMA for a >while and do a rtping e.g. This is important in order to schedule enough >time (=slot offset) between the arrival of the master's packet and the >time the slave are intended to reply. Put some load on your systems >during this test to reach worst-case regions.
I compiled RTnet in standard mode : ./configure --with-rtai=<PATH-TO-RTAI> --enable-allpci In this case, is it possible to load noMAC module without recompiling RTnet? If is it not possible, could you tell me how have i to do? you know that when you compile RTnet in above mode, when I execute the command : ./rtnet start, the tdma.ko module is loaded by default. how could I load noMAC module with the same command (./rtnet start), without loading tdma module? >This behaviour is really strange and untypical. But as some of your >application code is involved in the loop, I cannot say anything more >without having a look at it as well I wrote this code: MASTER: // MASTER [M1] #ifdef HAVE_CONFIG_H #include <config.h> //lpx: ??? #endif #include <iostream> //lpx: ??? #include <cstdlib> //lpx: ??? #include <sys/socket.h> //lpx: socket, PF_INET, SOCK_DGRAM #include <netinet/in.h> //lpx: socket, PF_INET, SOCK_DGRAM #include <arpa/inet.h> // for inet_addre() //lpx: necessarie per cambiare la priorità di un processo #include <sys/time.h> #include <sys/resource.h> //lpx: necessario per sprintf() #include <stdio.h> //lpx: lettura del tempo #include <time.h> #include <rtnet.h> using namespace std; int main(int argc, char *argv[]) { RT_TASK *task_rt; //lpx: task real time int udpSocket; //lpx: Socket UDP int nFamily=AF_INET; //lpx: protocollo di rete: IP int nType=SOCK_DGRAM; //lpx: protocollo di trasporto: UDP int nProtocol = 0; //lpx: ??? int nAddr=INADDR_ANY; //lpx: Questo indirizzo int nPort=15000; //lpx: porta // indirizzo interno struct sockaddr_in MyAdrs; //lpx: indirizzo IP memset( &MyAdrs, 0, sizeof( MyAdrs ) ); //lpx: azzero variabile // primo Socket MyAdrs.sin_family = nFamily; //lpx: tipo di indirizzo MyAdrs.sin_addr.s_addr = htonl( nAddr ); //lpx: indirizzo IP host MyAdrs.sin_port = htons( nPort ); //lpx: porta su cui collegarsi // indirizzi degli slave a cui mi devo connettere char slaveAddress[16] = "192.0.0.255"; int slavePort=6000; // l'inirizzo a cui invierò sarà di tipo broadcast struct sockaddr_in slaveAdrs; //indirizzo del server che si vuole connettere int len; //dimensione della struttura masterAdrs // i valori li otterro dal primo mesaggio che mi giunge memset(&slaveAdrs, 0, sizeof( slaveAdrs ) ); //lpx: azzero variabile // socket verso il primo slave S1 slaveAdrs.sin_family = nFamily; //lpx: tipo di indirizzo slaveAdrs.sin_addr.s_addr = inet_addr(slaveAddress); //lpx: indirizzo IP host slaveAdrs.sin_port = htons(slavePort); //lpx: porta su cui collegarsi const int BufferLen=256; //lpx: lunghezza buffer di ricezione char Buffer[BufferLen]; // lpx: punta ai dati da trasmettere char BufferRx[BufferLen]; //lpx: buffer di ricezione for (int j=1; j<BufferLen; j++) {// il Buffer[0] lo uso per inserire il numero di datagram Buffer[j]=j; } int flags=0; // lpx: vedi info sendoto() o recvfrom() int a,i; // a: ritorno errore , i indice int add_rtskbs=100; //numero di buffer in più da allocare per il socket int new_rtskbs; //contiene la quantità dei nuovi buffer realmente allocata //nice(-15); // creo i socket udpSocket = socket_rt( nFamily, nType, nProtocol); if (udpSocket<0) { printf("errore Socket non creato %d!\n",udpSocket); //devo rimuovere i socket precedentemente creati close_rt(udpSocket); //chiudo il socket exit(1); } //aggiungo nuovi buffer al socket new_rtskbs=ioctl_rt(udpSocket,RTNET_RTIOC_EXTPOOL,&add_rtskbs); if (new_rtskbs!=add_rtskbs) { //non ho allocato tutti i buffer close_rt(udpSocket); printf("new buffer = %d \n",new_rtskbs); exit(1); } printf("new buffer = %d \n",new_rtskbs); // inizializzo il task real-time, tutti i metodi usati devono essere RT task_rt = rt_task_init(4900,1,0,0); //Id_Task, priorità, ... if (task_rt==NULL) // controllo che il task sia stato creato { close_rt(udpSocket); //chiudo il socket printf("task non creato\n"); exit(1); } // vado in modalità Hard real time rt_make_hard_real_time(); // faccio l'associazione tra soket e porta if (bind_rt(udpSocket,(sockaddr*)&MyAdrs,sizeof(MyAdrs))<0) { //asssociazione nn riuscita close_rt(udpSocket); printf("errore BIND\n"); exit(1); } //associazione riuscita i=0; //i conta i segmenti in arrivo while (i<20) //aspetto l'invio di 10 segmenti { Buffer[0]=i+48; a=sendto_rt(udpSocket, Buffer, BufferLen,flags, (sockaddr*)&slaveAdrs,(socklen_t) sizeof(sockaddr)); // ricevo il segmento e lo reinvio al mittente recv_rt(udpSocket, BufferRx, sizeof(BufferRx),flags); // slaveA recv_rt(udpSocket, BufferRx, sizeof(BufferRx),flags); // slaveB i++; } // Passo nella modalità non real time rt_make_soft_real_time(); // chiudo il socket close_rt(udpSocket); // rimuovo il task rt_task_delete(task_rt); if (a<0) printf("errore %s!\n",strerror(a)); printf("flusso eseguito\n"); return 0;// EXIT_SUCCESS; } SLAVE: // SLAVE [S1] // NB. Cambiare l'indirizzo della Porta su cui aprire il socket #ifdef HAVE_CONFIG_H #include <config.h> //lpx: ??? #endif #include <iostream> //lpx: ??? #include <cstdlib> //lpx: ??? #include <sys/socket.h> //lpx: socket, PF_INET, SOCK_DGRAM #include <netinet/in.h> //lpx: socket, PF_INET, SOCK_DGRAM #include <arpa/inet.h> // for inet_addre() //lpx: necessarie per cambiare la priorità di un processo #include <sys/time.h> #include <sys/resource.h> //lpx: necessario per sprintf() #include <stdio.h> //lpx: lettura del tempo #include <time.h> #include <rtnet.h> using namespace std; int main(int argc, char *argv[]) { RT_TASK *task_rt; //lpx: task real time int udpSocket; //lpx: Socket UDP int nFamily=AF_INET; //lpx: protocollo di rete: IP int nType=SOCK_DGRAM; //lpx: protocollo di trasporto: UDP int nProtocol = 0; //lpx: ??? int nAddr=INADDR_ANY; //lpx: Questo indirizzo int nPort=6000; //lpx: porta 6000 // indirizzo interno struct sockaddr_in MyAdrs; //lpx: indirizzo IP memset( &MyAdrs, 0, sizeof( MyAdrs ) ); //lpx: azzero variabile MyAdrs.sin_family = nFamily; //lpx: tipo di indirizzo MyAdrs.sin_addr.s_addr = htonl( nAddr ); //lpx: indirizzo IP host MyAdrs.sin_port = htons( nPort ); //lpx: porta su cui collegarsi struct sockaddr_in masterAdrs; indirizzo del server che si vuole connettere int len; //dimensione della struttura masterAdrs // i valori li otterro dal primo mesaggio che mi giunge memset(&masterAdrs, 0, sizeof( masterAdrs ) ); //lpx: azzero variabile //masterAdrs.sin_family = nFamily; //lpx: tipo di indirizzo //masterAdrs.sin_addr.s_addr = inet_addr(masterAddress); //lpx: indirizzo IP host //masterAdrs.sin_port = htons(masterPort); //lpx: porta su cui collegarsi const int BufferRxLen=256; //lpx: lunghezza buffer di ricezione const int BufferLen=96; //lpx: lunghezza buffer di trasmissione int DataLen; //lpx: dimensione dati in arrivo char Buffer[BufferLen]; // lpx: punta ai dati da trasmettere char BufferRx[BufferRxLen]; //lpx: buffer di ricezione int flags=0; // lpx: vedi info sendoto() o recvfrom() int a,i; // a: ritorno errore , i indice int add_rtskbs=100; //numero di buffer in più da allocare per il socket int new_rtskbs; //contiene la quantità dei nuovi buffer realmente allocata //nice(-15); // creo il socket udpSocket = socket_rt( nFamily, nType, nProtocol); if (udpSocket<0) printf("errore Socket non creato %d!\n",udpSocket); //aggiungo nuovi buffer al socket new_rtskbs=ioctl_rt(udpSocket,RTNET_RTIOC_EXTPOOL,&add_rtskbs); if (new_rtskbs!=add_rtskbs) { //non ho allocato tutti i buffer close_rt(udpSocket); printf("new buffer = %d \n",new_rtskbs); exit(1); } printf("new buffer = %d \n",new_rtskbs); // inizializzo il task real-time, tutti i metodi usati devono essere RT task_rt = rt_task_init(4905,1,0,0); //Id_Task, priorità, ... if (task_rt==NULL) // controllo che il task sia stato creato { close_rt(udpSocket); //chiudo il socket printf("task non creato\n"); exit(1); } // vado in modalità Hard real time rt_make_hard_real_time(); // faccio l'associazione tra soket e porta if (bind_rt(udpSocket,(sockaddr*)&MyAdrs,sizeof(MyAdrs))<0) { //asssociazione nn riuscita close_rt(udpSocket); printf("errore BIND\n"); exit(1); } //associazione riuscita i=0; //i conta i segmenti in arrivo while (i<20) //aspetto l'invio di 10 segmenti { // ricevo il segmento e lo reinvio al mittente DataLen=recvfrom_rt(udpSocket, BufferRx, BufferRxLen,flags, (sockaddr*)&masterAdrs,(socklen_t*)&len); // uso BufferLen perchè voglio inviare una quantità di dati inferiore sendto_rt(udpSocket, BufferRx, BufferLen,flags, (sockaddr*)&masterAdrs,(socklen_t)len); i++; } // Passo nella modalità non real time rt_make_soft_real_time(); // chiudo il socket close_rt(udpSocket); // rimuovo il task rt_task_delete(task_rt); //if (a<0) printf("errore %s!\n",strerror(a)); printf("flusso eseguito\n"); printf("buffer %d",BufferRxLen); return 0;// EXIT_SUCCESS; } >> User space or kernel space application? I work in user-space I build the application with Kdevelop in KDE 3.3 I have a linux debian I compile the code in C++ ptimized mode > 600 us is indeed quite stressing, you should examine your system load > and the timing behaviour over a longer, loaded period very carefully > (the worst case counts...). Anyway, if the cycle period would already be > too high, you should rather observe more frequent cycle misses by one, > not by 5 or so. sorry, I don't undestand above paragraph. can you explain it better? thanks! ------------------------------------------------------- SF.Net email is sponsored by: Tame your development challenges with Apache's Geronimo App Server. Download it for free - -and be entered to win a 42" plasma tv or your very own Sony(tm)PSP. Click here to play: http://sourceforge.net/geronimo.php _______________________________________________ RTnet-users mailing list RTnet-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/rtnet-users