kernel.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /**
  2. * @file kernel.h
  3. * Furi Kernel primitives
  4. */
  5. #pragma once
  6. #include <core/base.h>
  7. #ifdef __cplusplus
  8. extern "C" {
  9. #endif
  10. /** Check if CPU is in IRQ or kernel running and IRQ is masked
  11. *
  12. * Originally this primitive was born as a workaround for FreeRTOS kernel primitives shenanigans with PRIMASK.
  13. *
  14. * Meaningful use cases are:
  15. *
  16. * - When kernel is started and you want to ensure that you are not in IRQ or IRQ is not masked(like in critical section)
  17. * - When kernel is not started and you want to make sure that you are not in IRQ mode, ignoring PRIMASK.
  18. *
  19. * As you can see there will be edge case when kernel is not started and PRIMASK is not 0 that may cause some funky behavior.
  20. * Most likely it will happen after kernel primitives being used, but control not yet passed to kernel.
  21. * It's up to you to figure out if it is safe for your code or not.
  22. *
  23. * @return true if CPU is in IRQ or kernel running and IRQ is masked
  24. */
  25. bool furi_kernel_is_irq_or_masked();
  26. /** Lock kernel, pause process scheduling
  27. *
  28. * @warning This should never be called in interrupt request context.
  29. *
  30. * @return previous lock state(0 - unlocked, 1 - locked)
  31. */
  32. int32_t furi_kernel_lock();
  33. /** Unlock kernel, resume process scheduling
  34. *
  35. * @warning This should never be called in interrupt request context.
  36. *
  37. * @return previous lock state(0 - unlocked, 1 - locked)
  38. */
  39. int32_t furi_kernel_unlock();
  40. /** Restore kernel lock state
  41. *
  42. * @warning This should never be called in interrupt request context.
  43. *
  44. * @param[in] lock The lock state
  45. *
  46. * @return new lock state or error
  47. */
  48. int32_t furi_kernel_restore_lock(int32_t lock);
  49. /** Get kernel systick frequency
  50. *
  51. * @return systick counts per second
  52. */
  53. uint32_t furi_kernel_get_tick_frequency();
  54. /** Delay execution
  55. *
  56. * @warning This should never be called in interrupt request context.
  57. *
  58. * Also keep in mind delay is aliased to scheduler timer intervals.
  59. *
  60. * @param[in] ticks The ticks count to pause
  61. */
  62. void furi_delay_tick(uint32_t ticks);
  63. /** Delay until tick
  64. *
  65. * @warning This should never be called in interrupt request context.
  66. *
  67. * @param[in] ticks The tick until which kerel should delay task execution
  68. *
  69. * @return The furi status.
  70. */
  71. FuriStatus furi_delay_until_tick(uint32_t tick);
  72. /** Get current tick counter
  73. *
  74. * System uptime, may overflow.
  75. *
  76. * @return Current ticks in milliseconds
  77. */
  78. uint32_t furi_get_tick(void);
  79. /** Convert milliseconds to ticks
  80. *
  81. * @param[in] milliseconds time in milliseconds
  82. * @return time in ticks
  83. */
  84. uint32_t furi_ms_to_ticks(uint32_t milliseconds);
  85. /** Delay in milliseconds
  86. *
  87. * This method uses kernel ticks on the inside, which causes delay to be aliased to scheduler timer intervals.
  88. * Real wait time will be between X+ milliseconds.
  89. * Special value: 0, will cause task yield.
  90. * Also if used when kernel is not running will fall back to `furi_delay_us`.
  91. *
  92. * @warning Cannot be used from ISR
  93. *
  94. * @param[in] milliseconds milliseconds to wait
  95. */
  96. void furi_delay_ms(uint32_t milliseconds);
  97. /** Delay in microseconds
  98. *
  99. * Implemented using Cortex DWT counter. Blocking and non aliased.
  100. *
  101. * @param[in] microseconds microseconds to wait
  102. */
  103. void furi_delay_us(uint32_t microseconds);
  104. #ifdef __cplusplus
  105. }
  106. #endif