英創(chuàng)ARM9工控主板的數(shù)據(jù)采集功能通常采用板上的GPIO實現(xiàn)數(shù)字輸入輸出、通過精簡ISA總線擴展相應(yīng)的AD或DA實現(xiàn)模擬數(shù)據(jù)的輸入輸出。在英創(chuàng)ARM9工控主板提供的基本開發(fā)資料中對GPIO和精簡ISA總線的驅(qū)動均以C的靜態(tài)庫的形式提供,對部分使用C#、LabView等其他開發(fā)工具的客戶來說,不能直接使用C的API函數(shù)。針對這一部分客戶的應(yīng)用需求,我們把相關(guān)C函數(shù)庫封裝成標(biāo)準(zhǔn)COM組件,使客戶能方便使用主板的數(shù)據(jù)采集功能。本文將詳細(xì)介紹數(shù)據(jù)采集COM組件的相關(guān)技術(shù)要點,供廣大客戶使用時參考。
COM(Component Object Model),即組件對象模型,是微軟公司開發(fā)的一種新的軟件開發(fā)技術(shù),提出了組件之間進(jìn)行交互的規(guī)范,也提供了實現(xiàn)交互的環(huán)境,因為組件對象之間交互的規(guī)范不依賴于任何特定的語言,所以COM也可以是不同語言協(xié)作開發(fā)的一種標(biāo)準(zhǔn),如VB、C#、LabView可以使用同一個COM組件來進(jìn)行軟件開發(fā)。COM組件的整體結(jié)構(gòu)大概分為三個層次:組件、接口、方法函數(shù),它們的關(guān)系如下圖所示:
COM組件與我們常用的C++類的關(guān)系,可以簡單的理解為:
COM組件名:即C++庫文件名稱
COM組件接口:即C++庫中的類
COM組件實現(xiàn)方法函數(shù):即C++中的類的成員函數(shù)
下面以EM9000的EM9000_ISA_API.LIB靜態(tài)庫為例,介紹在EVC開發(fā)環(huán)境,如何在EM9000_ISA_API.LIB靜態(tài)庫的基礎(chǔ)上構(gòu)建相應(yīng)的COM組件,該方法也可同樣應(yīng)用于英創(chuàng)公司的其他ARM9工控主板產(chǎn)品。
1、新建一個工程,在新建工程中選擇WCE ATL COM AppWizard,并給工程命名為“EM9000_ISA_API_COM”,工程會自動生成一個文件來。在工程編譯后,將生成“EM9000_ISA_API_COM.DLL”庫文件。這個文件就是要用的COM組件的目標(biāo)文件。
2、設(shè)置好以后,點擊“OK”進(jìn)入工程的類型選項,在這里,選擇動態(tài)鏈接庫并將對MFC的支持選擇上。即完成工程的建立。
3、將英創(chuàng)提供的EM9000_ISA_API.h文件復(fù)制到當(dāng)前這個工程目錄下面,并在工程的“Settings”下面的LINK中加入“EM9000_ISA_API.lib”。
4、為COM組件添加接口:這個接口名就是在調(diào)用COM組件時的入口名字,在工程中命為EM9000_ISA_COM,添加接口的方法是:Insert -> New ALT Object…,在彈出來的對話框中,直接點擊下一步,這時會再彈出一個對話框,這時,在對話框的Name表單的左上角框中輸出接口名EM9000_ISA_COM,這時會生成相應(yīng)的接口的名字,左邊是C++調(diào)用的頭文件及庫,右邊是COM組件的接口文件名。系統(tǒng)會自動地在接口名Interface項前加上一個大寫字符“I”。
5、為該COM組件添加方法函數(shù):將EM9000_ISA_API.H中的函數(shù)添加到COM組件中去。要注意一點,由于在制作COM組件過程中,COM組件實現(xiàn)的方法函數(shù)會調(diào)用EM9000_ISA_API.H中的函數(shù)且方法函數(shù)名和要調(diào)用的函數(shù)不能同名,所以在COM組件的方法函數(shù)名前加前綴“COM_”以便區(qū)分。在工程的workspace的ClassView中,單擊COM組件的接口名“IEM9000_ISA_COM”并單擊右鍵選擇“Add Method…”,彈出添加方法函數(shù)的對話框。
如將EM9000_ISA_API.H中的GetPortState( int Port )函數(shù)添加進(jìn)去。這里方法函數(shù)為就變?yōu)椤癈OM_GetPortState”,參數(shù)則有兩個,一個是輸入?yún)?shù),用[in]關(guān)鍵字說明,一個是函數(shù)返回值,用[out,retval]關(guān)鍵字說明,除了返回值的參數(shù)名外,其它的輸入輸出參數(shù)最好和函數(shù)的參數(shù)一樣。參數(shù)類型均為”long”,可以參考:http://www.vckbase.com/document/viewdoc/?id=1488。
輸入完畢后,點擊“OK”完成,這時可以看見新增加的這個方法函數(shù)出現(xiàn)在工程中了。雙擊接口名“IEM9000_ISA_COM”,就會看到該方法函數(shù)在文件中的定義:
interface IEM9000_ISA_COM : IDispatch
{
[id(1), helpstring('method COM_GetPortState')] HRESULT COM_GetPortState([in] long Port , [out,retval] long *pVal);
};
6、雙擊CEM9000_COM下的IEM9000_ISA_COM的方法函數(shù)名“COM_GetPortState(long Port,Long *Val)”,這時就打開具體實現(xiàn)的源文件EM9000_ISA_COM.CPP文件。在文件中加入:#include 'EM9000_ISA_API.h',并且在FileView的頭文件中加入該文件。
這時將COM_GetPortState方法函數(shù)的實現(xiàn)完成,即調(diào)用EM9000_ISA_API.h中相應(yīng)的函數(shù)完成功能。
STDMETHODIMP CEM9000_ISA_COM::COM_GetPortState(long Port, long *pVal)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState())
// TODO: Add your implementation code here
*pVal = GetPortState( Port );
return S_OK;
}
到這里,就完成了對靜態(tài)庫中的一個函數(shù)轉(zhuǎn)成COM組件的方法函數(shù)的基本操作,依照上述方法,將其它的函數(shù)需要加入到COM組件中,只需重復(fù)第5、6步的操作就行了。注意,最后還需要加入出錯處理的方法函數(shù):
方法函數(shù)名:_com_issue_errorex
參數(shù):HRESULT _hr1 , IUnknown *pthis1 , const GUID refiid1
通過編譯生成COM組件EM9000_ISA_API_COM.dll。
我們所提供的COM組件“EM9000_ISA_API_COM.dll”的文件說明:
COM組件文件名:EM9000_ISA_API_COM.dll
COM組件接口名:EM9000_ISA_COM
COM組件方法函數(shù)和EM9000_ISA_API靜態(tài)庫函數(shù)的對應(yīng)關(guān)系如下:
COM組件方法函數(shù)名 |
庫態(tài)庫函數(shù)名 |
功能描述 |
COM_InitEM9000ISA( ) | InitEM9000ISA( ) | 初始化EM9000的ISA總線 |
COM_GetPortState( int Port ) | GetPortState( int Port ) | 查詢Port設(shè)置狀態(tài) |
COM_Swap2ISA( int Port ) | Swap2ISA( int Port ) | 把Port設(shè)置為ISA總線 |
COM_Swap2DIO( int Port ) | Swap2DIO( int Port ) | 把Port設(shè)置為DIO功能 |
COM_SetPortDir( int Port, int Mode ) | SetPortDir( int Port, int Mode ) | 把Port對應(yīng)管腳設(shè)置為DIO狀態(tài) |
COM_EM9000_INB( int Port ) | EM9000_INB( int Port ) | 把Port對應(yīng)管腳設(shè)置為DIO狀態(tài) |
COM_EM9000_OUTB( int Port, UCHAR Value ) | EM9000_OUTB( int Port, UCHAR Value ) | 把Value輸出到Port對應(yīng)管腳 |
COM_EM9000_READ( int nSeg, UINT nOffset ) | EM9000_READ( int nSeg, UINT nOffset ) | 從ISA擴展總線某地址讀取一個字節(jié)的數(shù)據(jù) |
COM_EM9000_WRITE( int nSeg, UINT nOffset, UCHAR Value ) | EM9000_WRITE( int nSeg, UINT nOffset, UCHAR Value ) | 向ISA擴展總線某地址寫入一個字節(jié)的數(shù)據(jù) |
COM_EM9000_ResetISA( int milliseconds ) | EM9000_ResetISA( int milliseconds ) | 使RSTOUT#輸出低脈沖milliseconds毫秒 |
COM_EM9000_PWMOUT( int ChIdx, float* pFreq, float* pDuty ) | EM9000_PWMOUT( int ChIdx, float* pFreq, float* pDuty ) | 使能并輸出脈寬調(diào)制信號 |
COM_EM9000_PWMSTOP( int ChIdx ) | EM9000_PWMSTOP( int ChIdx ) | 停止輸出脈寬調(diào)制信號 |
COM_EM9000_StartWatchDog( ) | EM9000_StartWatchDog( ) | 啟動系統(tǒng)WATCH DOG TIMER |
COM_EM9000_KicktheDog( ) | EM9000_KicktheDog( ) | 重載系統(tǒng)WATCH DOG TIMER |
COM_EM9000_ResetBy( ) | EM9000_ResetBy( ) | 返回上次復(fù)位產(chǎn)生的原因 |
COM_EM9000_DelayInUs(int MicroSeconds ) | EM9000_DelayInUs(int MicroSeconds ) | 微秒延時 |
下面以EVC開發(fā)環(huán)境為基于MFC編程,調(diào)用EM9000_ISA_API_COM.dll實現(xiàn)GPIO操作為例,對如何使用COM組件“EM9000_ISA_API_COM.dll”進(jìn)行說明,以更指導(dǎo)客戶方便地使用COM組件來完成自有產(chǎn)品的開發(fā)。
在eVC中調(diào)用COM組件,需按如下基本步驟來完成:
1、注冊COM組件
運行英創(chuàng)公司提供的regsvr32程序進(jìn)行COM組件的注冊
2、初始化組件,并創(chuàng)建一個實體對像
(1)在測試文件的頭文件中,先定義所需要的對像及變量:
首先,先將COM組件EM9000_ISA_API_COM.dll文件放在當(dāng)前的工程目錄下,同時要在工程的StdAfx.h文件中,添加導(dǎo)入COM組件文件的語句:
#import “EM9000_ISA_API_COM.dll” no_namespace
// 如果COM組件文件沒在當(dāng)前應(yīng)用的工程目錄下面,則需要寫出COM組件文件所在的路徑
然后在測試工程文件頭COM_TESTDlg.h中,在CCOM_TESTDlg類中進(jìn)行定義:
private:
CLSID clsid; // 用以緩存所查詢到的COM組件的標(biāo)識
IEM9000_ISA_COM *m_pSimple; // 利用COM組件接口定義一個指針
(2)完成COM組件的初始化:
在測試工程文件COM_TESTDlg.cpp中,在BOOL CCOM_TESTDlg::OnInitDialog()過程中完成初始化部份
HRESULT hr;
CoInitializeEx(NULL,COINIT_MULTITHREADED) ;//初始化COM組件以便創(chuàng)建線程
Hr = CLSIDFromProgID( OLESTR ( 'EM9000_ISA_API_COM. EM9000_ISA_COM ' ) , &clsid );
// 查找組件是否存在,并獲取組件的標(biāo)識,這里的參數(shù)為:COM組件名字.接口名
C, oCreateInstance ( clsid , NULL , CLSCTX_INPROC_SERVER , _uuidof ( I EM9000_ISA_COM ) , ( void** ) &m_pSimple );
// 利用查找組件時所獲得的標(biāo)識創(chuàng)建實體對像,并交給指針。這里的第四個參數(shù)為組件的接口名
3、調(diào)用COM組件中的方法函數(shù)
利用, , 所定義的接口指針*m_pSimple,在事件中調(diào)用相應(yīng)的函數(shù)。如要調(diào)用COM_GetPortState方法函數(shù)來獲取GPIO(P4口)的狀態(tài),則可以如下方式來實現(xiàn)調(diào)用:
#define P4 4
int iState ;
iState= m_pSimple-> COM_GetPortState (P4); // 調(diào)用成員函數(shù)讀出GPIO(P4口)的狀態(tài)
4、當(dāng)使用后,應(yīng)當(dāng)釋放COM組件
CoUninitialize(); // 釋放COM組件
-
嵌入式主板
+關(guān)注
關(guān)注
7文章
6085瀏覽量
35295
發(fā)布評論請先 登錄
相關(guān)推薦
評論