>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

Reply via email to