首页 > 编程语言 >4 Diac中E_CYCLE模块源码分析

4 Diac中E_CYCLE模块源码分析

时间:2023-08-05 17:33:11浏览次数:36  
标签:scm const paTimerListEntry Diac mTimeListEntry 源码 static CYCLE

E_CYCLE的源码分析

一 E_CYCLE的功能

输入事件接口:START、STOP ,输出事件接口EO

数据输入接口:DT

START是开启定时事件,STOP结束定时事件,EO是时间到了触发的事件,DT是配置时间间隔参数,数据类型为字符串类型。

举例:DT输入T#10MS,则10MS触发一次EO事件

 

 

 

二 源码分析

该源码主要包含四个文件E_CYCLE.h、E_CYCLE.cpp和timedfb.h、timedfb.cpp

 

首先分析E_CYCLE.h文件,可以看出E_CYCLE这个类继承了CTimeFB类,E_CYCLE类继承了CTimeFB类的功能,包括定时功能块的执行逻辑。因此转定义到类CtimeFB。

#ifndef _E_CYCLE_H_

#define _E_CYCLE_H_

 

#include "../timedfb.h"

 

/*! \brief Implementation of the E_CYCLE FB.

 */

class E_CYCLE : public CTimedFB{

  DECLARE_FIRMWARE_FB(E_CYCLE)

private:

public:

  E_CYCLE(const CStringDictionary::TStringId paInstanceNameId, CResource *paSrcRes) :

      CTimedFB( paInstanceNameId, paSrcRes, e_Periodic){

  }

 

  virtual ~E_CYCLE() {}

 

};

 

#endif /*E_CYCLE_H_*/

 

 

以下为CtimeFB的定义文件(timedfb.h),其中给出了具体事件执行函数executeEvent()。

#ifndef _TIMEDFB_H_

#define _TIMEDFB_H_

 

#include "../core/esfb.h"

#include "../arch/timerha.h"

#include "../core/resource.h"

 

/*!\brief Base class for timed function block like E_CYCLE or E_DELAY providing this interface

 */

class CTimedFB : public CEventSourceFB{

private:

protected:

  static const SFBInterfaceSpec scm_stFBInterfaceSpec;

  static const CStringDictionary::TStringId scm_aunEINameIds[];

  static const TDataIOID scm_anEIWith[];

  static const TForteInt16 scm_anEIWithIndexes[];

  static const CStringDictionary::TStringId scm_aunEONameIds[];

  static const TForteInt16 scm_anEOWithIndexes[];

  static const CStringDictionary::TStringId scm_aunDINameIds[];

  static const CStringDictionary::TStringId scm_aunDIDataTypeNameIds[];

 

  static const TEventID csm_nEventSTARTID = 0;

  static const TEventID csm_nEventSTOPID = 1;

 

  static const TEventID csm_nEOID = 0;

 

  FORTE_FB_DATA_ARRAY(1,1,0, 0);

 

  bool mActive; //!> flag to indicate that the timed fb is currently active

  STimedFBListEntry mTimeListEntry; //!> The Timer list entry of this timed FB

/*!\brief execute the input events of timed FBs as far it is possible

 *

 * Derived Timed FBs only normaly need only the start event es this is different for each timed FB type (e.g. periodic vs. onetimeshot)

 */

  virtual void executeEvent(int pa_nEIID);

 

  CIEC_TIME& DT() {

     return *static_cast<CIEC_TIME*>(getDI(0));

  }

public:

  CTimedFB(const CStringDictionary::TStringId paInstanceNameId, CResource *paSrcRes, ETimerActivationType paType);

  virtual ~CTimedFB() {};

 

  virtual EMGMResponse changeFBExecutionState(EMGMCommandType pa_unCommand);

 

};

 

#endif /*TIMEDFB_H_*/

 

