本發(fā)明涉可編程邏輯控制器領域,尤其涉及一種多任務圖形構件化可編程邏輯控制器系統(tǒng)以及利用該系統(tǒng)實現(xiàn)應用開發(fā)的方法。
背景技術:
plc從提出至今一直在工業(yè)自動化中發(fā)揮著重要的作用。它是一種為實現(xiàn)工業(yè)自動化而設計的數(shù)據輸入/輸出的邏輯控制裝置,它可以實現(xiàn)邏輯運算、順序運算、計時以及計數(shù)等功能。同時,它還具有可編程的存儲器。因此plc不僅能夠控制各類的工業(yè)生產過程或者機械設備,而且還能夠方便的對其中的代碼進行更改從而適應不同的工業(yè)生產需求。
目前,世界上有數(shù)百家plc生產廠家,上千種plc產品。主要應用在汽車(23%)、糧食加工(16.4%)、化學/制藥(14.6%)、金屬/礦山(11.5%)、紙漿/造紙(11.3%)等行業(yè)。按照地域可以分為美國、日本、歐洲三個流派的產品。各個流派的產品都具有自己的特色,其中,美國是plc的生產大國,有數(shù)百家plc產商,著名的有通用電氣(ce)公司、a-b公司、德州儀器(ti)公司、莫迪康(modicon)公司。歐洲著名的plc制造商有法國的te公司、德國的西門子(siemens)公司、aeg公司等。日本也有很多著名的plc制造廠商,例如著名的三菱、歐姆龍、松下、富士等。這些廠家的產品在小型的plc市場中占有很大的份額。
多年來plc以功能完善、使用方便、抗干擾能力和可靠性強、可在線修改控制程序、方便與計算機接口、能夠控制模擬量、具有高速計數(shù)與定位能力等性能強大的功能一直在工業(yè)控制中占有不可或缺的地位。在化工、石油、機械、冶金、電力、輕工、紡織、食品等行業(yè)得到了廣泛的應用。
然而隨著工業(yè)控制的迅速發(fā)展和市場需求的多樣化,傳統(tǒng)的plc逐漸顯露出一些缺點:兼容性和擴展性差;構造開放的硬件體系比較困難;工作人員掌握plc的梯形圖編程需要經過很長的培訓時間;plc執(zhí)行大型任務的處理速度和多任務的同步協(xié)調工作的能力很差;一些廠商壟斷了plc的生產,使得plc的性價比的成長速度緩慢。這些因素都限制了plc的發(fā)展。
plc的編程系統(tǒng)為用戶提供梯形圖的編寫和編譯功能。設備的正常運作,需要plc硬件和軟件開發(fā)的密切配合。硬件指的是設備的機械部分和電氣部分,軟件開發(fā)指的是plc控制器上的plc梯形圖程序。目前,提供梯形圖程序編輯功能的一般分為兩類設備,一類是梯形圖程序編程專用設備,一類是基于pc的plc編程系統(tǒng)。
梯形圖程序編程專用設備是plc廠商生產研制的專門用于plc梯形圖編輯的開發(fā)環(huán)境,一般支持il指令表編程和組態(tài)編程。它存在使用不方便、編程語言單一、使用壽命有限以及不利于plc設備的推廣等問題。
技術實現(xiàn)要素:
本申請?zhí)峁┝艘环N多任務圖形構件化可編程邏輯控制器gcplc系統(tǒng),通過采用圖形拖動的編程方式,簡化了編程的模式,并通過引入多任務體系實現(xiàn)了多任務的同步、通信以及中斷機制。
第一方面,本申請?zhí)峁┝艘环N多任務圖形構件化可編程邏輯控制器gcplc系統(tǒng),包括執(zhí)行模塊和開發(fā)模塊,
所述執(zhí)行模塊包括pwm模塊、led數(shù)碼管模塊、輸入/輸出模塊、電源模塊、jtag模塊、復位模塊、485模塊、232模塊、以及can總線模塊、以及底層驅動模塊;
所述開發(fā)模塊包括:圖標控件模塊、圖標控件連接及設置模塊、代碼顯示模塊、編譯模塊、以及程序下載模塊;
所述底層驅動模塊用于完成gcplc系統(tǒng)驅動功能;
所述圖標控件模塊用于提供開發(fā)所需要的圖標控件;
所述圖標控件連接及設置模塊用于設置選中的圖標控件的屬性,并將選中的圖標控件按照需要進行連接;
所述代碼顯示模塊用于在所述圖標控件連接及設置模塊將各個圖標連接完成后,生成并顯示對應的代碼;
編譯模塊用于在所述代碼顯示模塊顯示對應的代碼之后,當確認無誤時,對當前程序進行編譯和鏈接;
所述程序下載模塊用于將編譯模塊編譯生成的機器碼文件下載。
進一步地,所述底層驅動模塊具體包括通用驅動模塊和多任務驅動模塊;
所述通用驅動模塊用于實現(xiàn)對pwm模塊、led數(shù)碼管模塊、輸入/輸出模塊、電源模塊、jtag模塊、復位模塊、485模塊、232模塊、以及can總線模塊的驅動功能;
所述多任務執(zhí)行驅動模塊用于驅動gcplc系統(tǒng)的多任務執(zhí)行,所述多任務執(zhí)行包括任務之間的同步、任務之間的通信及任務的中斷。
優(yōu)選地,利用輕量級事件實現(xiàn)任務之間的同步,利用輕量級消息隊列實現(xiàn)任務之間的通信,利用中斷服務例程實現(xiàn)任務的中斷。
優(yōu)選地,所述圖標控件包括執(zhí)行控件、傳感器控件、通信控件、流程控件、以及任務控件。
優(yōu)選地,所述圖標控件采用treeview樹形結構表示。
優(yōu)選地,所述圖標控件之間的互連采用貝塞爾曲線實現(xiàn)。
優(yōu)選地,所述程序下載模塊采用命令行的方式調用jlink實現(xiàn)一鍵下載。
第二方面,本申請?zhí)峁┝艘环N利用所述多任務圖形構件化可編程邏輯控制器gcplc系統(tǒng)開發(fā)應用的方法,包括以下步驟:
步驟1:利用圖標控件模塊及圖標控件連接及設置模塊創(chuàng)建主任務,在主任務中初始化底層驅動模塊;
步驟2:利用圖標控件模塊及圖標控件連接及設置模塊創(chuàng)建多個子任務,配置各個任務的相關屬性以及多任務之間的同步、通信和中斷功能;
步驟3:利用代碼顯示模塊生成并顯示對應的代碼;
步驟4:利用編譯模塊進行編譯鏈接生成機器碼;
步驟5:利用下載模塊對機器碼進行下載寫入。
優(yōu)選地,所述子任務包括pwm、led和uart任務,其中pwm任務用于按照初始化的頻率輸出指定的脈沖數(shù)然后停止,led任務用于指示當前的運行狀態(tài),uart任務用于接收來自于調試軟件的數(shù)據并按照指令進行處理。
附圖說明
圖1是本發(fā)明的多任務gcplc系統(tǒng)示意圖;
圖2是代碼顯示模塊的代碼刷新流程示意圖;
圖3是主任務建立后的示意圖
圖4是添加led后界面的變化示意圖
圖5是為任務添加輕量級事件示意圖
圖6是利用gcplc建立多個任務示意圖
具體實施方式
現(xiàn)在將參照附圖詳細說明本發(fā)明構思的特定實施例。
如圖1所示,本發(fā)明的gcplc系統(tǒng)包括開發(fā)模塊和執(zhí)行模塊兩部分,其中,所述執(zhí)行模塊包括脈沖寬度調制pwm模塊、led數(shù)碼管模塊、輸入/輸出模塊、電源模塊、jtag模塊、復位模塊、485模塊、232模塊、can總線模塊以及底層驅動模塊,所述開發(fā)模塊進一步包括圖標控件模塊、圖標控件連接及設置模塊、代碼顯示模塊、編譯模塊、以及程序下載模塊。
其中,所述底層驅動模塊用于完成gcplc系統(tǒng)驅動功能,具體包括通用驅動模塊和多任務驅動模塊。
●通用驅動模塊
所述通用驅動模塊用于實現(xiàn)對pwm模塊、led數(shù)碼管模塊、輸入/輸出模塊、電源模塊、jtag模塊、復位模塊、485模塊、232模塊、以及can總線模塊驅動功能。
●多任務執(zhí)行驅動模塊
所述多任務執(zhí)行驅動模塊用于驅動gcplc系統(tǒng)的多任務執(zhí)行,本發(fā)明實施例以多任務操作系統(tǒng)mqx為例,mqx驅動文件夾內包含app、bsp、config、include、kernel(內核)、psp、io、string共八個文件夾,下面對這些文件作具體功能說明,如表1所示。
表1mqx文件夾目錄及說明
上述文件目錄中,app文件夾下存放著用戶編寫的任務函數(shù),是多任務體系下編程的主要文件夾。該文件夾下的驅動設計如表2所示。
表2app文件夾目錄及說明
上述表2中,task_xxx.c文件并不是單一的,它是一種統(tǒng)稱,在用戶自定義多個任務后,會生成多個task_xxx.c文件。
●圖標控件模塊
本發(fā)明放棄傳統(tǒng)plc使用的梯形圖編程方法,轉而設計了開發(fā)者門檻更低、更加容易理解的圖標形式的控件。本發(fā)明進一步將圖標控件模塊劃分為執(zhí)行控件、傳感器控件、通信控件、流程控件、任務控件5個大類,以這五類控件為根節(jié)點,按照分類采用treeview樹形控件來表示所有的圖標控件,由此產生了樹狀結構圖標控件箱,最終形成圖標控件模塊。
執(zhí)行控件主要包括一些需要執(zhí)行的操作,例如開關中斷、輕量級事件位設置、設置延時、設置io輸入/輸出等;傳感器控件包含gcplc需要的傳感器,例如超聲波傳感器、ad傳感器等;通信控件包含與硬件核心板通信相關的控件,例如i2c、spi、uart等;流程控件則是與程序執(zhí)行相關,所以包含if判斷、條件循環(huán)、計數(shù)循環(huán)之類的控件;任務控件是針對添加任務時設計的,該控件模塊中的控件是動態(tài)增長的,僅當用戶添加任務后,任務控件中才會相應的圖標。當需要增加某種控件時,只需要設置好該控件的相應屬性,存入數(shù)據庫即可。而對于每一個用戶程序,其中的任務控件也各不相同。
●圖標控件連接及設置模塊
圖標控件連接及設置模塊是進行控件拖拉、連線、程序順序設計的模塊。當從圖標控件模塊拖出控件時,每個控件之間都是各自獨立的,即使設置好控件的屬性,這些控件仍然不具備實際功能,只有將每個控件頂部和底部的入口點及出口點連接起來時,這些控件才會真正起作用。
一般來講,除了流程控件的開始start和結束end以外的圖標控件都有入口點和出口點。在進行圖形化編程時,用戶可以根據需求將不同的圖標控件相互連接起來,即可完成圖形化編程。每個控件通過不同的順序連接,將會生成截然不同的程序。本發(fā)明依據這一特征,將圖標控件分為通用圖標控件(icoforgeneral)、多分支圖標控件(icoforswitch、icoforswitchend)類、循環(huán)圖標控件類(icoforloop)和判斷圖標控件類(icoforjudgestart、iconforjudgend),以icoforgeneral類為例,當通用圖標控件進行互連操作時,icoforgeneral類中各字段的值并不相同,icoforgeneral類的主要字段信息如表3所示。表3中前7行表示的是icoforgeneral類本身信息,其余的字段用于表示通用圖標控件互連時的相應連接參數(shù)。
表3icoforgeneral類的主要字段信息
在圖標連接時,從父圖標控件(以下簡稱父控件)的角度出發(fā),針對連接目標子圖標控件(以下簡稱子控件)的不同類型,同時結合表3中的相關字段來說明父控件icoforgemral類中字段的取值及對應圖標控件互連時字段取值的變化關系:
(1)如果子控件類型是iconforgeneral,則父控件的子圖標控件的類型typeforchild值為icoforgeneral,父控件的child字段為子控件圖標類型。由于子控件是iconforgeneral類型,其不帶分支結構,所以對應的childltorfdot、childlcasenumdot以及childliorldot等相關字段都為null;
(2)如果子控件類型是if控件,則字段typeforchild值為icoforjudgestart;字段child值為對應子控件類型的實例對象;剩余的字段信息則與子控件類型為iconforgeneral時相同。
(3)如果子控件類型是end控件,則字段typeforchild值為icoforjudgeend;字段child值為對應子控件類型的實例對象;如果連入的是icoforjudgeend子控件的真連入點,則字段childltorfdot值為真入口點;否則為假入口點。剩余的字段信息則與子控件類型為iconforgeneral時相同。
(4)如果子控件類型是icoforloop,則父控件的typeforchild字段值為icoforloop;child字段值為對應子控件類型的實例對象;如果連入的是icoforloop圖標控件的入口點,那么childltorfdot值為接入點;如果連入的是icoforloop圖標控件的循環(huán)入口點,那么childltorfdot值為循環(huán)接入點;剩余的字段信息則與子控件類型為iconforgeneral時相同。
(5)如果子控件類型是switch控件,則字段typeforchild值為icoforswitch;字段child值為對應子控件類型的實例對象。剩余的字段信息則與子控件類型為iconforgeneral時相同。
(6)如果子控件類型是switchend控件,則字段typeforchild值為icoforswitchend;字段child值為對應子控件類型的實例對象;字段childlcasenumdot為當前連入的switchend控件的分支序號。剩余的字段信息則與子控件類型為iconforgeneral時相同。
同時,可以通過雙擊每個控件以編輯該控件的屬性,以pwm初始化為例,當點擊pwm初始化控件時,便會跳出“pwm初始化”屬性窗口,可在窗口中配置pwm的輸出頻率,使用者可以很容易掌握。其他的控件也具各自的屬性窗口,控件的配置窗口也是類似的。
圖標控件互連操作是將圖標控件相互連起來的過程,分離操作是將圖標兩兩分開的過程。假設現(xiàn)在要連接與分離的圖標控件為x和y,其中x為父控件,y為子控件。下面將對這兩種操作進行詳細的闡述。
圖標控件之間的互連采用貝塞爾曲線實現(xiàn),其主要流程如下:
(1)保存x的圖標控件類型、實例對象和x連出點坐標。
(2)使用父控件的resetchild方法清x的子控件字段,并將y的圖標類型寫入到x實例對象的子控件字段中。
(3)使用子控件的resetparent方法清y的父控件字段,并將x的圖標控件類型給y實例對象的父控件字段中,最后記錄y連入點的坐標。
(4)根據x連出點的坐標和y連入點的坐標,采用貝塞爾曲線繪制x到y(tǒng)之間的連接線。
(5)再次刷新空間鏈接及設置模塊,并重新生成源代碼。
而圖標控件間的分離是指將x與y圖標控件間的連接取消,本發(fā)明通過resetparent和resetchild方法實現(xiàn)。假設現(xiàn)在要將圖標控件x和y進行分離,則x只需要調用resetchild方法清空子控件信息,y只需要調用resetparent方法清空父控件信息。
●代碼顯示模塊
在控件連接及設置模塊將各個圖標按照自己預想的順序連接完成后,如果沒有任何可以參照修改的功能,很有可能使得最后燒寫的程序無法正常運行,而且僅僅是圖標連接也會使得開發(fā)者感覺很疑惑。為了解決這些問題,設計了代碼顯示區(qū)域。該區(qū)域顯示的代碼跟控件連接模塊的連線方式是一一對應的。代碼顯示模塊顯示的代碼的更新流程如圖2所示。
從圖2中可以看出,代碼更新算法將代碼更新的流程分為兩個部分,這樣分割的依據是所有的全局變量存放在主任務中,而且子任務的相關代碼創(chuàng)建也在主任務中進行。而子任務中僅存有與當前任務相關的局部代碼及其其他代碼,這種設計方式使得整個程序中的全局變量和局部變量不易混淆,出錯概率低。
●編譯模塊
編譯模塊是在完成圖標控件的拖動和連接后,當確認程序無誤時,對當前程序進行編譯的模塊。該模塊通過創(chuàng)建新的進程,在進程中cmd來調用gnu提供的make工具、編譯器和連接器對圖形化程序進行編譯和鏈接,最后生成hex和elf兩種機器碼文件。在編譯的過程中,為了更加直觀的顯示編譯的信息以及最終程序的編譯結果,設計了可視化的編譯模塊。gcplc的圖形化編程環(huán)境使用跨線程調用的方式來實現(xiàn)編譯信息的顯示,這樣使得進行編譯時不會影響到程序其他地方的執(zhí)行,增強了整個系統(tǒng)運行的流暢性,編譯模塊的信息輸出包括編譯正確信息輸出和錯誤的信息輸出,以正確信息輸出為例,其關鍵工作如下。
可以看出,編譯信息使用委托的方式進行跨線程調用,當收到來自make工具的編譯信息后,p_outputdatareceived函數(shù)調用invoke方法喚醒委托readstdoutput,將信息輸出,而readstdoutaction方法是在編譯正確的情況下添加自定義信息“編譯成功”將成功結果輸出至界面。
●程序下載模塊
目前市場上的主流編程寫入器都采用了圖編程寫入器通過usb接口或串口與pc通信,同時通過寫入接口與目標mcu通信的框架結構來實現(xiàn)程序的下載。在這種框架結構下,編程調試器接收從pc發(fā)送來的操作命令和數(shù)據,對命令進行解析后,與目標mcu進行通信,讓目標mcu完成相應的功能操作。針對不同的目標mcu,由pc的傳統(tǒng)文本式集成開發(fā)環(huán)境或獨立寫入軟件發(fā)出命令傳達寫入器目標mcu的型號等信息。本發(fā)明設計開環(huán)環(huán)境的可配置機器碼下載單元時也遵循這種設計思想。
對于使用多任務體系開發(fā)環(huán)境的用戶來講,當完成圖形化程序的編寫并編譯成機器碼后,再打開文本式的集成開發(fā)環(huán)境使用其自帶的寫入功能進行下載,這種方法費時費力盡顯笨拙;相反的,獨立寫入軟件并不集成于某個固定的傳統(tǒng)文本式集成開發(fā)環(huán)境中,且每個芯片廠商都會針對使用自己公司研發(fā)的寫入協(xié)議的產品推出相應的寫入設備和獨立寫入軟件,方便用戶進行機器碼下載,同時還有類似segger公司這類的嵌入式中間件提供商針對一些標準寫入協(xié)議推出的獨立寫入軟件。
由此可看出,對于任何一款使用標準或非標準寫入協(xié)議的設備來講,都會有一個特定的獨立寫入軟件完全能夠完成其代碼寫入功能。
再次對各個獨立寫入軟件的安裝包進行分析,發(fā)明人發(fā)現(xiàn),獨立寫入軟件在安裝的過程中并不會修改注冊表或系統(tǒng)環(huán)境變量,只需要調用安裝目錄下的相關dll文件和配置信息文件即可完成運行。
以segger公司提供的wimdows平臺下的jlink獨立寫入軟件為例,其安裝完成之后安裝目錄如表3-3所示。
表4jlink安裝目錄文件信息
由表4可以看出,安裝完成后的獨立寫入軟件以安裝包為單位,可以拷貝到其它設備上,不需要再次配置即可運行。
為了使下載過程變得更加透明,本發(fā)明采用命令行的方式調用jlink實現(xiàn)真正意義上的一鍵下載,這樣不僅省去了繁瑣的下載配置操作,更提高了程序下載的速度,其實現(xiàn)的代碼如下:
上述代碼中,使用cmdprocess類調取命令行,并打開j-flash軟件,隨后打開已經設置好的工程“mk60dn512.jflash”,并設置下載模式為自動,讓寫入器開始自動檢測并下載程序,下載完成后再給出后續(xù)的給出的提示。
gcplc系統(tǒng)旨在應用于多任務需求的工業(yè)控制中。因此除了上述幾個基礎模塊外,還考慮將多任務體系融入到開發(fā)模塊中。仍然以mqx實現(xiàn)為例,mqx中多任務的協(xié)調工作的關鍵是各個任務之間的同步、通信及中斷管理。
在建立主任務之前,應當首先明確mqx的啟動過程。在運行mqx的嵌入式系統(tǒng)中,mqx工程的啟動過程可以分為芯片啟動和mqx操作系統(tǒng)啟動,其中硬件的啟動過程與nos(無操作系統(tǒng))一致,除去芯片的啟動過程,mqx啟動的第一步是進入main函數(shù),進入main函數(shù)后,再調用mqx的入口函數(shù),并開始無休止的運行,隨后進入任務調度與管理。因此mqx下圖形化編程的第一步是建立項目及主任務。建立主任務后的界面如圖3所示。圖中左側是圖標控件模塊,中間是圖標設置及連接模塊,右側是代碼刷顯示及刷新模塊,下方是編譯信息窗口。
可以看出,當前圖形化拖動及連接界面中僅有一個“main”圖標,這代表著當前項目中僅有一個任務,即mqx系統(tǒng)的主任務task_main。task_main將要做的主要工作如下:
(1)創(chuàng)建輕量級事件組;
(2)初始化相關全局變量;
(3)初始化相關模塊的驅動;
(4)安裝用戶的isr(中斷)
(5)開關中斷并且創(chuàng)建其他任務
(6)啟動自動阻塞任務
由于當前整個項目中僅有一個主任務,此時代碼窗口部分生成的代碼如下所示:
上述代碼中,由于當前項目中僅有一個主任務task_main,并沒有創(chuàng)建其他任務,因此代碼中只有創(chuàng)建輕量級事件組和啟動自動阻塞任務兩項。
在創(chuàng)建完主任務后,便可根據需求添加其他自定義任務,在添加任務時需要配置與任務相關的三個主要屬性,第一是選擇要添加的任務類型,目前gcplc體系中為用戶提供四種類型的任務,分別為小燈任務、led任務、pwm任務和通信任務。同時在選定好任務后需要添加任務的說明以及該任務需要的優(yōu)先級中,在mqx中,任務的優(yōu)先級值越大其優(yōu)先級越小,系統(tǒng)為了用戶提供了9-16的可選優(yōu)先級(main任務具有最高的優(yōu)先級8,所以優(yōu)先級從9開始)。
配置好任務相關屬性并點擊確定后,會在圖形拖動連接區(qū)域生成該任務和它的相關界面,以圖中l(wèi)ed任務為例,在開發(fā)環(huán)境的主界面中,會為led任務添加獨立的窗口,用于在其中根據自己的需求對led任務進行配置,如圖4所示。
并且在確定后首先會改變mqx驅動文件夾中app文件夾下的templates.c中的代碼,此時的代碼如下所示。
從上面代碼中可以看出,led任務已成功添加項目,并且其相關屬性也已經配置完成,可以看到這邊其優(yōu)先級配置為10,任務棧大小也配置為默認大小。
從圖4中可以看出右側代碼窗口顯示的代碼已經發(fā)生了變化,此時顯示的是led任務創(chuàng)建后生成的默認代碼。如下所示:
#include"01_app_include.h"http://應用任務公共頭文件
voidtask_led(uint32_tinitial_data)
{
mqx_tick_structmqx_tick1,mqx_tick2;
uint8_tstartdata;
uint8_tenddata;
uint8_ttempdata;
_time_get_ticks(&mqx_tick1);
_time_get_ticks(&mqx_tick2);
tempdata=startdata;
//以上代碼由系統(tǒng)自動生成,請勿隨意更改
}
從上述代碼中,可以看出在建立led后,系統(tǒng)會為該任務生成一系列變量和執(zhí)行語句,這正是開發(fā)環(huán)境所要做的事情,盡量使得整個過程更加對用戶更加透明,使用戶不必要了解具體的代碼實現(xiàn),而只需要了解程序的執(zhí)行流程即可,這樣使得整個開發(fā)過程更加直觀,容易理解。
當一個項目中存在多個任務時,如何在軟件環(huán)境中對各個任務的同步與通信進行設置是現(xiàn)實多個任務協(xié)調工作的基礎。gcplc多任務體系中使用mqx的輕量級事件(lightweightevent)來實現(xiàn)任務之間的同步,其具體流程如下:
1.準備階段
(1)創(chuàng)建輕量級事件組。按需求在任務函數(shù)所包含的頭文件中定義一個全局輕量級事件結構體變量。由于在大部分情況下,單一項目中僅需要一個輕量級事件組便可以滿足整個工程的需求,因此mqx文件夾的預定義頭文件app_include.h中加入了如下默認代碼:
lwevent_structlwevent_group;//輕量級事件組
接著,在某個任務中通過_lwevent_create函數(shù)創(chuàng)建輕量級事件組。需注意的是,包含初始化輕量級事件組函數(shù)的任務在就緒任務隊列中的位置,必須先于那些需要使用此輕量級事件組的任務,這就需要此任務有較高的優(yōu)先級或是在同等優(yōu)先級條件下先于其他任務創(chuàng)建。例如在3.1節(jié)中創(chuàng)建主任務時會自動創(chuàng)建相應的輕量級事件組,因為task_main任務相對于其他的任務具有最高的優(yōu)先級。
(2)命名輕量級事件位。在使用輕量級事件之前,需要先確定程序中需要使用哪些事件及它們對應的事件位。然后在任務所包含的預定義頭文件中對相應事件的事件位屏蔽字進行宏定義,以方便識別與使用,具體過程如下:
選擇任務右邊的下拉框會自動檢索當前工程中所有任務并且顯示在下拉框中,以當前選擇pwm任務為例,將它對應的輕量級事件名命名為event_pwm,這里需要注意的是事件名的命名的最佳方式是以event+任務名的形式,這樣會增強程序的可讀性。下面的“是否自動清零”屬性指示在該事件位是否在執(zhí)行完成后自動清零,這種屬性適用于整個項目中只有一個任務的情況。如圖5所示。
在點擊確定后,該操作會修改app_include.h中內容,根據當前已有的事件位的個數(shù)自動遞增,修改的部分如下所示:
lwevent_structlwevent_group;//輕量級事件組
#defineevent_pwm((1ul)<<(1))//pwm事件位
從上述代碼中可以看出,舉例的工程中目前共添加了三個事件位,并且他們的具體數(shù)值是逐次遞增的,不會出現(xiàn)重復的情況。
2.應用階段
在為任務添加并命名事件位后,便可以在項目中使用這些輕量級事件位,對輕量級事件位的操作有以下三種:
(1)設置輕量級事件位:這一步是在觸發(fā)事件的任務中進行的。按照需要在任務中的特定位置通過_lwevent_set函數(shù)對所觸發(fā)事件對應的事件位置位。
(2)等待輕量級事件位:這一步是在等待事件的任務中進行的。在等待事件的任務中需要同步的代碼前通過_lwevent_wait_for等函數(shù)獲取符合條件的輕量級事件位。
(3)清零輕量級事件位:這一步也是在等待事件的任務中進行的。若輕量級事件位不帶自清零屬性,則需在等待輕量級事件位置位后調用此函數(shù)對事件位清零,以便響應下次事件的到來。在清零輕量級事件位中使用_lwevent_clear函數(shù)來清除相應的事件位。
針對上述的三種操作,要解決任務的同步問題,需要設計專門用于管理輕量級事件的控件,根據上述對輕量級事件操作類型的描述可知,輕量級事件控件也需要提供上述的三種操作,并且可以與不同的任務相組合。
與在準備階段創(chuàng)建輕量級事件組時類似,在設置位時該窗體也會自動檢索當前工程中存在的所有任務,并在下拉框中顯示,從圖中可以看出,每個任務都可以對應三種不同的狀態(tài),選擇其中任意一種狀態(tài)將會生成對應的代碼,此處以pwm為例,選擇將其等待事件位,將會生成如下代碼:
voidtask_pwm(uint32_tinitial_data)
{
_lwevent_wait_for(&lwevent_group,event_pwm,false,null);
//開始pwm
ftm_pwmstart(0);
ftm_pwmstart(1);
ftm_pwmstart(2);
while(true){}
}
上述代碼中,_lwevent_wait_for(&lwevent_group,event_pwm,false,null)這一句為設置事件位后生成的代碼,這表示當前的task_pwm任務會在執(zhí)行到該處后無限等待event_pwm直到別的任務中設置了該任務的輕量級事件位,否則下面的程序語句不會得到執(zhí)行。
通過輕量級事件位的方式,可以便捷而穩(wěn)定的實現(xiàn)任務的同步與通信,它適合gcplc單處理器多任務的特性,可以通過占用最少的程序空間和cpu資源實現(xiàn)各個任務的協(xié)調工作。
任務的同步設計完成后,此時gcplc多任務體系中的各個任務之間已經可以進行同步,但是由于輕量級事件位只能傳遞1位2進制的數(shù)。因此,還需要在開發(fā)環(huán)境中實現(xiàn)任務的通信,本發(fā)明同樣將任務通信的設計過程分為準備階段和應用階段,下面進行詳細的敘述:
1.準備階段
在使用輕量級消息隊列之前,需要指定相應的消息隊列中所能容納的最大消息數(shù)目,以及單個消息的大小。最大消息數(shù)指示當前的消息隊列中同時能容納的消息的最大數(shù)目,單個消息指示每個消息所占的控件。同時,這兩個參數(shù)是計算輕量級所占用的空間的依據,其具體計算方法如下:
輕量級消息隊列空間=sizeof(lwmsgq_struct)/sizeof(uint_32)+最大消息數(shù)*單個消息大小
根據上述特征,設計的初始化消息隊列中設置的最大消息數(shù)目為可以是3,同時在開發(fā)環(huán)境中,提供了三種不同類型的消息類型,這三種數(shù)據類型基本能夠滿足大部分項目的需求。點擊確定后,將在app_include.h中添加如下代碼:
#definenum_messages3
#definemsg_sizeuint32_t
externuint_32
server_queue[sizeof(lwmsgq_struct)/sizeof(uint_32)+num_messages*msg_size];
同時,在初始化輕量級消息隊列的相應任務中,將生成如下的代碼:
_lwmsgq_init((pointer)server_queue,num_messages,msg_size);
至此,輕量級消息的初始化工作就已經完成,接下來可以進入應用階段。
2應用階段
輕量級消息隊列的應用方式分為兩種:
(1)在需要發(fā)送消息的任務中調用_lwmsgq_send函數(shù)向輕量級消息隊列發(fā)送消息。當隊列滿時,根據發(fā)送標志的值,對任務進行相應的操作。
(2)在需要接收消息的任務中調用_lwmsgq_receive函數(shù)從輕量級消息隊列接收消息。若此時消息隊列非空,則任務從消息隊列中刪除第一個消息,然后將信息復制到用戶緩沖區(qū),這個消息也就成為了任務的一個資源,若此時隊列空,則任務阻塞并等待。
若當前的操作為發(fā)送,則從相應的變量或者數(shù)組中取出數(shù)據,并將其放入輕量級消息隊列中;若為接收,則從輕量級消息隊列中取出數(shù)據并將其放棄對應的變量中。
本發(fā)明的多任務體系采用中斷服務例程(interruptserviceroutine)的方式來實現(xiàn)中斷。簡稱isr,通常也被稱為中斷處理函數(shù)。在這種中斷方式中。mqx中為中斷提供了一種機制,來打斷當前正在執(zhí)行的程序,并且保存當前cpu狀態(tài)(cpu內部寄存器),轉而去執(zhí)行一個中斷處理程序,然后恢復cpu狀態(tài),以將cpu恢復到執(zhí)行中斷之前的狀態(tài),同時使得中斷前的程序得以繼續(xù)執(zhí)行。
mqx中斷服務例程分為內核isr(_int_kernel_isr)和用戶isr兩個相對獨立部分。內核isr與特定處理器相關聯(lián),位于psp文件夾,用于實現(xiàn)硬件中斷到用戶isr的映射,一般通過匯編語言實現(xiàn),以確保mqx對中斷事件的快速響應。
在使用isr作為中斷服務例程的情況下,設計多任務情況下的中斷需要遵循一定的規(guī)則。
首先,用戶isr要能夠得到正確調用,須在系統(tǒng)初始化時調用
_int_install_isr()函數(shù),將用戶isr安裝到稀疏中斷向量表中。
_int_install_isr()函數(shù)有三個參數(shù),分別為中斷向量號、中斷服務例程入口地址(即中斷函數(shù)名稱)、中斷服務例程使用的參數(shù)。
例如,對于串口1中斷服務例程(uart1_rx_isr)的isr安裝,在mqx自啟動任務中包含下列語句:
_int_install_isr(int_uart4_rx_tx,uart4_rx_isr,null);//安裝串口4的isr
上述代碼中,實參“int_uart4_rx_tx”:為串口4的中斷向量號(本處為69)。實參“uart4_rx_isr”:為用戶編寫的串口4中斷服務例程的函數(shù)名;實參“null”:為uart4_rx_isr所使用的參數(shù)首地址,這里設為“null”,即uart4_rx_isr不需要參數(shù)。
因此,根據上述對與isr的描述,本發(fā)明在軟件開發(fā)環(huán)境中設計了與中斷服務例程相關的控件,專門用于針對各個任務的中斷進行相應的操作,下面仍然以pwm的中斷為例做詳盡的敘述。
pwm模塊中共有3路pwm輸出,每一路pwm輸出提供兩種選擇,分別為開啟和關閉中斷。每個pwm輸出都需要安裝各自的中斷,對于其他的模塊也是如此。設置好每一路中斷并點擊確定后,將生成一系列的代碼,需要注意的是,中斷的安裝是在taks_main任務中,其原理與創(chuàng)建輕量級事件組類似。因為中斷安裝也需要較高的優(yōu)先級。
屬性設置完成確定后將會生成如下的代碼:
//4.安裝用戶isr
_int_install_isr(int_ftm0,ftm0_isr,null);//ftm0的isr
_int_install_isr(int_ftm1,ftm1_isr,null);//ftm0的isr
_int_install_isr(int_ftm2,ftm2_isr,null);//ftm0的isr
//開中斷
enable_ftm_int(0);
enable_ftm_int(1);
enable_ftm_int(2);
上述代碼中值得注意的是,中斷服務例程的控件不僅生成安裝了用戶的isr相關代碼,而且也自動開啟了相應的模塊中斷。這樣做的目的是將多任務體系之外的操作相對于用戶透明,使用者僅需要了解與多任務操作相關的操作即可,從而降低了編程的難度。
本發(fā)明還提出了一種利用多任務gcplc系統(tǒng)開發(fā)應用的方法。
首先,利用圖標控件模塊及圖標控件連接及設置模塊創(chuàng)建主任務,在主任務中初始化底層驅動模塊,其中比較關鍵的pwm的初始化包括pwm模塊號、pwm通道和pwm頻率。
然后創(chuàng)建pwm、led、uart任務,配置任務的相關屬性,其中pwm任務負責按照初始化的頻率輸出指定的脈沖數(shù)然后停止,led任務負責指示當前的運行狀態(tài)(若運行正常則按照1-60數(shù)字循環(huán)變換),uart任務負責接收來自于調試軟件的數(shù)據并按照不同的指令進行不同處理;圖6顯示了主任務、pwm、led、uart任務的創(chuàng)建示意圖。
然后將每個任務在代碼刷新區(qū)域生成屬于自己任務的代碼;
在圖形化編程完成后,編譯模塊進行編譯鏈接以及機器碼的生成;
當機器碼生成后,下載模塊對機器碼進行下載寫入。
以上實施例僅用于說明本發(fā)明,而并非對本發(fā)明的限制,有關技術領域的普通技術人員,在不脫離本發(fā)明的精神和范圍的情況下,還可以做出各種變化和變型,因此所有等同的技術方案也屬于本發(fā)明的范疇,本發(fā)明的專利保護范圍應由權利要求限定。