> Hi Gilles,
>
> The following is some part of the code. It is receiving data at a period of
> 1 second intervals. The variable "lat" prints similar latency values for
> the current session, even though I stop the program and start again several
> times. The latency values change everytime I reboot the PC. Please
> advise.

I do not understand:
- how the "latency" may be 40us while it should be around 1s, if you say
that the periodic event happens every second;
- whether you are compiling for the native skin or posix skin, could you
show us the compilation arguments you pass?
- on what platform you get this issue?

-- 
Gilles.



Hello Gilles,

Sorry for any confusion, here are the responses to your questions:

The
 "latency" or time elapsed between events recieved on the serial port 
should ideally be 1 second. However the system will have some
 latency jitter, therefore I would expect the delay to be 1 second +- 
some number of microseconds.

Using the attached program running 
on an x86 system I see a "latency" of 1 second + some variable number of
 microseconds. Each time I reboot the system the variable number of 
micro seconds changes anywhere from 40 to 100 microseconds. The total 
latency is always greater than 1 second.

I know that the pulse 
generated by the function generator ( Agilent 33220A ) is acurrate to 1 
microsecond. This unit has also been recently calibrated.

How is 
this possible? Is it possible that the clock I am using on the x86 
system to capture timing is faster than the clock used on the function 
generator?

I am compiling using the POSIX skin. The compilation arguments are:

CFLAGS+= -g $(shell $(XENOCONFIG) --skin=posix --cflags) $(APP_CFLAGS)

LDFLAGS+= $(shell $(XENOCONFIG) --skin=posix --ldflags) $(APP_LDFLAGS)
 \
-L$(BUILD_ROOT)/usr/xenomai/lib -lrtdm -lrt


The results have been repeated on two different systems:

