威尼斯人线上娱乐

嵌入式框架Zorb,状态机的完毕

12 4月 , 2019  

本身是卓波,小编是一名嵌入式工程师,作者绝对没悟出我会在那里跟大家夸口皮。

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

小编是卓波,小编是一名嵌入式工程师,笔者相对没悟出笔者会在那里跟我们吹嘘皮。

自个儿是卓波,我是一名嵌入式工程师,小编相对没悟出小编会在那里跟大家吹捧皮。

嵌入式框架Zorb Framework搭建进程

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

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

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

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

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

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

嵌入式框架Zorb
Framework搭建7:职责的完成

 

嵌入式框架Zorb Framework搭建进度

嵌入式框架Zorb,状态机的完毕。嵌入式框架Zorb
Framework搭建1:嵌入式环境搭建、调节和测试输出和成立时间连串

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

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

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

嵌入式框架Zorb
Framework搭建伍:事件的落到实处

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

嵌入式框架Zorb
Framework搭建7:职责的完结

 

嵌入式框架Zorb Framework搭建进度

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

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

嵌入式框架Zorb
Framework搭建叁:列表的贯彻

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

嵌入式框架Zorb
Framework搭建伍:事件的落实

嵌入式框架Zorb
Framework搭建陆:定时器的兑现

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

 

嵌入式框架Zorb Framework搭建进度

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

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

嵌入式框架Zorb
Framework搭建三:列表的贯彻

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

嵌入式框架Zorb
Framework搭建伍:事件的落到实处

嵌入式框架Zorb
Framework搭建6:定时器的兑现

嵌入式框架Zorb
Framework搭建7:任务的完毕

 

一、前言

  在那一篇中,我们将为Zorb
Framework提供列表功能。列表是自己最欣赏用的数据结构,没有之一。在只要提到到管理对象不止多个的时候,作者就会想到列表。后边将要设计的状态机、事件、定时器和职务等等都亟需列表的支撑,能够说列表在总体框架之中是须要的2个功力。

 

一、前言

  在那一篇中,大家将为Zorb
Framework提供情形机成效。中型小型型嵌入式程序说白了就是由各样状态机组成,因而领悟了怎么着创设状态机,开发嵌入式应用程序能够说是手到拈来。不难的状态机能够用Switch-Case实现,但复杂一点的场地机再继续采取Switch-Case的话,层次会变得比较乱,不便于维护。由此大家为Zorb
Framework提供了函数式状态机。

 

一、前言

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

 

一、前言

  在这壹篇中,大家将为Zorb
Framework提供环形缓冲区的机能。环形缓冲区首要行使在字节数据流传输上,如串口、网口的收发都足以经过环形缓冲区实行缓存。例如笔者要透过串口发送命令“LED
ON”来决定开发板的led灯亮起来,但开发板串口接受不是3回把“LED
ON”同时收纳,而是二个字节1个字节地选取,因此供给动用缓冲区来缓存数据,然后解析器来分析缓冲区的多少。

 

二、列表设计

  大家先来看望要落到实处的列表提供什么意义:

  伊始要提供的机能如下:

  一、能够在钦赐地点扩充多少

  二、能够在钦定地方删除数据

  三、能够明白列表数据的个数

  肆、能够清空驶列车表

  5、能够不自由数据,仅仅把多少移出列表

  6、能够依照数据得到它所在的目录

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

 1 /* 列表节点结构 */
 2 typedef struct _ListNode
 3 {
 4     bool IsExternData;          /* 是否外部数据,是则销毁时不释放 */
 5     uint8_t *pData;             /* 指向数据的指针 */
 6     uint32_t Size;              /* 数据的大小 */
 7     struct _ListNode *Next;     /* 指向下一个节点 */
 8 } ListNode;
 9 
