Kaynağa Gözat

1.优化文件命名;

libo 2 yıl önce
ebeveyn
işleme
8ba0b45491
3 değiştirilmiş dosya ile 382 ekleme ve 0 silme
  1. 240 0
      lib/lib_ringbuf.c
  2. 25 0
      lib/lib_ringbuf.h
  3. 117 0
      lib/lib_ringbuf_test.c

+ 240 - 0
lib/lib_ringbuf.c

@@ -0,0 +1,240 @@
+#include <stdio.h>
+#include "string.h"
+#include "stdlib.h"
+#include "lib_ringbuf.h"
+#define VALID_LEN (Object->push_size - Object->pop_size)    //缓冲区有效长度
+int RingBuf_discard(RingBuf Object, int size)   ;
+
+RingBuf RingBuf_Init(RingBufOBJ *data, void *buffer, int buff_size)
+{
+    RingBuf result = NULL;
+    if (data != NULL && buffer != NULL && buff_size > 0)
+    {
+        data->pHead = buffer;
+        data->size = buff_size;
+        data->pTail = data->pHead + buff_size;
+        data->pValid = data->pHead;
+        data->pValidTail = data->pHead;
+        data->push_size = 0;
+        data->pop_size = 0;
+        result = data;
+    }
+    return result;
+}
+
+void RingBuf_Reset(RingBuf Object)
+{
+
+    if (Object != NULL)
+    {
+        Object->pValid = Object->pHead;
+        Object->pValidTail = Object->pHead;
+        Object->push_size = 0;
+        Object->pop_size = 0;
+    }
+    return ;
+}
+
+void RingBuf_Fini(RingBufOBJ *data)
+{
+    if (data != NULL)
+    {
+        data->pValid = data->pValidTail = data->pHead;
+        data->pop_size = data->push_size;
+    }    
+}
+
+int RingBuf_Push(RingBuf Object, const void *data, int size)
+{
+    int result = 0;
+    int _ValidLength = Object->push_size - Object->pop_size;
+    int _Size = Object->size - _ValidLength;    //实际可用 为0?	
+	
+		if( _Size <= size )
+		{
+			RingBuf_discard(Object,size);
+		}
+		
+		if(Object->pop_size >= Object->push_size )
+		{
+			RingBuf_Reset(Object);
+		}
+		
+    if (data == NULL)
+		{
+			result = -1;
+			return result;
+		}		
+        
+    if (size > 0 && _Size > 0) //保留原本不能丢弃
+    {
+        if (_Size < size)
+            size = _Size;
+        result = size;
+        if (Object->pValidTail + size > Object->pTail)//写入之后超出缓冲区 分两段
+        {
+            int rest = Object->pTail - Object->pValidTail;
+            memcpy(Object->pValidTail, data, rest);
+            memcpy(Object->pHead, (char *)data + rest, size - rest);
+            Object->pValidTail = Object->pHead + size - rest;
+        }
+        else
+        {
+            memcpy(Object->pValidTail, data, size);
+            Object->pValidTail += size;
+            if (Object->pValidTail == Object->pTail)
+                Object->pValidTail = Object->pHead;
+        }
+        Object->push_size += result;
+    }
+    // printf(" push = %s\n", Object->pHead);  
+    return result;
+}
+
+int RingBuf_Peek(RingBuf Object, void *data, int size)//返回实际尺寸
+{
+    int result = 0;
+    if (data == NULL)
+		{
+			result = -1;
+			return result;
+		}
+        
+    
+		if (size > 0 && Object->pop_size != Object->push_size)
+    {
+        int _ValidLength = Object->push_size - Object->pop_size;
+        if (size > _ValidLength)//可能会push VALID_LEN变大 导致size变大越界
+            size = _ValidLength;
+        if (Object->pValid + size > Object->pTail)//需要分成两段copy
+        {
+            int rest = Object->pTail - Object->pValid;
+            memcpy(data, Object->pValid, rest);
+            memcpy((char*)data + rest, Object->pHead, size - rest);//第二段,绕到整个存储区的开头
+        }
+        else
+        {
+            memcpy(data, Object->pValid, size);
+        }
+        result = size;
+    }
+    return result;
+}
+
+int RingBuf_Pop(RingBuf Object, void *data, int size)
+{
+    int result = 0;
+    if (data == NULL)
+        result = -1;
+    else if (size > 0 && Object->pop_size != Object->push_size)
+    {
+        int _ValidLength = Object->push_size - Object->pop_size;
+        if (size > _ValidLength)//可能会push VALID_LEN变大 导致size变大越界
+            size = _ValidLength;
+				
+				if((Object->pValidTail - size) >= Object->pHead)		
+				{
+					//数据在缓冲区中间,一次性读取;
+					Object->pValidTail = Object->pValidTail - size;
+					memcpy(data, Object->pValidTail, size);
+					memset(Object->pValidTail, 0x00, size);
+				}
+				else
+				{					
+					//数据在缓冲区首尾,需要分两段读取
+					Object->pValidTail = Object->pValidTail + Object->size - size;	
+					
+					int RestLength = Object->pTail - Object->pValidTail;
+					memcpy(data, Object->pValidTail, RestLength);
+					memset(Object->pValidTail, 0x00, RestLength);
+					
+					memcpy((char*)data+RestLength, Object->pHead, size - RestLength);	
+					memset(Object->pHead, 0x00, size - RestLength);
+				}
+
+				result = size;
+        Object->pop_size += result;
+    }
+    // printf("pop = %s\n",(char*)data);   
+    return result;
+}
+
+
+int RingBuf_Pop_head(RingBuf Object, void *data, int size)                                                                        
+{
+    int result = 0;
+    if (data == NULL)
+        result = -1;
+    else if (size > 0 && Object->pop_size != Object->push_size)
+    {
+        int _ValidLength = Object->push_size - Object->pop_size;
+        if (size > _ValidLength)//可能会push VALID_LEN变大 导致size变大越界
+            size = _ValidLength;
+        if (Object->pValid + size > Object->pTail)//需要分成两段copy
+        {
+            int rest = Object->pTail - Object->pValid;
+            memcpy(data, Object->pValid, rest);
+            memcpy((char*)data + rest, Object->pHead, size - rest);//第二段,绕到整个存储区的开头
+            Object->pValid = Object->pHead + size - rest;//更新已使用缓冲区的起始
+        }
+        else
+        {
+            memcpy(data, Object->pValid, size);
+            Object->pValid = Object->pValid + size;
+            if (Object->pValid == Object->pTail)
+                Object->pValid = Object->pHead;
+        }
+        result = size;
+        Object->pop_size += result;
+    }
+    // printf("pop = %s\n",(char*)data);   
+    return result;
+}
+
+
+int RingBuf_discard(RingBuf Object, int size)                                                                        
+{
+    int result = 0;
+
+    if (size > 0 && Object->pop_size != Object->push_size)
+    {
+        int _ValidLength = Object->push_size - Object->pop_size;
+        if (size > _ValidLength)//可能会push VALID_LEN变大 导致size变大越界
+            size = _ValidLength;
+        if (Object->pValid + size > Object->pTail)//需要分成两段copy
+        {
+            int rest = Object->pTail - Object->pValid;
+            memset(Object->pValid, 0x00,  rest);
+            memset(Object->pHead, 0x00,  size - rest);//第二段,绕到整个存储区的开头
+            Object->pValid = Object->pHead + size - rest;//更新已使用缓冲区的起始
+        }
+        else
+        {
+            memset(Object->pValid, 0x00, size);
+            Object->pValid = Object->pValid + size;
+            if (Object->pValid == Object->pTail)
+                Object->pValid = Object->pHead;
+        }
+        result = size;
+        Object->pop_size += result;
+    }
+    // printf("pop = %s\n",(char*)data);   
+    return result;
+}
+uint32_t RingBuf_obj_num(RingBuf Object,int obj_size)
+{
+		uint32_t obj_num = 0;
+	
+		obj_num = 0;
+		if(Object->push_size > Object->pop_size)
+		{
+			obj_num = Object->push_size - Object->pop_size;
+			obj_num = obj_num/obj_size;			
+		}
+		
+		return obj_num;
+}
+
+
+
+

