一个应用于嵌入式的通用工具包!

李肖遥 2023-04-17 08:00
    关注、星标公众号,直达精彩内容

来源:https://github.com/cproape/toolkit




1、介绍

ToolKit是一套应用于嵌入式系统的通用工具包,可灵活应用到有无RTOS的程序中,采用C语言面向对象的思路实现各个功能,尽可能最大化的复用代码,目前为止工具包包含:循环队列、软件定时器、事件集

  • • Queue 循环队列

  1. 1. 支持动态、静态方式进行队列的创建与删除。

  2. 2. 可独立配置缓冲区大小。

  3. 3. 支持数据最新保持功能,当配置此模式并且缓冲区已满,若有新的数据存入,将会移除最早数据,并保持缓冲区已满。

  • • Timer 软件定时器

    1. 1. 支持动态、静态方式进行定时器的创建与删除。

    2. 2. 支持循环单次模式。

    3. 3. 可配置有无超时回调函数。

    4. 4. 可配置定时器工作在周期间隔模式。

    5. 5. 使用双向链表,超时统一管理,不会因为增加定时器而增加超时判断代码。

  • • Event 事件集

    1. 1. 支持动态、静态方式进行事件集的创建与删除。

    2. 2. 每个事件最大支持32个标志位。

    3. 3. 事件的触发可配置为“标志与”“标志或”

    2 、文件目录

    toolkit
    ├── include                         // 包含文件目录
    |   ├── toolkit.h                   // toolkit头文件
    |   └── toolkit_cfg.h               // toolkit配置文件
    ├── src                             // toolkit源码目录
    |   ├── tk_queue.c                  // 循环队列源码
    |   ├── tk_timer.c                  // 软件定时器源码
    |   └── tk_event.c                  // 事件集源码
    ├── samples                         // 例子
    |   ├── tk_queue_samples.c          // 循环队列使用例程源码
    |   ├── tk_timer_samples.c          // 软件定时器使用例程源码
    |   └── tk_event_samples.c          // 事件集使用例程源码
    └── README.md                       // 说明文档

    3 、函数定义

    3.1 配置文件


    • • ToolKit配置项

      宏定义描述
      TOOLKIT_USING_ASSERTToolKit使用断言功能
      TOOLKIT_USING_QUEUEToolKit使用循环队列功能
      TOOLKIT_USING_TIMERToolKit使用软件定时器功能
      TOOLKIT_USING_EVENTToolKit使用事件集功能
    • • Queue 循环队列配置项

      宏定义描述
      TK_QUEUE_USING_CREATEQueue 循环队列使用动态创建和删除
    • • Timer 软件定时器配置项

      宏定义描述
      TK_TIMER_USING_CREATETimer 软件定时器使用动态创建和删除
      TK_TIMER_USING_INTERVALTimer 软件定时器使用间隔模式
      TK_TIMER_USING_TIMEOUT_CALLBACKTimer 软件定时器使用超时回调函数
    • • Event 事件集配置项

      宏定义描述
      TK_EVENT_USING_CREATEEvent 事件集使用动态创建和删除

    说明:当配置TOOLKIT_USING_ASSERT后,所有功能都将会启动参数检查。

    3.2 Queue 循环队列API函数


    以下为详细API说明及简要示例程序,综合demo可查看tk_queue_samples.c示例。

    3.2.1 动态创建队列

    注意:当配置TOOLKIT_USING_QUEUE后,才能使用此函数。此函数需要用到malloc

    struct tk_queue *tk_queue_create(uint16_t queue_size, uint16_t max_queues, bool keep_fresh);
    参数描述
    queue_size缓存区大小(单位字节)
    max_queues最大队列个数
    keep_fresh是否为保持最新模式,true:保持最新;false:默认(存满不能再存)
    返回值创建的队列对象(NULL为创建失败)

    队列创建示例:

    int main(int argc, char *argv[])
    {
        /* 动态方式创建一个循环队"queue",缓冲区大小50字节,不保持最新 */
        struct tk_queue *queue = tk_queue_create(501false);
        ifqueue == NULL){
            printf("队列创建失败!\n");
        }
        /* ... */
        /* You can add your code under here. */
        return 0;
    }

    3.2.2 动态删除队列

    注意:当配置TOOLKIT_USING_QUEUE后,才能使用此函数。此函数需要用到free。必须为动态方式创建的队列对象。

    bool tk_queue_delete(struct tk_queue *queue);
    参数描述
    queue要删除的队列对象
    返回值true:删除成功;false:删除失败

    3.2.3 静态初始化队列

    bool tk_queue_init(struct tk_queue *queuevoid *queuepool, uint16_t pool_size, uint16_t queue_size, bool keep_fresh);
    参数描述
    queue要初始化的队列对象
    *queuepool队列缓存区
    pool_size缓存区大小(单位字节)
    queue_size队列元素大小(单位字节)
    keep_fresh是否为保持最新模式,true:保持最新;false:默认(存满不能再存)
    返回值true:初始化成功;false:初始化失败

    队列创建示例:

    int main(int argc, char *argv[])
    {
        /* 定义一个循环队列 */
        struct tk_queue queue;
        /* 定义循环队列缓冲区 */
        uint8_t queue_pool[100];
        /* 静态方式创建一个循环队列"queue",缓存区为queue_pool,大小为queue_pool的大小,模式为保持最新 */
        if( tk_queue_init(&queue, queue_pool, sizeof(queue_pool), 
                          sizeof(queue_pool[0]), true) == false){
            printf("队列创建失败!\n");
        }
        /* ... */
        /* You can add your code under here. */
    }

    3.2.4 静态脱离队列

    注意: 会使缓存区脱离与队列的关联。必须为静态方式创建的队列对象。

    bool tk_queue_detach(struct tk_queue *queue);
    参数描述
    queue要脱离的队列对象
    返回值true:脱离成功;false:脱离失败

    3.2.5 清空队列

    bool tk_queue_clean(struct tk_queue *queue);
    参数描述
    queue要清空的队列对象
    返回值true:清除成功;false:清除失败

    3.2.6 判断队列是否为空

    bool tk_queue_empty(struct tk_queue *queue);
    参数描述
    queue要查询的队列对象
    返回值true:空;false:不为空

    3.2.7 判断队列是否已满

    bool tk_queue_full(struct tk_queue *queue);
    参数描述
    queue要查询的队列对象
    返回值true:满;false:不为满

    3.2.8 从队列中读取一个元素(不从队列中删除)

    bool tk_queue_peep(struct tk_queue *queuevoid *pval);
    参数描述
    queue队列对象
    *pval读取值地址
    返回值true:读取成功;false:读取失败

    3.2.9 移除一个元素

    bool tk_queue_remove(struct tk_queue *queue);
    参数描述
    queue要移除元素的对象
    返回值true:移除成功;false:移除失败

    3.2.10 向队列压入(入队)1个元素数据

    bool tk_queue_push(struct tk_queue *queuevoid *val);
    参数描述
    queue要压入的队列对象
    *val压入值
    返回值true:成功;false:失败

    3.2.11 从队列弹出(出队)1个元素数据

    bool tk_queue_pop(struct tk_queue *queuevoid *pval);
    参数描述
    queue要弹出的队列对象
    *pval弹出值
    返回值true:成功;false:失败

    3.2.12 查询队列当前数据长度

    uint16_t tk_queue_curr_len(struct tk_queue *queue);
    参数描述
    queue要查询的队列对象
    返回值队列数据当前长度

    3.2.13 向队列压入(入队)多个元素数据

    uint16_t tk_queue_push_multi(struct tk_queue *queuevoid *pval, uint16_t len);
    参数描述
    queue要压入的队列对象
    *pval压入数据首地址
    len压入元素个数
    返回值实际压入个数

    3.2.14 从队列弹出(出队)多个元素数据

    uint16_t tk_queue_pop_multi(struct tk_queue *queuevoid *pval, uint16_t len);
    参数描述
    queue要弹出的队列对象
    *pval存放弹出数据的首地址
    len希望弹出的数据个数
    返回值实际弹出个数

    3.3 Timer 软件定时器API函数


    以下为详细API说明及简要示例程序,综合demo可查看tk_timer_samples.c示例。

    3.3.1 软件定时器功能初始化

    注意:此函数在使用定时器功能最初调用,目的是创建定时器列表头结点,和配置tick获取回调函数。

    bool tk_timer_func_init(uint32_t (*get_tick_func)(void));
    参数描述
    get_tick_func获取系统tick回调函数
    返回值true:初始化成功;false:初始化失败

    3.3.2 动态创建定时器

    注意:当配置TOOLKIT_USING_TIMER后,才能使用此函数。此函数需要用到malloc

    struct tk_timer *tk_timer_create(void(*timeout_callback)(struct tk_timer *timer));
    参数描述
    timeout_callback定时器超时回调函数,不使用可配置为NULL
    返回值创建的定时器对象(NULL为创建失败)

    定时器创建示例:

    /* 定义获取系统tick回调函数 */
    uint32_t get_sys_tick(void)
    {
        return tick;
    }

    /* 定时器超时回调函数 */
    void timer_timeout_callback(struct tk_timer *timer)
    {
        printf("timeout_callback: timer timeout:%ld\n", get_sys_tick());
    }

    int main(int argc, char *argv[])
    {
        /* 初始化软件定时器功能,并配置tick获取回调函数*/
        tk_timer_func_init(get_sys_tick);
        
        /* 定义定时器指针 */
        tk_timer_t timer = NULL;
        /* 动态方式创建timer,并配置定时器超时回调函数 */
        timer = tk_timer_create((tk_timer_timeout_callback *)timer_timeout_callback);
        if (timer == NULL)
        {
            printf("定时器创建失败!\n");
            return 0;
        }
        /* ... */
        /* You can add your code under here. */
        return 0;
    }

    3.3.3 动态删除定时器

    当配置TOOLKIT_USING_TIMER后,才能使用此函数。此函数需要用到free。必须为动态方式创建的定时器对象。

    bool tk_timer_delete(struct tk_timer *timer);
    参数描述
    timer要删除的定时器对象
    返回值true:删除成功;false:删除失败

    3.3.4 静态初始化定时器

    bool tk_timer_init(struct tk_timer *timer, void (*timeout_callback)(struct tk_timer *timer));
    参数描述
    timer要初始化的定时器对象
    timeout_callback定时器超时回调函数,不使用可配置为NULL
    返回值true:创建成功;false:创建失败

    队列创建示例:

    /* 定义获取系统tick回调函数 */
    uint32_t get_sys_tick(void)
    {
        return tick;
    }

    /* 定时器超时回调函数 */
    void timer_timeout_callback(struct tk_timer *timer)
    {
        printf("timeout_callback: timer timeout:%ld\n", get_sys_tick());
    }

    int main(int argc, char *argv[])
    {
        /* 定义定时器timer */
        struct tk_timer timer;
        bool result = tk_timer_init( &timer,(tk_timer_timeout_callback *)timer_timeout_callback);
        if (result == NULL)
        {
            printf("定时器创建失败!\n");
            return 0;
        }
        /* ... */
        /* You can add your code under here. */
        return 0;
    }

    3.3.5 静态脱离定时器

    注意: 会将timer从定时器链表中移除。必须为静态方式创建的定时器对象。

    bool tk_timer_detach(struct tk_timer *timer);
    参数描述
    timer要脱离的定时器对象
    返回值true:脱离成功;false:脱离失败

    3.3.6 定时器启动

    bool tk_timer_start(struct tk_timer *timer, tk_timer_mode mode, uint32_t delay_tick);
    参数描述
    timer要启动的定时器对象
    mode工作模式,单次: TIMER_MODE_SINGLE循环: TIMER_MODE_LOOP
    delay_tick定时器时长(单位tick)
    返回值true:启动成功;false:启动失败

    3.3.7 定时器停止

    bool tk_timer_stop(struct tk_timer *timer);
    参数描述
    timer要停止的定时器对象
    返回值true:停止成功;false:停止失败

    3.3.8 定时器继续

    bool tk_timer_continue(struct tk_timer *timer);
    参数描述
    timer要继续的定时器对象
    返回值true:继续成功;false:继续失败

    3.3.9 定时器重启

    注意:重启时长为最后一次启动定时器时配置的时长。

    bool tk_timer_restart(struct tk_timer *timer);
    参数描述
    timer要重启的定时器对象
    返回值true:重启成功;false:重启失败

    3.3.10 获取定时器模式

    tk_timer_mode tk_timer_get_mode(struct tk_timer *timer);
    参数描述
    timer要获取的定时器对象
    返回值定时器模式
    定时器模式描述
    TIMER_MODE_SINGLE单次模式
    TIMER_MODE_LOOP循环模式

    3.3.11 获取定时器状态

    tk_timer_state tk_timer_get_state(struct tk_timer *timer);
    参数描述
    timer要获取的定时器对象
    返回值定时器状态
    定时器模式描述
    TIMER_STATE_RUNNING运行状态
    TIMER_STATE_STOP停止状态
    TIMER_STATE_TIMEOUT超时状态

    3.3.12 定时器处理

    bool tk_timer_loop_handler(void);
    参数描述
    返回值true:正常;false:异常,在调用此函数前,未初始化定时器功能“tk_timer_func_init

    注意:tk_timer_loop_handler函数要不断的循环调用。

    3.3.13 超时回调函数

    函数原型

    typedef void (*timeout_callback)(struct tk_timer *timer);

    说明:超时回调函数可定义多个,即一个定时器对应一个回调函数,也可多个定时器对应一个回调函数。

    一对一

    /* 定义两个回调函数,对应定时器timer1和timer2 */
    void timer1_timeout_callback(struct tk_timer *timer){
        printf("定时器1超时!\n");
    }
    void timer2_timeout_callback(struct tk_timer *timer){
        printf("定时器2超时!\n");
    }
    /* 创建两个定时器,配置单独超时回调函数 */
    timer1 = tk_timer_create((timeout_callback *)timer1_timeout_callback);
    timer2 = tk_timer_create((timeout_callback *)timer2_timeout_callback);

    多对一

    /* 定时器timer1和timer2共用一个回调函数,在回调函数做区分 */
    void timer_timeout_callback(struct tk_timer *timer){
        if (timer == timer1)
            printf("定时器1超时!\n");
        else if (timer == timer2)
            printf("定时器2超时!\n");
    }
    /* 创建两个定时器,使用相同的超时回调函数 */
    timer1 = tk_timer_create((timeout_callback *)timer_timeout_callback);
    timer2 = tk_timer_create((timeout_callback *)timer_timeout_callback);

    3.4 Event 事件集API函数


    以下为详细API说明及简要示例程序,综合demo可查看tk_event_samples.c示例。

    3.4.1 动态创建一个事件

    注意:当配置TOOLKIT_USING_EVENT后,才能使用此函数。此函数需要用到malloc

    struct tk_event *tk_event_create(void);
    参数描述
    返回值创建的事件对象(NULL为创建失败)

    3.4.2 动态删除一个事件

    当配置TOOLKIT_USING_TIMER后,才能使用此函数。此函数需要用到free。必须为动态方式创建的事件对象。

    bool tk_event_delete(struct tk_event *event);
    参数描述
    event要删除的事件对象
    返回值true:删除成功;false:删除失败

    3.4.3 静态初始化一个事件

    bool tk_event_init(struct tk_event *event);
    参数描述
    event要初始化的事件对象
    返回值true:创建成功;false:创建失败

    3.4.4 发送事件标志

    bool tk_event_send(struct tk_event *event, uint32_t event_set);
    参数描述
    event发送目标事件对象
    event_set事件标志,每个标志占1Bit,发送多个标志可“|”
    返回值true:发送成功;false:发送失败

    3.4.5 接收事件

    bool tk_event_recv(struct tk_event *event, uint32_t event_set, uint8_t option, uint32_t *recved);
    参数描述
    event接收目标事件对象
    event_set感兴趣的标志,每个标志占1Bit,多个标志可“|”
    option操作,标志与:TK_EVENT_OPTION_AND; 标志或:TK_EVENT_OPTION_OR; 清除标志:TK_EVENT_OPTION_CLEAR
    返回值true:发送成功;false:发送失败

    版权声明:本文来源网络,免费传达知识,版权归原作者所有。如涉及作品版权问题,请联系我进行删除。

    ‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧  END  ‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧

    关注我的微信公众号,回复“加群”按规则加入技术交流群。


    点击“阅读原文”查看更多分享,欢迎点分享、收藏、点赞、在看。

    李肖遥 公众号“技术让梦想更伟大”,作者:李肖遥,专注嵌入式,只推荐适合你的博文,干货,技术心得,与君共勉。
    评论
    • 1月7日-10日,2025年国际消费电子产品展览会(CES 2025)盛大举行,广和通发布Fibocom AI Stack,赋智千行百业端侧应用。Fibocom AI Stack提供集高性能模组、AI工具链、高性能推理引擎、海量模型、支持与服务一体化的端侧AI解决方案,帮助智能设备快速实现AI能力商用。为适应不同端侧场景的应用,AI Stack具备海量端侧AI模型及行业端侧模型,基于不同等级算力的芯片平台或模组,Fibocom AI Stack可将TensorFlow、PyTorch、ONNX、
      物吾悟小通 2025-01-08 18:17 26浏览
    • 故障现象一辆2017款东风风神AX7车,搭载DFMA14T发动机,累计行驶里程约为13.7万km。该车冷起动后怠速运转正常,热机后怠速运转不稳,组合仪表上的发动机转速表指针上下轻微抖动。 故障诊断 用故障检测仪检测,发动机控制单元中无故障代码存储;读取发动机数据流,发现进气歧管绝对压力波动明显,有时能达到69 kPa,明显偏高,推断可能的原因有:进气系统漏气;进气歧管绝对压力传感器信号失真;发动机机械故障。首先从节气门处打烟雾,没有发现进气管周围有漏气的地方;接着拔下进气管上的两个真空
      虹科Pico汽车示波器 2025-01-08 16:51 92浏览
    • 「他明明跟我同梯进来,为什么就是升得比我快?」许多人都有这样的疑问:明明就战绩也不比隔壁同事差,升迁之路却比别人苦。其实,之间的差异就在于「领导力」。並非必须当管理者才需要「领导力」,而是散发领导力特质的人,才更容易被晓明。许多领导力和特质,都可以通过努力和学习获得,因此就算不是天生的领导者,也能成为一个具备领导魅力的人,进而被老板看见,向你伸出升迁的橘子枝。领导力是什么?领导力是一种能力或特质,甚至可以说是一种「影响力」。好的领导者通常具备影响和鼓励他人的能力,并导引他们朝着共同的目标和愿景前
      优思学院 2025-01-08 14:54 82浏览
    • 村田是目前全球量产硅电容的领先企业,其在2016年收购了法国IPDiA头部硅电容器公司,并于2023年6月宣布投资约100亿日元将硅电容产能提升两倍。以下内容主要来自村田官网信息整理,村田高密度硅电容器采用半导体MOS工艺开发,并使用3D结构来大幅增加电极表面,因此在给定的占位面积内增加了静电容量。村田的硅技术以嵌入非结晶基板的单片结构为基础(单层MIM和多层MIM—MIM是指金属 / 绝缘体/ 金属) 村田硅电容采用先进3D拓扑结构在100um内,使开发的有效静电容量面积相当于80个
      知白 2025-01-07 15:02 150浏览
    • 根据环洋市场咨询(Global Info Research)项目团队最新调研,预计2030年全球中空长航时无人机产值达到9009百万美元,2024-2030年期间年复合增长率CAGR为8.0%。 环洋市场咨询机构出版了的【全球中空长航时无人机行业总体规模、主要厂商及IPO上市调研报告,2025-2031】研究全球中空长航时无人机总体规模,包括产量、产值、消费量、主要生产地区、主要生产商及市场份额,同时分析中空长航时无人机市场主要驱动因素、阻碍因素、市场机遇、挑战、新产品发布等。报告从中空长航时
      GIRtina 2025-01-09 10:35 21浏览
    • 在过去十年中,自动驾驶和高级驾驶辅助系统(AD/ADAS)软件与硬件的快速发展对多传感器数据采集的设计需求提出了更高的要求。然而,目前仍缺乏能够高质量集成多传感器数据采集的解决方案。康谋ADTF正是应运而生,它提供了一个广受认可和广泛引用的软件框架,包含模块化的标准化应用程序和工具,旨在为ADAS功能的开发提供一站式体验。一、ADTF的关键之处!无论是奥迪、大众、宝马还是梅赛德斯-奔驰:他们都依赖我们不断发展的ADTF来开发智能驾驶辅助解决方案,直至实现自动驾驶的目标。从新功能的最初构思到批量生
      康谋 2025-01-09 10:04 23浏览
    • 在智能网联汽车中,各种通信技术如2G/3G/4G/5G、GNSS(全球导航卫星系统)、V2X(车联网通信)等在行业内被广泛使用。这些技术让汽车能够实现紧急呼叫、在线娱乐、导航等多种功能。EMC测试就是为了确保在复杂电磁环境下,汽车的通信系统仍然可以正常工作,保护驾乘者的安全。参考《QCT-基于LTE-V2X直连通信的车载信息交互系统技术要求及试验方法-1》标准10.5电磁兼容试验方法,下面将会从整车功能层面为大家解读V2X整车电磁兼容试验的过程。测试过程揭秘1. 设备准备为了进行电磁兼容试验,技
      北汇信息 2025-01-09 11:24 22浏览
    • 光伏逆变器是一种高效的能量转换设备,它能够将光伏太阳能板(PV)产生的不稳定的直流电压转换成与市电频率同步的交流电。这种转换后的电能不仅可以回馈至商用输电网络,还能供独立电网系统使用。光伏逆变器在商业光伏储能电站和家庭独立储能系统等应用领域中得到了广泛的应用。光耦合器,以其高速信号传输、出色的共模抑制比以及单向信号传输和光电隔离的特性,在光伏逆变器中扮演着至关重要的角色。它确保了系统的安全隔离、干扰的有效隔离以及通信信号的精准传输。光耦合器的使用不仅提高了系统的稳定性和安全性,而且由于其低功耗的
      晶台光耦 2025-01-09 09:58 21浏览
    • 一个真正的质量工程师(QE)必须将一件产品设计的“意图”与系统的可制造性、可服务性以及资源在现实中实现设计和产品的能力结合起来。所以,可以说,这确实是一种工程学科。我们常开玩笑说,质量工程师是工程领域里的「侦探」、「警察」或「律师」,守护神是"墨菲”,信奉的哲学就是「墨菲定律」。(注:墨菲定律是一种启发性原则,常被表述为:任何可能出错的事情最终都会出错。)做质量工程师的,有时会不受欢迎,也会被忽视,甚至可能遭遇主动或被动的阻碍,而一旦出了问题,责任往往就落在质量工程师的头上。虽然质量工程师并不负
      优思学院 2025-01-09 11:48 27浏览
    • 本文介绍编译Android13 ROOT权限固件的方法,触觉智能RK3562开发板演示,搭载4核A53处理器,主频高达2.0GHz;内置独立1Tops算力NPU,可应用于物联网网关、平板电脑、智能家居、教育电子、工业显示与控制等行业。关闭selinux修改此文件("+"号为修改内容)device/rockchip/common/BoardConfig.mkBOARD_BOOT_HEADER_VERSION ?= 2BOARD_MKBOOTIMG_ARGS :=BOARD_PREBUILT_DTB
      Industio_触觉智能 2025-01-08 00:06 100浏览
    •  在全球能源结构加速向清洁、可再生方向转型的今天,风力发电作为一种绿色能源,已成为各国新能源发展的重要组成部分。然而,风力发电系统在复杂的环境中长时间运行,对系统的安全性、稳定性和抗干扰能力提出了极高要求。光耦(光电耦合器)作为一种电气隔离与信号传输器件,凭借其优秀的隔离保护性能和信号传输能力,已成为风力发电系统中不可或缺的关键组件。 风力发电系统对隔离与控制的需求风力发电系统中,包括发电机、变流器、变压器和控制系统等多个部分,通常工作在高压、大功率的环境中。光耦在这里扮演了
      晶台光耦 2025-01-08 16:03 80浏览
    我要评论
    0
    点击右上角,分享到朋友圈 我知道啦
    请使用浏览器分享功能 我知道啦