嵌入式环境搭建,嵌入式框架Zorb

自个儿是卓波,笔者是一名嵌入式工程师,作者相对没悟出笔者会在此间跟大家吹嘘皮。

本人是卓波,我是一名嵌入式工程师,我相对没悟出作者会在此间跟我们吹捧皮。

自个儿是卓波,作者是一名嵌入式工程师,小编相对没悟出我会在此地跟我们吹嘘皮。

本人是卓波,笔者是一名嵌入式工程师,笔者相对没悟出我会在此地跟我们吹捧皮。

嵌入式框架Zorb Framework搭建进度

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

嵌入式环境搭建,嵌入式框架Zorb。嵌入式框架Zorb
Framework搭建二:环形缓冲区的落到实处

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

嵌入式框架Zorb
Framework搭建四:状态机的完毕

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

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

嵌入式框架Zorb
Framework搭建7:职责的实现

 

嵌入式框架Zorb Framework搭建进度

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

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

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

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

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

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

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

 

嵌入式框架Zorb Framework搭建进程

亚洲必赢官网 ,嵌入式框架Zorb Framework搭建一:嵌入式环境搭建、调节和测试输出和成马上间体系

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

嵌入式框架Zorb Framework搭建叁:列表的得以实现

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

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

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

嵌入式框架Zorb Framework搭建七:义务的达成

嵌入式框架Zorb Framework搭建进程

嵌入式框架Zorb
Framework搭建一:嵌入式环境搭建、调节和测试输出和成登时间类别

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

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

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

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

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

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

 

一、前言

  在付出顺序时,有时候会发现单线程程序开发起来相比较费力,若是能够10二线程那该多好。本篇要为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

  7、职务作用zf_task

  前伍个效益,就足以兑现纯事件驱动的先后,基本能够满意中型小型型嵌入式应用程序开发的需要。加上任务成效,是为着满意部分程序对实时性必要较高的急需。当然,也得以将前四个功效裁剪出来,然后运营在存活的嵌入式系统方面,那样子也能够满意实时性的须求。

一、前言

  在嵌入式开发中,大家平常会用到定时器,大家能够用芯片的定时器外设,能够用基本的systick,也足以应用操作系统的定时器。本篇要规划的定时器类似与操作系统的定时器,是软件定时器。如若Zorb
Framework运营在操作系统上面,大能够不利用本篇的职能,直接选拔操作系统自带的定时器。

 

二、任务功效设计

  大家先来看望要落到实处的义务提供哪些效劳:

  早先要提供的效益如下:

  一、能够起来和终止职务

  二、职分有优先级分别

  三、能够拓展系统延时

  四、能够领略职责的运行时刻

  伍、可以动态成立和销毁职分

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

 1 /* 任务状态 */
 2 typedef enum _TaskState
 3 {
 4     TASK_STATE_STOP = 0,          /* 停止 */
 5     TASK_STATE_RUNNING            /* 运行 */
 6 } TaskState;
 7 
 8 /* 任务结构 */
 9 typedef struct _Task
10 {
11     uint32_t *pStkPtr;            /* 堆栈指针 */
12     uint32_t *pStkBase;           /* 堆栈基地址 */
13     uint32_t StkSize;             /* 堆栈大小 */
14     uint32_t DelayTime;           /* 任务延时时间(系统周期) */
15     uint8_t Priority;             /* 任务优先级 */
16     uint8_t State;                /* 任务状态 */
17     uint32_t RunTime;             /* 任务总运行时间(系统周期) */
18     
19     /* 开始任务 */
20     bool (*Start)(struct _Task * const pTask);
21     
22     /* 停止任务 */
23     bool (*Stop)(struct _Task * const pTask);
24     
25     /* 销毁任务 */
26     void (*Dispose)(struct _Task * const pTask);
27     
28     /* 延时任务 */
29     bool (*Delay)(struct _Task * const pTask, uint32_t tick);
30 } Task;

  为Zorb