以下为executeEvent函数转定义后timedfb.cpp文件部分代码,可以看出具体执行操作,根据传入的当前执行事件ID号(pa_nEIID),跳转swich分支语句判断。其中mActive为标志位,表示定时FB当前处于活动状态。其中mActive初始化为False,当START接口接收到事件时,执行getTimer().registerTimerFB(&mTimeListEntry,DT()),这里设置触发事件间隔。

CTimedFB::CTimedFB(const CStringDictionary::TStringId paInstanceNameId, CResource *paSrcRes, ETimerActivationType paType) :

      CEventSourceFB( paSrcRes, &scm_stFBInterfaceSpec, paInstanceNameId, m_anFBConnData, m_anFBVarsData){

  setEventChainExecutor(paSrcRes->getResourceEventExecution());

  mActive = false;

  mTimeListEntry.mTimeOut = 0;

  mTimeListEntry.mInterval = 0;

  mTimeListEntry.mNext = 0;

  mTimeListEntry.mType = paType;

  mTimeListEntry.mTimedFB = this;

}

 

void CTimedFB::executeEvent(int pa_nEIID){

  switch(pa_nEIID){

    case cg_nExternalEventID:

      sendOutputEvent(csm_nEOID);

      break;

     

    case csm_nEventSTOPID:

      if(mActive){

        getTimer().unregisterTimedFB(this);

        mActive = false;

      }

      break;

    case csm_nEventSTARTID:

      if(!mActive){

        getTimer().registerTimedFB( &mTimeListEntry, DT());

        mActive = true;

      }

      break;

    default:

      break;

  }

}

转定义到registerTimeFB进行分析

void CTimerHandler::registerTimedFB(STimedFBListEntry *paTimerListEntry, const CIEC_TIME &paTimeInterval) {

  //calculate the correct interval based on time-base and timer ticks per seconds

  paTimerListEntry->mInterval = static_cast<TForteUInt32>((paTimeInterval * getTicksPerSecond()) / cgForteTimeBaseUnitsPerSecond);

  // Correct null intervals that can lead to event queue overflow to at least 1 timer tick

  if(0 == paTimerListEntry->mInterval) {

    paTimerListEntry->mInterval = 1;

  }

  // set the first next activation time right here to reduce jitter, see Bug #568902 for details

  paTimerListEntry->mTimeOut = mForteTime + paTimerListEntry->mInterval;

  {

    CCriticalRegion criticalRegion(mAddListSync);

    paTimerListEntry->mNext = mAddFBList;

    mAddFBList = paTimerListEntry;

  }

}

根据传入的参数registerTimerFB(&mTimeListEntry,DT()),指针指向mTimeListEntry,DT()为我们输入的时间间隔。

paTimerListEntry->mInterval = static_cast<TForteUInt32>((paTimeInterval * getTicksPerSecond()) / cgForteTimeBaseUnitsPerSecond);

 

    /*! \brief Get the time base of the runtime

     *

     * \return internal runtime ticks per second

     */

    static TForteUInt32 getTicksPerSecond(void){

      return cg_nForteTicksPerSecond;

    }

 

这里计算了定时块功能的时间间隔,getTicksPersecond()这个函数获取每秒计时器滴答数(返回内部运行时间的每秒刻度数),paTimerInterval* getTicksPersecond(),这一步将传入的时间间隔转化为滴答数,再除以cgForteTimeBaseUnitsPerSecong(这个是Forte中时间单位的单位时间数),进行类型转换赋值给paTimerListEntry->mInterval。

如果传入的时间间隔为0,则将其设置为至少一个计时器滴答数,防止事件队列溢出。

设置下一次触发时间,根据当前时间和计算得到的间隔,计算触发事时间。

paTimerListEntry->mTimeOut = mForteTime+paTimerListEntry->mInterval;

 

 

标签:scm,const,paTimerListEntry,Diac,mTimeListEntry,源码,static,CYCLE
From: https://www.cnblogs.com/XZJY/p/17608286.html

