• 嵌入式框架Zorb Framework搭建一:嵌入式环境搭建、调试输出和建立时间系统


    我是卓波,我是一名嵌入式工程师,我万万没想到我会在这里跟大家吹牛皮。

    嵌入式框架Zorb Framework搭建过程

    嵌入式框架Zorb Framework搭建一:嵌入式环境搭建、调试输出和建立时间系统

    嵌入式框架Zorb Framework搭建二:环形缓冲区的实现

    嵌入式框架Zorb Framework搭建三:列表的实现

    嵌入式框架Zorb Framework搭建四:状态机的实现

    嵌入式框架Zorb Framework搭建五:事件的实现

    嵌入式框架Zorb Framework搭建六:定时器的实现

    嵌入式框架Zorb Framework搭建七:任务的实现

    一、前言

      之前,我一直以为C语言只是面向过程的语言,直到我发现它也可以用来创造对象。现在,我就要用面向对象的思想来搭建一个轻量级的嵌入式框架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的初始化。

     1 /******************************************************************************
     2  * 描述  :硬件环境初始化
     3  * 参数  :无
     4  * 返回  :无
     5 ******************************************************************************/
     6 void BSP_init(void)
     7 {
     8     /* 嵌套向量中断控制器组选择 */
     9     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    10     
    11     /* 初始化调试串口 */
    12     Debug_USART_init();
    13     
    14     /* Systick初始化 */
    15     SystemTick_init();
    16 }
    17 
    18 /******************************************************************************
    19  * 描述  :硬件底层程序
    20  * 参数  :无
    21  * 返回  :无
    22 ******************************************************************************/
    23 void BSP_process(void)
    24 {
    25 
    26 }

    三、调试输出

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

     1 /**
     2   *****************************************************************************
     3   * @file    zf_debug.h
     4   * @author  Zorb
     5   * @version V1.0.0
     6   * @date    2018-06-28
     7   * @brief   调试输出的头文件
     8   *****************************************************************************
     9   * @history
    10   *
    11   * 1. Date:2018-06-28
    12   *    Author:Zorb
    13   *    Modification:建立文件
    14   *
    15   *****************************************************************************
    16   */
    17 
    18 #ifndef __ZF_DEBUG_H__
    19 #define __ZF_DEBUG_H__
    20 
    21 #ifdef __cplusplus
    22 extern "C" {
    23 #endif
    24 
    25 #include "stdio.h"
    26 #include "stdbool.h"
    27 
    28 #define LOG_D 0; /* 信息等级:正常 */
    29 #define LOG_W 1; /* 信息等级:告警 */
    30 #define LOG_E 2; /* 信息等级:错误 */
    31 
    32 #define _ZF_DEBUG             /* 定义调试功能 */
    33 #define ZF_DEBUG_ON true      /* 启用调试功能 */
    34 
    35 #ifdef _ZF_DEBUG
    36     #if ZF_DEBUG_ON
    37         #define ZF_DEBUG(rank, x...) do     \
    38         {                                   \
    39             char code[10] = "[rank=0]";     \
    40             code[6] = '0' + (char)rank;     \
    41             if (code[6] != '0')             \
    42             {                               \
    43                 printf("%s", code);         \
    44             }                               \
    45             printf(x);                      \
    46         } while(0)
    47     #else
    48         #define ZF_DEBUG(rank, x...)
    49     #endif /* ZF_DEBUG_ON */
    50 #endif /* _ZF_DEBUG */
    51 
    52 #ifdef __cplusplus
    53 }
    54 #endif
    55 
    56 #endif /* __ZF_DEBUG_H__ */
    57 
    58 /******************************** END OF FILE ********************************/

    四、实现断言

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

     1 /**
     2   *****************************************************************************
     3   * @file    zf_assert.h
     4   * @author  Zorb
     5   * @version V1.0.0
     6   * @date    2018-06-28
     7   * @brief   断言的头文件
     8   *****************************************************************************
     9   * @history
    10   *
    11   * 1. Date:2018-06-28
    12   *    Author:Zorb
    13   *    Modification:建立文件
    14   *
    15   *****************************************************************************
    16   */
    17 
    18 #ifndef __ZF_ASSERT_H__
    19 #define __ZF_ASSERT_H__
    20 
    21 #ifdef __cplusplus
    22 extern "C" {
    23 #endif
    24 
    25 #include "stdint.h"
    26 
    27 #define _ZF_ASSERT              /* 定义断言功能 */
    28 #define ZF_ASSERT_ON true       /* 启用断言功能 */
    29 
    30 #ifdef _ZF_ASSERT
    31     #if ZF_ASSERT_ON
    32          #define ZF_ASSERT(expression_) ((expression_) ?\
    33             (void)0 : ZF_assertHandle((uint8_t *)__FILE__, (int)__LINE__));
    34     #else
    35          #define ZF_ASSERT(expression_)
    36     #endif /* ZF_ASSERT_ON */
    37 #endif /* _ZF_ASSERT */
    38 
    39 /* 断言产生时的处理 */
    40 void ZF_assertHandle(uint8_t *pFileName, int line);
    41 
    42 #ifdef __cplusplus
    43 }
    44 #endif
    45 
    46 #endif /* __ZF_ASSERT_H__ */
    47 
    48 /******************************** END OF FILE ********************************/

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

     1 /**
     2   *****************************************************************************
     3   * @file    zf_assert.c
     4   * @author  Zorb
     5   * @version V1.0.0
     6   * @date    2018-06-28
     7   * @brief   断言的实现
     8   *****************************************************************************
     9   * @history
    10   *
    11   * 1. Date:2018-06-28
    12   *    Author:Zorb
    13   *    Modification:建立文件
    14   *
    15   *****************************************************************************
    16   */
    17 
    18 #include "zf_assert.h"
    19 #include "zf_debug.h"
    20 
    21 /******************************************************************************
    22  * 描述  :断言产生时的处理
    23  * 参数  :(in)-pFileName 文件名
    24  *         (in)-line 行数
    25  * 返回  :无
    26 ******************************************************************************/
    27 void ZF_assertHandle(uint8_t *pFileName, int line)
    28 {
    29     ZF_DEBUG(LOG_E, "file:%s line:%d:asserted\r\n", pFileName, line);
    30     
    31     while (1);
    32 }
    33 
    34 /******************************** END OF FILE ********************************/

    五、建立时间系统

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

     1 /******************************************************************************
     2  * 描述  :SysTick中断服务程序
     3  * 参数  :无
     4  * 返回  :无
     5 ******************************************************************************/
     6 void SysTick_Handler(void)
     7 {
     8     /* 为zorb framework提供计时 */
     9     ZF_timeTick();
    10 }

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

     1 /**
     2   *****************************************************************************
     3   * @file    zf_time.h
     4   * @author  Zorb
     5   * @version V1.0.0
     6   * @date    2018-06-28
     7   * @brief   系统时间的头文件
     8   *****************************************************************************
     9   * @history
    10   *
    11   * 1. Date:2018-06-28
    12   *    Author:Zorb
    13   *    Modification:建立文件
    14   *
    15   *****************************************************************************
    16   */
    17 
    18 #ifndef __ZF_TIME_H__
    19 #define __ZF_TIME_H__
    20 
    21 #ifdef __cplusplus
    22 extern "C" {
    23 #endif
    24 
    25 #include "stdbool.h"
    26 #include "stdint.h"
    27 
    28 /* 系统滴答周期(ms) */
    29 #define ZF_TICK_PERIOD 1
    30 
    31 /* 获取系统滴答数 */
    32 #define ZF_SYSTICK() ZF_getSystemTick()
    33 
    34 /* 获取系统时间(ms) */
    35 #define ZF_SYSTIME_MS() ZF_getSystemTimeMS()
    36 
    37 /* 系统延时(ms) */
    38 #define ZF_DELAY_MS(ms_) do                            \
    39 {                                                      \
    40     if (ms_ % ZF_TICK_PERIOD)                          \
    41     {                                                  \
    42         ZF_delayTick((ms_ / ZF_TICK_PERIOD) + 1);      \
    43     }                                                  \
    44     else                                               \
    45     {                                                  \
    46         ZF_delayTick(ms_ / ZF_TICK_PERIOD);            \
    47     }                                                  \
    48 } while(0)
    49 
    50 /* 获取系统滴答数 */
    51 uint32_t ZF_getSystemTick(void);
    52 
    53 /* 获取系统时间(ms) */
    54 uint32_t ZF_getSystemTimeMS(void);
    55 
    56 /* 系统延时 */
    57 void ZF_delayTick(uint32_t tick);
    58 
    59 /* 系统滴答程序(需挂在硬件的时间中断里边) */
    60 void ZF_timeTick (void);
    61 
    62 #ifdef __cplusplus
    63 }
    64 #endif
    65 
    66 #endif /* __ZF_TIME_H__ */
    67 
    68 /******************************** END OF FILE ********************************/
     1 /**
     2   *****************************************************************************
     3   * @file    zf_time.c
     4   * @author  Zorb
     5   * @version V1.0.0
     6   * @date    2018-06-28
     7   * @brief   系统时间的实现
     8   *****************************************************************************
     9   * @history
    10   *
    11   * 1. Date:2018-06-28
    12   *    Author:Zorb
    13   *    Modification:建立文件
    14   *
    15   *****************************************************************************
    16   */
    17 
    18 #include "zf_time.h"
    19 
    20 /* 系统滴答数 */
    21 uint32_t ZF_tick = 0;
    22 
    23 /******************************************************************************
    24  * 描述  :获取系统滴答数
    25  * 参数  :无
    26  * 返回  :系统滴答数
    27 ******************************************************************************/
    28 uint32_t ZF_getSystemTick(void)
    29 {
    30     return ZF_tick;
    31 }
    32 
    33 /******************************************************************************
    34  * 描述  :获取系统时间(ms)
    35  * 参数  :无
    36  * 返回  :系统时间(ms)
    37 ******************************************************************************/
    38 uint32_t ZF_getSystemTimeMS(void)
    39 {
    40     return ZF_tick * ZF_TICK_PERIOD;
    41 }
    42 
    43 /******************************************************************************
    44  * 描述  :系统延时
    45  * 参数  :(in)-tick   需要延时的系统周期数
    46  * 返回  :无
    47 ******************************************************************************/
    48 void ZF_delayTick(uint32_t tick)
    49 {
    50     uint32_t startTick = ZF_getSystemTick();
    51     while((ZF_getSystemTick() - startTick) < tick);
    52 }
    53 
    54 /******************************************************************************
    55  * 描述  :系统滴答程序(需挂在硬件的时间中断里边)
    56  * 参数  :无
    57  * 返回  :无
    58 ******************************************************************************/
    59 void ZF_timeTick (void)
    60 {
    61     /* 系统滴答计数 */
    62     ZF_tick++;
    63 }
    64 
    65 /******************************** END OF FILE ********************************/

    六、最后

      本篇实现的功能比较基础,但是整个框架开发的根基,后面所有扩展的功能都需要在此环境下进行开发。搭建良好的调试输出环境,可以帮我们快速定位bug的所在,从而提高开发效率。

      本文工程代码:1-Zorb_Framework嵌入式环境搭建.rar

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

      版权所有,转载请打赏哟

    如果你喜欢我的文章,可以通过微信扫一扫给我打赏哟

  • 相关阅读:
    Android牟利之道(四)如何推广你的产品,即你的APP
    android权限
    OpenGL 中文 API
    为何不能上网浏览网页 但是可以用QQ聊天
    安装任何软件都提示不能访问windows Installer服务
    初识WAP
    用asp.net 2.0实现网站二级域名(转)
    Visual Studio .NET已检测到指定的Web服务器运行的不是ASP.NET 1.1 版
    用EasyBoot轻松做启动光盘
    我心中的痛房子
  • 原文地址:https://www.cnblogs.com/54zorb/p/9277802.html
Copyright © 2020-2023  润新知