Files
TAIXIN/sdk/include/lib/common/rbuffer.h

188 lines
5.6 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef __RBUFFER_H__
#define __RBUFFER_H__
#ifdef __cplusplus
extern "C" {
#endif
#define RB_NPOS(rb, pos, i) ({ \
uint32 __pos__ = (rb)->pos;\
((__pos__+(i)>=(rb)->qsize) ? (__pos__+(i)-(rb)->qsize) : (__pos__+(i))); \
})
/* rpos == wpos 表示 rbuffer 为空 */
#define RB_EMPTY(rb) ((rb)->wpos == (rb)->rpos)
/* wpos+1 == rpos 表示 rbuffer 已满 */
#define RB_FULL(rb) ({ \
uint32 _rpos_ = ((rb)->rpos);\
uint32 _wpos_ = ((rb)->wpos)+1;\
((_wpos_>=(rb)->qsize) ? (_wpos_-(rb)->qsize) : (_wpos_)) == (_rpos_);\
})
/* rbuffer 中未被读取的数据长度 */
#define RB_COUNT(rb) ({ \
uint32 _rpos_ = ((rb)->rpos);\
uint32 _wpos_ = ((rb)->wpos);\
((_rpos_<=_wpos_)? (_wpos_-_rpos_): ((rb)->qsize-_rpos_+_wpos_));\
})
/* rbuffer中剩余空间长度 */
#define RB_IDLE(rb) ({ \
uint32 _rpos_ = ((rb)->rpos);\
uint32 _wpos_ = ((rb)->wpos);\
((_wpos_<_rpos_)? (_rpos_-_wpos_-1): ((rb)->qsize-_wpos_+_rpos_-1));\
})
/*ringbuffer define*/
#define RBUFFER_DEF(name, type, size) \
struct {\
uint32 rpos, wpos, qsize;\
type rbq[(size)+1];\
}name
/*ringbuffer define (refference)*/
#define RBUFFER_DEF_R(name, type) \
struct {\
uint32 rpos, wpos, qsize;\
type *rbq;\
}name
/*get a value from ringbuffer*/
#define RB_GET(rb, val) ({\
uint8 __ret__ = 0;\
if(!RB_EMPTY(rb)){\
val = (rb)->rbq[(rb)->rpos];\
(rb)->rpos = RB_NPOS((rb), rpos, 1);\
__ret__ = 1;\
}\
__ret__;\
})
/*set a value into ringbuffer*/
#define RB_SET(rb, val) ({\
uint8 __ret__ = 0;\
if(!RB_FULL(rb)){\
(rb)->rbq[(rb)->wpos] = val;\
(rb)->wpos = RB_NPOS((rb), wpos, 1);\
__ret__ = 1;\
}\
__ret__;\
})
#define RB_SET_F(rb, val) ({\
if(RB_FULL(rb)) (rb)->rpos = RB_NPOS((rb), rpos, 1);\
(rb)->rbq[(rb)->wpos] = val;\
(rb)->wpos = RB_NPOS((rb), wpos, 1);\
1;\
})
/*get a value from ringbuffer in interrupt*/
#define RB_INT_GET(rb, val) ({\
uint8 __ret__ = 0;\
uint32 flag = disable_irq(); \
if(!RB_EMPTY(rb)){\
val = (rb)->rbq[(rb)->rpos];\
(rb)->rpos = RB_NPOS((rb), rpos, 1);\
__ret__ = 1;\
}\
enable_irq(flag);\
__ret__;\
})
/*set a value into ringbuffer in interrupt*/
#define RB_INT_SET(rb, val) ({\
uint8 __ret__ = 0;\
uint32 flag = disable_irq(); \
if(!RB_FULL(rb)){\
(rb)->rbq[(rb)->wpos] = val;\
(rb)->wpos = RB_NPOS((rb), wpos, 1);\
__ret__ = 1;\
}\
enable_irq(flag);\
__ret__;\
})
#define RB_INT_SET_F(rb, val) ({\
uint32 flag = disable_irq(); \
if(RB_FULL(rb)) (rb)->rpos = RB_NPOS((rb), rpos, 1);\
(rb)->rbq[(rb)->wpos] = val;\
(rb)->wpos = RB_NPOS((rb), wpos, 1);\
enable_irq(flag);\
1;\
})
/*ringbuffer init*/
#define RB_INIT(rb, size) do{\
(rb)->qsize = (size)+1;\
(rb)->rpos = 0;\
(rb)->wpos = 0;\
} while (0)
/*ringbuffer init (referrence mode)*/
#define RB_INIT_R(rb, size, buff) do{\
(rb)->qsize = (size);\
(rb)->rpos = 0;\
(rb)->wpos = 0;\
(rb)->rbq = buff;\
} while (0)
#define RB_RESET(rb) do{\
uint32 flag = disable_irq(); \
(rb)->rpos = 0;\
(rb)->wpos = 0;\
enable_irq(flag);\
}while(0)
#define RB_INIT_ALLOC(rb, size) rbuffer_alloc((struct rbuffer *)(rb), size)
#define RB_FREE(rb) rbuffer_free((struct rbuffer *)(rb))
struct rbuffer {
uint32 rpos, wpos, qsize, bpos;
char *rbq;
};
int32 rbuffer_init(struct rbuffer *rb, uint32 size, void *buff);
int32 rbuffer_set(struct rbuffer *rb, void *data, uint32 length);
int32 rbuffer_set_force(struct rbuffer *rb, void *data, uint32 length);
int32 rbuffer_get(struct rbuffer *rb, void *buff, uint32 size);
void rbuffer_destroy(struct rbuffer *rb);
void rbuffer_reset(struct rbuffer *rb);
int32 rbuffer_alloc(struct rbuffer *rb, uint32 size);
void rbuffer_free(struct rbuffer *rb);
int32 rbuffer_set_block(struct rbuffer *rb, void *data, uint32 length, uint8 block);
int32 rbuffer_get_block(struct rbuffer *rb, void *buff, uint32 size, uint8 *block);
////////////////////////////////////////////////////////////////
// 硬件模块可使用的ringbuffer, 默认仅支持 "1读-1写" 模式
// 如果要支持 "多读-多写" 模式,需要打开 HWRB_IRQ 宏定义: 关中断后访问ringbuffer
// 可支持 2~N 个小buffer乒乓使用max_size 决定了每个乒乓小buffer的大小
//#define HWRB_IRQ
struct hwrbuffer {
uint32 rpos, wpos, qsize, ipos;
uint16 min_size, max_size;
uint8 *buff;
};
//初始化 ringbuffer:
// max_size: 可写数据的buffer最大长度大于此长度则切分buffer使用
// min_size: 可写数据的buffer最小长度小于此长度则忽略调过此buffer使用下一块buffer
void hwrbuffer_init(struct hwrbuffer *rb, uint8 *buff, uint32 size, uint16 max_size, uint16 min_size);
//更新写地址 并 获取下一个可写的buffer地址 和 长度
//buff: 需要更新的buffer地址并输出 下一个可写的buffer地址
//size: 需要更新的buffer长度并输出 下一个可写的buffer长度
void hwrbuffer_update_wpos(struct hwrbuffer *rb, uint8 **buff, uint32 *size);
//更新读地址
//buff: 更新已读取数据的buffer地址
//size: 更新已读取数据的buffer长度
void hwrbuffer_update_rpos(struct hwrbuffer *rb, uint8 *buff, uint32 size);
#ifdef __cplusplus
}
#endif
#endif