嵌入式框架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
版权所有,转载请打赏哟
如果你喜欢我的文章,可以通过微信扫一扫给我打赏哟