基於MFC的USB上位機開發(4)環路模組
延伸閱讀:
目錄
本模組用於FPGA環路程式碼的效能測試,環路測試時上位機負責資料的先發後收和對比,FPGA僅負責資料的搬運。模組提供了4種傳送模式:Constant Byte、Random Byte、Incrementing Byte和Incrementing DWORD,依次對應固定數值、隨機數值、單位元組遞增和4位元組遞增的512位元組資料,上位機預設選擇單位元組遞增傳輸模式。傳輸位元組數必須為512、1024、1536和2048中的一個,傳輸非512整數倍的位元組數時,環路測試會一直報錯。環路傳輸過程中,成功和失敗的次數會實時顯示在上位機上。上位機上帶有一個出錯停止測試的複選框,用於環路測試出錯時停止環路測試。重置按鈕用於將環路成功和失敗次數置0,當上位機處於環路測試時,會被重置按鈕強制停止。
1. 設計思路
環路測試的原理很簡單,上位機先發送512位元組資料,再接收512位元組資料,最後將接收和傳送的資料進行比較,如果相同成功次數+1,否則失敗次數+1。
環路測試的流程圖如下,XferThread為環路測試的執行緒指標,系統預設為NULL。點選start按鈕,執行緒迴圈開關bLooping由false變為true,上位機建立環路測試執行緒XferThread並開始環路測試,在測試中不停的統計環路成功和失敗的次數。在“出錯停止測試按鈕”複選框勾上的情況下進行環路測試,只要接收資料和上一次傳送的不一致,環路執行緒立馬停止。在環路測試時,start按鈕會切換為stop按鈕,點選stop按鈕也可以停止環路執行緒。
重置按鈕用於統計資料的清零。在環路測試中點選該按鈕,環路測試會停止,統計的成功和失敗次數會清零,環路的傳送模式、資料的數目和數值均不會發生改變。在沒有進行環路測試的時候,點選該按鈕,僅對統計資料清零。
環路執行緒處理函式的程式碼如下:
UINT XferLoop( LPVOID params ) { OVERLAPPED outOvLap, inOvLap; CUSBprojDlg *pDlg = (CUSBprojDlg *) params; CString str; //UpdateData(true); LONG xfer = pDlg->m_XferSize; PUCHAR data = new UCHAR[xfer]; ZeroMemory(data,xfer); PUCHAR inData = new UCHAR[xfer]; ZeroMemory(inData,xfer); outOvLap.hEvent = CreateEvent(NULL, false, false, _T("CYUSB_OUT")); inOvLap.hEvent = CreateEvent(NULL, false, false, _T("CYUSB_IN")); LONG seed = pDlg->m_SeedValue; int stopOnError = pDlg->m_StopOnErrorChkBox.GetCheck(); stuffBuff(data,xfer,seed,pDlg->m_FillPatternComBox.GetCurSel()); pDlg->m_StatusLabel.SetWindowText(_T(" STATUS: Transferring data . . .")); pDlg->m_SuccessCount.SetWindowText(_T("0")); pDlg->m_FailureCount.SetWindowText(_T("0")); bool success; LONG nSuccess = 0; LONG nFailure = 0; pDlg->pOutEndpt->TimeOut = 2000; pDlg->pInEndpt->TimeOut = 2000; for (;pDlg->bLooping;) { LONG outlen,inlen,len; outlen = inlen = len = xfer; // Use temp var because XferData can change the value of len UCHAR *outContext = pDlg->pOutEndpt->BeginDataXfer(data,outlen,&outOvLap); UCHAR *inContext = pDlg->pInEndpt->BeginDataXfer(inData,inlen,&inOvLap); pDlg->pOutEndpt->WaitForXfer(&outOvLap,2000); pDlg->pInEndpt->WaitForXfer(&inOvLap,2000); success = pDlg->pOutEndpt->FinishDataXfer(data, outlen, &outOvLap,outContext); success = pDlg->pInEndpt->FinishDataXfer(inData,inlen, &inOvLap,inContext); if (success) { bool pass = (memcmp(data,inData,len) == 0); if (pass) nSuccess++; else nFailure++; } else nFailure++; str.Format(_T("%d"),nSuccess); pDlg->m_SuccessCount.SetWindowTextW(str); str.Format(_T("%d"),nFailure); pDlg->m_FailureCount.SetWindowTextW(str); if ((!success) && stopOnError) pDlg->bLooping = false; } CloseHandle(outOvLap.hEvent); CloseHandle(inOvLap.hEvent); delete [] data; delete [] inData; pDlg->m_StatusLabel.SetWindowText(_T(" STATUS: Stopped")); pDlg->XferThread = NULL; //pDlg->pUSBDevice->Close(); return true; }
2. MFC控制元件相關操作
2.1 下拉框控制元件
本模組下拉框名稱為IDC_FILLPATTERN_COMBOX ,與之關聯的變數是m_FillPatternComBox,下拉框的可選項可以在控制元件屬性——行為——資料中新增,不同選項之間使用分號隔開,IDC_FILLPATTERN_COMBOX 控制元件的可選項如下:
資料:Constant Byte;Random Byte;Incrementing Byte;Incrementing DWORD;
環路測試的預設傳輸模式是Incrementing Byte,使用SetCurSel()函式可以完成下拉框預設設定,用法如下:
m_FillPatternComBox.SetCurSel(2); //下拉框的預設選項為第3項Incrementing Byte
使用GetCurSel()函式可以獲取下拉框當前的選項,用法如下:
m_FillPatternComBox.GetCurSel();
2.2 複選框控制元件
本模組中複選框名稱為IDC_STOP_ON_ERROR_CHKBOX,與之關聯的變數為m_StopOnErrorChkBox。當複選框被選中,控制元件返回值為1,如果沒被選中則返回值為0,使用GetCheck()函式可以獲取複選框的返回值:
m_StopOnErrorChkBox.GetCheck();
2.3 靜態文字控制元件
本模組中用於狀態提示的靜態文字框的名稱是IDC_STATUS_LABEL,與之關聯的變數為m_StatusLabel,使用SetWindowText()函式即可完成靜態文字框的內容更新,用法如下:
m_StatusLabel.SetWindowText(_T(" STATUS: Transferring data . . ."));
3. 功能測試
(1) Constant Byte
(2)Random Byte
(3) Incrementing Byte
(4) Incrementing DWORD
(5)重置資料
4. 參考
[1] MFC使用ComboBox控制元件方法 - Jockr - CSDN部落格
https://blog.csdn.net/nonecode/article/details/8134095
[2] MFC CheckBox的使用 - gll028的專欄 - CSDN部落格
https://blog.csdn.net/gll028/article/details/8552480