相关文章

  • 动力节点|MyBatis从入门实战到深入源码
    MyBatis是一种简单易用、灵活性高且高性能的持久化框架,也是Java开发中不可或缺的一部分。动力节点老杜的MyBatis教程,上线后广受好评从零基础小白学习的角度出发,层层递进从简单到深入,从实战到源码一步一案例,一码一实操,嘴对嘴指导MyBatis重点、难点、考点一网打尽不管你是小白还是正......
  • 在线直播系统源码,移动端列表左右滑动效果
    在线直播系统源码,移动端列表左右滑动效果<view class="evaluationItem">                <scroll-view class="uni-swiper-tab" scroll-x :style="'height:'+scrollH+'px'">                    <view class="scrollx_i......
  • RTSP/Onvif视频服务器LntonNVR(源码版)平台在Windows系统中使用挂载盘的具体操作流程
    LntonNVR平台默认的录像存储位置在LntonNVR/mediaserver/data/hls中,若用户有其他需求,也可以修改存储路径,将录像文件存储在其他指定的磁盘。具体可参照这篇文章:【操作教程】新内核版LntonNVR如何更改录像文件的存储位置?有用户反馈,录像文件更改存储路径后,存储录像文件的时间核对不上,......
  • 小狐狸GPT付费源码-WEB版前端的监控代码
    今天搭建了下小狐狸的WEB版,里面有个隐藏的js代码调用外部接口可以看到下面的代码 会把当前的域名调用外部接口传递过去  ......
  • 国标GB28181视频平台LntonGBS(源码版)国标平台正确调阅实时录像接口的具体操作步骤
    LntonGBS之所以成为安防市场的主流视频平台,主要得益于其架构优势。首先,LntonGBS采用了云边端一体化的架构,将云计算、边缘计算和终端设备有机结合,实现了数据的高效传输和处理。这种架构不仅能够满足大规模视频数据的存储和分析需求,还能够实现实时监控和快速响应,提高了安防系统的整体......
  • 国标GB28181视频平台LntonGBS(源码版)国标视频平台优化设备通道视频播放出现跳屏的问题
    LntonGBS国标视频云服务支持设备/平台通过国标GB28181协议注册接入,并能实现视频的实时监控直播、录像、检索与回看、语音对讲、云存储、告警、平台级联等功能。平台部署简单、可拓展性强,支持将接入的视频流进行全终端、全平台分发,分发的视频流包括RTSP、RTMP、FLV、HLS、WebRTC等格......
  • Spring源码分析(五) MappingJackson2HttpMessageConverter
    大家用过springmvc的肯定都用过@RequestBody和@ResponseBody注解吧,你了解这个的原理吗?这篇文章我们就来说下它是怎么实现json转换的。首先来看一个类RequestResponseBodyMethodProcessor,这个类继承了AbstractMessageConverterMethodProcessor,我们来看看这个类的构造方法protec......
  • 在线直播系统源码,js循环数组的方法合集
    在线直播系统源码,js循环数组的方法合集一、forEach循环注:没有return返回值,且不能用break跳出循环。 letarrlist=['123','456','789'];arrlist.forEach(function(value,index){  //value是每一项,index是索引  console.log(value,index);}); ​二、for循环......
  • ajax 源码分析
    /**源码来源:https://github.com/wendux/Ajax-hook*XHR属性方法:*TypeFunction:[abort,getAllResponseHeaders,getResponseHeader,open,overrideMimeType,send,setRequestHeader]*typeobject:[onreadystatechange,upload,responseXML,onprogress,onabort,onloadst......
  • RTSP流媒体服务器LntonNVR(源码版)视频监控平台通过ODM工具手动输入onvif地址添加通道的
    LntonNVR是一种轻量级的视频监控平台,具有强大的拓展性和高兼容度。它可以支持通过RTSP/ONVIF协议接入前端设备,包括摄像头等。在接入前端设备时,LntonNVR提供了自带的ONVIF探测功能,可以方便地将摄像头设备接入平台。一旦接入成功,您就可以通过LntonNVR实现对摄像头的云台控制,包括转动......