ringbuff_stream.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. /*
  2. * Copyright (c) 2019 Actions Semiconductor Co., Ltd
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. /**
  7. * @file psram stream interface
  8. */
  9. #define SYS_LOG_DOMAIN "ringstream"
  10. #include <mem_manager.h>
  11. #include <string.h>
  12. #include <stdlib.h>
  13. #include <stdio.h>
  14. #include "ringbuff_stream.h"
  15. #include "stream_internal.h"
  16. /**ringbff info */
  17. typedef struct
  18. {
  19. struct acts_ringbuf *buf;
  20. } ringbuff_info_t;
  21. #define RINGBUFFER_STREAM_IMAG_NUM 0x55
  22. static int ringbuff_stream_open(io_stream_t handle,stream_mode mode)
  23. {
  24. ringbuff_info_t *info = (ringbuff_info_t *)handle->data;
  25. if(!info)
  26. return -EACCES;
  27. handle->mode = mode;
  28. return 0;
  29. }
  30. static int ringbuff_stream_read(io_stream_t handle, unsigned char *buf, int len)
  31. {
  32. int ret = 0;
  33. ringbuff_info_t *info = (ringbuff_info_t *)handle->data;
  34. if (!info)
  35. return -EACCES;
  36. ret = acts_ringbuf_get(info->buf, buf, len);
  37. if (ret != len) {
  38. //SYS_LOG_WRN("want read %d bytes ,but only read %d bytes \n",len,ret);
  39. }
  40. handle->rofs = info->buf->head;
  41. handle->wofs = info->buf->tail;
  42. return ret;
  43. }
  44. static int ringbuff_stream_write(io_stream_t handle, unsigned char *buf, int len)
  45. {
  46. int ret = 0;
  47. ringbuff_info_t *info = (ringbuff_info_t *)handle->data;
  48. if (!info)
  49. return -EACCES;
  50. /**fill none when buf is NULL, allow user modify write offset only*/
  51. if (!buf) {
  52. ret = acts_ringbuf_fill_none(info->buf, len);
  53. } else {
  54. ret = acts_ringbuf_put(info->buf, buf, len);
  55. }
  56. if (ret != len) {
  57. //SYS_LOG_WRN("want write %d bytes ,but only write %d bytes \n",len,ret);
  58. }
  59. handle->rofs = info->buf->head;
  60. handle->wofs = info->buf->tail;
  61. return ret;
  62. }
  63. static int ringbuff_stream_get_length(io_stream_t handle)
  64. {
  65. ringbuff_info_t *info = (ringbuff_info_t *)handle->data;
  66. if (!info)
  67. return -EACCES;
  68. return acts_ringbuf_length(info->buf);
  69. }
  70. static int ringbuff_stream_get_space(io_stream_t handle)
  71. {
  72. ringbuff_info_t *info = (ringbuff_info_t *)handle->data;
  73. if (!info)
  74. return -EACCES;
  75. return acts_ringbuf_space(info->buf);
  76. }
  77. static int ringbuff_stream_tell(io_stream_t handle)
  78. {
  79. return ringbuff_stream_get_length(handle);
  80. }
  81. static int ringbuff_stream_flush(io_stream_t handle)
  82. {
  83. int len = 0;
  84. ringbuff_info_t *info = (ringbuff_info_t *)handle->data;
  85. if (!info)
  86. return -EACCES;
  87. len = acts_ringbuf_length(info->buf);
  88. return acts_ringbuf_drop(info->buf, len);
  89. }
  90. static int ringbuff_stream_close(io_stream_t handle)
  91. {
  92. int ret = 0;
  93. ringbuff_info_t *info = (ringbuff_info_t *)handle->data;
  94. if (!info)
  95. return -EACCES;
  96. return ret;
  97. }
  98. static int ringbuff_stream_destroy(io_stream_t handle)
  99. {
  100. int ret = 0;
  101. ringbuff_info_t *info = (ringbuff_info_t *)handle->data;
  102. if (!info)
  103. return -EACCES;
  104. mem_free(info);
  105. handle->data = NULL;
  106. return ret;
  107. }
  108. static int ringbuff_stream_init(io_stream_t handle, void *param)
  109. {
  110. ringbuff_info_t *info = NULL;
  111. info = mem_malloc(sizeof(ringbuff_info_t));
  112. if (!info) {
  113. SYS_LOG_ERR(" malloc failed \n");
  114. return -ENOMEM;
  115. }
  116. info->buf = (struct acts_ringbuf *)param;
  117. handle->data = info;
  118. handle->type = RINGBUFFER_STREAM_IMAG_NUM;
  119. handle->total_size = acts_ringbuf_size(info->buf);
  120. return 0;
  121. }
  122. void *ringbuff_stream_get_ringbuf(io_stream_t handle)
  123. {
  124. if (handle && handle->type == RINGBUFFER_STREAM_IMAG_NUM ) {
  125. ringbuff_info_t *info = (ringbuff_info_t *)handle->data;
  126. if (info)
  127. return (void *)(info->buf);
  128. }
  129. return NULL;
  130. }
  131. const stream_ops_t ringbuff_stream_ops = {
  132. .init = ringbuff_stream_init,
  133. .open = ringbuff_stream_open,
  134. .read = ringbuff_stream_read,
  135. .seek = NULL,
  136. .tell = ringbuff_stream_tell,
  137. .flush = ringbuff_stream_flush,
  138. .get_length = ringbuff_stream_get_length,
  139. .get_space = ringbuff_stream_get_space,
  140. .write = ringbuff_stream_write,
  141. .close = ringbuff_stream_close,
  142. .destroy = ringbuff_stream_destroy,
  143. .get_ringbuffer = ringbuff_stream_get_ringbuf,
  144. };
  145. io_stream_t ringbuff_stream_create(struct acts_ringbuf *param)
  146. {
  147. return stream_create(&ringbuff_stream_ops, param);
  148. }
  149. /**ringbff stream init param */
  150. struct ringbuff_stream_init_param_t
  151. {
  152. void *ring_buff;
  153. uint32_t ring_buff_size;
  154. };
  155. #define MAX_SESSION_BUFF_NUM 8
  156. static struct acts_ringbuf buff_pool[MAX_SESSION_BUFF_NUM] __in_section_unique(DSP_SHARE_RAM);
  157. static int bit_mask = 0;
  158. static struct acts_ringbuf * malloc_ring_buf(int size)
  159. {
  160. for (int i = 0 ; i < MAX_SESSION_BUFF_NUM; i++) {
  161. if (!(bit_mask & (1 << i))) {
  162. bit_mask |= (1 << i);
  163. memset(&buff_pool[i], 0, sizeof(struct acts_ringbuf));
  164. os_printk("ring malloc %p\n",&buff_pool[i]);
  165. return &buff_pool[i];
  166. }
  167. }
  168. os_printk("session malloc failed\n");
  169. return NULL;
  170. }
  171. static void free_ring_buf(struct acts_ringbuf * session_buf)
  172. {
  173. for (int i = 0 ; i < MAX_SESSION_BUFF_NUM; i++) {
  174. if (&buff_pool[i] == session_buf) {
  175. bit_mask &= (~(1 << i));
  176. return;
  177. }
  178. }
  179. }
  180. static int ringbuff_stream_init_ext(io_stream_t handle, void *param)
  181. {
  182. struct ringbuff_stream_init_param_t *init_param = (struct ringbuff_stream_init_param_t *)param;
  183. struct acts_ringbuf *ringbuff = (struct acts_ringbuf *)malloc_ring_buf(sizeof(struct acts_ringbuf));
  184. if (!ringbuff) {
  185. return -ENOMEM;
  186. }
  187. acts_ringbuf_init(ringbuff, init_param->ring_buff, init_param->ring_buff_size);
  188. ringbuff_stream_init(handle, ringbuff);
  189. return 0;
  190. }
  191. static int ringbuff_stream_destroy_ext(io_stream_t handle)
  192. {
  193. int ret = 0;
  194. ringbuff_info_t *info = (ringbuff_info_t *)handle->data;
  195. if (info->buf) {
  196. free_ring_buf(info->buf);
  197. }
  198. ringbuff_stream_destroy(handle);
  199. return ret;
  200. }
  201. const stream_ops_t ringbuff_stream_ops_ext = {
  202. .init = ringbuff_stream_init_ext,
  203. .open = ringbuff_stream_open,
  204. .read = ringbuff_stream_read,
  205. .seek = NULL,
  206. .tell = ringbuff_stream_tell,
  207. .flush = ringbuff_stream_flush,
  208. .get_length = ringbuff_stream_get_length,
  209. .get_space = ringbuff_stream_get_space,
  210. .write = ringbuff_stream_write,
  211. .close = ringbuff_stream_close,
  212. .destroy = ringbuff_stream_destroy_ext,
  213. .get_ringbuffer = ringbuff_stream_get_ringbuf,
  214. };
  215. io_stream_t ringbuff_stream_create_ext(void *ring_buff, uint32_t ring_buff_size)
  216. {
  217. struct ringbuff_stream_init_param_t param = {
  218. .ring_buff = ring_buff,
  219. .ring_buff_size = ring_buff_size,
  220. };
  221. return stream_create(&ringbuff_stream_ops_ext, &param);
  222. }