威尼斯人线上娱乐

调节输出和建立即间连串,嵌入式框架Zorb

11 4月 , 2019  

本身是卓波,作者是一名嵌入式工程师,我相对没悟出笔者会在那里跟大家说大话皮。

小编是卓波,作者是一名嵌入式工程师,笔者相对没悟出小编会在那里跟大家说大话皮。

自身是卓波,作者是一名嵌入式工程师,笔者绝对没悟出笔者会在那里跟大家吹嘘皮。

自家是卓波,我是一名嵌入式工程师,笔者相对没悟出小编会在此处跟大家吹捧皮。

嵌入式框架Zorb Framework搭建进度

嵌入式框架Zorb
Framework搭建1:嵌入式环境搭建、调节和测试输出和成马上间种类

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

嵌入式框架Zorb
Framework搭建三:列表的落到实处

嵌入式框架Zorb
Framework搭建4:状态机的兑现

嵌入式框架Zorb
Framework搭建伍:事件的达成

嵌入式框架Zorb
Framework搭建陆:定时器的贯彻

嵌入式框架Zorb
Framework搭建7:职务的兑现

 

嵌入式框架Zorb Framework搭建进度

嵌入式框架Zorb
Framework搭建1:嵌入式环境搭建、调节和测试输出和树马上间体系

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

嵌入式框架Zorb
Framework搭建叁:列表的落实

嵌入式框架Zorb
Framework搭建4:状态机的兑现

嵌入式框架Zorb
Framework搭建伍:事件的达成

嵌入式框架Zorb
Framework搭建陆:定时器的贯彻

嵌入式框架Zorb
Framework搭建七:职责的兑现

 

嵌入式框架Zorb Framework搭建进度

嵌入式框架Zorb
Framework搭建一:嵌入式环境搭建、调试输出和创制即间系列

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

嵌入式框架Zorb
Framework搭建叁:列表的落到实处

嵌入式框架Zorb
Framework搭建4:状态机的兑现

调节输出和建立即间连串,嵌入式框架Zorb。嵌入式框架Zorb
Framework搭建伍:事件的达成

嵌入式框架Zorb
Framework搭建六:定时器的贯彻

嵌入式框架Zorb
Framework搭建7:职分的兑现

 

嵌入式框架Zorb Framework搭建进程

嵌入式框架Zorb Framework搭建1:嵌入式环境搭建、调节和测试输出和成马上间连串

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

嵌入式框架Zorb Framework搭建叁:列表的落实

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

嵌入式框架Zorb Framework搭建伍:事件的完毕

嵌入式框架Zorb Framework搭建6:定时器的贯彻

嵌入式框架Zorb Framework搭建7:职务的达成

一、前言

  事件有联袂事件和异步事件,在那1篇中,我们将为Zorb
Framework提供异步事件作用。在不少时候,大家来比不上处理部分操作依旧对操作的实时性必要不高时,能够思索采取异步事件功效。如在刹车中拍卖大量的操作是不太明智的,这时候就足以生出一个事件出来,等待事件处理程序在刹车外形成。

 

一、前言

  在嵌入式开发中,大家平常会用到定时器,大家得以用芯片的定时器外设,能够用基本的systick,也可以行使操作系统的定时器。本篇要统一筹划的定时器类似与操作系统的定时器,是软件定时器。假如Zorb
Framework运维在操作系统上面,大能够不采纳本篇的功力,直接运用操作系统自带的定时器。

 

一、前言

  在那一篇中,我们将为Zorb
Framework提供情状机功效。中型小型型嵌入式程序说白了正是由各样状态机组成,因而控制了什么创设状态机,开发嵌入式应用程序能够说是手到拈来。简单的状态机能够用Switch-Case实现,但复杂一点的景色机再继续行使Switch-Case的话,层次会变得相比乱,不便利维护。因而我们为Zorb
Framework提供了函数式状态机。

 

