0

I am not able to read what i send to serial port, when i randomly generate data, and I want to send it over COM1, and read from COM2 with two different real time threads I used RTAI functions,

Lets say;I send 'H' 'E' 'L' 'L' 'O' some random bytes and 0x01; howeverI cannot read 'H' 'E' 'L' 'L' 'O' some byte and 0x01. I read different values than I send over serial port. What can be the reason? 1-) I am using null modem cable between COM1 and COM2 2-) I have posted writer and reader script sequentially. 3-) Serial port transmitting( writing side) gives an error for rt_sperr, most probably overrun or buffer full error. 4-) i did a replica of this project in the user space, and i encountered a RESOURCE TEMPORARY UNAVAILABLE message, is this related to size of serial port, if so could you suggest me a place to read about adjusting serial port buffer size. Is there any action do you suggest me to take? Best

#include <linux/kernel.h>       
#include <linux/module.h>       
#include <linux/version.h>      
#include "rtai.h"              
#include "rtai_sched.h"      
#include "rtai_sem.h"                 

#include "rtai_serial.h"
#ifndef _P1003_1B_VISIBLE
#define MCL_CURRENT 0x0001
#define MCL_FUTURE 0x0002  
#define _P1003_1B_VISIBLE
#endif
#if ! defined(RT_LOWEST_PRIORITY)
#if defined(RT_SCHED_LOWEST_PRIORITY)
#define RT_LOWEST_PRIORITY RT_SCHED_LOWEST_PRIORITY
#else
#error RT_SCHED_LOWEST_PRIORITY not defined
#endif
#endif
#define TASK_PRIORITY 1
#include <linux/errno.h>       
#include <asm/io.h>              
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,0)
MODULE_LICENSE("GPL");
#endif

#define TICK_PERIOD 10000000
#define STACK_SIZE 1024
#define BAUD 115200  
#define NUMBITS 8
#define STOPBITS 1
#define TWOPWR31M1 2147483647   
static RT_TASK simulator_task;  

static RTIME simulator_period_ns = 31857600;
static RTIME now;
static SEM eben; 


