I try to send data (an array of 'double')
from a PC to an other, using a Null-Modem
cable.

I've modified the rtlinux COM driver to be able to
wake up a thread each time an interrupt is triggered, because
the target must get the data as soon as they are arrived.

actually the thread that reads the data is in an other module, and the custom
isr handler is called thrue a fonction pointer :

So in rt_linux.c I wrote :

-------------------------------------------------------------------------
static unsigned int rt_com0_isr( unsigned int num, struct pt_regs *r)
{

 unsigned int ret =  rt_com_isr(0, NULL);

 if (custom_isr_handler)
 {
  custom_isr_handler();
 }

 return ret;

}
-------------------------------------------------------------------------

and in the module that reads the data we find :

-------------------------------------------------------------------------
static void my_isr_handler(void){
 pthread_wakeup_np(thread_app);
}
-------------------------------------------------------------------------

with custom_isr_handler = my_isr_handler (initialized when the module that
reads the data is loaded).

the thread 'thread_app' reads available data each time it is waken up,
with a rt_com_read.

I send my data from COM1 to COM0 with a user space program that sends these data
continously, with no pause.

The rtlinux driver wait for the data on COM0, and wakeup my thread that reads
the data

Everything is OK if the total amount of sent data does not exced 16Ko
I get all my data, even with a 115200Bd rate.

But, when I try to send more than 16Ko, it seems that the data above 16Ko are
lost : the handler is called, the tread is waken up, the rt_com_read function
is called and returns 8 (so 8 chars must have been received), but the chars
in the buffer filled by rt_com_read are all equal to 0.

The user space program I uses to send my doubles :
(I'm sorry for the french language used for some variables)

------------------------------------------------------------------------
include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>


#define BAUD_RATE B115200

/*
----------------------
----------------------
here is the 16Ko limit
2050 works, 2055 fails) :
----------------------
----------------------
*/

#define NOMBRE_DOUBLE  2054


const char *DEVICE = "/dev/ttyS1";

int
main (int ac, char **av)
{

 int fd, i, n;
 struct termios tty;
 double d = 1;
 double swap = 1;
 double cumul = 0;
 int taille_restante;
 double source;


 if ((fd = open (DEVICE, O_RDWR | O_NOCTTY | O_NDELAY)) < 0)
 {

  perror (DEVICE);

  exit (1);
 }
 else
 {


  tcgetattr (fd, &tty);
  cfsetispeed (&tty, BAUD_RATE);
  cfsetospeed (&tty, BAUD_RATE);
  tcsetattr (fd, TCSANOW, &tty);

  tcgetattr (fd, &tty);
  tty.c_cflag |= (CLOCAL | CREAD);
  tcsetattr (fd, TCSANOW, &tty);

  tcgetattr (fd, &tty);
  tty.c_cflag &= ~PARENB;
  tcsetattr (fd, TCSANOW, &tty);



  tcgetattr (fd, &tty);
  tty.c_cflag &= ~CSTOPB;
  tcsetattr (fd, TCSANOW, &tty);

  tcgetattr (fd, &tty);
  tty.c_cflag &= ~CSIZE;
  tcsetattr (fd, TCSANOW, &tty);


  tcgetattr (fd, &tty);
  tty.c_cflag |= CS8;
  tcsetattr (fd, TCSANOW, &tty);


  for (i = 0; i < NOMBRE_DOUBLE; i++)
  {
   if (i != NOMBRE_DOUBLE - 1)
   {
    source = i + 1;
    cumul = cumul + swap * source;
    swap *= (-1);
   }
   else


    /* the lastest value will be 1000000*/
    source = 1000000;
   }

   taille_restante = sizeof (double);
   do
   {
    n = write (fd,
        (char *) (&source) +
        (sizeof (double) -
         taille_restante),
        taille_restante);
    if (n > 0)
    {

     taille_restante -= n;
     printf ("Element=%d n=%d\n",
      (int) source, n);
    }
   }
   while (taille_restante);

  }
  printf ("Element envoyes : %d, CUMUL=%d\n", NOMBRE_DOUBLE,
   (int) cumul);


  close (fd);

 }


 return 0;

}