一、前言

  以前,作者间接以为C语言只是面向进度的言语,直到作者意识它也能够用来创制对象。未来,笔者快要用面向对象的思想来搭建多个轻量级的嵌入式框架Zorb
Framework。搭建Zorb
Framework的目标是为在不能够运作Linux的芯片上神速支付应用,不用反复造轮子。

  Zorb Framework的伊始设计作用有

  壹、时间种类机能zf_time

  二、环形缓冲区功能zf_buffer

  三、列表成效zf_list

  四、状态机成效zf_fsm

  5、事件效能zf_event

  陆、定时器成效zf_timer

  七、任务功效zf_task

  前多少个效益,就能够实现纯事件驱动的次序,基本得以满足中小型嵌入式应用程序开发的须求。加上职分作用,是为着知足部分程序对实时性必要较高的急需。当然,也得以将前八个作用裁剪出来,然后运行在现有的嵌入式系统方面,那样子也足以满意实时性的供给。

二、事件效能设计

  大家先来看看要促成的轩然大波提供什么样功效:

  起先要提供的效率如下:

  1、能够转移事件

  2、事件之中应该有事件处理函数

  三、能够添加事件处理函数的参数

  四、最棒事件能够有优先级,优先级高的先实施

  5、最棒事件可以活动回收

  由此,初始设计的数据结构如下: 

 1 /* 事件结构 */
 2 struct _Event
 3 {
 4     uint8_t Priority;               /* 优先级 */
 5     IEventProcess EventProcess;     /* 事件程序 */
 6     List *pArgList;                 /* 事件程序的参数指针 */
 7     
 8     /* 增加程序参数(深拷贝,按先后顺序入队列) */
 9     bool (*AddArg)(Event * const pEvent, void *pArg, uint32_t size);
10     
11     /* 销毁事件 */
12     bool (*Dispose)(Event * const pEvent);
13 };
14 
15 /* 事件处理器结构 */
16 struct _EventHandler
17 {
18     List *pEventList;   /* 事件列表 */
19     bool IsRunning;     /* 是否正在运行:默认开 */
20     
21     /* 获取事件数 */
22     uint32_t (*GetEventCount)(EventHandler * const pEventHandler);
23     
24     /* 增加事件(按优先级排序) */
25     bool (*Add)(EventHandler * const pEventHandler, Event *pEvent);
26     
27     /* 删除事件(释放空间) */
28     bool (*Delete)(EventHandler * const pEventHandler, Event *pEvent);
29     
30     /* 清空事件列表(释放空间) */
31     bool (*Clear)(EventHandler * const pEventHandler);
32     
33     /* 销毁事件处理器(释放空间) */
34     bool (*Dispose)(EventHandler * const pEventHandler);
35     
36     /* 执行事件(按列表位置) */
37     void (*Execute)(struct _EventHandler * const pEventHandler);
38 };

  事件和事件处理器已经安插好了,再定义二个宏来支持推送事件。

1 /* 推送事件 */
2 #define EVENT_POST(handler_, event_) handler_->Add(handler_, event_)

  具体贯彻请看附属类小部件代码或在文末的github地址拉框架源码。

 

