1 /*
2  * Copyright (C) 2015-2017 Alibaba Group Holding Limited
3  */
4 
5 #ifndef K_MM_RINGBUF_H
6 #define K_MM_RINGBUF_H
7 
8 #ifdef __cplusplus
9 extern "C" {
10 #endif
11 
12 /** @addtogroup aos_rhino ringbuf
13  *  Ringbuf is a FIFO communication mechanism.
14  *
15  *  @{
16  */
17 
18 /**
19  * The msg size of each push and pop operation is fixed, and it is determined at initialization
20  */
21 #define RINGBUF_TYPE_FIX 0
22 /**
23  * The msg size of each push and pop operation is not fixed
24  */
25 #define RINGBUF_TYPE_DYN 1
26 
27 /**
28  * ringbuf object
29  */
30 typedef struct {
31     uint8_t *buf;
32     uint8_t *end;
33     uint8_t *head;
34     uint8_t *tail;
35     size_t   freesize;
36     size_t   type;      /**< RINGBUF_TYPE_FIX or RINGBUF_TYPE_DYN */
37     size_t   blk_size;
38 } k_ringbuf_t;
39 
40 /**
41  * Push a msg to the ring.
42  *
43  * @param[in] p_ringbuf pointer to the ringbuf
44  * @param[in] data      data address
45  * @param[in] len       data length
46  *
47  * @return the operation status, RHINO_SUCCESS is OK, others is error
48  */
ringbuf_queue_push(k_ringbuf_t * p_ringbuf,void * data,size_t len)49 RHINO_INLINE kstat_t ringbuf_queue_push(k_ringbuf_t *p_ringbuf, void *data, size_t len)
50 {
51     if (p_ringbuf->tail == p_ringbuf->end) {
52         p_ringbuf->tail = p_ringbuf->buf;
53     }
54 
55     memcpy(p_ringbuf->tail, data, p_ringbuf->blk_size);
56     p_ringbuf->tail += p_ringbuf->blk_size;
57 
58     return RHINO_SUCCESS;
59 }
60 
61 /**
62  * Pop a msg from the ring.
63  *
64  * @param[in] p_ringbuf pointer to the ringbuf
65  * @param[in] pdata     data address
66  * @param[out] plen     data length
67  *
68  * @return the operation status, RHINO_SUCCESS is OK, others is error
69  */
ringbuf_queue_pop(k_ringbuf_t * p_ringbuf,void * pdata,size_t * plen)70 RHINO_INLINE kstat_t ringbuf_queue_pop(k_ringbuf_t *p_ringbuf, void *pdata, size_t *plen)
71 {
72     if (p_ringbuf->head == p_ringbuf->end) {
73         p_ringbuf->head = p_ringbuf->buf;
74     }
75 
76     memcpy(pdata, p_ringbuf->head, p_ringbuf->blk_size);
77     p_ringbuf->head += p_ringbuf->blk_size;
78 
79     if (plen != NULL) {
80         *plen = p_ringbuf->blk_size;
81     }
82 
83     return RHINO_SUCCESS;
84 }
85 
86 /** @} */
87 
88 #ifdef __cplusplus
89 }
90 #endif
91 
92 #endif /* K_RINGBUF_H */
93 
94