适合单片机裸机的开源软件框架:Zorb

发布时间:2024-02-22  

很多时候,做单片机项目,会因为性能和内存资源的限制,没办法运行一些“大型”的通用框架,这个时候,一些轻量级的软件框架有显得尤为重要了。   这里就给大家分享一款一款适合单片机裸机的开源软件框架:Zorb


Zorb简介

Zorb Framework是一个基于面向对象的思想来搭建一个轻量级的嵌入式框架。

搭建Zorb Framework的目的是为在不能运行Linux的芯片上快速开发应用,不用反复造轮子。

Zorb Framework的初步设计功能有:

1、时间系统功能zf_time

2、环形缓冲区功能zf_buffer

3、列表功能zf_list

4、状态机功能zf_fsm

5、事件功能zf_event

6、定时器功能zf_timer

7、任务功能zf_task

前6个功能,就可以实现纯事件驱动的程序,基本可以满足中小型嵌入式应用程序开发的需求。加上任务功能,是为了满足部分程序对实时性要求较高的需求。

当然,也可以将前6个功能裁剪出来,然后运行在现有的嵌入式系统上面,这样子也可以满足实时性的需求。

环境搭建

采用STM32F429开发板作为硬件运行环境,硬件资源用到串口1和systick,其中串口1提供调试打印功能,systick提供系统时间计数功能。

87c8058c-a470-11ee-8b88-92fbcf53809c.png

关于硬件环境的搭建不多说,可以参照开发板提供的例程来搭建,板级初始化完成了调试串口和systick的初始化。


/******************************************************************************

 * 描述  :硬件环境初始化

 * 参数  :无

 * 返回  :无

******************************************************************************/

void BSP_init(void)

{

    /* 嵌套向量中断控制器组选择 */

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);


    /* 初始化调试串口 */

    Debug_USART_init();


    /* Systick初始化 */

    SystemTick_init();

}


/******************************************************************************

 * 描述  :硬件底层程序

 * 参数  :无

 * 返回  :无

******************************************************************************/

void BSP_process(void)

{


}

调试


开发一个程序,最开始也最重要的是搭建调试的环境,我们采用串口1作为调试输出(printf映射),然后调试信息分为三个等级,后续上位机可以根据不同等级进行高亮提示:


/**

  *****************************************************************************

  * @file    zf_debug.h

  * @author  Zorb

  * @version V1.0.0

  * @date    2018-06-28

  * @brief   调试输出的头文件

  *****************************************************************************

  * @history

  *

  * 1. Date:2018-06-28

  *    Author:Zorb

  *    Modification:建立文件

  *

  *****************************************************************************

  */


#ifndef __ZF_DEBUG_H__

#define __ZF_DEBUG_H__


#ifdef __cplusplus

extern "C" {

#endif


#include "stdio.h"

#include "stdbool.h"


#define LOG_D 0; /* 信息等级:正常 */

#define LOG_W 1; /* 信息等级:告警 */

#define LOG_E 2; /* 信息等级:错误 */


#define _ZF_DEBUG             /* 定义调试功能 */

#define ZF_DEBUG_ON true      /* 启用调试功能 */


#ifdef _ZF_DEBUG

    #if ZF_DEBUG_ON

        #define ZF_DEBUG(rank, x...) do     

        {                                   

            char code[10] = "[rank=0]";     

            code[6] = '0' + (char)rank;     

            if (code[6] != '0')             

            {                               

                printf("%s", code);         

            }                               

            printf(x);                      

        } while(0)

    #else

        #define ZF_DEBUG(rank, x...)

    #endif /* ZF_DEBUG_ON */

#endif /* _ZF_DEBUG */


#ifdef __cplusplus

}

#endif


#endif /* __ZF_DEBUG_H__ */


/******************************** END OF FILE ********************************/

断言


在开发过程中,在关键地方进行一些断言,可以方便定位bug。


/**

  *****************************************************************************

  * @file    zf_assert.h

  * @author  Zorb

  * @version V1.0.0

  * @date    2018-06-28

  * @brief   断言的头文件

  *****************************************************************************

  * @history

  *

  * 1. Date:2018-06-28

  *    Author:Zorb

  *    Modification:建立文件

  *

  *****************************************************************************

  */


#ifndef __ZF_ASSERT_H__

#define __ZF_ASSERT_H__


#ifdef __cplusplus