2、定时器设计

  大家先来看看要贯彻的定时器提供如何效益:

  开端要提供的法力如下:

  一、能够安装定时时间

  2、能够安装定时器是单次照旧再一次运营

  叁、能够安装定时器处理函数

  4、定时器函数可以从来运维照旧推送异步事件

  5、可以打开和倒闭定时器

  因而,开端设计的数据结构如下: 

 1 /* 定时器处理程序 */
 2 typedef void (*ITimerProcess)(void);
 3 
 4 /* 定时器结构 */
 5 typedef struct _Timer
 6 {
 7     uint8_t Priority;               /* 事件优先级 */
 8     uint32_t Interval;              /* 时间间隔(ms) */
 9     uint32_t AlarmTime;             /* 定时到达时间 */
10     bool IsAutoReset;               /* 重复运行(默认开) */
11     bool IsRunning;                 /* 是否正在运行(默认关) */
12     /* 事件的处理者,事件将推送到处理者的队列 */
13     /* 不设置处理者则本地执行(挂载Timer_process的地方) */
14     EventHandler *pEventHandler;
15     /* 处理事件 */
16     ITimerProcess TimerProcess;
17     
18     /* 开始定时器 */
19     void (*Start)(struct _Timer * const pTimer);
20     
21     /* 关闭定时器 */
22     void (*Stop)(struct _Timer * const pTimer);
23     
24     /* 重新运行定时器 */
25     void (*Restart)(struct _Timer * const pTimer);
26     
27     /* 销毁定时器(释放空间) */
28     bool (*Dispose)(struct _Timer * const pTimer);
29 } Timer;

  事件和事件处理器已经规划好了,再把定时器的处理程序添加到系统滴答程序中即可:

 1 /******************************************************************************
 2  * 描述  :系统滴答程序(需挂在硬件的时间中断里边)
 3  * 参数  :无
 4  * 返回  :无
 5 ******************************************************************************/
 6 void ZF_timeTick (void)
 7 {
 8     /* 系统滴答计数 */
 9     ZF_tick++;
10     
11     /* 软件定时器程序 */
12     Timer_process();
13 }

  具体落到实处请看附属类小部件代码或在文末的github地址拉框架源码。

 

贰、状态机设计

  大家先来看看要达成的状态机提供怎么样服从:

  开头要提供的效能如下:

  一、能够安装初叶状态

  二、能够展开处境转换

  三、能够实行频限信号调度

  4、最CANON够在进入和离开状态的时候可以做壹些自定义的工作

  5、最好能够有子状态机

  由此,开端设计的数据结构如下: 

 1 /* 状态机结构 */
 2 struct _Fsm
 3 {
 4     uint8_t Level;                  /* 嵌套层数,根状态机层数为1,子状态机层数自增 */
 5                                     /* 注:严禁递归嵌套和环形嵌套 */
 6     List *ChildList;                /* 子状态机列表 */
 7     Fsm *Owner;                     /* 父状态机 */
 8     IFsmState OwnerTriggerState;    /* 当父状态机为设定状态时,才触发当前状态机 */
 9                                     /* 若不设定,则当执行完父状态机,立即运行子状态机 */
10     IFsmState CurrentState;         /* 当前状态 */
11     bool IsRunning;                 /* 是否正在运行(默认关) */
12     
13     /* 设置初始状态 */
14     void (*SetInitialState)(Fsm * const pFsm, IFsmState initialState);
15     
16     /* 运行当前状态机 */
17     bool (*Run)(Fsm * const pFsm);
18     
19     /* 运行当前状态机和子状态机 */
20     bool (*RunAll)(Fsm * const pFsm);
21     
22     /* 停止当前状态机 */
23     bool (*Stop)(Fsm * const pFsm);
24     
25     /* 停止当前状态机和子状态机 */
26     bool (*StopAll)(Fsm * const pFsm);
27     
28     /* 释放当前状态机 */
29     bool (*Dispose)(Fsm * const pFsm);
30     
31     /* 释放当前状态机和子状态机 */
32     bool (*DisposeAll)(Fsm * const pFsm);
33     
34     /* 添加子状态机 */
35     bool (*AddChild)(Fsm * const pFsm, Fsm * const pChildFsm);
36     
37     /* 移除子状态机(不释放空间) */
38     bool (*RemoveChild)(Fsm * const pFsm, Fsm * const pChildFsm);
39     
40     /* 调度状态机 */
41     bool (*Dispatch)(Fsm * const pFsm, FsmSignal const signal);
42     
43     /* 状态转移 */
44     void (*Transfer)(Fsm * const pFsm, IFsmState nextState);
45     
46     /* 状态转移(触发转出和转入事件) */
47     void (*TransferWithEvent)(Fsm * const pFsm, IFsmState nextState);
48 };

  关于数字信号,Zorb Framework做了以下定义:

