亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

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

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

        ,,,,

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

        引 言

        IEC61131是國際電工委員會(IEC)頒布的可編程控制器(PLC)國際標(biāo)準(zhǔn)[1-5],它可以規(guī)范工業(yè)控制系統(tǒng)平臺和應(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)先級算法的相關(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í)行方式有編譯型和解釋型方式。編譯型效率高,需要針對運(yùn)行的硬件環(huán)境開發(fā)專門的編譯器。解釋型執(zhí)行方式具有靈活性高、易于跨平臺移植的特點(diǎn),適用于在線無擾更新的應(yīng)用場景,但在實(shí)時(shí)性方面存在不足。針對參考文獻(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)算為例,在存儲時(shí)指令類型占用1字節(jié),指令存在二元運(yùn)算如add(rd,rs1,rs2)、一元運(yùn)算如not(rd,rs)、跳轉(zhuǎn)指令jmp(lab)、函數(shù)調(diào)用scall等模式。采用緊湊型存儲,根據(jù)指令類型動態(tài)輸出形參個(gè)數(shù)??紤]內(nèi)存對齊、方便快速掃描定位的前提下,內(nèi)存中三地址碼指令存儲格式定義如下:

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

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

        1.2 指令文件格式

        圖1 指令文件格式

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

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

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

        單個(gè)IEC61131定義的基本變量用IecVar結(jié)構(gòu)體表示,作為最小粒度的邏輯分區(qū)存儲單元,它有兩個(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; //是否上升沿檢測

        ushort bfedge: 1; //是否下降沿檢測

        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é)表示長度,2字節(jié)表示在字符串池中的起始位置。

        指令編碼定義如下:

        struct IRCode {

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

        ushort arg1; //通常是目的地址序號

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

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

        };

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

        struct IRItem{

        ushort idx; //指令序號

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

        uint parg2; //形參2對應(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;

        //存儲字符串列表

        …};

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

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

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

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

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

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

        數(shù)據(jù)刷新任務(wù):通過監(jiān)視接口對內(nèi)存文本中的數(shù)據(jù)進(jìn)行設(shè)置、觀測,通過調(diào)試接口和調(diào)試符號表對指令區(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在文件中存儲時(shí)按照實(shí)際類型大小存儲,在讀取時(shí),需要根據(jù)變量類型動態(tài)調(diào)整讀取的buf長度,單個(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ū)序號,查找到動態(tài)分配的IecVar變量的地址,形成IRItem條目結(jié)構(gòu),并根據(jù)指令類型關(guān)聯(lián)對應(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)號和指令序號的hash表,即QHashm_labelHash, 實(shí)現(xiàn)運(yùn)行shi跳轉(zhuǎn)指令快速跳轉(zhuǎn)到對應(yīng)的指令區(qū)域。

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

        根據(jù)ST語言的基本指令碼索引其函數(shù)指針數(shù)組,獲得對應(yīng)功能函數(shù)指針,傳入形參地址,進(jìn)行解釋執(zhí)行。對于系統(tǒng)庫函數(shù)指令碼的解釋執(zhí)行,首先定位scall指令,再根據(jù)其第一個(gè)形參值(系統(tǒng)庫函數(shù)的指令碼值)索引定位系統(tǒng)庫函數(shù)指令碼函數(shù)指針數(shù)組,獲取對應(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)號,之后順序執(zhí)行從新下標(biāo)起始對應(yīng)的指令。由于初始化過程中已經(jīng)根據(jù)指令類型設(shè)置了對應(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ù)的作用是動態(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()){

        //動態(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é) 語

        猜你喜歡
        序號指令定義
        聽我指令:大催眠術(shù)
        ARINC661顯控指令快速驗(yàn)證方法
        LED照明產(chǎn)品歐盟ErP指令要求解讀
        電子測試(2018年18期)2018-11-14 02:30:34
        技術(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é)的重大定義
        国产精品无码午夜福利| 国产精品福利高清在线| 极品精品视频在线观看| 99热门精品一区二区三区无码| 免费一区啪啪视频| 国产人澡人澡澡澡人碰视频| 日韩精品精品一区二区三区| 亚洲成av人片在线天堂无| 丰满人妻无套内射视频| 精品久久一区二区av| 丝袜人妻中文字幕首页| 中文字幕有码在线人妻| 亚洲一二三四区免费视频 | 婷婷精品国产亚洲av麻豆不片| 狠狠色狠狠色综合网| 无码人妻一区二区三区在线| 又色又爽又黄高潮的免费视频| 国产成人av一区二区三区| 亚洲精品无码久久久久牙蜜区| 国产精品露脸视频观看| 久久精品亚洲中文无东京热| 亚洲日本国产乱码va在线观看| 日韩女优中文字幕在线| 久久久成人av毛片免费观看| 亚洲天堂av福利在线| 日产一区二区三区免费看| 激情综合色综合啪啪开心| 卡一卡二卡三无人区| 女人扒开下面无遮挡| 久久综合给合久久狠狠狠97色69 | 国产一级一厂片内射视频播放| 国产亚洲一区二区毛片| 亚洲av久播在线一区二区| 色拍自拍亚洲综合图区| 中文字幕日本特黄aa毛片| 国产精品99久久久久久宅男| 日本一区二区啪啪视频| 久久精品熟女亚洲av艳妇| 日本中文字幕人妻精品| 亚洲综合在不卡在线国产另类| 麻花传媒68xxx在线观看|