extern "C" {

#endif


#include "stdint.h"


#define _ZF_ASSERT              /* 定义断言功能 */

#define ZF_ASSERT_ON true       /* 启用断言功能 */


#ifdef _ZF_ASSERT

    #if ZF_ASSERT_ON

         #define ZF_ASSERT(expression_) ((expression_) ?

            (void)0 : ZF_assertHandle((uint8_t *)__FILE__, (int)__LINE__));

    #else

         #define ZF_ASSERT(expression_)

    #endif /* ZF_ASSERT_ON */

#endif /* _ZF_ASSERT */


/* 断言产生时的处理 */

void ZF_assertHandle(uint8_t *pFileName, int line);


#ifdef __cplusplus

}

#endif


#endif /* __ZF_ASSERT_H__ */


/******************************** END OF FILE ********************************/

断言的处理很简单,就是告诉我们在哪个文件哪一行出错就可以,实现如下


/**

  *****************************************************************************

  * @file    zf_assert.c

  * @author  Zorb

  * @version V1.0.0

  * @date    2018-06-28

  * @brief   断言的实现

  *****************************************************************************

  * @history

  *

  * 1. Date:2018-06-28

  *    Author:Zorb

  *    Modification:建立文件

  *

  *****************************************************************************

  */


#include "zf_assert.h"

#include "zf_debug.h"


/******************************************************************************

 * 描述  :断言产生时的处理

 * 参数  :(in)-pFileName 文件名

 *         (in)-line 行数

 * 返回  :无

******************************************************************************/

void ZF_assertHandle(uint8_t *pFileName, int line)

{

    ZF_DEBUG(LOG_E, "file:%s line:%d:asserted

", pFileName, line);


    while (1);

}


/******************************** END OF FILE ********************************/

调度时间


为了减少框架对资源的消耗,所以初步设定框架的最小时间周期为1ms,因此我们需要设置systick的定时周期为1ms,然后每次进入中断为我们的框架计数即可。


/******************************************************************************

 * 描述  :SysTick中断服务程序

 * 参数  :无

 * 返回  :无

******************************************************************************/

void SysTick_Handler(void)

{

    /* 为zorb framework提供计时 */

    ZF_timeTick();

}

现在时间系统提供的功能比较基础,只有系统滴答计数和系统死等待延时,后面我们开发定时器功能和任务功能的时候会重新扩展时间系统。


/**

  *****************************************************************************

  * @file    zf_time.h

  * @author  Zorb

  * @version V1.0.0

  * @date    2018-06-28

  * @brief   系统时间的头文件

  *****************************************************************************

  * @history

  *

  * 1. Date:2018-06-28

  *    Author:Zorb

  *    Modification:建立文件

  *

  *****************************************************************************

  */


#ifndef __ZF_TIME_H__

#define __ZF_TIME_H__


#ifdef __cplusplus

extern "C" {

#endif


#include "stdbool.h"

#include "stdint.h"


/* 系统滴答周期(ms) */

#define ZF_TICK_PERIOD 1


/* 获取系统滴答数 */

#define ZF_SYSTICK() ZF_getSystemTick()


/* 获取系统时间(ms) */

#define ZF_SYSTIME_MS() ZF_getSystemTimeMS()


/* 系统延时(ms) */

#define ZF_DELAY_MS(ms_) do                            

{                                                      

    if (ms_ % ZF_TICK_PERIOD)                          

    {                                                  

        ZF_delayTick((ms_ / ZF_TICK_PERIOD) + 1);      

    }                                                  

    else                                               

    {                                                  

        ZF_delayTick(ms_ / ZF_TICK_PERIOD);            

    }                                                  

} while(0)


/* 获取系统滴答数 */

uint32_t ZF_getSystemTick(void);


/* 获取系统时间(ms) */

uint32_t ZF_getSystemTimeMS(void);


/* 系统延时 */

void ZF_delayTick(uint32_t tick);


/* 系统滴答程序(需挂在硬件的时间中断里边) */

void ZF_timeTick (void);


#ifdef __cplusplus

}

#endif


#endif /* __ZF_TIME_H__ */


/******************************** END OF FILE ********************************/

最后


本篇实现的功能比较基础,但是整个框架开发的根基,后面所有扩展的功能都需要在此环境下进行开发。


搭建良好的调试输出环境,可以帮我们快速定位bug的所在,从而提高开发效率。


文章来源于:电子工程世界    原文链接
本站所有转载文章系出于传递更多信息之目的,且明确注明来源,不希望被转载的媒体或个人可与我们联系,我们将立即进行删除处理。

相关文章

    、4个八位并口、一个全双工串行口、2个16位定时/计数器。寻址范围64K,并有控制功能较强的布尔处理器。单板机单片机。   80C51是MCS-51系列中的典型品种;其它厂商以80C51为基......
    单片机不配叫嵌入式吗?嵌入式和单片机有啥关系?;一定有很多人都听说过嵌入式和单片机,但在刚开始接触时,不知道大家有没有听说过嵌入式就是单片机这样的说法,其实嵌入式和单片机还是有区别的。单片机......
    电子的地方,就有单片机的身影。 我们再谈一下嵌入式单片机开发专业在这10年的变化。 14年前我刚上大学,学习单片机的时候,单片机还是一个比较冷门的专业。 我们大多数人都不知道单片机是个什么东西,也不知道学习单片机......
    大家有筛选能力的话,大家可以选择适合自己的课程来学习。 但是单片机的C语言和我们平常讲的C语言还是有一定的区别的。 C语言是基于计算机(电脑)平台开发的一种语言,可以开发很多的应用软件,但单片机C语言的是基于单片机......
    单片机的就业方向是什么?搞单片机是青春饭吗?;这段时间,很多刚入门的小伙伴找到我,问的最多的问题应该就是单片机的前景和就业方向了。 还有一个顾虑是搞单片机是青春饭吗?20多岁学晚不晚? 我们......
    智能化的传感器,一般会以标准的485接口,要想通过485做一些数据的接口,单片机还是要使用串行通信,要用接口芯片把它转成485的接口。 单片机内部的串行通信相对比较重要,在做系统构建的时候,或者一些调试程序的过程当中也经常会使用单片机......
    以80C51单片机为例讲述单片机如何运行;前言 要想理解单片机是如何运行程序的,首先需要了解单片机的组成。本文以80C51单片机为例,给大家讲一讲程序在单片机中是如何运行的。 单片机......
    多核CPU成为了现在的主流)。 所以裸机程序指令就在Flash(Flash memory)中存放,而数据就放在了RAM中(flash的写入次数有限制,同时它的速度和RAM还是差很多)。更广泛说,在单片机......
    80C51单片机里的程序是如何运行的;前言 我们想要理解单片机是如何运行程序的,我们首先需要了解单片机的组成,我们这里以80C51单片机为例来理解程序在单片机中是如何运行的。 单片机......
    arduino好还是单片机好,arduino和单片机的区别;很多初学者和我当初一样不知道arduino和单片机的区别。 其实我也是学完才知道arduino的存在,还好当初是直接学的51单片机,不然......