1 /* 状态机信号0-31保留,用户信号在32以后定义 */
2 enum {
3     FSM_NULL_SIG = 0,
4     FSM_ENTER_SIG,
5     FSM_EXIT_SIG,
6     FSM_USER_SIG_START = 32
7     /* 用户信号请在用户文件定义,不允许在此定义 */
8 };

  当中,0-3一为框架数字信号,用户实信号在3二从此定义。

  状态机已经陈设好了,具体完毕请看附属类小部件代码或在文末的github地址拉框架源码。

 

二、嵌入式环境搭建

  采取STM32F42九开发板作为硬件运营环境,硬件能源用到串口壹和systick,在那之中串口一提供调节和测试打字与印刷功用,systick提供系统时间计数作用。

  威尼斯人线上娱乐 1

  关于硬件环境的搭建不多说,能够参考开发板提供的例程来搭建,板级初阶化实现了调剂串口和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 /**
  2   *****************************************************************************
  3   * @file    app_event.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 "app_event.h"
 19 #include "zf_includes.h"
 20 
 21 /* 事件处理器 */
 22 static EventHandler *pEventHandler;
 23 
 24 /******************************************************************************
 25  * 描述  :事件程序1
 26  * 参数  :(in)-pArgList 事件参数列表指针
 27  * 返回  :无
 28 ******************************************************************************/
 29 void EventProcess1(List *pArgList)
 30 {
 31     uint32_t i;
 32     
 33     ZF_DEBUG(LOG_D, "\r\n");
 34     ZF_DEBUG(LOG_D, "event1 arg count is %d\r\n", pArgList->Count);
 35     for (i = 0; i < pArgList->Count; i ++)
 36     {
 37         ZF_DEBUG(LOG_D, "event1 arg %d is %s\r\n", i,
 38             pArgList->GetElementDataAt(pArgList, i));
 39     }
 40 }
 41 
 42 /******************************************************************************
 43  * 描述  :事件程序2
 44  * 参数  :(in)-pArgList 事件参数列表指针
 45  * 返回  :无
 46 ******************************************************************************/
 47 void EventProcess2(List *pArgList)
 48 {
 49     uint32_t i;
 50     
 51     ZF_DEBUG(LOG_D, "\r\n");
 52     ZF_DEBUG(LOG_D, "event2 arg count is %d\r\n", pArgList->Count);
 53     for (i = 0; i < pArgList->Count; i ++)
 54     {
 55         ZF_DEBUG(LOG_D, "event2 arg %d is %s\r\n", i,
 56             pArgList->GetElementDataAt(pArgList, i));
 57     }
 58 }
 59 
 60 /******************************************************************************
 61  * 描述  :任务初始化
 62  * 参数  :无
 63  * 返回  :无
 64 ******************************************************************************/
 65 void App_Event_init(void)
 66 {
 67     Event *pEvent; /* 事件指针 */
 68     
 69     /* 初始化事件处理器 */
 70     EventHandler_create(&pEventHandler);
 71     
 72     /* 创建事件1 */
 73     Event_create(&pEvent);
 74     pEvent->EventProcess = EventProcess1;
 75     pEvent->AddArg(pEvent, "hello", sizeof("hello") + 1);
 76     
 77     /* 推送事件1 */
 78     EVENT_POST(pEventHandler, pEvent);
 79     
 80     /* 创建事件2 */
 81     Event_create(&pEvent);
 82     pEvent->EventProcess = EventProcess2;
 83     pEvent->AddArg(pEvent, "zorb", sizeof("zorb") + 1);
 84     pEvent->AddArg(pEvent, "framework", sizeof("framework") + 1);
 85     
 86     /* 推送事件2 */
 87     EVENT_POST(pEventHandler, pEvent);
 88 }
 89 
 90 /******************************************************************************
 91  * 描述  :任务程序
 92  * 参数  :无
 93  * 返回  :无
 94 ******************************************************************************/
 95 void App_Event_process(void)
 96 {
 97     while(1)
 98     {
 99         /* 执行事件 */
100         if (pEventHandler->GetEventCount(pEventHandler) > 0)
101         {
102             pEventHandler->Execute(pEventHandler);
103         }
104         else
105         {
106             /* 可在此实现低功耗 */
107         }
108     }
109 }
110 
111 /******************************** END OF FILE ********************************/

  结果:

