diff --git a/include/HRingBuffer.h b/include/HRingBuffer.h index 701a825..e60d254 100644 --- a/include/HRingBuffer.h +++ b/include/HRingBuffer.h @@ -68,13 +68,13 @@ typedef struct __attribute__ ((__packed__)) _HRingBuffer32 { // 用于辅助多类型数值计算 #ifdef _HRING_BUFFER_LEN_USE32 -#define _HRING_BUFFER_INIT_SIZE(size) ((size >> 24) & 0xff), ((size >> 16) & 0xff), ((size >> 8) & 0xff), (size & 0xff) +#define _HRING_BUFFER_INIT_SIZE(size) (((size) >> 24) & 0xff), (((size) >> 16) & 0xff), (((size) >> 8) & 0xff), ((size) & 0xff) #define _HRING_BUFFER_INIT_SIZE_INIT(size) ((size[0] << 24) | (size[1] << 16) | (size[2] << 8) | (size[3] & 0xff)) #elif defined(_HRING_BUFFER_LEN_USE16) -#define _HRING_BUFFER_INIT_SIZE(size) ((size >> 8) & 0xff), (size & 0xff) +#define _HRING_BUFFER_INIT_SIZE(size) (((size) >> 8) & 0xff), ((size) & 0xff) #define _HRING_BUFFER_INIT_SIZE_INIT(size) ((size[0] << 8) | (size[1] & 0xff)) #else -#define _HRING_BUFFER_INIT_SIZE(size) (size & 0xff) +#define _HRING_BUFFER_INIT_SIZE(size) ((size) & 0xff) #define _HRING_BUFFER_INIT_SIZE_INIT(size) (size[0] & 0xff) #endif @@ -95,6 +95,14 @@ typedef struct __attribute__ ((__packed__)) _HRingBuffer32 { #define HRING_BUFFER_DEFINE16(name, size) HRingBufferType name[_HRING_BUFFER_CALC_LEN(size, 16)] = _HRING_BUFFER_INIT(size, 16) #define HRING_BUFFER_DEFINE32(name, size) HRingBufferType name[_HRING_BUFFER_CALC_LEN(size, 32)] = _HRING_BUFFER_INIT(size, 32) +/** + * @brief 给缓存区初始化成环形缓冲区, 最低需要 sizeof(_HRingBufferBase) + * @param buffer 缓冲区的指针 + * @param size 缓冲区长度 + * @return 返回缓存区长度, 如内存不足返回0 + */ +HRingBufferLenType HRingbufferInit8(void *buffer, HRingBufferLenType size); + // 添加数据到环形缓冲区, 成功返回1, 失败返回0 uint8_t HRingBufferAddData(HRingBufferType* buffer, HRingBufferDataType data); @@ -107,11 +115,17 @@ HRingBufferDataType HRingBufferGetData(HRingBufferType* buffer, HRingBufferLenTy // 获取环形缓冲区数据, 失败返回 HRING_BUFFER_ERROR HRingBufferDataType HRingBufferPopData(HRingBufferType* buffer); -// 获取环形缓冲区数据长度 -HRingBufferLenType HRingBufferGetLen(HRingBufferType* buffer); +// 获取环状缓冲区数据, 返回获取的数据长度 +HRingBufferLenType HRingBufferGetByteDatas(HRingBufferType* buffer, uint8_t *data, HRingBufferLenType len); -// 获取环形缓冲区数据字节长度 -HRingBufferLenType HRingBufferGetByteLen(HRingBufferType* buffer); +// 获取环形缓冲区已使用数据长度 +HRingBufferLenType HRingBufferGetUseLen(HRingBufferType* buffer); + +// 获取环形缓冲区已使用数据字节长度 +HRingBufferLenType HRingBufferGetUseByteLen(HRingBufferType* buffer); + +// 获取环形缓冲区长度 +HRingBufferLenType HRingBufferGetLen(HRingBufferType* buffer); // 清空环形缓冲区 void HRingBufferClear(HRingBufferType* buffer); diff --git a/src/HRingBuffer.c b/src/HRingBuffer.c index 6222059..d7be6a0 100644 --- a/src/HRingBuffer.c +++ b/src/HRingBuffer.c @@ -64,6 +64,17 @@ static HRingBufferDataType GetRingBufferData(const HRingBufferType *ringBuffer, return HRING_BUFFER_ERROR; } +static const uint8_t *GetRingByteData(const HRingBufferType *ringBuffer, HRingBufferLenType pos) { + const void *result = NULL; + switch(GetRingBufferType(ringBuffer)) { + case kHRingBufferFlag8: result = &((const _HRingBuffer8 *)ringBuffer)->data[pos]; break; + case kHRingBufferFlag16: result = &((const _HRingBuffer16 *)ringBuffer)->data[pos]; break; + case kHRingBufferFlag32: result = &((const _HRingBuffer32 *)ringBuffer)->data[pos]; break; + } + + return (const uint8_t *)result; +} + static void SetRingBufferData(HRingBufferType *ringBuffer, HRingBufferLenType pos, HRingBufferDataType data) { switch(GetRingBufferType(ringBuffer)) { case kHRingBufferFlag8: ((_HRingBuffer8 *)ringBuffer)->data[pos] = (uint8_t)data; break; @@ -88,6 +99,27 @@ static void SetRingBufferFull(HRingBufferType *ringBuffer, uint8_t full) { } } +static void AdjustReadPos(HRingBufferType *ringBuffer, HRingBufferLenType pos) { + const uint8_t isFull = IsRingBufferFull(ringBuffer); + _HRingBufferBase *base = (_HRingBufferBase *)ringBuffer; + base->start = (base->start + pos) % base->len; + if (isFull) { + SetRingBufferFull(ringBuffer, 0); + } +} + +HRingBufferLenType HRingbufferInit8(void *buffer, HRingBufferLenType size) +{ + const int len = size - sizeof(_HRingBufferBase); + if (buffer == NULL || len <= 0) { + return 0; + } + + uint8_t init[] = _HRING_BUFFER_INIT8(len); + memcpy(buffer, init, sizeof(init)); + return HRingBufferGetLen((HRingBufferType *)buffer); +} + // 添加数据到环形缓冲区, 成功返回1, 失败返回0 uint8_t HRingBufferAddData(HRingBufferType* buffer, HRingBufferDataType data) { if (buffer == NULL) { @@ -133,7 +165,7 @@ HRingBufferDataType HRingBufferGetData(HRingBufferType* buffer, HRingBufferLenTy return HRING_BUFFER_ERROR; } - if (HRingBufferGetLen(buffer) <= index) { + if (HRingBufferGetUseLen(buffer) <= index) { LogD("error index[%d], len[%d]", index, HRingBufferGetLen(buffer)); return HRING_BUFFER_ERROR; } @@ -144,7 +176,7 @@ HRingBufferDataType HRingBufferGetData(HRingBufferType* buffer, HRingBufferLenTy // 获取环形缓冲区数据, 失败返回 HRING_BUFFER_ERROR HRingBufferDataType HRingBufferPopData(HRingBufferType* buffer) { - if (HRingBufferGetLen(buffer) == 0) { + if (HRingBufferGetUseLen(buffer) == 0) { return HRING_BUFFER_ERROR; } @@ -158,8 +190,50 @@ HRingBufferDataType HRingBufferPopData(HRingBufferType* buffer) { return data; } +// 获取环状缓冲区数据, 返回获取的数据长度 +HRingBufferLenType HRingBufferGetByteDatas(HRingBufferType* buffer, uint8_t *data, HRingBufferLenType len) +{ + if (HRingBufferGetUseLen(buffer) == 0) { + return 0; + } + + _HRingBufferBase *base = (_HRingBufferBase *)buffer; + const HRingBufferLenType typeSize = GetRingBufferTypeSize(buffer); + const HRingBufferLenType dataLen = HRingBufferGetUseByteLen(buffer); + len = len / typeSize * typeSize; + len = (len > dataLen) ? dataLen : len; + HRingBufferLenType readLen = 0; + if (base->start >= base->end) { + int copySize = (base->len - base->start) * typeSize; + if (copySize > len) { + copySize = len; + } + + memcpy(data, GetRingByteData(buffer, base->start), copySize); + readLen += copySize; + data += copySize; + len -= copySize; + AdjustReadPos(buffer, copySize / typeSize); + } + + if (len == 0) { + return readLen; + } + + int copySize = (base->end - base->start) * typeSize; + if (copySize > len) { + copySize = len; + } + + memcpy(data, GetRingByteData(buffer, base->start), copySize); + readLen += copySize; + len -= copySize; + AdjustReadPos(buffer, copySize / typeSize); + return readLen; +} + // 获取环形缓冲区数据长度 -HRingBufferLenType HRingBufferGetLen(HRingBufferType* buffer) { +HRingBufferLenType HRingBufferGetUseLen(HRingBufferType* buffer) { if (buffer == NULL) { return 0; } @@ -178,8 +252,18 @@ HRingBufferLenType HRingBufferGetLen(HRingBufferType* buffer) { } // 获取环形缓冲区数据字节长度 -HRingBufferLenType HRingBufferGetByteLen(HRingBufferType* buffer) { - return HRingBufferGetLen(buffer) * GetRingBufferTypeSize(buffer); +HRingBufferLenType HRingBufferGetUseByteLen(HRingBufferType* buffer) { + return HRingBufferGetUseLen(buffer) * GetRingBufferTypeSize(buffer); +} + +HRingBufferLenType HRingBufferGetLen(HRingBufferType* buffer) { + if (buffer == NULL) { + return 0; + } + + _HRingBufferBase *base = (_HRingBufferBase *)buffer; + InitRingBuffer(buffer); + return base->len; } // 清空环形缓冲区 @@ -197,5 +281,5 @@ void HRingBufferClear(HRingBufferType* buffer) { // 判断环形缓冲区是否为空 uint8_t HRingBufferEmpty(HRingBufferType* buffer) { - return HRingBufferGetLen(buffer) == 0; + return HRingBufferGetUseLen(buffer) == 0; } diff --git a/src/HTimer.c b/src/HTimer.c index 2b14ff5..97ddd8d 100644 --- a/src/HTimer.c +++ b/src/HTimer.c @@ -1,7 +1,9 @@ -#include +#include "HTimer.h" +#include "HDLog.h" +// 用于拷贝定时器文件使用可直接删除HDLog.h文件避免依赖 #ifndef LogD #define LogD(...) #endif @@ -11,10 +13,10 @@ static uint32_t (*GetCurrentMs)(void); #define CHECK_VALUE (0x0FFFFFFF) -struct TimeRegisterInfo { +struct __attribute__((packed)) TimeRegisterInfo { uint16_t enable : 1; ///< 定时器使能 - uint16_t curr : 1; ///< 当前定时器 - uint16_t len; ///< 定时器个数 + uint16_t curr : 1; ///< 当前定时器 + uint16_t len : 14; ///< 定时器个数 HTimerInfo *timers; ///< 定时器 }; @@ -78,7 +80,7 @@ static int16_t AddTimerData(uint8_t id, uint32_t duration, HTimerCallType call, return i; } - LogD("timers full, duration[%d], flags[%d]", duration, flags); + LogD("timers full, id[%d], duration[%d], flags[%d]", id, duration, flags); return HTIMER_INVALID; }