------------------------------------------------------------------------

And, the module that reads the data :

(I uses the value 1000000 to catch the
lastest double (but, when it fails,I never get
1000000, I get 0...) )

rt_com_set_isr_handler is a function I added to the rt_com
driver. It allow to dynamically register your own function for isr

Sorry again for the french stuff everywhere...

--------------------------------------------------------------------------
#include <rtl.h>
#include <rtl_fifo.h>

#include <time.h>
#include <pthread.h>
#include <asm/io.h>
#include "rt_com.h"
#define BAUD_RATE 115200


static void* func_app(void* param);
static void my_isr_handler(void);

static pthread_t thread_app = 0;
static int stop_thread_app = 0;


static void my_isr_handler(void)
{

 pthread_wakeup_np(thread_app);
}

int init_module(void)
{
 struct sched_param p;
 pthread_attr_t attr;



   rtl_printf ("Mise en place des parametres du port serie\n");
 rt_com_setup(0, BAUD_RATE, RT_COM_PARITY_NONE, 1, 8);

 rtl_printf ("tentative de demarrage du thread de lecture des parameters\n");
 pthread_attr_init(&attr);
 pthread_attr_setfp_np(&attr, 1);
 pthread_create (&thread_app, &attr, func_app, NULL);
 p . sched_priority = 1;
 pthread_setschedparam (thread_app, SCHED_FIFO, &p);


 rtl_printf ("Mise en place du handler d'IRQ\n");
 rt_com_set_isr_handler(my_isr_handler);

 return 0;
}


void cleanup_module(void)
{

 stop_thread_app = 1;
        pthread_wakeup_np(thread_app);
        pthread_join(thread_app, NULL);

 rtl_printf ("Suppression du handler d'IRQ\n");
 rt_com_set_isr_handler(0);


        rtl_printf ("Suppression des parametres du port serie\n");
 rt_com_setup(0, -1, 0, 0, 0);
}



static void *func_app(void* param)
{


    int n,i =0;

    double swap = 1;
    double cumul = 0;
    double target = 0;
    int taille_restante;
    int progression = 0;


    int dernier_element_valide =0;

    rtl_printf( "Demarrage du Thread de lecture du port s�rie.\n" );


    taille_restante = sizeof(double);
    pthread_suspend_np(pthread_self());
    while(!stop_thread_app)
    {

 n = rt_com_read(0, (char*)(&target)+(sizeof(double)-taille_restante),taille_restante);
 if (n > 0)
 {
  taille_restante -= n;
  rtl_printf("r=%d\n",taille_restante);

 }


  if(  0 == taille_restante)
  {
   taille_restante = sizeof(double);

  rtl_printf("t=%d\n",(int)target);
   i++;
   if(target != 1000000)
  {
      cumul = cumul + swap * target;
             swap *=(-1);

  }
  else
  {
              rtl_printf("Element recus=%d CUMUL = %d\n", i, (int)cumul);
      swap = 1;
      cumul = 0;
       i = 0;

  }
 }


      pthread_suspend_np(pthread_self());

    }

    rtl_printf("Fin du Thread de lecture du port s�rie.\n" );

   return 0;

}
-------------------------------------------------------------------------



Any idea for this problem ?









L'int�grit� de ce message n'�tant pas assur�e sur Internet, SYNTEGRA ne peut �tre tenu 
responsable de son contenu.
Si vous n'�tes pas destinataire de ce message confidentiel, merci de le d�truire et 
d'avertir imm�diatement l'exp�diteur.

The integrity of this message cannot be guaranteed on the Internet. SYNTEGRA can not 
therefore be considered responsible for the contents.
If you are not the intended recipient of this confidential message, then please delete 
it and notify immediatly the sender.
-- [rtl] ---
To unsubscribe:
echo "unsubscribe rtl" | mail [EMAIL PROTECTED] OR
echo "unsubscribe rtl <Your_email>" | mail [EMAIL PROTECTED]
--
For more information on Real-Time Linux see:
http://www.rtlinux.org/

Reply via email to