static inline long next_rand(long rand)
{
    const long a = 16807;
    const long m = TWOPWR31M1;
    const long q = 127773;
    const long r = 2836;

    long lo, hi;

    hi = rand/q;
    lo = rand - hi*q;
    rand = a*lo - r*hi;
    if (rand <= 0) {
            rand += m;
    }
    return rand;
    }


   static inline long irandu(unsigned long range)
   {
    static long seed = 783637;
    const long m = TWOPWR31M1;

    seed = next_rand(seed);
    return rtai_imuldiv(seed, range, m);
   }


  void generate_rn(int mean, int std, unsigned int *x){

  unsigned int a=0, b=0;
    unsigned long rand_num=0;
       unsigned long rand_max = 100;
    int fp, ret;
         a=mean-2*std;
     b=mean+2*std;

       rand_num = irandu(rand_max);

         *x = a + ((b-a)*rand_num)/rand_max;
             }



    void simulasyon(long int arg)
    {
    unsigned int unit_data=0 ;
    unsigned int size = 367;
    unsigned char mydata[size];  
    int min=0, max=0;
    int rand_num=0;
    int rand_max = 100;
    int std=1;
    int i;
    int ierr;
    mydata[0] = 'A';  
    mydata[1] = 'S';  
    mydata[2] = 'C';  
    mydata[3] = 'I';  
    mydata[size-1] = 0x01;






   while(1){

   for(i = 4 ; i < size-1 ; i ++){

    generate_rn(i, 1, &unit_data);



            mydata[i] = unit_data;

  }

 //ierr= rt_sem_wait(&eben);  

  rt_spclear_tx(COM1);

  ierr= rt_spwrite_timed(COM1,(void *)mydata, size,
   DELAY_FOREVER);  
  //if(ierr=-1){printk("succes\n");}

  rt_task_wait_period();
   }

   return;
   }


  int init_module(void)
  {
  RTIME simulator_period_count; 
  RTIME timer_period_count;     
  int retval;                  
  int res;
  int mutx;

    res=rt_spopen(COM1, BAUD, NUMBITS, STOPBITS,RT_SP_PARITY_NONE,
    RT_SP_NO_HAND_SHAKE, RT_SP_FIFO_DISABLE);
    if(res) {
   printk("Error: rt_spopen\n");

      switch(res) {
   case -ENODEV:
   printk("No device %d\n", res);
   break;
   case -EINVAL:
   printk("Invalid val %d\n", res);
   break;
   case -EADDRINUSE:
   printk("Address in use %d\n", res);
   break;
   default:
   printk("Unknown %d\n", res);
   break;
       }
   do_exit(0);   }



      //rt_typed_sem_init(&eben, 0, BIN_SEM);

     rt_spclear_tx(COM1);


     rt_set_periodic_mode();


       simulator_period_count = nano2count(simulator_period_ns);
       timer_period_count = start_rt_timer(simulator_period_count);



           retval = rt_task_init(&simulator_task,  
             simulasyon, 
             0,            
             1024,         
             RT_LOWEST_PRIORITY, 
             0,            
             0);           
              if (0 != retval) {
if (-EINVAL == retval) {

  printk("periodic task: task structure already in use\n");
} else if (-ENOMEM == retval) {

  printk("periodic task: can't allocate stack\n");
} else {

  printk("periodic task: error initializing task structure\n");
}
          return retval;
             }

          retval = rt_task_make_periodic(&simulator_task, 
                      rt_get_time() + simulator_period_count,
                      simulator_period_count); 
    if (0 != retval) {
if (-EINVAL == retval) {

  printk("periodic task: task structure is invalid\n");
} else {

  printk("periodic task: error starting task\n");
}
        return retval;
       }

         return 0;
           }

      void cleanup_module(void)
         {
        int retval;

      retval = rt_task_delete(&simulator_task);

       if (0 !=  retval) {
    if (-EINVAL == retval) {

      printk("periodic task: task structure is invalid\n");
    } else {
     printk("periodic task: error stopping task\n");
     }
    }
    //rt_stop_timer();
   //rt_busy_sleep(10000000);
    rt_spclose(COM1);
   //rt_sem_delete(&eben);

    return;
    }



    #include <linux/kernel.h>
    #include <linux/module.h>
    #include <linux/version.h>
    #include "rtai.h"
    #include "rtai_serial.h"
    #include "rtai_sched.h"
    #include "rtai_fifos.h"
    #include <rtai_sem.h>

    #define BAUD 115200
    #define NUMBITS 8
    #define STOPBITS 1

    #define TASK_PRIORITY 1
    #define TICK_PERIOD 10000000
    #define STACK_SIZE 1024

    #if ! defined(RT_LOWEST_PRIORITY)
    #if defined(RT_SCHED_LOWEST_PRIORITY)
    #define RT_LOWEST_PRIORITY RT_SCHED_LOWEST_PRIORITY
    #else
    #error RT_SCHED_LOWEST_PRIORITY not defined
    #endif
    #endif  


   #if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,0)
   MODULE_LICENSE("GPL");
   #endif
   static RTIME tick_period_ns = 31857600;
   static SEM eben; 
   struct rt_task_struct rt_task1;

   static void  task_read (long int arg)
   {

    int i=0;
unsigned char cha[367];
unsigned char mydata[362];

unsigned int max_data_len=367;
unsigned int max_mydata_len=362;

    int ierr;


while(1){
    rt_spclear_rx(COM2);
   //ierr= rt_sem_wait(&eben);
   rt_spread_timed(COM2, (char *) cha , max_data_len, DELAY_FOREVER);

    for (i=0;i<367;i++){
  //ierr=rt_sem_signal(&eben);
  //printk("ch[%d], %d\n", i, ch[i]);
  }


   if (cha[0]=='A'  && cha[1]=='S' && cha[2]=='C' && cha[3]=='I'  &&              cha[size]==0x01 )
    {
        for (i=0;i<362;i++)
        {
            mydata[i]=cha[i+4];     
        rtf_put(0, (char *)mydata, max_mydata_len);             //PUTTING DATA IN FIFO


    }       
    rt_task_wait_period();


}
return;


   }


  int init_module(void)
 {

 int res;
 int retval;
 RTIME tick_period_get;
 RTIME tick_period_count;

 res=rt_spopen(COM2, BAUD, NUMBITS, STOPBITS, RT_SP_PARITY_ODD, RT_SP_NO_HAND_SHAKE, RT_SP_FIFO_DISABLE);


 if(res) {
  printk("Error: rt_spopen\n");

switch(res) {
   case -ENODEV:
   printk("No device %d\n", res);
   break;
   case -EINVAL:
   printk("Invalid val %d\n", res);
   break;
   case -EADDRINUSE:
   printk("Address in use %d\n", res);
   break;
   default:
   printk("Unknown %d\n", res);
   break;
  }
    do_exit(0);
 }

   rt_spclear_rx(COM2);
   retval = rtf_create(0,4096);
   if (retval) {
   printk("could not create RT-FIFO /dev/rtf0\n");
   return retval;
   }
   rtf_reset(0);
   rt_set_periodic_mode();
   tick_period_get = nano2count(tick_period_ns);
   tick_period_count = start_rt_timer(tick_period_get);

rt_typed_sem_init(&eben, 0, BIN_SEM);
    retval=rt_task_init(&rt_task1, task_read, 0, 1024, RT_LOWEST_PRIORITY,0,0);

if (0 != retval) {
    if (-EINVAL == retval) {
        /* task structure is already in use */
        printk("periodic task: task structure already in use\n");
    } else if (-ENOMEM == retval) {
        /* stack could not be allocated */
        printk("periodic task: can't allocate stack\n");
    } else {
        /* unknown error */
        printk("periodic task: error initializing task structure\n");
    }
    return retval;
}



retval = rt_task_make_periodic(&rt_task1, rt_get_time() + tick_period_get, tick_period_get); 
if (0 != retval) {
    if (-EINVAL == retval) {
        /* task structure is already in use */
        printk("periodic task: task structure is invalid\n");
    } else {

        printk("periodic task: error starting task\n");
    }
    return retval;
}




 return 0;   }

 void cleanup_module(void)
 {

//rt_sem_delete(&eben);
 stop_rt_timer();
 rtf_destroy(0);
 rt_task_delete(&rt_task1);
 rt_spclose(COM2); 

 return;
mexes
  • 23
  • 7
  • Well, when you send goes to the DCE device, and what the DCE device sends is what you will receive. You don't receive what you send. And you can't simply connect your two serial ports with a cable, because there is no DCE device. You need a null modem for that. – Ben Voigt Feb 05 '14 at 05:05
  • how are you connecting? Do you cross RX and TX? Do you use the same baudrate? – Thorsten Staerk Feb 05 '14 at 06:00
  • I have a null modem cable, from com1 to com2. I define baudrates in my script as #define Baudrate 112500; for both writer and reader script. My question; if i never be able to read what i send, so how am i gonna install an accurate system. – mexes Feb 05 '14 at 17:33
  • i have put reader code? In reader code, do i need to put a udelay() – mexes Feb 06 '14 at 17:31
  • @ThorstenStaerk I updated with reading script – mexes Feb 06 '14 at 21:35
  • @Ben Voigt I have a null modem cable, from com1 to com2. I define baudrates in my script as #define Baudrate 112500; for both writer and reader script. My question; if i never be able to read what i send, so how am i gonna install an accurate system. – mexes Feb 07 '14 at 18:16
  • @Ben Voigt I do apologize but I couldnt get that; my issue is how to read exactly what I write. – mexes Feb 07 '14 at 19:01
  • @Ben Voigt I didnt use; as can be seen above (i am very sorry) – mexes Feb 07 '14 at 19:04
  • Have you tested the serial port hardware using normal user-mode software (for example, `minicom`)? Have you tried with your kernel code on the sending side and `minicom` on receive side? Have you looked at the data lines with an oscilloscope and/or logic analyzer to make sure the correct timing and data actually went out over the cable? – Ben Voigt Feb 07 '14 at 22:42
  • you are right, i only checked dmesg messages and compared them. due to the huge difference, I raised this question.. King Regards – mexes Feb 07 '14 at 22:45
  • @Ben Voigt I mean; I put rt_spset_err and it gave a message, most probably it is a serial buffer overflow or full message. Right now I am trying to figure out how to overcome "serial port buffer" full problem – mexes Feb 07 '14 at 22:49
  • Did you get "buffer full" from transmit or receive side? Why isn't that information (the error you got) in your question? – Ben Voigt Feb 07 '14 at 22:50
  • I only checked the transmit side – mexes Feb 07 '14 at 22:51
  • I hope the soldering of your connectors is cleaner than your code... – Walter Tross Feb 07 '14 at 22:52
  • @Walter Tross They are fine, real time system works but not accurately – mexes Feb 07 '14 at 23:14
  • @BenVoigt i did a replica of this project in the user space, and i encountered a RESOURCE TEMPORARY UNAVAILABLE message, is this related to size of serial port, if so could you suggest me a place to read about adjusting serial port buffer size. – mexes Feb 12 '14 at 00:42
  • @BenVoigt i tried my code in one thread . it is writing and reading fairly(i used loop back connector) , and read buffer matches write buffer exactly element by element. However when i make two different threads each for writing and reading (write 4 com1 read for com2 via null modem cable) read buffer doesnt match to write buffer? I tried a replica this scenerio in user space with general linux codes;again couldnt read well and it gave me resource temporarily unavailable. Beside hardware issues; what can it be? – mexes Apr 22 '14 at 12:49

0 Answers0