> 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