10 /* 列表结构 */
11 typedef struct _List
12 {
13     ListNode *pRootNode;        /* 指向根节点数据 */
14     uint32_t Count;             /* 节点个数 */
15     
16     /* 在尾端增加节点 */
17     bool (*Add)(struct _List * const pList, ListNode *pNode);
18     
19     /* 删除节点(释放空间) */
20     bool (*Delete)(struct _List * const pList, ListNode *pNode);
21     
22     /* 移除节点(不释放空间) */
23     bool (*Remove)(struct _List * const pList, ListNode *pNode);
24     
25     /* 返回指定索引处的节点的指针 */
26     bool (*GetElementAt)(struct _List * const pList, uint32_t index,
27         ListNode **ppNode);
28     
29     /* 返回数据区指向data的节点的指针 */
30     bool (*GetElementByData)(struct _List * const pList, void *pdata,
31         ListNode **ppNode);
32     
33     /* 返回指定索引处的节点的数据缓冲区的指针 */
34     void *(*GetElementDataAt)(struct _List * const pList, uint32_t index);
35     
36     /* 返回节点的索引 */
37     bool (*GetElementIndex)(struct _List * const pList, ListNode *pNode,
38         uint32_t *pIndex);
39     
40     /* 在指定索引处增加节点 */
41     bool (*AddElementAt)(struct _List * const pList, uint32_t index,
42         ListNode *pNode);
43     
44     /* 在指定索引处删除节点(释放空间) */
45     bool (*DeleteElementAt)(struct _List * const pList, uint32_t index);
46     
47     /* 在指定索引处移除节点(不释放空间) */
48     bool (*RemoveElementAt)(struct _List * const pList, uint32_t index);
49     
50     /* 清空列表(释放空间) */
51     bool (*Clear)(struct _List * const pList);
52     
53     /* 释放列表(释放空间) */
54     bool (*Dispose)(struct _List * const pList);
55 } List;

  为了促成动态列表,在列表中提供了二个Dispose的功效。

  列表已经布署好了,具体贯彻请看附属类小部件代码或在文末的github地址拉框架源码。

 

2、状态机设计

  我们先来探望要促成的状态机提供如何功用:

  起始要提供的法力如下:

  壹、能够安装初步状态

  二、可以展开状态转换

  三、能够开始展览功率信号调度

  肆、最佳能(CANON)够在进入和距离状态的时候能够做壹些自定义的事体

  五、最棒能够有子状态机

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

 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地址拉框架源码。

 

二、定时器设计

  大家先来探视要完结的定时器提供什么样作用:

  伊始要提供的意义如下:

  一、可以设置定时时间

  二、能够安装定时器是单次依旧重国民党的新生活运动行

  3、可以安装定时器处理函数

  四、定时器函数能够间接运营还是推送异步事件

  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地址拉框架源码。

 

二、环形缓冲区设计

  大家先来看看要促成的缓冲镇长什么样子,提供什么作用,那样便于大家规划。

  开始要提供的效益如下:

  一、要有能够缓存数据的空中

  贰、能够清楚总空间的分寸

  三、能够知晓已用空间的数量

  四、能够压入数据

  五、能够弹出多少

  陆、作者也得以在不弹出多少的图景下,读到特定长度的数量

威尼斯人线上娱乐,  由此,早先设计的数据结构如下:

 1 /* 环形缓冲区数据结构 */
 2 typedef struct _RingBuffer
 3 {
 4     bool IsExternBuffer;  /* 是否外部缓冲区,是则销毁时不释放 */
 5     uint8_t *pBuf;        /* 缓冲区指针 */
 6     uint32_t Head;        /* 缓冲区头地址 */
 7     uint32_t Trail;       /* 缓冲区尾地址 */
 8     uint32_t Size;        /* 缓冲区大小 */
 9     uint32_t Count;       /* 数据字节数 */
10     
11     /* 缓冲器是否已满 */
12     bool (*IsFull)(struct _RingBuffer * const pRb);
13     
14     /* 缓冲器是否空 */
15     bool (*IsEmpty)(struct _RingBuffer * const pRb);
16     
17     /* 压入一个字节 */
18     bool (*SaveByte)(struct _RingBuffer * const pRb, uint8_t byte);
19     
20     /* 取出一个字节 */
21     bool (*GetByte)(struct _RingBuffer * const pRb, uint8_t *pByte);
22     
23     /* 读取缓冲器已使用字节个数 */
24     uint32_t (*GetCount)(struct _RingBuffer * const pRb);
25     
26     /* 读取n个字节(n超过最大数据数时全部读出) */
27     bool (*ReadBytes)(struct _RingBuffer * const pRb, uint8_t *pArray,
28         uint32_t n);
29     
30     /* 丢弃n个字节(n超过最大数据数时全部丢弃) */
31     bool (*DropBytes)(struct _RingBuffer * const pRb, uint32_t n);
32     
33     /* 清空缓冲器 */
34     bool (*Clear)(struct _RingBuffer * const pRb);
35     
36     /* 释放缓冲器(不释放外部创建的缓冲区) */
37     bool (*Dispose)(struct _RingBuffer * const pRb);
38 } RingBuffer;

  其实按其实须要,恐怕远不止上边提到的六种情景,例如笔者得以废弃特定数量的字节数据,也足以一贯清空掉缓冲区数据,甚至足以思虑提供动态缓冲区的职能,也正是说可以释放缓冲器自个儿。

  缓冲区已经规划好了,具体落到实处请看附属类小部件代码或在文末的github地址拉框架源码。

 

