> 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
[email protected]
https://mail.gna.org/listinfo/xenomai-help