You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

167 lines
4.0KB

  1. /*
  2. * ppstest.c -- simple tool to monitor PPS timestamps
  3. *
  4. * Copyright (C) 2005-2007 Rodolfo Giometti <giometti@linux.it>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. */
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <unistd.h>
  19. #include <fcntl.h>
  20. #include <sys/types.h>
  21. #include <sys/stat.h>
  22. #include "timepps.h"
  23. static struct timespec offset_assert = {0, 0};
  24. int find_source(char *path, pps_handle_t *handle, int *avail_mode)
  25. {
  26. pps_params_t params;
  27. int ret;
  28. printf("trying PPS source \"%s\"\n", path);
  29. /* Try to find the source by using the supplied "path" name */
  30. ret = open(path, O_RDWR);
  31. if (ret < 0) {
  32. fprintf(stderr, "unable to open device \"%s\" (%m)\n", path);
  33. return ret;
  34. }
  35. /* Open the PPS source (and check the file descriptor) */
  36. ret = time_pps_create(ret, handle);
  37. if (ret < 0) {
  38. fprintf(stderr, "cannot create a PPS source from device "
  39. "\"%s\" (%m)\n", path);
  40. return -1;
  41. }
  42. printf("found PPS source \"%s\"\n", path);
  43. /* Find out what features are supported */
  44. ret = time_pps_getcap(*handle, avail_mode);
  45. if (ret < 0) {
  46. fprintf(stderr, "cannot get capabilities (%m)\n");
  47. return -1;
  48. }
  49. if ((*avail_mode & PPS_CAPTUREASSERT) == 0) {
  50. fprintf(stderr, "cannot CAPTUREASSERT\n");
  51. return -1;
  52. }
  53. /* Capture assert timestamps */
  54. ret = time_pps_getparams(*handle, &params);
  55. if (ret < 0) {
  56. fprintf(stderr, "cannot get parameters (%m)\n");
  57. return -1;
  58. }
  59. params.mode |= PPS_CAPTUREASSERT;
  60. /* Override any previous offset if possible */
  61. if ((*avail_mode & PPS_OFFSETASSERT) != 0) {
  62. params.mode |= PPS_OFFSETASSERT;
  63. params.assert_offset = offset_assert;
  64. }
  65. ret = time_pps_setparams(*handle, &params);
  66. if (ret < 0) {
  67. fprintf(stderr, "cannot set parameters (%m)\n");
  68. return -1;
  69. }
  70. return 0;
  71. }
  72. int fetch_source(int i, pps_handle_t *handle, int *avail_mode)
  73. {
  74. struct timespec timeout;
  75. pps_info_t infobuf;
  76. int ret;
  77. /* create a zero-valued timeout */
  78. timeout.tv_sec = 3;
  79. timeout.tv_nsec = 0;
  80. retry:
  81. if (*avail_mode & PPS_CANWAIT) /* waits for the next event */
  82. ret = time_pps_fetch(*handle, PPS_TSFMT_TSPEC, &infobuf,
  83. &timeout);
  84. else {
  85. sleep(1);
  86. ret = time_pps_fetch(*handle, PPS_TSFMT_TSPEC, &infobuf,
  87. &timeout);
  88. }
  89. if (ret < 0) {
  90. if (ret == -EINTR) {
  91. fprintf(stderr, "time_pps_fetch() got a signal!\n");
  92. goto retry;
  93. }
  94. fprintf(stderr, "time_pps_fetch() error %d (%m)\n", ret);
  95. return -1;
  96. }
  97. printf("source %d - "
  98. "assert %ld.%09ld, sequence: %ld - "
  99. "clear %ld.%09ld, sequence: %ld\n",
  100. i,
  101. infobuf.assert_timestamp.tv_sec,
  102. infobuf.assert_timestamp.tv_nsec,
  103. infobuf.assert_sequence,
  104. infobuf.clear_timestamp.tv_sec,
  105. infobuf.clear_timestamp.tv_nsec, infobuf.clear_sequence);
  106. fflush(stdout);
  107. return 0;
  108. }
  109. void usage(char *name)
  110. {
  111. fprintf(stderr, "usage: %s <ppsdev> [<ppsdev> ...]\n", name);
  112. exit(EXIT_FAILURE);
  113. }
  114. int main(int argc, char *argv[])
  115. {
  116. int num;
  117. pps_handle_t handle[4];
  118. int avail_mode[4];
  119. int i = 0;
  120. int ret;
  121. /* Check the command line */
  122. if (argc < 2)
  123. usage(argv[0]);
  124. for (i = 1; i < argc && i <= 4; i++) {
  125. ret = find_source(argv[i], &handle[i - 1], &avail_mode[i - 1]);
  126. if (ret < 0)
  127. exit(EXIT_FAILURE);
  128. }
  129. num = i - 1;
  130. printf("ok, found %d source(s), now start fetching data...\n", num);
  131. /* loop, printing the most recent timestamp every second or so */
  132. while (1) {
  133. for (i = 0; i < num; i++) {
  134. ret = fetch_source(i, &handle[i], &avail_mode[i]);
  135. if (ret < 0 && errno != ETIMEDOUT)
  136. exit(EXIT_FAILURE);
  137. }
  138. }
  139. for (; i >= 0; i--)
  140. time_pps_destroy(handle[i]);
  141. return 0;
  142. }