scheduler.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /*
  2. * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
  3. */
  4. #include <gtest/gtest.h>
  5. #include <uavcan/node/timer.hpp>
  6. #include <uavcan/util/method_binder.hpp>
  7. #include "../clock.hpp"
  8. #include "../transport/can/can.hpp"
  9. #include "test_node.hpp"
  10. #if !defined(UAVCAN_CPP11) || !defined(UAVCAN_CPP_VERSION)
  11. # error UAVCAN_CPP_VERSION
  12. #endif
  13. struct TimerCallCounter
  14. {
  15. std::vector<uavcan::TimerEvent> events_a;
  16. std::vector<uavcan::TimerEvent> events_b;
  17. void callA(const uavcan::TimerEvent& ev) { events_a.push_back(ev); }
  18. void callB(const uavcan::TimerEvent& ev) { events_b.push_back(ev); }
  19. typedef uavcan::MethodBinder<TimerCallCounter*, void (TimerCallCounter::*)(const uavcan::TimerEvent&)> Binder;
  20. Binder bindA() { return Binder(this, &TimerCallCounter::callA); }
  21. Binder bindB() { return Binder(this, &TimerCallCounter::callB); }
  22. };
  23. /*
  24. * This test can fail on a non real time system. That's kinda sad but okay.
  25. */
  26. TEST(Scheduler, Timers)
  27. {
  28. SystemClockDriver clock_driver;
  29. CanDriverMock can_driver(2, clock_driver);
  30. TestNode node(can_driver, clock_driver, 1);
  31. /*
  32. * Registration
  33. */
  34. {
  35. TimerCallCounter tcc;
  36. uavcan::TimerEventForwarder<TimerCallCounter::Binder> a(node, tcc.bindA());
  37. uavcan::TimerEventForwarder<TimerCallCounter::Binder> b(node, tcc.bindB());
  38. ASSERT_EQ(0, node.getScheduler().getDeadlineScheduler().getNumHandlers());
  39. const uavcan::MonotonicTime start_ts = clock_driver.getMonotonic();
  40. a.startOneShotWithDeadline(start_ts + durMono(100000));
  41. b.startPeriodic(durMono(1000));
  42. ASSERT_EQ(2, node.getScheduler().getDeadlineScheduler().getNumHandlers());
  43. /*
  44. * Spinning
  45. */
  46. ASSERT_EQ(0, node.spin(start_ts + durMono(1000000)));
  47. ASSERT_EQ(1, tcc.events_a.size());
  48. ASSERT_TRUE(areTimestampsClose(tcc.events_a[0].scheduled_time, start_ts + durMono(100000)));
  49. ASSERT_TRUE(areTimestampsClose(tcc.events_a[0].scheduled_time, tcc.events_a[0].real_time));
  50. ASSERT_LT(900, tcc.events_b.size());
  51. ASSERT_GT(1100, tcc.events_b.size());
  52. {
  53. uavcan::MonotonicTime next_expected_deadline = start_ts + durMono(1000);
  54. for (unsigned i = 0; i < tcc.events_b.size(); i++)
  55. {
  56. ASSERT_TRUE(areTimestampsClose(tcc.events_b[i].scheduled_time, next_expected_deadline));
  57. ASSERT_TRUE(areTimestampsClose(tcc.events_b[i].scheduled_time, tcc.events_b[i].real_time));
  58. next_expected_deadline += durMono(1000);
  59. }
  60. }
  61. /*
  62. * Deinitialization
  63. */
  64. ASSERT_EQ(1, node.getScheduler().getDeadlineScheduler().getNumHandlers());
  65. ASSERT_FALSE(a.isRunning());
  66. ASSERT_EQ(uavcan::MonotonicDuration::getInfinite(), a.getPeriod());
  67. ASSERT_TRUE(b.isRunning());
  68. ASSERT_EQ(1000, b.getPeriod().toUSec());
  69. }
  70. ASSERT_EQ(0, node.getScheduler().getDeadlineScheduler().getNumHandlers()); // Both timers were destroyed by now
  71. ASSERT_EQ(0, node.spin(durMono(1000))); // Spin some more without timers
  72. }
  73. #if UAVCAN_CPP_VERSION >= UAVCAN_CPP11
  74. TEST(Scheduler, TimerCpp11)
  75. {
  76. SystemClockDriver clock_driver;
  77. CanDriverMock can_driver(2, clock_driver);
  78. TestNode node(can_driver, clock_driver, 1);
  79. int count = 0;
  80. uavcan::Timer tm(node, [&count](const uavcan::TimerEvent&) { count++; });
  81. ASSERT_EQ(0, node.getScheduler().getDeadlineScheduler().getNumHandlers());
  82. tm.startPeriodic(uavcan::MonotonicDuration::fromMSec(10));
  83. ASSERT_EQ(1, node.getScheduler().getDeadlineScheduler().getNumHandlers());
  84. ASSERT_EQ(0, node.spin(uavcan::MonotonicDuration::fromMSec(100)));
  85. std::cout << count << std::endl;
  86. ASSERT_LE(5, count);
  87. ASSERT_GE(15, count);
  88. }
  89. #endif