rt_fifo.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /******************************************************************************
  2. 版权所有:
  3. 文件名称: rt_fifo.c
  4. 文件版本: 01.01
  5. 创建作者:
  6. 创建日期:
  7. 功能说明: 实时FIFO,采用免锁算法,只支持单进单出。
  8. 其它说明:
  9. 修改记录:
  10. */
  11. /*------------------------------- 头文件 --------------------------------------
  12. */
  13. #include "rt.h"
  14. #include "rt_fifo.h"
  15. /*------------------------------- 宏定义 --------------------------------------
  16. */
  17. /*------------------------------ 类型结构 -------------------------------------
  18. */
  19. /*------------------------------ 全局变量 -------------------------------------
  20. */
  21. /*------------------------------ 函数声明 -------------------------------------
  22. */
  23. /*------------------------------ 外部函数 -------------------------------------
  24. 外部函数供其它实体文件引用,必须仔细检查传入参数的合法性.
  25. */
  26. /******************************************************************************
  27. 函数名称: rt_fifo_init
  28. 函数版本: 01.01
  29. 创建作者: sunxi
  30. 创建日期: 2020-06-18
  31. 函数说明: rt_fifo初始化
  32. 参数说明:
  33. fifo: 要初始化的rt_fifo结构的指针
  34. buffer 需要和fifo相连接的buffer
  35. size buffer的大小,必须是2的n次方
  36. 返回值:
  37. 0: 成功
  38. 其它: 失败
  39. 修改记录:
  40. */
  41. int rt_fifo_init(struct rt_fifo *fifo, unsigned char *buffer, unsigned int size)
  42. {
  43. // size 必须是2的n次方
  44. if(!is_power_of_2(size) && buffer == NULL)
  45. {
  46. fifo->buffer = 0;
  47. fifo->size = 0;
  48. fifo->in = fifo->out = 0;
  49. return -1;
  50. }
  51. fifo->buffer = buffer;
  52. fifo->size = size;
  53. fifo->in = fifo->out = 0;
  54. return 0;
  55. }
  56. /******************************************************************************
  57. 函数名称: rt_fifo_get
  58. 函数版本: 01.01
  59. 创建作者: sunxi
  60. 创建日期: 2020-06-18
  61. 函数说明: 从fifo中读出数据
  62. 参数说明:
  63. fifo: rt_fifo结构的指针
  64. buffer 读出buffer的指针
  65. len 读出buffer的大小
  66. 返回值: 读出数据的长度
  67. 修改记录:
  68. */
  69. unsigned int rt_fifo_get(struct rt_fifo *fifo,unsigned char *buffer, unsigned int len)
  70. {
  71. unsigned int l;
  72. // 得到需要读出的数据长度
  73. len = min(len, fifo->in - fifo->out);
  74. // 处理buffer尾部环绕问题
  75. // 读尾部数据
  76. l = min(len, fifo->size - (fifo->out & (fifo->size - 1)));
  77. memcpy(buffer, fifo->buffer + (fifo->out & (fifo->size - 1)), l);
  78. // 读头部数据
  79. memcpy(buffer + l, fifo->buffer, len - l);
  80. // 修正出偏移
  81. fifo->out += len;
  82. return len;
  83. }
  84. /******************************************************************************
  85. 函数名称: rt_fifo_put
  86. 函数版本: 01.01
  87. 创建作者: sunxi
  88. 创建日期: 2020-06-18
  89. 函数说明: 往fifo中写入数据
  90. 参数说明:
  91. fifo: rt_fifo结构的指针
  92. buffer 写入buffer的指针
  93. len 写入buffer的大小
  94. 返回值: 写入数据的长度
  95. 修改记录:
  96. */
  97. unsigned int rt_fifo_put(struct rt_fifo *fifo,unsigned char *buffer, unsigned int len)
  98. {
  99. unsigned int l;
  100. // 得到需要写入的数据长度
  101. len = min(len, fifo->size - fifo->in + fifo->out);
  102. // 处理buffer尾部环绕问题
  103. // 写尾部数据
  104. l = min(len, fifo->size - (fifo->in & (fifo->size - 1)));
  105. memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), buffer, l);
  106. //写头部数据
  107. memcpy(fifo->buffer, buffer + l, len - l);
  108. // 修正进偏移
  109. fifo->in += len;
  110. return len;
  111. }
  112. /*------------------------------ 内部函数 -------------------------------------
  113. 内部函数以下划线‘_’开头,不需要检查参数的合法性.
  114. */
  115. /*------------------------------ 测试函数 -------------------------------------
  116. 一个实体文件必须带一个本模块的测试函数来进行单元测试,如果的确不方便在本模块中
  117. 进行单元测试,必须在此注明实际的测试位置(例如在哪个实体文件中使用哪个测试函数).
  118. */
  119. /*------------------------------ 文件结束 -------------------------------------
  120. */