我们与500+贴片厂合作,完美满足客户的定制需求。为品牌提供定制化的推广方案、专属产品特色页,多渠道推广,SEM/SEO精准营销以及与公众号的联合推广...详细>>

利用葫芦芯平台的卓越技术服务和新产品推广能力,原厂代理能轻松打入消费物联网(IOT)、信息与通信(ICT)、汽车及新能源汽车、工业自动化及工业物联网、装备及功率电子...详细>>

充分利用其强大的电子元器件采购流量,创新性地为这些物料提供了一个全新的窗口。我们的高效数字营销技术,不仅可以助你轻松识别与连接到需求方,更能够极大地提高“闲置物料”的处理能力,通过葫芦芯平台...详细>>

我们的目标很明确:构建一个全方位的半导体产业生态系统。成为一家全球领先的半导体互联网生态公司。目前,我们已成功打造了智能汽车、智能家居、大健康医疗、机器人和材料等五大生态领域。更为重要的是...详细>>

我们深知加工与定制类服务商的价值和重要性,因此,我们倾力为您提供最顶尖的营销资源。在我们的平台上,您可以直接接触到100万的研发工程师和采购工程师,以及10万的活跃客户群体...详细>>

凭借我们强大的专业流量和尖端的互联网数字营销技术,我们承诺为原厂提供免费的产品资料推广服务。无论是最新的资讯、技术动态还是创新产品,都可以通过我们的平台迅速传达给目标客户...详细>>

我们不止于将线索转化为潜在客户。葫芦芯平台致力于形成业务闭环,从引流、宣传到最终销售,全程跟进,确保每一个potential lead都得到妥善处理,从而大幅提高转化率。不仅如此...详细>>