• 
    

    
    

      99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看

      ?

      IEC61131標(biāo)準(zhǔn)的結(jié)構(gòu)化文本語言解釋器設(shè)計(jì)

      2019-01-17 03:14:50,,,,
      關(guān)鍵詞:序號(hào)指令定義

      ,,,,

      (南京南瑞繼保電氣有限公司,南京 211102)

      引 言

      IEC61131是國際電工委員會(huì)(IEC)頒布的可編程控制器(PLC)國際標(biāo)準(zhǔn)[1-5],它可以規(guī)范工業(yè)控制系統(tǒng)平臺(tái)和應(yīng)用程序開發(fā),從而降低用戶的使用難度和維護(hù)成本[6]。IEC61131-3為軟件設(shè)計(jì)提供了標(biāo)準(zhǔn)化的編程概念和編程方法,定義了5種語言規(guī)范,國內(nèi)外工控廠家和科研機(jī)構(gòu)已經(jīng)開始提供基于該標(biāo)準(zhǔn)的產(chǎn)品并進(jìn)行了應(yīng)用[7-10]。參考文獻(xiàn)[7]介紹了嵌入式軟PLC系統(tǒng)的架構(gòu),設(shè)計(jì)了將IEC61131-3語言轉(zhuǎn)換為C語言的開發(fā)系統(tǒng)。參考文獻(xiàn)[8]提出一種將ST語言轉(zhuǎn)換為IL指令的方法,解決了ST語言語法分解和優(yōu)先級(jí)算法的相關(guān)問題。參考文獻(xiàn)[9]提出了基于指令向量表的軟PLC系統(tǒng)實(shí)現(xiàn)方法,實(shí)現(xiàn)了梯形圖指令的高效執(zhí)行。參考文獻(xiàn)[10]是本課題組的前期研究成果,介紹了結(jié)構(gòu)化文本的虛擬機(jī)指令架構(gòu)和編譯優(yōu)化方法。PLC系統(tǒng)編程指令的執(zhí)行方式有編譯型和解釋型方式。編譯型效率高,需要針對(duì)運(yùn)行的硬件環(huán)境開發(fā)專門的編譯器。解釋型執(zhí)行方式具有靈活性高、易于跨平臺(tái)移植的特點(diǎn),適用于在線無擾更新的應(yīng)用場(chǎng)景,但在實(shí)時(shí)性方面存在不足。針對(duì)參考文獻(xiàn)[10]開發(fā)的編譯器形成的二進(jìn)制虛擬機(jī)指令,設(shè)計(jì)了配套的上位機(jī)仿真用解釋器,本文介紹了一種高效解釋執(zhí)行的方案。

      1 解釋器設(shè)計(jì)

      1.1 指令格式設(shè)計(jì)

      本文在指令設(shè)計(jì)時(shí)參考了VCODE和CIL指令集的部分理念[10]:使執(zhí)行頻繁的部分保持高效,使其他部分保持正確。根據(jù)ST語言的規(guī)范和特性,支持可變形參,可內(nèi)置調(diào)用更豐富的庫函數(shù)接口。以算術(shù)運(yùn)算為例,在存儲(chǔ)時(shí)指令類型占用1字節(jié),指令存在二元運(yùn)算如add(rd,rs1,rs2)、一元運(yùn)算如not(rd,rs)、跳轉(zhuǎn)指令jmp(lab)、函數(shù)調(diào)用scall等模式。采用緊湊型存儲(chǔ),根據(jù)指令類型動(dòng)態(tài)輸出形參個(gè)數(shù)??紤]內(nèi)存對(duì)齊、方便快速掃描定位的前提下,內(nèi)存中三地址碼指令存儲(chǔ)格式定義如下:

      指令碼(2 Bytes)參數(shù)1(2 Bytes)參數(shù)2可選(2 Bytes)參數(shù)3可選(2 Bytes)

      存儲(chǔ)和讀取時(shí)根據(jù)指令類型動(dòng)態(tài)計(jì)算參數(shù)偏移,例如add指令為3個(gè)形參,not指令為2個(gè)形參。

      1.2 指令文件格式

      圖1 指令文件格式

      在上位機(jī)通過工具處理將ST/FBD/LD/SFC等類型的POU編譯形成解釋器側(cè)所需的指令文件,文件采用小端方式存儲(chǔ)。文件結(jié)構(gòu)如圖1所示,包括文件頭 、引用的外部變量信息區(qū)、POU變量區(qū)、常量區(qū)、臨時(shí)變量區(qū)、指令區(qū)、字符串池(變長(zhǎng)存儲(chǔ))、擴(kuò)展信息段等。

      圖中的變量區(qū)按照POU聲明的變量順序排列,即POU的輸入變量、輸出變量、輸入-輸出變量、中間變量。變量序號(hào)從0遞增,指令區(qū)的操作數(shù)記錄的是變量序號(hào),對(duì)于復(fù)雜結(jié)構(gòu)體采用深度優(yōu)先遍歷平鋪展開為基本變量類型的成員變量。

      1.3 關(guān)鍵數(shù)據(jù)結(jié)構(gòu)定義

      單個(gè)IEC61131定義的基本變量用IecVar結(jié)構(gòu)體表示,作為最小粒度的邏輯分區(qū)存儲(chǔ)單元,它有兩個(gè)子結(jié)構(gòu)體成員,為VAR_FLAG和VAR_VALUE。邏輯變量定義如圖2所示。

      圖2 邏輯變量定義

      VAR_FLAG是個(gè)2字節(jié)的結(jié)構(gòu)體,記錄變量下IEC61131定義的變量屬性:

      struct VAR_FLAG{

      ushort var_type: 5; //參照ST的標(biāo)準(zhǔn)定義

      ushort bretain: 1; //是否掉電保留

      ushort bnegate: 1; //是否取反,

      ushort bin_out: 1; //是否為輸入-輸出類型

      ushort bconst: 1; //是否為常量,寫保護(hù)

      ushort bredge: 1; //是否上升沿檢測(cè)

      ushort bfedge: 1; //是否下降沿檢測(cè)

      ushort bwrite_back: 1; //是否需要回寫

      ushort bupdate: 1; //更新位

      ushort resv : 3;

      };

      VAR_VALUE用于表示變量的值、字符串類型信息、時(shí)間類型變量信息,為枚舉結(jié)構(gòu):

      union LOGIC_VAR_VALUE{

      uint m_uint;

      int m_int;

      float m_float;

      USTR m_str; //字符串

      uint64 m_uint64;

      double m_double;

      IEC_TIME m_t;

      IEC_DATE m_date;

      …};

      其中字符串用4字節(jié)的結(jié)構(gòu)體表示,2字節(jié)表示長(zhǎng)度,2字節(jié)表示在字符串池中的起始位置。

      指令編碼定義如下:

      struct IRCode {

      OpType tp; //指令類型add/sub等

      ushort arg1; //通常是目的地址序號(hào)

      ushort arg2; //通常是源操作數(shù)序號(hào)1

      ushort arg3; //通常是源操作數(shù)序號(hào)2

      };

      指令運(yùn)行條目信息,存儲(chǔ)運(yùn)行中變量地址和關(guān)聯(lián)的指令執(zhí)行函數(shù),是運(yùn)行時(shí)調(diào)度的基本單位:

      struct IRItem{

      ushort idx; //指令序號(hào)

      uint parg1; //形參1對(duì)應(yīng)變量區(qū)變量地址

      uint parg2; //形參2對(duì)應(yīng)變量區(qū)變量地址

      uint parg3; //形參地址或立即數(shù)

      void (*irfunc)(IRItem* p); //指令執(zhí)行函數(shù)

      };

      指令文件類定義如下:

      class CMidFile {

      public:

      CMidFile(); ~CMidFile();

      public:

      MID_HEADER m_header; //文件頭

      QList m_externVarList; //外部變量區(qū)

      QList m_pouVarList; //POU數(shù)據(jù)區(qū)

      QList m_constVarList; //常量區(qū)

      QList m_tempVarList; //臨時(shí)變量區(qū)

      QList m_IRList; //指令數(shù)組

      QList m_strList;

      //存儲(chǔ)字符串列表

      …};

      解釋器在初始化時(shí),讀取指令文件,形成變量鏈表和指令數(shù)組。

      1.4 解釋器架構(gòu)設(shè)計(jì)

      根據(jù)控制器內(nèi)ST指令文件解析、執(zhí)行的流程,可將解釋器的功能結(jié)構(gòu)分為三個(gè)子模塊,如圖3所示。

      圖3 解釋器運(yùn)行模型

      初始化加載:對(duì)指令文件進(jìn)行初步解析,包括將緊湊排列的變量按照以IecVar為單位分配,方便數(shù)據(jù)信息的結(jié)構(gòu)化封裝以及索引定位。

      解釋執(zhí)行任務(wù):根據(jù)預(yù)處理后形成的內(nèi)存文件,對(duì)指令區(qū)的指令逐條解釋執(zhí)行,并讀取外部變量區(qū)和本地變量區(qū)的相關(guān)數(shù)據(jù)。

      數(shù)據(jù)刷新任務(wù):通過監(jiān)視接口對(duì)內(nèi)存文本中的數(shù)據(jù)進(jìn)行設(shè)置、觀測(cè),通過調(diào)試接口和調(diào)試符號(hào)表對(duì)指令區(qū)執(zhí)行過程進(jìn)行干預(yù)控制。

      1.5 初始化設(shè)計(jì)

      解釋器在初始化時(shí)讀取指令文件,先讀取文件頭,獲取各個(gè)變量區(qū)變量個(gè)數(shù)、指令個(gè)數(shù)等統(tǒng)計(jì)信息。之后依次讀取變量區(qū)、指令區(qū)、字符串池、調(diào)試表、擴(kuò)展信息區(qū)。為了節(jié)省空間,變量值VAR_VALUE在文件中存儲(chǔ)時(shí)按照實(shí)際類型大小存儲(chǔ),在讀取時(shí),需要根據(jù)變量類型動(dòng)態(tài)調(diào)整讀取的buf長(zhǎng)度,單個(gè)變量的讀取示例如下:

      CIecVar* pvar = new CIecVar(varIdx++);

      varList.append(pvar);

      getMemory(buf, &tmpoff, (uchar*)&pvar->flag, len1);

      switch( pvar->m_flag.var_type){

      case e_BOOL:

      case e_SINT:

      pvar->m_val.m_char = (char)getChar(buf, &tmpoff);

      break;

      case e_USINT:

      case e_BYTE:

      pvar->m_val.m_uchar = getChar(buf, &tmpoff);

      break;

      …}

      指令區(qū)解析根據(jù)指令類型解析若干形參,形成指令編碼如下:

      IRCode* pIR = new IRCode();

      m_IRList.append(pIR);

      pIR->tp = (OpType)getInt16(pbuf, &tmpoff);

      switch(pIR->tp){

      case e_add: //3個(gè)形參

      case e_div:

      pIR->arg1 = getInt16(pbuf, &tmpoff);

      pIR->arg2 = getInt16(pbuf, &tmpoff);

      pIR->arg3 = getInt16(pbuf, &tmpoff);

      break;

      case e_asgn: // 2個(gè)形參

      case e_not:

      pIR->arg1 = getInt16(pbuf, &tmpoff);

      pIR->arg2 = getInt16(pbuf, &tmpoff);

      break;

      case e_jmp:// 1個(gè)形參

      case e_lab:

      pIR->arg1 = getInt16(pbuf, &tmpoff);

      break;

      }

      在初始化過程中,通過如下處理為運(yùn)行時(shí)提高效率創(chuàng)造條件:

      ① 在讀取完變量區(qū)和指令區(qū)后,根據(jù)指令形參中記錄的變量區(qū)序號(hào),查找到動(dòng)態(tài)分配的IecVar變量的地址,形成IRItem條目結(jié)構(gòu),并根據(jù)指令類型關(guān)聯(lián)對(duì)應(yīng)的指令解析函數(shù)或系統(tǒng)庫函數(shù)指針,在初始化時(shí)完成數(shù)據(jù)形參、執(zhí)行函數(shù)的關(guān)聯(lián),實(shí)現(xiàn)初始化一次查找關(guān)聯(lián),執(zhí)行時(shí)直接使用轉(zhuǎn)換。圖4是add指令的形參和執(zhí)行函數(shù)的關(guān)聯(lián)過程。

      圖4 IRItem形成過程示例

      ② 創(chuàng)建lab標(biāo)號(hào)和指令序號(hào)的hash表,即QHashm_labelHash, 實(shí)現(xiàn)運(yùn)行shi跳轉(zhuǎn)指令快速跳轉(zhuǎn)到對(duì)應(yīng)的指令區(qū)域。

      1.6 運(yùn)行時(shí)設(shè)計(jì)

      根據(jù)ST語言的基本指令碼索引其函數(shù)指針數(shù)組,獲得對(duì)應(yīng)功能函數(shù)指針,傳入形參地址,進(jìn)行解釋執(zhí)行。對(duì)于系統(tǒng)庫函數(shù)指令碼的解釋執(zhí)行,首先定位scall指令,再根據(jù)其第一個(gè)形參值(系統(tǒng)庫函數(shù)的指令碼值)索引定位系統(tǒng)庫函數(shù)指令碼函數(shù)指針數(shù)組,獲取對(duì)應(yīng)功能函數(shù)指針,傳入在系統(tǒng)庫變量區(qū)的功能塊結(jié)構(gòu)體首地址,進(jìn)行解釋執(zhí)行。當(dāng)執(zhí)行到JZ、JMP等跳轉(zhuǎn)指令時(shí),將當(dāng)前執(zhí)行的指令數(shù)組下標(biāo)修改為跳轉(zhuǎn)指令記錄的跳轉(zhuǎn)目的標(biāo)號(hào),之后順序執(zhí)行從新下標(biāo)起始對(duì)應(yīng)的指令。由于初始化過程中已經(jīng)根據(jù)指令類型設(shè)置了對(duì)應(yīng)的執(zhí)行函數(shù)指針,故運(yùn)行過程中不需要進(jìn)行指令類型判斷,順次執(zhí)行即可:

      void CInterpreter:::execIRList(){

      readInput(); //刷新外部輸入

      m_curpos = 0;

      m_it =m_IRList.begin();

      while(m_curpos

      IRItem* pitem =*m_it;

      if(pitem->irfunc ) pitem->irfunc(pitem);

      ++m_it;

      ++m_curpos; }

      writeOutput(); //將值更新到輸出

      }

      其中跳轉(zhuǎn)指令執(zhí)行函數(shù)的作用是動(dòng)態(tài)調(diào)整當(dāng)前指令游標(biāo)m_it、m_curpos,從而間接修改主函數(shù)while循環(huán)中下次運(yùn)行的起始位置,實(shí)現(xiàn)指令數(shù)組順次執(zhí)行可跳轉(zhuǎn)的功能:

      inline exec_jmp(IRItem* p){

      ushort label = (ushort)p->arg1;

      QHash::Iterator it;

      it = m_labelHash.find(label);

      if(it!=m_labelHash.end()){

      //動(dòng)態(tài)調(diào)整當(dāng)前下標(biāo)到跳轉(zhuǎn)的標(biāo)簽處

      int labpos = (int)it.value();

      m_it += labpos-m_curpos;

      m_curpos = labpos;

      }

      }

      結(jié) 語

      猜你喜歡
      序號(hào)指令定義
      聽我指令:大催眠術(shù)
      ARINC661顯控指令快速驗(yàn)證方法
      LED照明產(chǎn)品歐盟ErP指令要求解讀
      技術(shù)指標(biāo)選股
      技術(shù)指標(biāo)選股
      技術(shù)指標(biāo)選股
      技術(shù)指標(biāo)選股
      成功的定義
      山東青年(2016年1期)2016-02-28 14:25:25
      坐標(biāo)系旋轉(zhuǎn)指令數(shù)控編程應(yīng)用
      修辭學(xué)的重大定義
      介休市| 克拉玛依市| 高陵县| 晋州市| 留坝县| 克拉玛依市| 鹿泉市| 吉木乃县| 高唐县| 永丰县| 达尔| 溧水县| 武平县| 章丘市| 茂名市| 卓尼县| 二连浩特市| 贵港市| 周至县| 罗山县| 石泉县| 杭锦旗| 安阳县| 巴马| 榆社县| 保靖县| 井研县| 大竹县| 蒲城县| 牙克石市| 慈溪市| 景东| 广灵县| 寻甸| 资讯 | 方山县| 昌邑市| 涿州市| 弥勒县| 禹城市| 如皋市|