clock_time_core.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /*
  2. * Copyright (c) 2006-2024, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2025-01-01 RT-Thread Clock time core
  9. */
  10. #include <rthw.h>
  11. #include <rtthread.h>
  12. #include <rtdevice.h>
  13. #include <drivers/clock_time.h>
  14. #define CLOCK_TIME_NSEC_PER_SEC (1000000000ULL)
  15. static rt_uint64_t _clock_time_tick_get_freq(struct rt_clock_time_device *dev)
  16. {
  17. RT_UNUSED(dev);
  18. return RT_TICK_PER_SECOND;
  19. }
  20. static rt_uint64_t _clock_time_tick_get_counter(struct rt_clock_time_device *dev)
  21. {
  22. RT_UNUSED(dev);
  23. return (rt_uint64_t)rt_tick_get();
  24. }
  25. static rt_err_t _clock_time_tick_set_timeout(struct rt_clock_time_device *dev, rt_uint64_t delta)
  26. {
  27. RT_UNUSED(dev);
  28. RT_UNUSED(delta);
  29. return -RT_ENOSYS;
  30. }
  31. static const struct rt_clock_time_ops _clock_time_tick_ops =
  32. {
  33. _clock_time_tick_get_freq,
  34. _clock_time_tick_get_counter,
  35. _clock_time_tick_set_timeout,
  36. };
  37. static struct rt_clock_time_device _clock_time_tick_dev =
  38. {
  39. .ops = &_clock_time_tick_ops,
  40. .res_scale = RT_CLOCK_TIME_RESMUL,
  41. .caps = RT_CLOCK_TIME_CAP_SOURCE,
  42. };
  43. static struct rt_clock_time_device * _clock_time_default_source = &_clock_time_tick_dev;
  44. static struct rt_clock_time_device * _clock_time_default_event = RT_NULL;
  45. rt_weak void rt_clock_time_source_init(void)
  46. {
  47. return;
  48. }
  49. static rt_uint64_t _clock_time_get_res_scaled(struct rt_clock_time_device *dev)
  50. {
  51. rt_uint64_t freq;
  52. rt_uint64_t scale;
  53. if (dev == RT_NULL || dev->ops == RT_NULL || dev->ops->get_freq == RT_NULL)
  54. {
  55. return 0;
  56. }
  57. freq = dev->ops->get_freq(dev);
  58. if (freq == 0)
  59. {
  60. return 0;
  61. }
  62. scale = dev->res_scale ? dev->res_scale : RT_CLOCK_TIME_RESMUL;
  63. return (CLOCK_TIME_NSEC_PER_SEC * scale) / freq;
  64. }
  65. rt_err_t rt_clock_time_device_register(struct rt_clock_time_device *dev, const char *name, rt_uint8_t caps)
  66. {
  67. rt_err_t result = RT_EOK;
  68. RT_ASSERT(dev != RT_NULL);
  69. RT_ASSERT(dev->ops != RT_NULL);
  70. dev->caps = caps;
  71. if (dev->res_scale == 0)
  72. {
  73. dev->res_scale = RT_CLOCK_TIME_RESMUL;
  74. }
  75. if (name != RT_NULL)
  76. {
  77. dev->parent.type = RT_Device_Class_Timer;
  78. result = rt_device_register(&dev->parent, name,
  79. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE);
  80. }
  81. if ((caps & RT_CLOCK_TIME_CAP_SOURCE) && _clock_time_default_source == &_clock_time_tick_dev)
  82. {
  83. _clock_time_default_source = dev;
  84. }
  85. if ((caps & RT_CLOCK_TIME_CAP_EVENT) && _clock_time_default_event == RT_NULL)
  86. {
  87. _clock_time_default_event = dev;
  88. }
  89. return result;
  90. }
  91. void rt_clock_time_set_default_source(struct rt_clock_time_device *dev)
  92. {
  93. if (dev != RT_NULL)
  94. {
  95. _clock_time_default_source = dev;
  96. }
  97. }
  98. void rt_clock_time_set_default_event(struct rt_clock_time_device *dev)
  99. {
  100. if (dev != RT_NULL)
  101. {
  102. _clock_time_default_event = dev;
  103. }
  104. }
  105. struct rt_clock_time_device *rt_clock_time_get_default_source(void)
  106. {
  107. return _clock_time_default_source ? _clock_time_default_source : &_clock_time_tick_dev;
  108. }
  109. struct rt_clock_time_device *rt_clock_time_get_default_event(void)
  110. {
  111. return _clock_time_default_event;
  112. }
  113. rt_uint64_t rt_clock_time_get_freq(void)
  114. {
  115. struct rt_clock_time_device *src = rt_clock_time_get_default_source();
  116. if (src == RT_NULL || src->ops == RT_NULL || src->ops->get_freq == RT_NULL)
  117. {
  118. return 0;
  119. }
  120. return src->ops->get_freq(src);
  121. }
  122. rt_uint64_t rt_clock_time_get_counter(void)
  123. {
  124. struct rt_clock_time_device *src = rt_clock_time_get_default_source();
  125. if (src == RT_NULL || src->ops == RT_NULL || src->ops->get_counter == RT_NULL)
  126. {
  127. return 0;
  128. }
  129. return src->ops->get_counter(src);
  130. }
  131. rt_uint64_t rt_clock_time_get_res_scaled(void)
  132. {
  133. return _clock_time_get_res_scaled(rt_clock_time_get_default_source());
  134. }
  135. rt_uint64_t rt_clock_time_get_event_freq(void)
  136. {
  137. struct rt_clock_time_device *event = rt_clock_time_get_default_event();
  138. if (event == RT_NULL)
  139. {
  140. return rt_clock_time_get_freq();
  141. }
  142. if (event->ops == RT_NULL || event->ops->get_freq == RT_NULL)
  143. {
  144. return 0;
  145. }
  146. return event->ops->get_freq(event);
  147. }
  148. rt_uint64_t rt_clock_time_get_event_res_scaled(void)
  149. {
  150. struct rt_clock_time_device *event = rt_clock_time_get_default_event();
  151. if (event == RT_NULL)
  152. {
  153. return rt_clock_time_get_res_scaled();
  154. }
  155. return _clock_time_get_res_scaled(event);
  156. }
  157. rt_uint64_t rt_clock_time_counter_to_ns(rt_uint64_t cnt)
  158. {
  159. rt_uint64_t res = rt_clock_time_get_res_scaled();
  160. if (res == 0)
  161. {
  162. return 0;
  163. }
  164. return (cnt * res) / RT_CLOCK_TIME_RESMUL;
  165. }
  166. rt_uint64_t rt_clock_time_ns_to_counter(rt_uint64_t ns)
  167. {
  168. rt_uint64_t res = rt_clock_time_get_res_scaled();
  169. if (res == 0)
  170. {
  171. return 0;
  172. }
  173. return (ns * RT_CLOCK_TIME_RESMUL) / res;
  174. }
  175. rt_err_t rt_clock_time_set_timeout(rt_uint64_t delta)
  176. {
  177. struct rt_clock_time_device *event = rt_clock_time_get_default_event();
  178. if (event == RT_NULL || event->ops == RT_NULL || event->ops->set_timeout == RT_NULL)
  179. {
  180. return -RT_ENOSYS;
  181. }
  182. return event->ops->set_timeout(event, delta);
  183. }