event1 arg count is 1
event1 arg 0 is hello

event2 arg count is 2
event2 arg 0 is zorb
event2 arg 1 is framework

 

三、定时器结果测试

  简单的测试代码如下:

 1 /**
 2   *****************************************************************************
 3   * @file    app_timer.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 "app_timer.h"
19 #include "zf_includes.h"
20 
21 /* 事件处理器 */
22 static EventHandler *pEventHandler;
23 /* 定时器1 */
24 static Timer *pTimer1;
25 /* 定时器2 */
26 static Timer *pTimer2;
27 
28 /******************************************************************************
29  * 描述  :定时器程序1
30  * 参数  :void
31  * 返回  :无
32 ******************************************************************************/
33 void TimerProcess1(void)
34 {
35     ZF_DEBUG(LOG_D, "%dms:timer process 1 run\r\n", ZF_SYSTIME_MS());
36 }
37 
38 /******************************************************************************
39  * 描述  :定时器程序2
40  * 参数  :void
41  * 返回  :无
42 ******************************************************************************/
43 void TimerProcess2(void)
44 {
45     ZF_DEBUG(LOG_D, "%dms:timer process 2 run\r\n", ZF_SYSTIME_MS());
46 }
47 
48 /******************************************************************************
49  * 描述  :任务初始化
50  * 参数  :无
51  * 返回  :无
52 ******************************************************************************/
53 void App_Timer_init(void)
54 {
55     /* 初始化事件处理器 */
56     EventHandler_create(&pEventHandler);
57     
58     /* 创建定时器1 */
59     Timer_create(&pTimer1);
60     pTimer1->Priority = 1;
61     pTimer1->Interval = 500;
62     pTimer1->TimerProcess = TimerProcess1;
63     pTimer1->IsAutoReset = true;
64     pTimer1->pEventHandler = pEventHandler;
65     pTimer1->Start(pTimer1);
66     
67     /* 创建定时器2 */
68     Timer_create(&pTimer2);
69     pTimer2->Priority = 2;
70     pTimer2->Interval = 1000;
71     pTimer2->TimerProcess = TimerProcess2;
72     pTimer2->IsAutoReset = true;
73     pTimer2->pEventHandler = pEventHandler;
74     pTimer2->Start(pTimer2);
75 }
76 
77 /******************************************************************************
78  * 描述  :任务程序
79  * 参数  :无
80  * 返回  :无
81 ******************************************************************************/
82 void App_Timer_process(void)
83 {
84     while(1)
85     {
86         /* 执行事件 */
87         if (pEventHandler->GetEventCount(pEventHandler) > 0)
88         {
89             pEventHandler->Execute(pEventHandler);
90         }
91         else
92         {
93             /* 可在此实现低功耗 */
94         }
95     }
96 }
97 /******************************** END OF FILE ********************************/

  结果:

500ms:timer process 1 run
1000ms:timer process 1 run
1002ms:timer process 2 run
1500ms:timer process 1 run
2000ms:timer process 1 run
2002ms:timer process 2 run
2500ms:timer process 1 run
3000ms:timer process 1 run
3002ms:timer process 2 run
3500ms:timer process 1 run
4000ms:timer process 1 run
4002ms:timer process 2 run
4500ms:timer process 1 run
5000ms:timer process 1 run
5002ms:timer process 2 run

