xml地图|网站地图|网站标签 [设为首页] [加入收藏]
环形缓冲区的实现,嵌入式框架Zorb澳门新葡亰手
分类:编程

前言

所谓泛型,即通过参数化类型来实现在同一份代码上操作多种数据类型。

泛型编程是一种编程范式,它利用“参数化类型”将类型抽象化,从而实现更为灵活的复用。在定义泛型类时,在对客户端代码能够在实例化类时,可以用类型参数的类型种类施加限制。在搭建底层框架时,是最常见的编程方式。

 

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

二、状态机设计

  我们先来看看要实现的状态机提供什么功能:

  初步要提供的功能如下:

  1、可以设置初始状态

  2、可以进行状态转换

  3、可以进行信号调度

  4、最好可以在进入和离开状态的时候可以做一些自定义的事情

  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-31为框架信号,用户信号在32之后定义。

  状态机已经设计好了,具体实现请看附件代码或在文末的github地址拉框架源码。

 

.NET泛型约束

如果客户端代码尝试使用某个约束所不允许的类型来实例化类,则会产生编译时错误。这些限制称为约束。约束是使用 where 上下文关键字指定的。

下表列出了五种类型的约束:

 

约束 说明

T:struct

类型参数必须是值类型。可以指定除 Nullable 以外的任何值类型。

T:class

类型参数必须是引用类型,包括任何类、接口、委托或数组类型。

T:new()

类型参数必须具有无参数的公共构造函数。当与其他约束一起使用时,new() 约束必须最后指定。

T:<基类名>

类型参数必须是指定的基类或派生自指定的基类。

T:<接口名称>

类型参数必须是指定的接口或实现指定的接口。可以指定多个接口约束。约束接口也可以是泛型的。

T:U

为 T 提供的类型参数必须是为 U 提供的参数或派生自为 U 提供的参数。这称为裸类型约束.

 

 

 

派生约束

1.常见的

public class MyClass5 where T :IComparable { }

2.约束放在类的实际派生之后

public class B { }

public class MyClass6 : B where T : IComparable { }

3.可以继承一个基类和多个接口,且基类在接口前面

public class B { }

public class MyClass7 where T : B, IComparable, ICloneable { }

 

构造函数约束

1.常见的

public class MyClass8 where T : new() { }

2.可以将构造函数约束和派生约束组合起来,前提是构造函数约束出现在约束列表的最后

public class MyClass8 where T : IComparable, new() { }

 

值约束

1.常见的

public class MyClass9 where T : struct { }

2.与接口约束同时使用,在最前面(不能与基类约束,构造函数约束一起使用)

public class MyClass11 where T : struct, IComparable { }

 

引用约束

常见的

public class MyClass10 where T : class { }

多个泛型参数

public class MyClass12<T, U> where T : IComparable where U : class { }

 

 

PS:欢迎扫描下方二维码,加入QQ群

澳门新葡亰手机版 1

 

作者:Jacky

来源:

声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

三、环形缓冲区结果测试

  简单的测试代码如下:

 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 %drn", 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 %drn", 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, "rnrn");
67     
68     /* 弹出数据 */
69     for (i = 0; i < 10; i++)
70     {
71         rb->GetByte(rb, &byte);
72         
73         ZF_DEBUG(LOG_D, "byte %d is %drn", i, byte);
74         ZF_DEBUG(LOG_D, "rb count is %drn", 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:

  版权所有,转载请打赏哟

 

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

澳门新葡亰手机版 2

本文由澳门新葡亰手机版发布于编程,转载请注明出处:环形缓冲区的实现,嵌入式框架Zorb澳门新葡亰手

上一篇:没有了 下一篇:没有了
猜你喜欢
热门排行
精彩图文