Framework提供的天职成效相比简单,状态也唯有运维和关闭三种情景。职务成效完毕的关键在于职分调度,而职务调度的基本又在于任务堆栈的保留和还原。那有的必要基于使用的芯片举办改动,在STM3第22中学,通过触发PendSV很是进行职务切换:

 1 /******************************************************************************
 2  * 描述  :PendSV异常处理
 3  * 参数  :无
 4  * 返回  :无
 5 ******************************************************************************/
 6 __asm void PendSV_Handler(void)
 7 {
 8     IMPORT  pCurrentTask
 9     IMPORT  pTopPriorityTask
10     
11     /* 任务的保存,即把CPU寄存器的值存储到任务的堆栈中 */
12     /* 关中断,NMI和HardFault除外 */
13     CPSID   I
14     
15     /* 判断是否第一次运行 */
16     MRS     R0, PSP
17     CBZ     R0, PendSVHandler_NotSave
18     
19     /**
20         在进入PendSV异常的时候,当前CPU的xPSR,PC(任务入口地址),
21         R14,R12,R3,R2,R1,R0会自动存储到当前任务堆栈,同时递减PSP的值
22     **/
23     /* 手动存储CPU寄存器R4-R11的值到当前任务的堆栈 */
24     STMDB   R0!, {R4-R11}
25     
26     /* R0指向pCurrentTask的堆栈指针(指向空闲位置的顶部) */
27     LDR     R1, = pCurrentTask
28     LDR     R1, [R1]
29     STR     R0, [R1]
30     NOP
31     
32 /* 任务的切换,即把下一个要运行的任务的堆栈内容加载到CPU寄存器中 */
33 PendSVHandler_NotSave
34 
35     /* 等效操作pCurrentTask = pTopPriorityTask; */
36     LDR     R0, = pCurrentTask
37     LDR     R1, = pTopPriorityTask
38     LDR     R2, [R1]
39     STR     R2, [R0]
40     
41     /* pTopPriorityTask的信息出栈 */
42     LDR     R0, [R2]
43     LDMIA   R0!, {R4-R11}
44     
45     /* 设置PSP指向下一个要执行的任务的堆栈的栈底(已弹出了寄存器信息) */
46     MSR     PSP, R0
47     /* 确保异常返回使用的堆栈指针是PSP */
48     ORR     LR, LR, #0x04 /* 设置LR寄存器的位2为1 */
49     CPSIE   I /* 开中断 */
50     
51     /**
52         函数返回,这个时候任务堆栈中的剩下内容将会自动加载到
53         xPSR,PC(任务入口地址),R14,R12,R3,R2,R1,R0(任务的形参)
54         同时PSP的值也将更新,即指向任务堆栈的栈顶。
55         在STM32中,堆栈是由高地址向低地址生长的
56     **/
57     BX      LR
58     NOP
59 }

  具体贯彻请看附属类小部件代码或在文末的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-31为框架信号,用户复信号在3二过后定义。

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

 

贰、嵌入式环境搭建

  选择STM3贰F42九开发板作为硬件运维条件,硬件财富用到串口一和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 }

2、定时器设计

  大家先来看望要贯彻的定时器提供哪些效益:

  初叶要提供的效益如下:

  一、能够安装定时时间

  二、能够安装定时器是单次还是再度运营

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

  4、定时器函数可以平素运转依然推送异步事件

  伍、能够打开和倒闭定时器

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

 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   *****************************************************************************
  3   * @file    app_task.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_task.h"
 19 #include "zf_includes.h"
 20 
 21 static Task *pTask1; /* 任务1 */
 22 static Task *pTask2; /* 任务2 */
 23 static Task *pTask3; /* 任务3 */
 24 
 25 static void Process1(void *pArg); /* 任务1程序定义 */
 26 static void Process2(void *pArg); /* 任务2程序定义 */
 27 static void Process3(void *pArg); /* 任务3程序定义 */
 28 
 29 /******************************************************************************
 30  * 描述  :任务1程序
 31  * 参数  :(in)-pArg  参数指针
 32  * 返回  :无
 33 ******************************************************************************/
 34 static void Process1(void *pArg)
 35 {
 36     ZF_DEBUG(LOG_D, "\r\n");
 37     ZF_DEBUG(LOG_D, "system time is %dms\r\n", ZF_SYSTIME_MS());
 38     ZF_DEBUG(LOG_D, "I am %s\r\n", (char *)pArg);
 39     ZF_DEBUG(LOG_D, "task count is %d\r\n", TASK_GET_TASK_COUNT());
 40     
 41     ZF_DEBUG(LOG_D, "I will create task3\r\n");
 42     
 43     /* 创建任务3 */
 44     Task_create(&pTask3, Process3, "task3", 3, 256);
 45     
 46     ZF_DEBUG(LOG_D, "task count is %d\r\n", TASK_GET_TASK_COUNT());
 47     
 48     ZF_DEBUG(LOG_D, "I will dispose myself\r\n");
 49     
 50     pTask1->Dispose(pTask1);
 51 }
 52 
 53 /******************************************************************************
 54  * 描述  :任务2程序
 55  * 参数  :(in)-pArg  参数指针
 56  * 返回  :无
 57 ******************************************************************************/
 58 static void Process2(void *pArg)
 59 {
 60     while(1)
 61     {
 62         ZF_DEBUG(LOG_D, "\r\n");
 63         ZF_DEBUG(LOG_D, "system time is %dms\r\n", ZF_SYSTIME_MS());
 64         ZF_DEBUG(LOG_D, "I am %s\r\n", (char *)pArg);
 65         ZF_DEBUG(LOG_D, "task count is %d\r\n", TASK_GET_TASK_COUNT());
 66         ZF_DEBUG(LOG_D, "I will sleep 1000ms\r\n");
 67         ZF_DEBUG(LOG_D, "wake up time is %dms\r\n", ZF_SYSTIME_MS() + 1000);
 68         ZF_DELAY_MS(1000);
 69     }
 70 }
 71 
 72 /******************************************************************************
 73  * 描述  :任务3程序
 74  * 参数  :(in)-pArg  参数指针
 75  * 返回  :无
 76 ******************************************************************************/
 77 static void Process3(void *pArg)
 78 {
 79     while(1)
 80     {
 81         ZF_DEBUG(LOG_D, "\r\n");
 82         ZF_DEBUG(LOG_D, "system time is %dms\r\n", ZF_SYSTIME_MS());
 83         ZF_DEBUG(LOG_D, "I am %s\r\n", (char *)pArg);
 84         ZF_DEBUG(LOG_D, "task count is %d\r\n", TASK_GET_TASK_COUNT());
 85         ZF_DEBUG(LOG_D, "I will sleep 1000ms\r\n");
 86         ZF_DEBUG(LOG_D, "wake up time is %dms\r\n", ZF_SYSTIME_MS() + 1000);
 87         ZF_DELAY_MS(1000);
 88     }
 89 }
 90 
 91 /******************************************************************************
 92  * 描述  :任务初始化
 93  * 参数  :无
 94  * 返回  :无
 95 ******************************************************************************/
 96 void App_Task_init(void)
 97 {
 98     /* 创建任务1 */
 99     Task_create(&pTask1, Process1, "task1", 1, 512);
100     /* 创建任务1 */
101     Task_create(&pTask2, Process2, "task2", 2, 512);
102     /* 运行任务系统 */
103     Task_run();
104     
105     /* 程序不会到这 */
106 }
107 
108 /******************************** END OF FILE ********************************/

  结果:

