Files
2025-08-27 09:51:58 +01:00

151 lines
3.9 KiB
C

#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
/*reset ringbuffer in interrupt*/
#define RB_RESET(rb) ({\
uint32 flag = disable_irq(); \
(rb)->rpos = 0; \
(rb)->wpos = 0; \
enable_irq(flag);\
})
/*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__;\
})
/*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_RESET(rb) do{\
uint32 flag = disable_irq(); \
(rb)->rpos = 0;\
(rb)->wpos = 0;\
enable_irq(flag);\
}while(0)
/*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_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;
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);
#ifdef __cplusplus
}
#endif
#endif