• 嵌入式软件设计之美-以实际项目应用MVC框架与状态模式(下)


    上节我们分享了MVC框架、状态模式组合在实际开发中的应用,它能够让我们的软件设计流程更加的清晰、易于维护:

    嵌入式软件设计之美-以实际项目应用MVC框架与状态模式(上)

    那么这一节我们就直接开门见山,从接下来的这个开源项目分享开始:

    项目开源仓库:

    https://github.com/Yangyuanxin/IotSensorDetect
    
    • 1

    项目获取方法:

    git close https://github.com/Yangyuanxin/IotSensorDetect
    
    • 1

    该项目会不断的添加新的示例来持续完善。

    这是一个基于MVC模式+状态设计模式的物联网气体检测开源项目,目前的整体软件通信框架图(后续会根据需求继续拓展)如下所示:
    在这里插入图片描述

    如上软件通信框架图所示,腾讯连连小程序 & 腾讯云IoT Explorer物联网平台相对于设备端来说是上位机,而下位机部分则是由四个主要的任务来协作完成的,分别是ControllerTask、IotRecvTask、ModelHnadlerControolerTask以及ModelSensorHandlerTask,而Task与Task之间的通信方式是基于消息队列的形式来实现的。采用消息队列通讯是一种软件设计解耦的实现方式,线程与线程之间通过消息队列通信,能够实现业务隔离,让整个系统的可拓展性大大提高。除此之外,采用消息队列的好处是能够携带数据载体,数据格式也可以由用户自定义。例如本开源项目的自定义消息结构体如下:

    struct Msg_t
    {
      uint8_t Type;         //消息类型
      uint32_t SensorValue; //传感器数值
      char Data[MSG_LEN];   //其它可能的数据承载
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    其中,软件通信时序分为两种模式:

    1、Ctrl Mode
    该模式由APP端发起,对于APP端来说,APP端可以下发三种命令,分别是检测、停止、返回,如下图所示:
    在这里插入图片描述

    当用户在APP端按下检测时,APP端会下发START命令,当Controller接收到Iot端下发的指令时会将其转发给Model模块来控制传感器进行检测,期间检测过程中的设备状态以及传感器数值会进行更新,检测过程也可以通过下发停止来打断;而返回则是根据当前的设备状态来返回到上一个检测状态;这一切是通过状态模式来维护的,其状态流程图如下:
    在这里插入图片描述

    在程序中,该状态流程图是通过一个结构体数组来定义的:

    SensorStateItem_t SensorStateTable[] =
    {
        {IDLE,   START, CALI},      //IDLE->START->CALI
        {CALI,   NEXT,  DETECT},    //CALI->NEXT->DETECT
        {CALI,   STOP,  IDLE},      //CALI->STOP->IDLE
        {DETECT, NEXT,  RESULT},    //DETECT->NEXT->RESULT
        {DETECT, PREV,  CALI},      //DETECT->PREV->CALI
        {DETECT, STOP,  IDLE},      //DETECT->STOP->IDLE
        {RESULT, PREV,  DETECT},    //RESULT->PREV->DETECT
        {RESULT, STOP,  IDLE},      //RESULT->STOP->IDLE
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    切换状态的过程是由DoSensorStatus来实现的:

    __IO SensorState_t CurState = IDLE;  //当前状态
    __IO SensorState_t PrevState = IDLE; //上一个状态
    
    SensorStateItem_t *FindCurStateAndEvent(SensorState_t CurState, SensorEvent_t Event)
    {
        int Index = 0;
        //查状态表
        for(Index = 0; Index < NR_MODEL(SensorStateTable); Index++)
        {
            if(SensorStateTable[Index].CurState == CurState \
                    && SensorStateTable[Index].Event == Event)  \
                return &SensorStateTable[Index];
        }
    
        return NULL;
    }
    //执行状态机
    int DoSensorStatus(SensorEvent_t Event)
    {
        int Ret = 1;
        SensorStateItem_t *Item;
        //根据当前的状态、事件找到状态表中的那一项,取到那一项的地址
        Item = FindCurStateAndEvent(CurState, Event);
    
        if (!Item)
            return 0;
        //保存上一个状态
        PrevState = CurState;
        //切换到下一个状态
        CurState = Item->NextSate;
        return Ret;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    2、Auto Report Mode
    该模式是由设备端主动定时上报给到APP端,如下图所示:
    在这里插入图片描述

    检测设备在没有启动检测功能时,设备端也会定时上报传感器数值以及设备状态;因此,Iot端能够定时看到数据在不断发生变化。

    以上便是MCV框架与状态模式最简单的应用了。当然,从上节我们就已经知道,对于Controller和View而言,它的体现形式可以有很多种,它不局限于仅仅是Iot的形式,它也可以是由其它模块来构成;这部分待后续项目更新后上传。

    参考资料
    [1]https://www.runoob.com/design-pattern/mvc-pattern.html
    [2]https://refactoringguru.cn/design-patterns/state

  • 相关阅读:
    基于组件的架构:现代软件开发的基石
    Vue3最佳实践 第六章 Pinia,Vuex与axios,VueUse 4(axios)
    路由与交换技术-18-热备份路由选择协议HSRP
    如何配置frp到linux服务器和windows本地,服务端支持自启动
    python unittest以及coverage report
    回溯算法的了解
    多视图聚类论文阅读(二)
    40期《Pandas数据处理与分析》|pandas基础笔记2|pandas 基础|joyfulPandas
    【动态规划】121. 买卖股票的最佳时机、122. 买卖股票的最佳时机 II
    tomcat springboot war包 部署
  • 原文地址:https://blog.csdn.net/morixinguan/article/details/127972451