text: #ifndef DATAQUEUE_H__
  #define DATAQUEUE_H__
  
  #include <rtthread.h>
  
  #define RT_DATAQUEUE_EVENT_UNKNOWN   0x00
  #define RT_DATAQUEUE_EVENT_POP       0x01
  #define RT_DATAQUEUE_EVENT_PUSH      0x02
  #define RT_DATAQUEUE_EVENT_LWM       0x03
  
  struct rt_data_item;
  #define RT_DATAQUEUE_SIZE(dq)        ((dq)->put_index - (dq)->get_index)
  #define RT_DATAQUEUE_EMPTY(dq)       ((dq)->size - RT_DATAQUEUE_SIZE(dq))
  /* data queue implementation */
  struct rt_data_queue
  {
      rt_uint16_t size;
      rt_uint16_t lwm;
      rt_bool_t   waiting_lwm;
  
      rt_uint16_t get_index;
      rt_uint16_t put_index;
  
      struct rt_data_item *queue;
  
      rt_list_t suspended_push_list;
      rt_list_t suspended_pop_list;
  
      /* event notify */
      void (*evt_notify)(struct rt_data_queue *queue, rt_uint32_t event);
  };
  
  /**
   * DataQueue for DeviceDriver
   */
  rt_err_t rt_data_queue_init(struct rt_data_queue *queue,
                              rt_uint16_t           size,
                              rt_uint16_t           lwm,
                              void (*evt_notify)(struct rt_data_queue *queue, rt_uint32_t event));
  rt_err_t rt_data_queue_push(struct rt_data_queue *queue,
                              const void           *data_ptr,
                              rt_size_t             data_size,
                              rt_int32_t            timeout);
  rt_err_t rt_data_queue_pop(struct rt_data_queue *queue,
                             const void          **data_ptr,
                             rt_size_t            *size,
                             rt_int32_t            timeout);
  rt_err_t rt_data_queue_peak(struct rt_data_queue *queue,
                              const void          **data_ptr,
                              rt_size_t            *size);
  void rt_data_queue_reset(struct rt_data_queue *queue);
  
  #endif
  