背景
在基于英創工控主板的智能整機設備的開發過程中,客戶應用程序的開發通常都是最為關鍵性的工作,其工作量往往也是最大的。一個高質量的應用程序,首先表現在較少的現場維護,不僅大幅度降低了設備開發費用,同時也為客戶贏得后續的市場聲譽。因此如何在設備出廠之前就能確定應用程序的基本質量,就變得至關重要了。
基于我們十多年長期不斷地對客戶應用程序的技術支持的經驗,一般來說,如果一個應用程序在完成基本的應用功能的基礎上,整個應用進程(包括進程的所有活動線程)的CPU負載率保持在一個合理的水平,比如低于70%,那么我們就可以認為運行于英創工控主板上的這個應用程序其質量是有基本保證的。為了方便客戶隨時了解應用程序的運行狀況,我們計劃在主板中嵌入一款稱為應用程序助手(AppHelper)的監測程序。AppHelper僅使用很少的CPU資源,就可為客戶提供系統各個進程的CPU開銷情況,對客戶的應用進程,還將提供進程中各個活動線程的運行狀況。客戶根據這些信息及可方便及時的了解程序運行的總體情況,快速確定程序代碼需要優化的地方。
本文的后續部分主要介紹AppHelper的使用方法及信息輸出的格式。
AppHelper的輸出接口
CE應用程序助手AppHelper的主要功能是提供系統運行狀況的基本信息。這些基本信息可支持多種通訊接口輸出,這些接口包括調試串口、USB OTG接口、應用串口COM2 – COM9、以太網接口。客戶可根據自身設備的特點,方便地選擇輸出接口。調試串口是AppHelper的缺省輸出接口。
AppHelper輸出信息的基本格式都是標準的ASCII碼字符串,客戶通過PC上的一款串口終端窗口程序(推薦使用開源的Tara Term),就可看到輸出的信息。
若客戶希望使用USB或應用串口來觀察AppHelper的輸出信息,需要通過執行主板上的AppHelperConfig進行端口配置:
\> AppHelperConfig p1 [p2]
上式中p1 = 1, 2, .. 9;其中 = 1表示使用COM1端口,在英創主板中COM1端口是基于USB OTG的虛擬串口,英創公司的EM335x產品線和EM928x產品線的所有產品均支持USB OTG虛擬串口功能,虛擬串口的使用方法與實際物理串口完全一致。參數p1 = 2 – 9分別對應物理串口COM2 – COM9。注意在選擇物理串口時,應避免使用低速串口。參數p2為串口的波特率,缺省配置為115200bps。除非特別的需求,一般不設置該參數,即推薦使用115200波特率。
用戶只需在輸出串口上輸入3個以上的字符(鍵盤連按3次以上),就會激活AppHelper。AppHelper將按2秒間隔輸出系統運行狀態信息。
若用戶希望通過以太網口來觀察AppHelper的輸出信息,則可通過telnet登錄系統后,直接運行SysInfo.exe,就可在CMD窗口看到系統的運行信息。SysInfo可帶一個輸入參數,來確定輸出信息的時間,缺省的時間為10s。AppHelper每2秒輸出一次系統運行參數。
AppHelper信息輸出格式
AppHelper的輸出格式如下:
AppHelper v0.1 Oct 18 2015 17:36:33 Emtronix(c)
CPU:2% FreeMemory=148.59MiB FreeNand=123.99MiB
….
第一行是AppHelper的版本信息,第二行是系統總的CPU負載、程序內存的剩余空間,以及NandFlash的剩余空間。之后的每一行是一個進程或線程的CPU占用率。其中每個進程的名稱就是對應的exe文件名,而對線程來說,系統只提供有線程ID。客戶一般說來很難根據線程ID來辨識具體是應用程序中哪個線程,例如串口接收線程。
應用線程命名
為了客戶更容易識別應用線程,AppHelper為應用程序提供了2個API函數。應用程序在創建線程后,通過API函數來為該線程注冊一個希望字符串名;當線程退出時,則通過API函數注銷該字符串。AppHelper提供的這兩個API函數為:
BOOL RegisterThreadName(DWORD dwThreadID, TCHAR* sThreadName);
BOOL UnRegisterThreadName(DWORD dwThreadID);
注冊操作一般直接跟在線程創建之后,其代碼如下:
DWORD dwThreadID = 0;
TCHAR sThreadName[] = L” ReceiveThread”;//注意32個字符!
// create rx thread
m_hRxThread = CreateThread((LPSECURITY_ATTRIBUTES)NULL,
0,
(LPTHREAD_START_ROUTINE)ReceiveThread,
(LPVOID)pPara,
0,
&dwThreadID);
RegisterThreadName(dwThreadID, sThreadName);
線程名注銷操作則更簡單,直接放在線程退出之前即可。
以下是AppHelper提供的這兩個API函數的具體實現,該代碼應包含在應用程序之中。
struct _THREAD_INDEX
{
DWORD dwSize; // struct size in byte
DWORD dwThreadID; // a thread id
TCHAR szThreadName[32]; // user-defined name associated with the
// thread id above
struct _THREAD_INDEX *pNext; // = NULL
};
typedef struct _THREAD_INDEX THREAD_INDEX, *PTHREAD_INDEX;
BOOL RegisterThreadName(DWORD dwThreadID, TCHAR* sThreadName)
{
BOOL bRet = TRUE;
THREAD_INDEX ThreadNode;
PTHREAD_INDEX pNode = &ThreadNode;
DWORD dwLen;
HANDLE hDevFile = NULL;
memset(&ThreadNode, 0, sizeof(THREAD_INDEX));
pNode->dwSize = sizeof(THREAD_INDEX);
dwLen = wcslen(sThreadName);
if(!dwThreadID || (dwLen >= 32))
{
bRet = FALSE;
goto cleanup;
}
pNode->dwThreadID = dwThreadID;
wcscpy(pNode->szThreadName, sThreadName);
hDevFile = CreateFile(L"HLP1:", // name of device
GENERIC_READ|GENERIC_WRITE, // desired access
0, // sharing mode
NULL, // security attributes
OPEN_EXISTING, // creation disposition
0, // flags/attributes
NULL); // template file
if(hDevFile == INVALID_HANDLE_VALUE)
{
hDevFile = NULL;
bRet = FALSE;
goto cleanup;
}
dwLen = 0;
if(!WriteFile(hDevFile, pNode, sizeof(THREAD_INDEX), &dwLen, NULL))
{
bRet = FALSE;
}
CloseHandle(hDevFile);
cleanup:
return bRet;
}
BOOL UnRegisterThreadName(DWORD dwThreadID)
{
BOOL bRet = TRUE;
THREAD_INDEX ThreadNode;
PTHREAD_INDEX pNode = &ThreadNode;
DWORD dwLen;
HANDLE hDevFile = NULL;
memset(&ThreadNode, 0, sizeof(THREAD_INDEX));
pNode->dwSize = sizeof(THREAD_INDEX);
if(!dwThreadID)
{
bRet = FALSE;
goto cleanup;
}
pNode->dwThreadID = dwThreadID;
hDevFile = CreateFile(L"HLP1:", // name of device
GENERIC_READ|GENERIC_WRITE, // desired access
0, // sharing mode
NULL, // security attributes
OPEN_EXISTING, // creation disposition
0, // flags/attributes
NULL); // template file
if(hDevFile == INVALID_HANDLE_VALUE)
{
hDevFile = NULL;
bRet = FALSE;
goto cleanup;
}
dwLen = 0;
if(!WriteFile(hDevFile, pNode, sizeof(THREAD_INDEX), &dwLen, NULL))
{
bRet = FALSE;
}
CloseHandle(hDevFile);
cleanup:
return bRet;
}
預計在2015年10月底前,AppHelper將首先安裝到EM335x產品線的所有主板,并在11月份部署到EM928x產品線。歡迎新老客戶評估測試CE應用程序助手。
-
嵌入式主板
+關注
關注
7文章
6085瀏覽量
35443
發布評論請先 登錄
相關推薦
評論