>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
[email protected]
https://lists.sourceforge.net/lists/listinfo/rtnet-users