root@phi:/min3/test/rthr# lscpu
Architecture: i686
CPU op-mode(s): 32-bit, 64-bit
CPU(s): 2
Thread(s) per core: 1
Core(s) per socket: 2
CPU socket(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 15
Stepping: 6
CPU MHz: 1000.000
Virtualization: VT-x
L1d cache: 32K
L1i cache: 32K
L2 cache: 4096K

root@phi:/min3/test/rthr# lscpu
Architecture: i686
CPU op-mode(s): 32-bit
CPU(s): 2
Thread(s) per core: 2
Core(s) per socket: 1
CPU socket(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 28
Stepping: 2
CPU MHz: 1599.820
Virtualization: VT-x
L1d cache: 24K
L1i cache: 32K
L2 cache: 512K


Here is my complete program:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include
 <posix/time.h>
#include <fcntl.h>
#include <posix/posix.h>
#include <rtdm/rtserial.h>


//******************
// Global defines
//******************
#define DEVICE_NAME "rtser0"

//***********************
// Global Structures
//***********************
struct rtser_config set_config =
{
.config_mask = 0xFFFF,
.baud_rate = 9600,
.parity = RTSER_DEF_PARITY,
.data_bits = RTSER_DEF_BITS,
.stop_bits = RTSER_DEF_STOPB,
.handshake = RTSER_DEF_HAND,
.fifo_depth = RTSER_FIFO_DEPTH_8,
.rx_timeout = RTSER_DEF_TIMEOUT,
.tx_timeout = RTSER_DEF_TIMEOUT,
.event_timeout = 6000000000, /* 6 s */
.timestamp_history = RTSER_RX_TIMESTAMP_HISTORY,
.event_mask = RTSER_EVENT_MODEMHI,
};

static int device_fd = -1;


//***********************************************************
//
// int open_serial_port(void)
//
// rt_dev_ioctl returns - Positive
 value on success,
// negative error code.
//
// rt_dev_open returns - Positive value on success,
// negative error code
//
//***********************************************************
static int open_serial_port(void)
{
int err = 0;

// Open RT Serial Port
device_fd = rt_dev_open(DEVICE_NAME, 0);
if (device_fd < 0)
{

printf("\nopen_serial_port => can't open %s (write), %s\n", DEVICE_NAME,
strerror(-device_fd));
return device_fd;
}

printf("\nopen_serial_port => opened\n");


// Setting port config
err = rt_dev_ioctl(device_fd, RTSER_RTIOC_SET_CONFIG, &set_config);
if (err < 0)
{
printf("open_serial_port => error while RTSER_RTIOC_SET_CONFIG, %s\n",
strerror(-err));
return err;
}

printf("open_serial_port => port config set\n");

return
 err;
}



/************************************************************
*
* int get_args(int argc, char *argv[])
*
************************************************************/
int get_args(int argc, char *argv[])
{
int c = 0;
int ok = -1;

while (ok != 0)
{
if ( argc == 0 ) 
{
printf("usage: %s filename", argv[0]);
}
else
{
while ((c = getopt (argc, argv, "bd")) != -1)
{
switch (c)
{
case 'b':
set_config.baud_rate = atoi(argv[2]);
printf("get_args => baud_rate set to %d\n", atoi(argv[2]));
break;

case 'd':
set_config.data_bits = atoi(argv[4]);
printf("get_args => data bit set to %d\n", atoi(argv[4]));
break;

default:
break;
}
}

ok =0;
}
}
return ok;
}

//***********************************************************
//
// void
 cleanup_all(void)
//
//***********************************************************
static void cleanup_all(void)
{
rt_dev_close(device_fd); // close serial port
printf("cleanup_all => close port and/or cancel pthread\n");
}


//***********************************************************
//
// struct timespec calc_time(struct timespec start,
// struct timespec end)
//
//
//***********************************************************
struct timespec calc_time(struct timespec start, struct timespec end)
{
struct timespec temp;

if ((end.tv_nsec - start.tv_nsec) < 0) {
temp.tv_sec = end.tv_sec - start.tv_sec - 1;
temp.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec;
} else {
temp.tv_sec = end.tv_sec - start.tv_sec;
temp.tv_nsec = end.tv_nsec - start.tv_nsec;
}
return temp;
}

//***********************************************************
//
// int
 main(void)
//
// clock_settime returns - 0 on success, -1 if failed.
//***********************************************************

int main (int argc, char *argv[])
{
int rtn_code = 0;
struct timespec res;
int stat = 0;
int err = 0;
struct rtser_event rx_event;

struct timespec curr_time;
struct timespec prev_time;
struct timespec elapsed_time;
double lat = 0.0;

// Process arguments from command line
rtn_code = get_args(argc, argv);

// No memory-swapping for this program
mlockall(MCL_CURRENT | MCL_FUTURE);

// Open serial port
rtn_code = open_serial_port();
if (rtn_code < 0)
goto error;

stat = clock_getres(CLOCK_MONOTONIC, &res);
printf("clock resolution => %d %ld\n", (int)res.tv_sec, res.tv_nsec);

rx_event.events = RTSER_EVENT_MODEMHI;

// part of code in main function

while (1)
{ 
// waiting for event from the serial
 driver
err = rt_dev_ioctl(device_fd, RTSER_RTIOC_WAIT_EVENT, &rx_event);
if (err < 0)
{
printf("serial_recv -> error on RTSER_RTIOC_WAIT_EVENT, %s\n",
strerror(-err));
} 
else if (clock_gettime(CLOCK_MONOTONIC, &curr_time) == -1)
perror("clock gettinme");

// elapsed time between previous and current message
elapsed_time = calc_time(prev_time, curr_time);

// Convert to seconds
lat = elapsed_time.tv_sec + elapsed_time.tv_nsec/1000000000.0;

prev_time = curr_time;

printf("%d", (int)curr_time.tv_sec);
printf(" %ld", curr_time.tv_nsec);
printf(" %lf\n", lat);
}

error:
cleanup_all();
return rtn_code;

}


Please advise.

Thank you,

Philip Ha
_______________________________________________
Xenomai-help mailing list
Xenomai-help@gna.org
https://mail.gna.org/listinfo/xenomai-help

Reply via email to