嵌入式软件开发的通用工具包ToolKit(开源)

一起学嵌入式 2023-05-22 07:50

扫描关注一起学嵌入式,一起学习,一起成长


1、介绍

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

仓库地址(浏览器中打开):
https://github.com/cproape/toolkit

• Queue 循环队列

    支持动态、静态方式进行队列的创建与删除。
    可独立配置缓冲区大小。

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

• Timer 软件定时器

    支持动态、静态方式进行定时器的创建与删除。
    支持循环单次模式。
    可配置有无超时回调函数。
    可配置定时器工作在周期间隔模式。
    使用双向链表,超时统一管理,不会因为增加定时器而增加超时判断代码。

• Event 事件集

    支持动态、静态方式进行事件集的创建与删除。
    每个事件最大支持32个标志位。

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

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 *queue, void *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 *queue, void *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 *queue, void *val);


参数描述
queue要压入的队列对象
*val压入值
返回值true:成功;false:失败

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

bool tk_queue_pop(struct tk_queue *queue, void *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 *queue, void *pval, uint16_t len);


参数描述
queue要压入的队列对象
*pval压入数据首地址
len压入元素个数
返回值实际压入个数

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

uint16_t tk_queue_pop_multi(struct tk_queue *queue, void *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:发送失败

【资源获取】:

(1)自己从git仓库拉取。

(2)公众号后台回复【2011】,获取打包好的项目文件。


个人微信开放,扫码添加,进高质量嵌入式交流群


关注我【一起学嵌入式】,一起学习,一起成长。


觉得文章不错,点击“分享”、“”、“在看” 呗!

一起学嵌入式 公众号【一起学嵌入式】,RTOS、Linux编程、C/C++,以及经验分享、行业资讯、物联网等技术知
评论
  • 光耦合器作为关键技术组件,在确保安全性、可靠性和效率方面发挥着不可或缺的作用。无论是混合动力和电动汽车(HEV),还是军事和航空航天系统,它们都以卓越的性能支持高要求的应用环境,成为现代复杂系统中的隐形功臣。在迈向更环保技术和先进系统的过程中,光耦合器的重要性愈加凸显。1.混合动力和电动汽车中的光耦合器电池管理:保护动力源在电动汽车中,电池管理系统(BMS)是最佳充电、放电和性能监控背后的大脑。光耦合器在这里充当守门人,将高压电池组与敏感的低压电路隔离开来。这不仅可以防止潜在的损坏,还可以提高乘
    腾恩科技-彭工 2024-11-29 16:12 119浏览
  • 艾迈斯欧司朗全新“样片申请”小程序,逾160种LED、传感器、多芯片组合等产品样片一触即达。轻松3步完成申请,境内免费包邮到家!本期热荐性能显著提升的OSLON® Optimal,GF CSSRML.24ams OSRAM 基于最新芯片技术推出全新LED产品OSLON® Optimal系列,实现了显著的性能升级。该系列提供五种不同颜色的光源选项,包括Hyper Red(660 nm,PDN)、Red(640 nm)、Deep Blue(450 nm,PDN)、Far Red(730 nm)及Ho
    艾迈斯欧司朗 2024-11-29 16:55 157浏览
  • 最近几年,新能源汽车愈发受到消费者的青睐,其销量也是一路走高。据中汽协公布的数据显示,2024年10月,新能源汽车产销分别完成146.3万辆和143万辆,同比分别增长48%和49.6%。而结合各家新能源车企所公布的销量数据来看,比亚迪再度夺得了销冠宝座,其10月新能源汽车销量达到了502657辆,同比增长66.53%。众所周知,比亚迪是新能源汽车领域的重要参与者,其一举一动向来为外界所关注。日前,比亚迪汽车旗下品牌方程豹汽车推出了新车方程豹豹8,该款车型一上市就迅速吸引了消费者的目光,成为SUV
    刘旷 2024-12-02 09:32 62浏览
  • 国产光耦合器正以其创新性和多样性引领行业发展。凭借强大的研发能力,国内制造商推出了适应汽车、电信等领域独特需求的专业化光耦合器,为各行业的技术进步提供了重要支持。本文将重点探讨国产光耦合器的技术创新与产品多样性,以及它们在推动产业升级中的重要作用。国产光耦合器创新的作用满足现代需求的创新模式新设计正在满足不断变化的市场需求。例如,高速光耦合器满足了电信和数据处理系统中快速信号传输的需求。同时,栅极驱动光耦合器支持电动汽车(EV)和工业电机驱动器等大功率应用中的精确高效控制。先进材料和设计将碳化硅
    克里雅半导体科技 2024-11-29 16:18 161浏览
  • 戴上XR眼镜去“追龙”是种什么体验?2024年11月30日,由上海自然博物馆(上海科技馆分馆)与三湘印象联合出品、三湘印象旗下观印象艺术发展有限公司(下简称“观印象”)承制的《又见恐龙》XR嘉年华在上海自然博物馆重磅开幕。该体验项目将于12月1日正式对公众开放,持续至2025年3月30日。双向奔赴,恐龙IP撞上元宇宙不久前,上海市经济和信息化委员会等部门联合印发了《上海市超高清视听产业发展行动方案》,特别提到“支持博物馆、主题乐园等场所推动超高清视听技术应用,丰富线下文旅消费体验”。作为上海自然
    电子与消费 2024-11-30 22:03 75浏览
  • RDDI-DAP错误通常与调试接口相关,特别是在使用CMSIS-DAP协议进行嵌入式系统开发时。以下是一些可能的原因和解决方法: 1. 硬件连接问题:     检查调试器(如ST-Link)与目标板之间的连接是否牢固。     确保所有必要的引脚都已正确连接,没有松动或短路。 2. 电源问题:     确保目标板和调试器都有足够的电源供应。     检查电源电压是否符合目标板的规格要求。 3. 固件问题: &n
    丙丁先生 2024-12-01 17:37 57浏览
  • 在电子技术快速发展的今天,KLV15002光耦固态继电器以高性能和强可靠性完美解决行业需求。该光继电器旨在提供无与伦比的电气隔离和无缝切换,是现代系统的终极选择。无论是在电信、工业自动化还是测试环境中,KLV15002光耦合器固态继电器都完美融合了效率和耐用性,可满足当今苛刻的应用需求。为什么选择KLV15002光耦合器固态继电器?不妥协的电压隔离从本质上讲,KLV15002优先考虑安全性。输入到输出隔离达到3750Vrms(后缀为V的型号为5000Vrms),确保即使在高压情况下,敏感的低功耗
    克里雅半导体科技 2024-11-29 16:15 119浏览
  • 学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习笔记&记录学习习笔记&记学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&
    youyeye 2024-11-30 14:30 65浏览
  • 光伏逆变器是一种高效的能量转换设备,它能够将光伏太阳能板(PV)产生的不稳定的直流电压转换成与市电频率同步的交流电。这种转换后的电能不仅可以回馈至商用输电网络,还能供独立电网系统使用。光伏逆变器在商业光伏储能电站和家庭独立储能系统等应用领域中得到了广泛的应用。光耦合器,以其高速信号传输、出色的共模抑制比以及单向信号传输和光电隔离的特性,在光伏逆变器中扮演着至关重要的角色。它确保了系统的安全隔离、干扰的有效隔离以及通信信号的精准传输。光耦合器的使用不仅提高了系统的稳定性和安全性,而且由于其低功耗的
    晶台光耦 2024-12-02 10:40 63浏览
  • 《高速PCB设计经验规则应用实践》+PCB绘制学习与验证读书首先看目录,我感兴趣的是这一节;作者在书中列举了一条经典规则,然后进行详细分析,通过公式推导图表列举说明了传统的这一规则是受到电容加工特点影响的,在使用了MLCC陶瓷电容后这一条规则已经不再实用了。图书还列举了高速PCB设计需要的专业工具和仿真软件,当然由于篇幅所限,只是介绍了一点点设计步骤;我最感兴趣的部分还是元件布局的经验规则,在这里列举如下:在这里,演示一下,我根据书本知识进行电机驱动的布局:这也算知行合一吧。对于布局书中有一句:
    wuyu2009 2024-11-30 20:30 89浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