【嵌入式框架】搭建调试输出、建立时间系统

一、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提供系统时间计数功能。

关于硬件环境的搭建不多说,可以参照开发板提供的例程来搭建,板级初始化完成了调试串口和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\r\n", 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的所在,从而提高开发效率。

Zorb Framework github:https://github.com/54zorb/Zorb-Framework

来源:https://github.com/54zorb/Zorb-Framework

-END-

相关推荐
远翔调光芯片^138287988722 小时前
远翔升压恒流芯片FP7209X与FP7209M什么区别?做以下应用市场摄影补光灯、便携灯、智能家居(调光)市场、太阳能、车灯、洗墙灯、舞台灯必看!
科技·单片机·智能家居·能源
极客小张3 小时前
基于STM32的智能充电桩:集成RTOS、MQTT与SQLite的先进管理系统设计思路
stm32·单片机·嵌入式硬件·mqtt·sqlite·毕业设计·智能充电桩
Thanks_ks5 小时前
探索计算机互联网的奇妙世界:从基础到前沿的无尽之旅
物联网·云计算·区块链·tcp/ip协议·计算机互联网·万维网·未来科技
m0_739312876 小时前
【STM32】项目实战——OV7725/OV2604摄像头颜色识别检测(开源)
stm32·单片机·嵌入式硬件
嵌入式小章6 小时前
基于STM32的实时时钟(RTC)教学
stm32·嵌入式硬件·实时音视频
TeYiToKu6 小时前
笔记整理—linux驱动开发部分(9)framebuffer驱动框架
linux·c语言·arm开发·驱动开发·笔记·嵌入式硬件·arm
基极向上的三极管7 小时前
【AD】3-4 在原理图中放置元件
嵌入式硬件
徐嵌7 小时前
STM32项目---水质水位检测
stm32·单片机·嵌入式硬件
徐嵌7 小时前
STM32项目---畜牧定位器
c语言·stm32·单片机·物联网·iot
lantiandianzi8 小时前
基于单片机的老人生活安全监测系统
单片机·嵌入式硬件·生活