osal_none.h 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. /**************************************************************************/
  2. /*!
  3. @file osal_none.h
  4. @author hathach (tinyusb.org)
  5. @section LICENSE
  6. Software License Agreement (BSD License)
  7. Copyright (c) 2013, hathach (tinyusb.org)
  8. All rights reserved.
  9. Redistribution and use in source and binary forms, with or without
  10. modification, are permitted provided that the following conditions are met:
  11. 1. Redistributions of source code must retain the above copyright
  12. notice, this list of conditions and the following disclaimer.
  13. 2. Redistributions in binary form must reproduce the above copyright
  14. notice, this list of conditions and the following disclaimer in the
  15. documentation and/or other materials provided with the distribution.
  16. 3. Neither the name of the copyright holders nor the
  17. names of its contributors may be used to endorse or promote products
  18. derived from this software without specific prior written permission.
  19. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
  20. EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  21. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  22. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
  23. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  24. INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  25. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND
  26. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS
  28. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. This file is part of the tinyusb stack.
  30. */
  31. /**************************************************************************/
  32. /** \ingroup group_osal
  33. * \defgroup Group_OSNone None OS
  34. * @{ */
  35. #ifndef _TUSB_OSAL_NONE_H_
  36. #define _TUSB_OSAL_NONE_H_
  37. #include "osal_common.h"
  38. #include "common/tusb_fifo.h"
  39. #ifdef __cplusplus
  40. extern "C" {
  41. #endif
  42. //--------------------------------------------------------------------+
  43. // TASK API
  44. // NOTES: Each blocking OSAL_NONE services such as semaphore wait,
  45. // queue receive embedded return statement, therefore local variable
  46. // retain value before/after such services needed to declare as static
  47. // OSAL_TASK_LOOP
  48. // {
  49. // OSAL_TASK_BEGIN
  50. //
  51. // task body statements
  52. //
  53. // OSAL_TASK_LOOP_ENG
  54. // }
  55. //
  56. // NOTE: no switch statement is allowed in Task and subtask
  57. //--------------------------------------------------------------------+
  58. typedef void (*osal_func_t)(void *param);
  59. typedef void* osal_task_t;
  60. static inline osal_task_t osal_task_create(osal_func_t code, const char* name, uint32_t stack_size, void* param, uint32_t prio)
  61. {
  62. (void) code; (void) name; (void) stack_size; (void) param; (void) prio;
  63. return (osal_task_t) 1;
  64. }
  65. #define TASK_RESTART \
  66. _state = 0
  67. #define OSAL_TASK_BEGIN \
  68. static uint16_t _state = 0; \
  69. ATTR_UNUSED static uint32_t _timeout = 0; \
  70. (void) _timeout; \
  71. switch(_state) { \
  72. case 0: {
  73. #define OSAL_TASK_END \
  74. default: TASK_RESTART; break; \
  75. }}\
  76. return;
  77. #define osal_task_delay(msec) \
  78. do {\
  79. _timeout = tusb_hal_millis();\
  80. _state = __LINE__; case __LINE__:\
  81. if ( _timeout + msec > tusb_hal_millis() ) \
  82. return TUSB_ERROR_OSAL_WAITING;\
  83. }while(0)
  84. //--------------------------------------------------------------------+
  85. // SUBTASK (a sub function that uses OS blocking services & called by a task
  86. //--------------------------------------------------------------------+
  87. #define OSAL_SUBTASK_BEGIN OSAL_TASK_BEGIN
  88. #define OSAL_SUBTASK_END \
  89. default: TASK_RESTART; break; \
  90. }} \
  91. return TUSB_ERROR_NONE;
  92. #define STASK_INVOKE(_subtask, _status) \
  93. do { \
  94. _state = __LINE__; case __LINE__: \
  95. { \
  96. (_status) = _subtask; /* invoke sub task */ \
  97. if (TUSB_ERROR_OSAL_WAITING == (_status)) return TUSB_ERROR_OSAL_WAITING; \
  98. } \
  99. }while(0)
  100. //------------- Sub Task Assert -------------//
  101. #define STASK_RETURN(error) do { TASK_RESTART; return error; } while(0)
  102. #define STASK_ASSERT_ERR(_err) VERIFY_ERR_HDLR(_err, TASK_RESTART)
  103. #define STASK_ASSERT_ERR_HDLR(_err, _func) VERIFY_ERR_HDLR(_err, _func; TASK_RESTART )
  104. #define STASK_ASSERT(_cond) VERIFY_HDLR(_cond, TASK_RESTART)
  105. #define STASK_ASSERT_HDLR(_cond, _func) VERIFY_HDLR(_cond, _func; TASK_RESTART)
  106. //--------------------------------------------------------------------+
  107. // QUEUE API
  108. //--------------------------------------------------------------------+
  109. typedef fifo_t* osal_queue_t;
  110. static inline osal_queue_t osal_queue_create(uint32_t depth, uint32_t item_size)
  111. {
  112. fifo_t* ff = (fifo_t* ) tu_malloc( sizeof(fifo_t) );
  113. uint8_t* buf = (uint8_t*) tu_malloc( depth*item_size );
  114. VERIFY( ff && buf, NULL);
  115. *ff = (fifo_t) {
  116. .buffer = buf, .depth = depth, .item_size = item_size,
  117. .count = 0, .wr_idx =0, .rd_idx = 0, .overwritable = false
  118. };
  119. return (osal_queue_t) ff;
  120. }
  121. static inline bool osal_queue_send(osal_queue_t const queue_hdl, void const * data)
  122. {
  123. return fifo_write( (fifo_t*) queue_hdl, data);
  124. }
  125. static inline void osal_queue_flush(osal_queue_t const queue_hdl)
  126. {
  127. queue_hdl->count = queue_hdl->rd_idx = queue_hdl->wr_idx = 0;
  128. }
  129. #define osal_queue_receive(queue_hdl, p_data, msec, p_error) \
  130. do {\
  131. _timeout = tusb_hal_millis();\
  132. _state = __LINE__; case __LINE__:\
  133. if( queue_hdl->count == 0 ) {\
  134. if ( (msec != OSAL_TIMEOUT_WAIT_FOREVER) && ( _timeout + msec <= tusb_hal_millis()) ) /* time out */ \
  135. *(p_error) = TUSB_ERROR_OSAL_TIMEOUT;\
  136. else\
  137. return TUSB_ERROR_OSAL_WAITING;\
  138. } else{\
  139. /*TODO mutex lock tusb_hal_int_disable */\
  140. memcpy(p_data, queue_hdl->buffer + (queue_hdl->rd_idx * queue_hdl->item_size), queue_hdl->item_size);\
  141. queue_hdl->rd_idx = (queue_hdl->rd_idx + 1) % queue_hdl->depth;\
  142. queue_hdl->count--;\
  143. /*TODO mutex unlock tusb_hal_int_enable */\
  144. *(p_error) = TUSB_ERROR_NONE;\
  145. }\
  146. }while(0)
  147. //--------------------------------------------------------------------+
  148. // Semaphore API
  149. //--------------------------------------------------------------------+
  150. typedef struct
  151. {
  152. volatile uint16_t count;
  153. uint16_t max_count;
  154. }osal_semaphore_data_t;
  155. typedef osal_semaphore_data_t* osal_semaphore_t;
  156. static inline osal_semaphore_t osal_semaphore_create(uint32_t max_count, uint32_t init)
  157. {
  158. osal_semaphore_data_t* sem_data = (osal_semaphore_data_t*) tu_malloc( sizeof(osal_semaphore_data_t));
  159. VERIFY(sem_data, NULL);
  160. sem_data->count = init;
  161. sem_data->max_count = max_count;
  162. return sem_data;
  163. }
  164. static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl)
  165. {
  166. if (sem_hdl->count < sem_hdl->max_count ) sem_hdl->count++;
  167. return true;
  168. }
  169. static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl)
  170. {
  171. sem_hdl->count = 0;
  172. }
  173. #define osal_semaphore_wait(sem_hdl, msec, p_error) \
  174. do {\
  175. _timeout = tusb_hal_millis();\
  176. _state = __LINE__; case __LINE__:\
  177. if( sem_hdl->count == 0 ) {\
  178. if ( (msec != OSAL_TIMEOUT_WAIT_FOREVER) && (_timeout + msec <= tusb_hal_millis()) ) /* time out */ \
  179. *(p_error) = TUSB_ERROR_OSAL_TIMEOUT;\
  180. else\
  181. return TUSB_ERROR_OSAL_WAITING;\
  182. } else{\
  183. if (sem_hdl->count) sem_hdl->count--; /*TODO mutex tusb_hal_int_disable consideration*/\
  184. *(p_error) = TUSB_ERROR_NONE;\
  185. }\
  186. }while(0)
  187. //--------------------------------------------------------------------+
  188. // MUTEX API (priority inheritance)
  189. //--------------------------------------------------------------------+
  190. typedef osal_semaphore_t osal_mutex_t;
  191. static inline osal_mutex_t osal_mutex_create(void)
  192. {
  193. return osal_semaphore_create(1, 0);
  194. }
  195. static inline bool osal_mutex_release(osal_mutex_t mutex_hdl)
  196. {
  197. return osal_semaphore_post(mutex_hdl);
  198. }
  199. // TOOD remove
  200. static inline void osal_mutex_reset(osal_mutex_t mutex_hdl)
  201. {
  202. osal_semaphore_reset(mutex_hdl);
  203. }
  204. #define osal_mutex_wait osal_semaphore_wait
  205. #ifdef __cplusplus
  206. }
  207. #endif
  208. #endif /* _TUSB_OSAL_NONE_H_ */
  209. /** @} */