省略...

  在测试程序中,定时器1周期为500ms,定时器2周期为一千ms。至于定时器2程序先是次执行的日子为100二ms的原由:定时器1和定时器2同时在一千ms处响应,但定时器壹 的事先级比定时器2的事先级高,由此事件处理器先处理完定时器一的事件再处理定时器2的风浪,而调节和测试串口波特率115200,定时器壹程序把调试数据发送完的年月大体二ms,因而定时器2的首先次施行时间为1002ms。

 

三、状态机结果测试

  简单的测试代码如下:

  1 /**
  2   *****************************************************************************
  3   * @file    app_fsm.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 "app_fsm.h"
 19 #include "zf_includes.h"
 20 
 21 /* 定义用户信号 */
 22 enum Signal
 23 {
 24     SAY_HELLO = FSM_USER_SIG_START
 25 };
 26 
 27 Fsm *pFsm;        /* 父状态机 */
 28 Fsm *pFsmSon;     /* 子状态机 */
 29 
 30 /* 父状态机状态1 */
 31 static void State1(Fsm * const pFsm, FsmSignal const fsmSignal);
 32 /* 父状态机状态2 */
 33 static void State2(Fsm * const pFsm, FsmSignal const fsmSignal);
 34 
 35 /******************************************************************************
 36  * 描述  :父状态机状态1
 37  * 参数  :-pFsm       当前状态机
 38  *         -fsmSignal  当前调度信号
 39  * 返回  :无
 40 ******************************************************************************/
 41 static void State1(Fsm * const pFsm, FsmSignal const fsmSignal)
 42 {
 43     switch(fsmSignal)
 44     {
 45         case FSM_ENTER_SIG:
 46             ZF_DEBUG(LOG_D, "enter state1\r\n");
 47             break;
 48         
 49         case FSM_EXIT_SIG:
 50             ZF_DEBUG(LOG_D, "exit state1\r\n\r\n");
 51             break;
 52         
 53         case SAY_HELLO:
 54             ZF_DEBUG(LOG_D, "state1 say hello, and want to be state2\r\n");
 55             /* 切换到状态2 */
 56             pFsm->TransferWithEvent(pFsm, State2);
 57             break;
 58     }
 59 }
 60 
 61 /******************************************************************************
 62  * 描述  :父状态机状态2
 63  * 参数  :-pFsm       当前状态机
 64  *         -fsmSignal  当前调度信号
 65  * 返回  :无
 66 ******************************************************************************/
 67 static void State2(Fsm * const pFsm, FsmSignal const fsmSignal)
 68 {
 69     switch(fsmSignal)
 70     {
 71         case FSM_ENTER_SIG:
 72             ZF_DEBUG(LOG_D, "enter state2\r\n");
 73             break;
 74         
 75         case FSM_EXIT_SIG:
 76             ZF_DEBUG(LOG_D, "exit state2\r\n\r\n");
 77             break;
 78         
 79         case SAY_HELLO:
 80             ZF_DEBUG(LOG_D, "state2 say hello, and want to be state1\r\n");
 81             /* 切换到状态1 */
 82             pFsm->TransferWithEvent(pFsm, State1);
 83             break;
 84     }
 85 }
 86 
 87 /******************************************************************************
 88  * 描述  :子状态机状态
 89  * 参数  :-pFsm       当前状态机
 90  *         -fsmSignal  当前调度信号
 91  * 返回  :无
 92 ******************************************************************************/
 93 static void SonState(Fsm * const pFsm, FsmSignal const fsmSignal)
 94 {
 95     switch(fsmSignal)
 96     {
 97         case SAY_HELLO:
 98             ZF_DEBUG(LOG_D, "son say hello only in state2\r\n");
 99             break;
100     }
101 }
102 
103 /******************************************************************************
104  * 描述  :任务初始化
105  * 参数  :无
106  * 返回  :无
107 ******************************************************************************/
108 void App_Fsm_init(void)
109 {
110     /* 创建父状态机,并设初始状态 */
111     Fsm_create(&pFsm);
112     pFsm->SetInitialState(pFsm, State1);
113     
114     /* 创建子状态机,并设初始状态 */
115     Fsm_create(&pFsmSon);
116     pFsmSon->SetInitialState(pFsmSon, SonState);
117     
118     /* 设置子状态机仅在父状态State2触发 */
119     pFsmSon->OwnerTriggerState = State2;
120     
121     /* 把子状态机添加到父状态机 */
122     pFsm->AddChild(pFsm, pFsmSon);
123     
124     /* 运行状态机 */
125     pFsm->RunAll(pFsm);
126 }
127 
128 /******************************************************************************
129  * 描述  :任务程序
130  * 参数  :无
131  * 返回  :无
132 ******************************************************************************/
133 void App_Fsm_process(void)
134 {
135     ZF_DELAY_MS(1000);
136     /* 每1000ms调度状态机,发送SAY_HELLO信号 */
137     pFsm->Dispatch(pFsm, SAY_HELLO);
138 }
139 
140 /******************************** END OF FILE ********************************/

  结果:

