From 2dfab4bef57fbfb63e447c98f7ec410dc3d63bc6 Mon Sep 17 00:00:00 2001 From: coffee Date: Wed, 12 Mar 2025 11:04:56 +0800 Subject: [PATCH] =?UTF-8?q?1.=20init=20bit=20byteStack=20time=20vector?= =?UTF-8?q?=E5=9F=BA=E7=A1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/HBit.h | 89 ++++++++++++++++++++ include/HByteStack.h | 132 +++++++++++++++++++++++++++++ include/HTimer.h | 56 +++++++++++++ include/HVector.h | 142 +++++++++++++++++++++++++++++++ src/HBit.c | 105 +++++++++++++++++++++++ src/HByteStack.c | 159 +++++++++++++++++++++++++++++++++++ src/HTimer.c | 132 +++++++++++++++++++++++++++++ src/HVector.c | 195 +++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 1010 insertions(+) create mode 100644 include/HBit.h create mode 100644 include/HByteStack.h create mode 100644 include/HTimer.h create mode 100644 include/HVector.h create mode 100644 src/HBit.c create mode 100644 src/HByteStack.c create mode 100644 src/HTimer.c create mode 100644 src/HVector.c diff --git a/include/HBit.h b/include/HBit.h new file mode 100644 index 0000000..7d16f3f --- /dev/null +++ b/include/HBit.h @@ -0,0 +1,89 @@ +/** + * 日期: 2025-03-08 + * 作者: coffee + * 描述: 比特数组, 支持多字节 + * 定义上使用宏 HBIT_DEFINE 定义变量名 + * 支持超长比特, 默认支持255比特, 需要更高需定义HBIT_LEN_USE16 或 HBIT_LEN_USE32 + */ + + +#ifndef __H_BIT__ +#define __H_BIT__ + + +#include + +typedef uint8_t HBitType; + +#ifdef HBIT_LEN_USE32 +typedef uint32_t HBitLenType; +typedef uint32_t HBitIndexType; +#elif defined(HBIT_LEN_USE16) +typedef uint16_t HBitLenType; +typedef uint16_t HBitIndexType; +#else +typedef uint8_t HBitLenType; +typedef uint8_t HBitIndexType; +#endif + +/** ============================================================================================= **/ + +// 开头带_的宏都是内部辅助宏, 不需要直接调用 + +enum eHBitFlag { + + kHBitInitFlag = 0x80, +}; + +#pragma pack(1) +typedef struct _HBitBase { + uint8_t flag; + HBitLenType len; + uint8_t data[0]; +} _HBitBase; +#pragma pack() + +#define _HBIT_CALC_LEN(num) (sizeof(_HBitBase) + (((num) + 7) / 8)) + +#ifdef HBIT_LEN_USE32 +#define _HBIT_INIT_SIZE(size) ((size >> 24) & 0xff), ((size >> 16) & 0xff), ((size >> 8) & 0xff), (size & 0xff) +#define _HBIT_INIT_SIZE_INIT(size) ((size[0] << 24) | (size[1] << 16) | (size[2] << 8) | (size[3] & 0xff)) +#elif defined(HBIT_LEN_USE16) +#define _HBIT_INIT_SIZE(size) ((size >> 8) & 0xff), (size & 0xff) +#define _HBIT_INIT_SIZE_INIT(size) ((size[0] << 8) | (size[1] & 0xff)) +#else +#define _HBIT_INIT_SIZE(size) (size & 0xff) +#define _HBIT_INIT_SIZE_INIT(size) (size[0] & 0xff) +#endif + +/** ============================================================================================= **/ + +// 定义HBit变量, name为变量名, num为需要比特长度 +#define HBIT_DEFINE(name, num) HBitType name[_HBIT_CALC_LEN(num)] = { kHBitInitFlag, _HBIT_INIT_SIZE(num), 0 } + +// 声明HBit变量 +#define HBIT_EXTERN(name, num) extern HBitType name[_HBIT_CALC_LEN(num)] + +// 设置比特值 +void HBitSet(HBitType *data, HBitIndexType index, HBitType value); + +// 获取比特值 +HBitType HBitGet(const HBitType *data, HBitIndexType index); + +// 填充比特值 +void HBitFill(HBitType *data, HBitType value); + +// 取反指定位的比特值 +void HBitReverse(HBitType *data, HBitIndexType index); + +// 如果存在任意比特为1, 返回1, 否则返回0 +HBitType HBitAny(const HBitType *data); + +// 如果所有比特为1, 返回1, 否则返回0 +HBitType HBitAll(const HBitType *data); + +// 如果所有比特为0, 返回1, 否则返回0 +HBitType HBitNone(const HBitType *data); + + +#endif //__H_BIT__ diff --git a/include/HByteStack.h b/include/HByteStack.h new file mode 100644 index 0000000..ed70c26 --- /dev/null +++ b/include/HByteStack.h @@ -0,0 +1,132 @@ +/** + * 日期: 2025-03-08 + * 作者: coffee + * 描述: 字节栈, 支持数据为8位, 16位, 32位 + * 长度可最大支持到32位, 需定义宏, 默认支持8位长度 + * 使用宏定义定义变量, HBYTE_STACK_DEFINE(name, size) + */ + + +#ifndef __H_BYTE_STACK_H__ +#define __H_BYTE_STACK_H__ + + +#include + + +typedef uint8_t HByteType; // 栈类型 +typedef uint32_t HByteDataType; // 栈数据类型 + +#ifdef _HBYTE_STACK_LEN_USE32 +typedef uint32_t HByteLenType; +#elif defined(_HBYTE_STACK_LEN_USE16) +typedef uint16_t HByteLenType; +#else +typedef uint8_t HByteLenType; // 栈长度类型 +#endif + +// 失败返回值 +#define HBYTE_STACK_ERROR (-1) + +/** ================================================================================ **/ + +enum eHByteStackFlag { + kHByteStackFlag8 = 0x01, // 数据为8位 + kHByteStackFlag16 = 0x02, // 数据为16位 + kHByteStackFlag32 = 0x04, // 数据为32位 + + kHByteStackFlagAllMask = 0x07, // 栈数据类型掩码 + + kHByteStackNeedInit = 0x80, // 需要初始化 +}; + +#pragma pack(1) +typedef struct _HByteStackBase { + uint8_t flag; + HByteLenType len; + HByteLenType useLen; +} _HByteStackBase; + +typedef struct _HByteStack8 { + _HByteStackBase base; + uint8_t data[]; +} _HByteStack8; + +typedef struct _HByteStack16 { + _HByteStackBase base; + uint16_t data[]; +} _HByteStack16; + +typedef struct _HByteStack32 { + _HByteStackBase base; + uint32_t data[]; +} _HByteStack32; +#pragma pack() + +// 用于支持多数据类型的宏 +#define _HBYTE_STACK_CALC_LEN8(num) (sizeof(_HByteStack8) + num) +#define _HBYTE_STACK_CALC_LEN16(num) (sizeof(_HByteStack16) + num * sizeof(uint16_t)) +#define _HBYTE_STACK_CALC_LEN32(num) (sizeof(_HByteStack32) + num * sizeof(uint32_t)) +#define _HBYTE_STACK_CALC_LEN(num, type) (_HBYTE_STACK_CALC_LEN##type(num)) + +// 用于辅助数值初始化 +#ifdef _HBYTE_STACK_LEN_USE32 +#define _HBYTE_STACK_INIT_SIZE(size) ((size >> 24) & 0xff), ((size >> 16) & 0xff), ((size >> 8) & 0xff), (size & 0xff) +#define _HBYTE_STACK_INIT_SIZE_INIT(size) ((size[0] << 24) | (size[1] << 16) | (size[2] << 8) | (size[3] & 0xff)) +#elif defined(_HBYTE_STACK_LEN_USE16) +#define _HBYTE_STACK_INIT_SIZE(size) ((size >> 8) & 0xff), (size & 0xff) +#define _HBYTE_STACK_INIT_SIZE_INIT(size) ((size[0] << 8) | (size[1] & 0xff)) +#else +#define _HBYTE_STACK_INIT_SIZE(size) (size & 0xff) +#define _HBYTE_STACK_INIT_SIZE_INIT(size) (size[0] & 0xff) +#endif + +// 用于初始化栈数据 +#define _HBYTE_STACK_INIT8(size) { kHByteStackNeedInit | kHByteStackFlag8, _HBYTE_STACK_INIT_SIZE(size), _HBYTE_STACK_INIT_SIZE(0)} +#define _HBYTE_STACK_INIT16(size) { kHByteStackNeedInit | kHByteStackFlag16, _HBYTE_STACK_INIT_SIZE(size), _HBYTE_STACK_INIT_SIZE(0)} +#define _HBYTE_STACK_INIT32(size) { kHByteStackNeedInit | kHByteStackFlag32, _HBYTE_STACK_INIT_SIZE(size), _HBYTE_STACK_INIT_SIZE(0)} +#define _HBYTE_STACK_INIT(size, type) _HBYTE_STACK_INIT##type(size) + +/** ================================================================================ **/ + +// 定义字节栈, name: 栈名, size: 栈长度 +#define HBYTE_STACK_DEFINE(name, size) HByteType name[_HBYTE_STACK_CALC_LEN(size, 8)] = _HBYTE_STACK_INIT(size, 8) +#define HBYTE_STACK_DEFINE16(name, size) HByteType name[_HBYTE_STACK_CALC_LEN(size, 16)] = _HBYTE_STACK_INIT(size, 16) +#define HBYTE_STACK_DEFINE32(name, size) HByteType name[_HBYTE_STACK_CALC_LEN(size, 32)] = _HBYTE_STACK_INIT(size, 32) + +// 声明字节栈, name: 栈名, size: 栈长度 +#define HBYTE_STACK_EXTERN(name, size) extern HByteType name[_HBYTE_STACK_CALC_LEN(size, 8)] +#define HBYTE_STACK_EXTERN16(name, size) extern HByteType name[_HBYTE_STACK_CALC_LEN(size, 16)] +#define HBYTE_STACK_EXTERN32(name, size) extern HByteType name[_HBYTE_STACK_CALC_LEN(size, 32)] + +// 入栈, 成功返回1, 失败返回 0 +uint8_t HByteStackPush(HByteType *stackData, HByteDataType value); + +// 出栈, 成功返回出栈数据, 失败返回 HBYTE_STACK_ERROR +HByteDataType HByteStackPop(HByteType *stackData); + +// 返回栈顶数据, 失败返回 HBYTE_STACK_ERROR +HByteDataType HByteStackTop(const HByteType *stackData); + +// 返回栈长度 +HByteLenType HByteStackLen(const HByteType *stackData); + +// 返回栈是否为空 +uint8_t HByteStackEmpty(const HByteType *stackData); + +// 清空栈 +void HByteStackClear(HByteType *stackData); + +// 从栈顶开始查找, 成功返回位置, 失败返回 HBYTE_STACK_ERROR +HByteLenType HByteStackFind(const HByteType *stackData, HByteDataType value); + +// 即当前栈位置 +HByteLenType HByteStackGetUseLen(const HByteType *stackData); + +// 设置当前栈位置, 设置超过当前栈位置则不修改 +void HByteStackSetUseLen(HByteType *stackData, HByteLenType pos); + +// 返回栈中指定元素元素个数, 不存在返回0 +HByteLenType HByteStackCount(const HByteType *stackData, HByteDataType value); + +#endif //__H_BYTE_STACK_H__ diff --git a/include/HTimer.h b/include/HTimer.h new file mode 100644 index 0000000..23c11bd --- /dev/null +++ b/include/HTimer.h @@ -0,0 +1,56 @@ +/** + * 日期: 2025-03-08 + * 作者: coffee + * 描述: 毫秒级定时器, 添加即可使用, 定时器最大数量为 HTIMER_MAX + */ + + +#ifndef __H_TIMER_H__ +#define __H_TIMER_H__ + + +#include + +// 定时器最大数量 +#ifndef HTIMER_MAX +#define HTIMER_MAX 10 +#endif + +#ifndef HTIMER_INVALID +#define HTIMER_INVALID -1 +#endif + +// 检查添加定时任务超出限制后进入死循环, 方便调试 +#ifdef HTIMER_CHECK_LOOP +#define HTIMER_CHECK_INVALID_LOOP +#endif + + +typedef enum +{ + kHTimerOnce = 0, ///< 仅执行一次 + kHTimerLoop, ///< 循环执行 +} eHTimerFlags; + + +typedef void (*HTimerCallType)(); + +///< 初始化毫秒定时器, 需要传递获取毫秒的函数 +void HTimerInitMs(uint32_t (*func)(void)); + +///< 获取毫秒 +uint32_t HTimerGetMs(); + +///< 运行定时器可执行任务, 需要在主循环中调用 +void HTimerRun(); + +///< 添加一个定时任务, 添加失败返回 HTIMER_INVALID, ms不超过24比特 +int16_t HTimerAdd(uint32_t ms, HTimerCallType call, eHTimerFlags flags); + +///< 移除一个定时任务 +void HTimerRemove(int16_t index); + +///< 在定时器回调任务中获取当前定时器调用者索引, 不存在返回 HTIMER_INVALID +int16_t HTimerGetCurrentCaller(); + +#endif //__H_TIMER_H__ diff --git a/include/HVector.h b/include/HVector.h new file mode 100644 index 0000000..6e0443d --- /dev/null +++ b/include/HVector.h @@ -0,0 +1,142 @@ +/** + * 日期: 2025-03-08 + * 作者: coffee + * 描述: vector数组, 可用于存储8, 16, 32位数据 + * 长度可扩展到4字节, 需定义宏, 默认1字节长度 + * 使用宏定义变量, HVECTOR_DEFINE + */ + + +#ifndef _H_VECTOR_H +#define _H_VECTOR_H + + +#include + + +enum eHVectorFlag { + kHVectorFlag8 = 0x01, // 数据8位 + kHVectorFlag16 = 0x02, // 数据16位 + kHVectorFlag32 = 0x04, // 数据32位 + + kHVectorFlagAllMask = 0x07, // 数据掩码 + + kHVectorNeedInit = 0x80, // 需要初始化 +}; + +#define HVECTOR_ERROR (-1) + +typedef uint8_t HVectorType; // vector类型 +typedef uint32_t HVectorDataType; // vector统一数据类型 + +#ifdef _HVECTOR_LEN_USE32 +typedef uint32_t HVectorLenType; +#elif defined(_HVECTOR_LEN_USE16) +typedef uint16_t HVectorLenType; +#else +typedef uint8_t HVectorLenType; // vector长度类型 +#endif + +#pragma pack(1) + +typedef struct _HVectorBase { + uint8_t flag; + HVectorLenType len; + HVectorLenType useLen; +} _HVectorBase; + +typedef struct _HVector8 { + _HVectorBase base; + uint8_t data[0]; +} _HVector8; + +typedef struct _HVector16 { + _HVectorBase base; + uint16_t data[0]; +} _HVector16; + +typedef struct _HVector32 { + _HVectorBase base; + uint32_t data[0]; +} _HVector32; +#pragma pack() + +// 用于支持多数据类型的宏 +#define _HVECTOR_CALC_LEN8(len) (sizeof(_HVector8) + (len)) +#define _HVECTOR_CALC_LEN16(len) (sizeof(_HVector16) + (len) * sizeof(uint16_t)) +#define _HVECTOR_CALC_LEN32(len) (sizeof(_HVector32) + (len) * sizeof(uint32_t)) +#define _HVECTOR_CALC_LEN(num, type) (_HVECTOR_CALC_LEN##type(num)) + +// 用于辅助多类型数值计算 +#ifdef _HVECTOR_LEN_USE32 +#define _HVECTOR_INIT_SIZE(size) ((size >> 24) & 0xff), ((size >> 16) & 0xff), ((size >> 8) & 0xff), (size & 0xff) +#define _HVECTOR_INIT_SIZE_INIT(size) ((size[0] << 24) | (size[1] << 16) | (size[2] << 8) | (size[3] & 0xff)) +#elif defined(_HVECTOR_LEN_USE16) +#define _HVECTOR_INIT_SIZE(size) ((size >> 8) & 0xff), (size & 0xff) +#define _HVECTOR_INIT_SIZE_INIT(size) ((size[0] << 8) | (size[1] & 0xff)) +#else +#define _HVECTOR_INIT_SIZE(size) (size & 0xff) +#define _HVECTOR_INIT_SIZE_INIT(size) (size[0] & 0xff) +#endif + +// 用于初始化vector宏 +#define _HVECTOR_INIT8(size) { kHVectorNeedInit | kHVectorFlag8, _HVECTOR_INIT_SIZE(size), _HVECTOR_INIT_SIZE(0) } +#define _HVECTOR_INIT16(size) { kHVectorNeedInit | kHVectorFlag16, _HVECTOR_INIT_SIZE(size), _HVECTOR_INIT_SIZE(0) } +#define _HVECTOR_INIT32(size) { kHVectorNeedInit | kHVectorFlag32, _HVECTOR_INIT_SIZE(size), _HVECTOR_INIT_SIZE(0) } +#define _HVECTOR_INIT(size, type) _HVECTOR_INIT##type(size) + +/** ================================================================================ **/ + + +// 定义vector, name为变量名, size为数据长度 +#define HVECTOR_DEFINE(name, size) HVectorType name[_HVECTOR_CALC_LEN(size, 8)] = _HVECTOR_INIT(size, 8) +#define HVECTOR_DEFINE16(name, size) HVectorType name[_HVECTOR_CALC_LEN(size, 16)] = _HVECTOR_INIT(size, 16) +#define HVECTOR_DEFINE32(name, size) HVectorType name[_HVECTOR_CALC_LEN(size, 32)] = _HVECTOR_INIT(size, 32) + +#define HVECTOR_EXTERN(name, size) extern HVectorType name[_HVECTOR_CALC_LEN(size, 8)] +#define HVECTOR_EXTERN16(name, size) extern HVectorType name[_HVECTOR_CALC_LEN(size, 16)] +#define HVECTOR_EXTERN32(name, size) extern HVectorType name[_HVECTOR_CALC_LEN(size, 32)] + + +// 添加数据, 成功返回1, 失败返回 0 +uint8_t HVectorAddData(HVectorType *vector, HVectorDataType data); +// 添加字节数据, 超出仅复制到最大长度 +void HVectorAddBytes(HVectorType *vector, const uint8_t *datas, HVectorLenType byteLen); +// 添加对应格式数据, 要求datas类型是同一对应位类型, 长度为字节长度, 超出仅复制到最大长度 +void HVectorAddDatas(HVectorType *vector, const void *datas, HVectorLenType byteLen); + +// 获取数据, 失败返回 HVECTOR_ERROR +HVectorDataType HVectorGetData(HVectorType *vector, HVectorLenType index); +// 超出位置返回NULL, 数据长度是根据字节长度 +void *HVectorGetByteDataPtr(HVectorType *vector, HVectorLenType pos); +// 超出位置返回NULL, 数据长度是根据类型长度的, 非字节长度 +void *HVectorGetDataPtr(HVectorType *vector, HVectorLenType pos); + +// 获取数据总长度 +HVectorLenType HVectorGetLen(HVectorType *vector); + +// 获取数据字节总长度 +HVectorLenType HVectorGetByteLen(HVectorType *vector); + +// 获取数据使用长度 +HVectorLenType HVectorGetUseLen(HVectorType *vector); + +// 获取数据使用字节长度 +HVectorLenType HVectorGetUseByteLen(HVectorType *vector); + +// 清空数据 +void HVectorClear(HVectorType *vector); + +// 设置数据使用长度, 超过使用长度则不修改 +void HVectorSetUseLen(HVectorType *vector, HVectorLenType len); + +// 查找数据, 返回索引, 不存在返回 HVECTOR_ERROR +HVectorLenType HVectorFindData(HVectorType *vector, HVectorDataType data); + +// 判断数据是否为空 +uint8_t HVectorEmpty(HVectorType *vector); + +// 移除数据 +void HVectorRemoveData(HVectorType *vector, HVectorLenType index, HVectorLenType len); + +#endif // _H_VECTOR_H diff --git a/src/HBit.c b/src/HBit.c new file mode 100644 index 0000000..5bd44fa --- /dev/null +++ b/src/HBit.c @@ -0,0 +1,105 @@ + + +#include + +static void InitHBit(HBitType *data) { + if ((data[0] & kHBitInitFlag) == 0) { + return; + } + + _HBitBase *base = (_HBitBase *)data; + base->flag &= ~kHBitInitFlag; + uint8_t *len = (uint8_t *)&base->len; + base->len = _HBIT_INIT_SIZE_INIT(len); +} + +static HBitLenType GetBitLen(const HBitType *data) { + const _HBitBase *base = (const _HBitBase *)data; + InitHBit((HBitType *)data); + return base->len; +} + +static void SetBit(HBitType *data, HBitIndexType index, HBitType value) { + _HBitBase *base = (_HBitBase *)data; + base->data[index / 8] = (base->data[index / 8] & ~(0x01 << (index % 8))) | ((!!value) << (index % 8)); +} + +static HBitType GetBit(const HBitType *data, HBitIndexType index) { + _HBitBase *base = (_HBitBase *)data; + return (base->data[index / 8] >> (index % 8)) & 0x01; +} + +void HBitSet(HBitType *data, HBitIndexType index, HBitType value) { + if (index >= GetBitLen(data)) { + return ; + } + + SetBit(data, index, value); +} + + +HBitType HBitGet(const HBitType *data, HBitIndexType index) { + if (index >= GetBitLen(data)) { + return 0; + } + + return GetBit(data, index); +} + + +void HBitFill(HBitType *data, HBitType value) { + InitHBit(data); + _HBitBase *base = (_HBitBase *)data; + for (int i = 0; i < base->len / 8; ++i) { + base->data[i] = value ? 0xFF : 0x00; + } + + for (int i = base->len / 8 * 8; i < base->len; ++i) { + SetBit(data, i, value); + } +} + + +void HBitReverse(HBitType *data, HBitIndexType index) { + HBitSet(data, index, !HBitGet(data, index)); +} + +HBitType HBitAny(const HBitType *data) { + const _HBitBase *base = (_HBitBase *)data; + InitHBit((HBitType *)data); + for (int i = 0; i < base->len / 8; ++i) { + if (base->data[i] != 0x00) { + return 1; + } + } + + for (int i = base->len / 8 * 8; i < base->len; ++i) { + if (HBitGet(data, i)) { + return 1; + } + } + + return 0; +} + +HBitType HBitAll(const HBitType *data) { + const _HBitBase *base = (_HBitBase *)data; + InitHBit((HBitType *)data); + for (int i = 0; i < base->len / 8; ++i) { + if (base->data[i] != 0xFF) { + return 0; + } + } + + for (int i = base->len / 8 * 8; i < base->len; ++i) { + if (!HBitGet(data, i)) { + return 0; + } + } + + return 1; +} + +HBitType HBitNone(const HBitType *data) { + return !HBitAny(data); +} diff --git a/src/HByteStack.c b/src/HByteStack.c new file mode 100644 index 0000000..b4a424c --- /dev/null +++ b/src/HByteStack.c @@ -0,0 +1,159 @@ + + +#include + + +static void InitStack(HByteType *stackData) { + if ((stackData[0] & kHByteStackNeedInit) == 0) { + return; + } + + // 初始化, 需要纠正长度数据, 因多字节时候存在大小端问题 + _HByteStackBase *base = (_HByteStackBase *)stackData; + base->flag &= ~kHByteStackNeedInit; + uint8_t *len = (uint8_t *)&base->len; + base->len = _HBYTE_STACK_INIT_SIZE_INIT(len); + len = (uint8_t *)&base->useLen; + base->useLen = _HBYTE_STACK_INIT_SIZE_INIT(len); +} + +// 获取栈类型 +static uint8_t GetStackType(const HByteType *stackData) { + InitStack((HByteType *)stackData); + _HByteStackBase *base = (_HByteStackBase *)stackData; + return base->flag & kHByteStackFlagAllMask; +} + +static HByteDataType GetStackData(const HByteType *stackData, HByteLenType pos) { + switch (GetStackType(stackData)) { + case kHByteStackFlag8: return ((const _HByteStack8 *)stackData)->data[pos]; break; + case kHByteStackFlag16: return ((const _HByteStack16 *)stackData)->data[pos]; break; + case kHByteStackFlag32: return ((const _HByteStack32 *)stackData)->data[pos]; break; + } + + return HBYTE_STACK_ERROR; +} + +static void SetStackData(HByteType *stackData, HByteLenType pos, HByteDataType data) { + switch (GetStackType(stackData)) { + case kHByteStackFlag8: ((_HByteStack8 *)stackData)->data[pos] = (uint8_t)data; break; + case kHByteStackFlag16: ((_HByteStack16 *)stackData)->data[pos] = (uint16_t)data; break; + case kHByteStackFlag32: ((_HByteStack32 *)stackData)->data[pos] = (uint32_t)data; break; + } +} + +// 获取栈长度 +static HByteLenType GetStackLen(const HByteType *stackData) { + const _HByteStackBase *base = (const _HByteStackBase *)stackData; + InitStack((HByteType *)stackData); + + if ((base->flag & kHByteStackFlagAllMask) == 0) { + return 0; + } + + return base->len; +} + +static HByteLenType GetStackUseLen(const HByteType *stackData) { + const _HByteStackBase *base = (const _HByteStackBase *)stackData; + InitStack((HByteType *)stackData); + + if ((base->flag & kHByteStackFlagAllMask) == 0) { + return 0; + } + + return base->useLen; +} + +static void SetStackUseLen(HByteType *stackData, HByteLenType len) { + _HByteStackBase *base = (_HByteStackBase *)stackData; + InitStack((HByteType *)stackData); + + if ((base->flag & kHByteStackFlagAllMask) == 0) { + return ; + } + + base->useLen = len; +} + +uint8_t HByteStackPush(HByteType *stackData, HByteDataType value) { + if (GetStackUseLen(stackData) >= GetStackLen(stackData)) { + return 0; + } + + HByteLenType len = GetStackUseLen(stackData); + SetStackData(stackData, len, value); + SetStackUseLen(stackData, len + 1); + return 1; +} + +HByteDataType HByteStackPop(HByteType *stackData) { + if (HByteStackEmpty(stackData)) { + return HBYTE_STACK_ERROR; + } + + HByteLenType len = GetStackUseLen(stackData) - 1; + SetStackUseLen(stackData, len); + return GetStackData(stackData, len); +} + +HByteDataType HByteStackTop(const HByteType *stackData) { + if (HByteStackEmpty(stackData)) { + return HBYTE_STACK_ERROR; + } + + return GetStackData(stackData, GetStackUseLen(stackData) - 1); +} + +HByteLenType HByteStackLen(const HByteType *stackData) { + return GetStackLen(stackData); +} + +uint8_t HByteStackEmpty(const HByteType *stackData) { + return GetStackUseLen(stackData) == 0; +} + +void HByteStackClear(HByteType *stackData) { + SetStackUseLen(stackData, 0); +} + +HByteLenType HByteStackFind(const HByteType *stackData, HByteDataType value) { + if (HByteStackEmpty(stackData)) { + return HBYTE_STACK_ERROR; + } + + for (HByteLenType i = GetStackUseLen(stackData); i-- > 0;) { + if (GetStackData(stackData, i) == value) { + return i; + } + } + + return HBYTE_STACK_ERROR; +} + +HByteLenType HByteStackGetUseLen(const HByteType *stackData) { + return GetStackUseLen(stackData); +} + +void HByteStackSetUseLen(HByteType *stackData, HByteLenType pos) { + if (pos >= HByteStackGetUseLen(stackData)) { + return; + } + + SetStackUseLen(stackData, pos); +} + +HByteLenType HByteStackCount(const HByteType *stackData, HByteDataType value) { + if (HByteStackEmpty(stackData)) { + return 0; + } + + HByteType count = 0; + for (HByteType i = GetStackUseLen(stackData); i-- > 0;) { + if (GetStackData(stackData, i) == value) { + ++count; + } + } + + return count; +} diff --git a/src/HTimer.c b/src/HTimer.c new file mode 100644 index 0000000..7a72853 --- /dev/null +++ b/src/HTimer.c @@ -0,0 +1,132 @@ + + +#include + + +static uint32_t (*GetCurrentMs)(void); + +#define CHECK_VALUE (0x0FFFFFFF) + +struct Timer { + uint32_t flags : 1; ///< 定时器标志, eTimerFlags + uint32_t enable : 1; ///< 定时器使能 + uint32_t curr : 1; ///< 当前回调者 + uint32_t duration : 29; ///< 定时触发时长, 毫秒为计数单元 + uint32_t lastTime; ///< 上次触发时间 + HTimerCallType call; ///< 定时触发函数 +}; + + +static struct Timer timers[HTIMER_MAX]; + + +static void CallTimer(int16_t index) { + if (index < 0 || index >= HTIMER_MAX) { + return ; + } + + timers[index].curr = 1; + if (timers[index].flags == kHTimerOnce) { + timers[index].enable = 0; + } + + timers[index].call(); + timers[index].curr = 0; + timers[index].lastTime = GetCurrentMs(); +} + +static int16_t AddTimerData(uint32_t duration, HTimerCallType call, eHTimerFlags flags) { + if (!GetCurrentMs) { + return HTIMER_INVALID; + } + + if ((duration & ~CHECK_VALUE) != 0) { + return HTIMER_INVALID; + } + + for (uint16_t i = 0; i < HTIMER_MAX; ++i) { + if (timers[i].enable == 1) { + continue; + } + + timers[i].enable = 1; + timers[i].duration = duration; + timers[i].lastTime = GetCurrentMs(); + timers[i].call = call; + timers[i].flags = flags; + return i; + } + + return HTIMER_INVALID; +} + +void HTimerInitMs(uint32_t (*func)(void)) { + GetCurrentMs = func; +} + +uint32_t HTimerGetMs() { + if (!GetCurrentMs) { + return 0; + } + + return GetCurrentMs(); +} + +void HTimerRun() { + if (!GetCurrentMs) { + return ; + } + + // 没必要每次都扫描, 当时间更新时再检查 + static uint32_t lastMs = 0; + if (lastMs == GetCurrentMs()) { + return ; + } + lastMs = GetCurrentMs(); + + for (uint16_t i = 0; i < HTIMER_MAX; ++i) { + if (timers[i].enable == 0) { + continue; + } + + // 这里每次都获取最新时间是因为执行任务期间可能会导致时间变化 + uint32_t diff = GetCurrentMs() - timers[i].lastTime; + uint32_t timeDuration = timers[i].duration; + if (diff < timeDuration) { + continue; + } + + CallTimer(i); + } +} + +int16_t HTimerAdd(uint32_t ms, HTimerCallType call, eHTimerFlags flags) { +#ifdef HTIMER_CHECK_INVALID_LOOP + int16_t result = AddTimerData(ms, call, flags); + if (result == HTIMER_INVALID) { + while (1); + } + return result; +#else + return AddTimerData(ms, call, flags); +#endif +} + +void HTimerRemove(int16_t index) { + if (index < 0 || index >= HTIMER_MAX) { + return ; + } + + timers[index].enable = 0; +} + +int16_t HTimerGetCurrentCaller() { + for (uint16_t i = 0; i < HTIMER_MAX; ++i) { + if (timers[i].curr == 1) { + return i; + } + } + + return HTIMER_INVALID; +} + diff --git a/src/HVector.c b/src/HVector.c new file mode 100644 index 0000000..952f79a --- /dev/null +++ b/src/HVector.c @@ -0,0 +1,195 @@ + + +#include +#include + +static void InitVector(HVectorType *vector) { + if ((vector[0] & kHVectorNeedInit) == 0) { + return ; + } + + _HVectorBase *base = (_HVectorBase *)vector; + base->flag &= ~kHVectorNeedInit; + uint8_t *len = (uint8_t *)&base->len; + base->len = _HVECTOR_INIT_SIZE_INIT(len); + len = (uint8_t *)&base->useLen; + base->useLen = _HVECTOR_INIT_SIZE_INIT(len); +} + +static uint8_t GetVectorType(const HVectorType *vector) { + InitVector((HVectorType *)vector); + const _HVectorBase *base = (const _HVectorBase *)vector; + return base->flag & kHVectorFlagAllMask; +} + +static HVectorLenType GetVectorTypeSize(const HVectorType *vector) { + switch(GetVectorType(vector)) { + case kHVectorFlag8: return sizeof(uint8_t); break; + case kHVectorFlag16: return sizeof(uint16_t); break; + case kHVectorFlag32: return sizeof(uint32_t); break; + } + + return 0; +} + +static HVectorDataType GetVectorData(const HVectorType *vector, HVectorLenType pos) { + switch(GetVectorType(vector)) { + case kHVectorFlag8: return ((const _HVector8 *)vector)->data[pos]; break; + case kHVectorFlag16: return ((const _HVector16 *)vector)->data[pos]; break; + case kHVectorFlag32: return ((const _HVector32 *)vector)->data[pos]; break; + } + + return HVECTOR_ERROR; +} + +static void SetVectorData(HVectorType *vector, HVectorLenType pos, HVectorDataType data) { + switch(GetVectorType(vector)) { + case kHVectorFlag8: ((_HVector8 *)vector)->data[pos] = (uint8_t)data; break; + case kHVectorFlag16: ((_HVector16 *)vector)->data[pos] = (uint16_t)data; break; + case kHVectorFlag32: ((_HVector32 *)vector)->data[pos] = (uint32_t)data; break; + } +} + +static HVectorLenType GetVectorLen(const HVectorType *vector) { + const _HVectorBase *base = (const _HVectorBase *)vector; + InitVector((HVectorType *)vector); + return base->len; +} + +static HVectorLenType GetVectorUseLen(const HVectorType *vector) { + const _HVectorBase *base = (const _HVectorBase *)vector; + InitVector((HVectorType *)vector); + return base->useLen; +} + +static HVectorLenType GetVectorByteLen(const HVectorType *vector) { + return GetVectorTypeSize(vector) * ((const _HVectorBase *)vector)->len; +} + +static HVectorLenType GetVectorByteUseLen(const HVectorType *vector) { + return GetVectorTypeSize(vector) * ((const _HVectorBase *)vector)->useLen; +} + +static void *GetVectorDataBytePtr(HVectorType *vector, HVectorLenType bytePos) { + if (bytePos >= GetVectorByteLen(vector)) { + return NULL; + } + + return ((_HVector8 *)vector)->data + bytePos; +} + +static void *GetVectorDataPtr(HVectorType *vector, HVectorLenType pos) { + return GetVectorDataBytePtr(vector, pos * GetVectorTypeSize(vector)); +} + +static void SetVectorUseLen(HVectorType *vector, HVectorLenType len) { + _HVectorBase *base = (_HVectorBase *)vector; + InitVector((HVectorType *)vector); + base->useLen = len; +} + + +uint8_t HVectorAddData(HVectorType *vector, HVectorDataType data) { + HVectorLenType len = GetVectorUseLen(vector); + if (len >= GetVectorLen(vector)) { + return 0; + } + + SetVectorData(vector, len, data); + SetVectorUseLen(vector, len + 1); + return 1; +} + +void HVectorAddBytes(HVectorType *vector, const uint8_t *datas, HVectorLenType byteLen) { + HVectorLenType useLen = GetVectorUseLen(vector); + HVectorLenType maxLen = GetVectorByteLen(vector) - useLen; + HVectorLenType typeSize = GetVectorTypeSize(vector); + if (byteLen > maxLen) { + byteLen = maxLen; + } + + if (byteLen == 0) { + return; + } + + uint8_t *dest = (uint8_t *)GetVectorDataBytePtr(vector, GetVectorByteUseLen(vector)); + memcpy(dest, datas, byteLen); + SetVectorUseLen(vector, useLen + (byteLen + typeSize - 1) / typeSize); +} + +void HVectorAddDatas(HVectorType *vector, const void *datas, HVectorLenType byteLen) { + HVectorAddBytes(vector, (const uint8_t *)datas, byteLen * GetVectorTypeSize(vector)); +} + +// 获取数据, 失败返回 HVECTOR_ERROR +HVectorDataType HVectorGetData(HVectorType *vector, HVectorLenType index) { + return GetVectorData(vector, index); +} + +// 超出位置返回NULL, 数据长度是根据字节长度 +void *HVectorGetByteDataPtr(HVectorType *vector, HVectorLenType pos) { + return GetVectorDataBytePtr(vector, pos); +} + +void *HVectorGetDataPtr(HVectorType *vector, HVectorLenType pos) { + return GetVectorDataPtr(vector, pos); +} + +HVectorLenType HVectorGetLen(HVectorType *vector) { + return GetVectorLen(vector); +} + +HVectorLenType HVectorGetByteLen(HVectorType *vector) { + return GetVectorByteLen(vector); +} + +HVectorLenType HVectorGetUseLen(HVectorType *vector) { + return GetVectorUseLen(vector); +} + +HVectorLenType HVectorGetUseByteLen(HVectorType *vector) { + return GetVectorByteUseLen(vector); +} + +void HVectorClear(HVectorType *vector) { + SetVectorUseLen(vector, 0); +} + +void HVectorSetUseLen(HVectorType *vector, HVectorLenType len) { + if (len >= GetVectorUseLen(vector)) { + return; + } + + SetVectorUseLen(vector, len); +} + +// 查找数据, 返回索引, 不存在返回 HVECTOR_ERROR +HVectorLenType HVectorFindData(HVectorType *vector, HVectorDataType data) { + for (HVectorLenType i = 0; i < GetVectorUseLen(vector); ++i) { + if (GetVectorData(vector, i) == data) { + return i; + } + } + + return HVECTOR_ERROR; +} + +uint8_t HVectorEmpty(HVectorType *vector) { + return GetVectorUseLen(vector) == 0; +} + +void HVectorRemoveData(HVectorType *vector, HVectorLenType index, HVectorLenType len) { + if (index >= GetVectorUseLen(vector)) { + return; + } + + if (index + len > GetVectorUseLen(vector)) { + SetVectorUseLen(vector, index); + return; + } + + void *src = GetVectorDataPtr(vector, index + len); + void *dest = GetVectorDataPtr(vector, index); + memcpy(dest, src, (GetVectorUseLen(vector) - index - len) * GetVectorTypeSize(vector)); + SetVectorUseLen(vector, GetVectorUseLen(vector) - len); +}