+ 25 - 0
lib/lib_ringbuf.h

@@ -0,0 +1,25 @@
+#ifndef LIB_RINGBUF_H
+#define LIB_RINGBUF_H
+
+#include <stdint.h>
+
+typedef struct
+{
+    unsigned char  *pHead;//环形存储区的首地址
+    unsigned char  *pTail;//环形存储区的结尾地址   
+    unsigned char  *pValid;//已使用的缓冲区的首地址
+    unsigned char  *pValidTail;//已使用的缓冲区的尾地址
+    unsigned int 		pop_size;
+    unsigned int 		push_size;
+    unsigned int   	size;
+} RingBufOBJ;
+
+typedef RingBufOBJ* RingBuf;
+
+RingBuf RingBuf_Init(RingBufOBJ *data, void *buffer, int buff_size);
+void RingBuf_Fini(RingBufOBJ *data);
+int RingBuf_Push(RingBuf Object, const void *data, int size);
+int RingBuf_Peek(RingBuf Object, void *data, int size); //返回实际尺寸
+int RingBuf_Pop(RingBuf Object, void *data, int size);
+uint32_t RingBuf_obj_num(RingBuf Object,int obj_size);
+#endif 

+ 117 - 0
lib/lib_ringbuf_test.c

@@ -0,0 +1,117 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include "signal.h"
+#include "lib_ringbuf.h"
+#include "cmsis_os.h"
+//用push_count 压入
+//检查pop_count-push_count ? 
+//错误休眠
+//错误打印信息
+//数据流连续压入 不能断开
+char str[20] = {'1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','w','a','1','2','3'};
+
+bool run_over = false;
+
+void sighandler(int signum)
+{
+    run_over = true;
+}
+
+void *push(void *arg)
+{
+    int RetSize = 0;
+    int Push_Ptr = 0;
+    RingBuf tmp = (RingBuf)arg;
+    if (tmp != NULL)
+    {
+        while (!run_over)
+        {
+            RetSize = RingBuf_Push(tmp, str + Push_Ptr, sizeof(str) - Push_Ptr);
+            if (RetSize < sizeof(str) - Push_Ptr)
+            {
+                Push_Ptr += RetSize;
+                osDelay(1);   
+            }
+            else
+                Push_Ptr = 0;
+        }
+    }
+    else
+        printf("RingBufOBJ  ERR");
+    return NULL;
+}
+
+
+void *pop(void *arg)
+{
+    char buf[10];
+    int RetSize = 0;
+    int Pop_Ptr = 0;
+    RingBuf tmp = (RingBuf)arg;
+    if (tmp != NULL)
+    {
+       while (!run_over)
+       {
+            RetSize = RingBuf_Pop(tmp, buf, sizeof(buf) - 1);//size?
+            if (RetSize == 0)   //无有效数据
+               osDelay(1);
+            else        //检查
+            {
+                // char str[20] = {'1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','w','a','1','2','3'};
+                //1.开始比较 比较完之后 Pop_Ptr指针往后移动RetSize
+                //2.需要回到模板头部时 即 RetSize > sizeof(str) - Pop_Ptr 
+                //分成两部分比较 第一部分比较 (sizeof(str) - Pop_Ptr)个长度,Pop_Ptr清零
+                //第二部分比较 RetSize - (sizeof(str) - Pop_Ptr)个长度
+                if (RetSize > sizeof(str) - Pop_Ptr)
+                {
+                    int PreSize = sizeof(str) - Pop_Ptr;
+                    if (memcmp(str + Pop_Ptr, buf, PreSize) != 0 || memcmp(str, buf + PreSize, RetSize - PreSize) != 0)//?
+                    {
+                        puts("ERR 1");
+                        run_over = true;
+                    }
+                    Pop_Ptr = RetSize - PreSize;
+                }
+                else
+                {
+                    if (memcmp(str + Pop_Ptr, buf, RetSize) != 0)
+                    {
+                        puts("ERR 2");
+                        run_over = true;
+                    }
+                    Pop_Ptr += RetSize;//到头处理
+                    if (Pop_Ptr == sizeof(str))
+                        Pop_Ptr = 0;
+                }
+            }
+        }        
+    }
+    else
+       printf("RingBufOBJ ERR");
+    return NULL;
+}
+#if 0
+RingBufOBJ _data;
+
+
+int main() 
+{
+     char buf[16];
+      RingBuf tmp = RingBuf_Init(&_data, buf, sizeof(buf));
+    if (tmp != NULL)
+    {
+        pthread_t th1, th2;
+        signal(SIGINT, sighandler);
+        pthread_create(&th1, NULL, push, tmp);
+        pthread_create(&th2, NULL, pop, tmp);
+        
+        pthread_join(th1, NULL);
+        pthread_join(th2, NULL);
+    }
+    else
+        printf("Failed to initialize");
+    return 0;
+}     
+#endif