state1 say hello, and want to be state2
exit state1

enter state2
son say hello only in state2
state2 say hello, and want to be state1
exit state2

enter state1
state1 say hello, and want to be state2
exit state1

enter state2
son say hello only in state2
state2 say hello, and want to be state1
exit state2

enter state1
state1 say hello, and want to be state2
exit state1

省略...

 

三、调节和测试输出

  开发2个程序,最初始也最主要的是搭建调节和测试的条件,大家采用串口一作为调剂输出,然后调节和测试音信分为三个级次,后续上位机能够依照差异阶段进行高亮提醒:

 1 /** 2   ***************************************************************************** 3   * @file    zf_debug.h 4   * @author  Zorb 5   * @version V1.0.0 6   * @date    2018-06-28 7   * @brief   调试输出的头文件 8   ***************************************************************************** 9   * @history10   *11   * 1. Date:2018-06-2812   *    Author:Zorb13   *    Modification:建立文件14   *15   *****************************************************************************16   */17 18 #ifndef __ZF_DEBUG_H__19 #define __ZF_DEBUG_H__20 21 #ifdef __cplusplus22 extern "C" {23 #endif24 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_DEBUG36     #if ZF_DEBUG_ON37         #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;                      \46         } while(0)47     #else48         #define ZF_DEBUG(rank, x...)49     #endif /* ZF_DEBUG_ON */50 #endif /* _ZF_DEBUG */51 52 #ifdef __cplusplus53 }54 #endif55 56 #endif /* __ZF_DEBUG_H__ */57 58 /******************************** END OF FILE ********************************/

四、最后

  本篇为Zorb
Framework提供了风波作用。事件作用首要用以搭建基于事件驱动的主次,若是直接习惯于付出时间驱动程序(轮询程序)的您,尝试一下事件驱动程序,你会发现别有一番韵味。

 

  Zorb Framework
github:

  版权全体,转发请打赏哟

 

假如您喜爱笔者的篇章,能够透过微信扫一扫给自家打赏哟

威尼斯人线上娱乐 2

四、最后

  本篇为Zorb
Framework提供了定时器功效。在对定时精度须要不高(微秒级),完全可以使用软件定时器。软件定时器是在硬件定时器的根基上支出的,好处在于能够挂载多少个定时器,不用再为芯片的定时器资源不够而闹心。

 

  Zorb Framework
github:

  版权全体,转发请打赏哟

 

假使你喜欢自个儿的篇章,能够经过微信扫一扫给自家打赏哟

威尼斯人线上娱乐 3

四、最后

  本篇为Zorb