system time is 3ms
I am task1
task count is 3
I will create task3
task count is 4
I will dispose myself

system time is 13ms
I am task2
task count is 3
I will sleep 1000ms
wake up time is 1019ms

system time is 21ms
I am task3
task count is 3
I will sleep 1000ms
wake up time is 1028ms

system time is 1021ms
I am task2
task count is 3
I will sleep 1000ms
wake up time is 2027ms

system time is 1030ms
I am task3
task count is 3
I will sleep 1000ms
wake up time is 2036ms

system time is 2029ms
I am task2
task count is 3
I will sleep 1000ms
wake up time is 3035ms

system time is 2038ms
I am task3
task count is 3
I will sleep 1000ms
wake up time is 3044ms

省略...

 

叁、状态机结果测试

  不难的测试代码如下:

  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

省略...

 

3、调节和测试输出

  开发2个先后,最开头也最器重的是搭建调节和测试的条件,咱们使用串口1作为调剂输出,然后调节和测试音讯分为八个级次,后续上位机能够依照差别阶段进行高亮提醒:

 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 ********************************/

三、定时器结果测试

  不难的测试代码如下:

 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的原因:定时器一和定时器2同时在1000ms处响应,但定时器1 的先期级比定时器二的先行级高,因而事件处理器先处理完定时器1的轩然大波再处理定时器2的轩然大波,而调节和测试串口Porter率115200,定时器一程序把调节和测试数据发送完的时光大概二ms,因而定时器2的率先次执行时间为100二ms。

 

四、最后

  本篇为Zorb
Framework提供了义务成效。使用多职务效率拓展支付是惠及了广大,但与此同时任务间的合营和财富调用加大了调节和排错的难度。在分享多职分带来的高兴的同时,要做好排错开上下班时间难受的预备。

 

  Zorb Framework
github:

  版权全部,转发请打赏哟

 

假定你喜欢本人的篇章,可以经过微信扫1扫给小编打赏哟

亚洲必赢官网 2

四、最后

  本篇为Zorb
Framework提供了气象机效率,复杂的图景转换关系被分解成了二个个境况函数,然后在意况函数中单单供给处理本状态现身的景况,忽然感觉世界变得简单很多。前边再配上就要为框架添加的事件成效,会让状态机的效能发挥到极致。

 

  Zorb Framework
github:

  版权全部,转发请打赏哟

 

假如你快乐自身的文章,能够由此微信扫一扫给自家打赏哟

亚洲必赢官网 3

四、完结断言

  在开发进度中,在显要地方举行部分预知,能够便宜定位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 ********************************/

四、最后

  本篇为Zorb
Framework提供了定时器功用。在对定时精度供给不高(阿秒级),完全能够使用软件定时器。软件定时器是在硬件定时器的根基上支出的,好处在于能够挂载八个定时器,不用再为芯片的定时器财富不够而抑郁。

 

  Zorb Framework
github:

  版权全部,转发请打赏哟

 

假使你喜爱小编的文章,能够经过微信扫1扫给本身打赏哟

亚洲必赢官网 4

5、建立即间连串

  为了削减框架对财富的消耗,所以起初设定框架的蝇头时间周期为1ms,因而大家需求安装systick的定时周期为一ms,然后每便进入暂停为大家的框架计数即可。

 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的中国人民解放军第四野战军,从而增强支付作用。

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

  Zorb Framework github:

  版权全体,转发请打赏哟

设若您喜爱笔者的文章,可以透过微信扫1扫给笔者打赏哟

亚洲必赢官网 5

网站地图xml地图