counter_example.c 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /* Counter - example userspace application
  3. *
  4. * The userspace application opens /dev/counter0, configures the
  5. * COUNTER_EVENT_INDEX event channel 0 to gather Count 0 count and Count
  6. * 1 count, and prints out the data as it becomes available on the
  7. * character device node.
  8. *
  9. * Copyright (C) 2021 William Breathitt Gray
  10. */
  11. #include <errno.h>
  12. #include <fcntl.h>
  13. #include <linux/counter.h>
  14. #include <stdio.h>
  15. #include <string.h>
  16. #include <sys/ioctl.h>
  17. #include <unistd.h>
  18. static struct counter_watch watches[2] = {
  19. {
  20. /* Component data: Count 0 count */
  21. .component.type = COUNTER_COMPONENT_COUNT,
  22. .component.scope = COUNTER_SCOPE_COUNT,
  23. .component.parent = 0,
  24. /* Event type: Index */
  25. .event = COUNTER_EVENT_INDEX,
  26. /* Device event channel 0 */
  27. .channel = 0,
  28. },
  29. {
  30. /* Component data: Count 1 count */
  31. .component.type = COUNTER_COMPONENT_COUNT,
  32. .component.scope = COUNTER_SCOPE_COUNT,
  33. .component.parent = 1,
  34. /* Event type: Index */
  35. .event = COUNTER_EVENT_INDEX,
  36. /* Device event channel 0 */
  37. .channel = 0,
  38. },
  39. };
  40. int main(void)
  41. {
  42. int fd;
  43. int ret;
  44. int i;
  45. struct counter_event event_data[2];
  46. fd = open("/dev/counter0", O_RDWR);
  47. if (fd == -1) {
  48. perror("Unable to open /dev/counter0");
  49. return 1;
  50. }
  51. for (i = 0; i < 2; i++) {
  52. ret = ioctl(fd, COUNTER_ADD_WATCH_IOCTL, watches + i);
  53. if (ret == -1) {
  54. fprintf(stderr, "Error adding watches[%d]: %s\n", i,
  55. strerror(errno));
  56. return 1;
  57. }
  58. }
  59. ret = ioctl(fd, COUNTER_ENABLE_EVENTS_IOCTL);
  60. if (ret == -1) {
  61. perror("Error enabling events");
  62. return 1;
  63. }
  64. for (;;) {
  65. ret = read(fd, event_data, sizeof(event_data));
  66. if (ret == -1) {
  67. perror("Failed to read event data");
  68. return 1;
  69. }
  70. if (ret != sizeof(event_data)) {
  71. fprintf(stderr, "Failed to read event data\n");
  72. return -EIO;
  73. }
  74. printf("Timestamp 0: %llu\tCount 0: %llu\n"
  75. "Error Message 0: %s\n"
  76. "Timestamp 1: %llu\tCount 1: %llu\n"
  77. "Error Message 1: %s\n",
  78. event_data[0].timestamp, event_data[0].value,
  79. strerror(event_data[0].status),
  80. event_data[1].timestamp, event_data[1].value,
  81. strerror(event_data[1].status));
  82. }
  83. return 0;
  84. }