Framework提供了景况机作用,复杂的情状转换关系被分解成了1个个场地函数,然后在场合函数中然则供给处理本状态现身的情事,忽然感觉世界变得不难很多。前面再配上即将为框架添加的事件成效,会让状态机的效应发挥到极致。

 

  Zorb Framework
github:

  版权全部,转发请打赏哟

 

要是您喜爱作者的篇章,能够透过微信扫1扫给自个儿打赏哟

威尼斯人线上娱乐 4

肆、达成断言

威尼斯人线上娱乐 ,  在支付进度中,在事关心尊敬大地点开展部分预知,能够便宜定位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   * @history10   *11   * 1. Date:2018-06-2812   *    Author:Zorb13   *    Modification:建立文件14   *15   *****************************************************************************16   */17 18 #ifndef __ZF_ASSERT_H__19 #define __ZF_ASSERT_H__20 21 #ifdef __cplusplus22 extern "C" {23 #endif24 25 #include "stdint.h"26 27 #define _ZF_ASSERT              /* 定义断言功能 */28 #define ZF_ASSERT_ON true       /* 启用断言功能 */29 30 #ifdef _ZF_ASSERT31     #if ZF_ASSERT_ON32          #define ZF_ASSERT(expression_) ((expression_) ?\33             (void)0 : ZF_assertHandle((uint8_t *)__FILE__, (int)__LINE__));34     #else35          #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 __cplusplus43 }44 #endif45 46 #endif /* __ZF_ASSERT_H__ */47 48 /******************************** END OF FILE ********************************/

  断言的处理很简短,正是告诉我们在哪个文件哪1行出错就足以,完结如下

 1 /** 2   ***************************************************************************** 3   * @file    zf_assert.c 4   * @author  Zorb 5   * @version V1.0.0 6   * @date    2018-06-28 7   * @brief   断言的实现 8   ***************************************************************************** 9   * @history10   *11   * 1. Date:2018-06-2812   *    Author:Zorb13   *    Modification:建立文件14   *15   *****************************************************************************16   */17 18 #include "zf_assert.h"19 #include "zf_debug.h"20 21 /******************************************************************************22  * 描述  :断言产生时的处理23  * 参数  :-pFileName 文件名24  *         -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 ********************************/

伍、建立即间体系

  为了减弱框架对财富的花费,所以开端设定框架的小不点儿时间周期为一ms,由此大家须要设置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   * @history10   *11   * 1. Date:2018-06-2812   *    Author:Zorb13   *    Modification:建立文件14   *15   *****************************************************************************16   */17 18 #ifndef __ZF_TIME_H__19 #define __ZF_TIME_H__20 21 #ifdef __cplusplus22 extern "C" {23 #endif24 25 #include "stdbool.h"26 #include "stdint.h"27 28 /* 系统滴答周期 */29 #define ZF_TICK_PERIOD 130 31 /* 获取系统滴答数 */32 #define ZF_SYSTICK() ZF_getSystemTick()33 34 /* 获取系统时间 */35 #define ZF_SYSTIME_MS() ZF_getSystemTimeMS()36 37 /* 系统延时 */38 #define ZF_DELAY_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 /* 获取系统时间 */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 __cplusplus63 }64 #endif65 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   * @history10   *11   * 1. Date:2018-06-2812   *    Author:Zorb13   *    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  * 描述  :获取系统时间35  * 参数  :无36  * 返回  :系统时间37 ******************************************************************************/38 uint32_t ZF_getSystemTimeMS(void)39 {40     return ZF_tick * ZF_TICK_PERIOD;41 }42 43 /******************************************************************************44  * 描述  :系统延时45  * 参数  :-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的中国人民解放军第6野战军,从而提升开支功用。

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

  Zorb Framework github:

  版权全部,转发请打赏哟

如若你喜欢本人的稿子,可以经过微信扫1扫给自个儿打赏哟

威尼斯人线上娱乐 5


相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图