叁、列表结果测试

  简单的测试代码如下:

  1 /**
  2   *****************************************************************************
  3   * @file    app_list.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_list.h"
 19 #include "zf_includes.h"
 20 #include "string.h"
 21 
 22 /* 列表指针 */
 23 List *pBookList;
 24 
 25 /* 书本数据结构 */
 26 typedef struct _Book
 27 {
 28     uint32_t Index; /* 索引 */
 29     char Name[10];  /* 书名 */
 30 } Book;
 31 
 32 /******************************************************************************
 33  * 描述  :任务初始化
 34  * 参数  :无
 35  * 返回  :无
 36 ******************************************************************************/
 37 void App_List_init(void)
 38 {
 39     /* 创建列表 */
 40     List_create(&pBookList);
 41 }
 42 
 43 /******************************************************************************
 44  * 描述  :任务程序
 45  * 参数  :无
 46  * 返回  :无
 47 ******************************************************************************/
 48 void App_List_process(void)
 49 {
 50     uint32_t i;
 51     ListNode *pNode;
 52     Book *pBook;
 53     
 54     ZF_DEBUG(LOG_D, "book list count before adding data is %d\r\n",
 55         pBookList->Count);
 56     
 57     /* 填充10个数据 */
 58     for (i = 0; i < 10; i++)
 59     {
 60         /* 创建节点 */
 61         List_mallocNode(&pNode, (void **)&pBook, sizeof(Book));
 62         
 63         /* 填充节点内容 */
 64         pBook->Index = i;
 65         strcpy(pBook->Name, "book x");
 66         pBook->Name[5] = '0' + i;
 67         
 68         /* 添加到列表 */
 69         pBookList->Add(pBookList, pNode);
 70     }
 71     
 72     ZF_DEBUG(LOG_D, "book list count after adding data is %d\r\n",
 73         pBookList->Count);
 74     
 75     /* 读出第3个数据看是否正确 */
 76     pBook = (Book *)pBookList->GetElementDataAt(pBookList, 2);
 77     
 78     ZF_DEBUG(LOG_D, "book index is %d\r\n", pBook->Index);
 79     ZF_DEBUG(LOG_D, "book name is %s\r\n", pBook->Name);
 80     
 81     ZF_DEBUG(LOG_D, "\r\n");
 82     
 83     /* 删除第5个数据 */
 84     pBookList->DeleteElementAt(pBookList, 4);
 85     
 86     ZF_DEBUG(LOG_D, "book list count after deleteing data is %d\r\n",
 87         pBookList->Count);
 88     
 89     /* 显示现有数据 */
 90     for (i = 0; i < pBookList->Count; i++)
 91     {
 92         pBook = (Book *)pBookList->GetElementDataAt(pBookList, i);
 93         
 94         ZF_DEBUG(LOG_D, "\r\n");
 95         ZF_DEBUG(LOG_D, "book index is %d\r\n", pBook->Index);
 96         ZF_DEBUG(LOG_D, "book name is %s\r\n", pBook->Name);
 97     }
 98     
 99     while(1);
100 }
101 
102 /******************************** END OF FILE ********************************/

  结果:

book list count before adding data is 0
book list count after adding data is 10
book index is 2
book name is book 2

book list count after deleteing data is 9

book index is 0
book name is book 0

book index is 1
book name is book 1

book index is 2
book name is book 2

book index is 3
book name is book 3

book index is 5
book name is book 5

book index is 6
book name is book 6

book index is 7
book name is book 7

book index is 8
book name is book 8

book index is 9
book name is book 9

 

3、状态机结果测试

  不难的测试代码如下:

  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

省略...

 

叁、定时器结果测试

  不难的测试代码如下:

 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。至于定时器贰程序先是次执行的大运为拾0二ms的来由:定时器1和定时器2同时在1000ms处响应,但定时器一 的先行级比定时器贰的事先级高,由此事件处理器先处理完定时器壹的风浪再处理定时器二的风浪,而调节和测试串口Porter率115200,定时器一程序把调节和测试数据发送完的时间大约2ms,由此定时器贰的首先次执行时间为100二ms。

 

3、环形缓冲区结果测试

  简单的测试代码如下:

 1 /**
 2   *****************************************************************************
 3   * @file    app_buffer.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_buffer.h"
19 #include "zf_includes.h"
20 
21 /* 环形缓冲区指针 */
22 RingBuffer *rb;
23 
24 /******************************************************************************
25  * 描述  :任务初始化
26  * 参数  :无
27  * 返回  :无
28 ******************************************************************************/
29 void App_Buffer_init(void)
30 {
31     /* 创建500字节的缓冲区 */
32     RB_create(&rb, 500);
33 }
34 
35 /******************************************************************************
36  * 描述  :任务程序
37  * 参数  :无
38  * 返回  :无
39 ******************************************************************************/
40 void App_Buffer_process(void)
41 {
42     uint32_t i;
43     uint8_t buf[11];
44     uint8_t byte;
45     
46     ZF_DEBUG(LOG_D, "rb count before adding data is %d\r\n", rb->Count);
47     
48     /* 填充10个字节数据(0-9) */
49     for (i = 0; i < 10; i++)
50     {
51         rb->SaveByte(rb, i);
52     }
53     
54     ZF_DEBUG(LOG_D, "rb count after adding data is %d\r\n", rb->Count);
55     
56     /* 读出数据看是否正确 */
57     rb->ReadBytes(rb, buf, 10);
58     
59     ZF_DEBUG(LOG_D, "rb data is ");
60     
61     for (i = 0; i < 10; i++)
62     {
63         ZF_DEBUG(LOG_D, "%d ", buf[i]);
64     }
65     
66     ZF_DEBUG(LOG_D, "\r\n\r\n");
67     
68     /* 弹出数据 */
69     for (i = 0; i < 10; i++)
70     {
71         rb->GetByte(rb, &byte);
72         
73         ZF_DEBUG(LOG_D, "byte %d is %d\r\n", i, byte);
74         ZF_DEBUG(LOG_D, "rb count is %d\r\n", rb->Count);
75     }
76     
77     while(1);
78 }
79 
80 /******************************** END OF FILE ********************************/

  结果:

rb count before adding data is 0
rb count after adding data is 10
rb data is 0 1 2 3 4 5 6 7 8 9 

byte 0 is 0
rb count is 9
byte 1 is 1
rb count is 8
byte 2 is 2
rb count is 7
byte 3 is 3
rb count is 6
byte 4 is 4
rb count is 5
byte 5 is 5
rb count is 4
byte 6 is 6
rb count is 3
byte 7 is 7
rb count is 2
byte 8 is 8
rb count is 1
byte 9 is 9
rb count is 0

 

四、最后

  本篇为Zorb
Framework提供了列表功能,而且以此列表可以装载分裂类别的数量。能够说是小作用,马虎义。

 

  Zorb Framework
github:

  版权全数,转发请打赏哟

 

若是您喜爱笔者的篇章,能够经过微信扫1扫给自个儿打赏哟

威尼斯人线上娱乐 1

四、最后

  本篇为Zorb
Framework提供了动静机成效,复杂的情况转换关系被分解成了二个个景况函数,然后在气象函数中单单需求处理本状态出现的情景,忽然感觉世界变得不难很多。后边再配上就要为框架添加的事件功用,会让状态机的效益发挥到极致。

 

  Zorb Framework
github:

  版权全数,转发请打赏哟

 

比方你欢悦本人的小说,能够因此微信扫一扫给本身打赏哟

威尼斯人线上娱乐 2

四、最后

  本篇为Zorb
Framework提供了定时器效能。在对定时精度要求不高(皮秒级),完全能够APP定时器。软件定时器是在硬件定时器的功底上付出的,好处在于能够挂载三个定时器,不用再为芯片的定时器财富不够而消沉。

 

  Zorb Framework
github:

  版权全数,转发请打赏哟

 

借使您喜爱作者的篇章,能够透过微信扫1扫给本人打赏哟

威尼斯人线上娱乐 3

四、最后

  本篇为Zorb
Framework提供了环形缓冲区功效,只要提到到字节流通讯,基本都亟待缓冲区来兑现,能够说利用功效比较高。以后造了这些轮子,前面就能够直接造跑车了。

 

  Zorb Framework
github:

  版权全数,转发请打赏哟

 

如果您欣赏作者的稿子,能够因此微信扫1扫给作者打赏哟

威尼斯人线上娱乐 4


相关文章

发表评论

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

网站地图xml地图