因為沒有偏好軟體或韌體,其實都是工作的一部分,在寫韌體時,可以自己寫一點軟體,
是可以協助完成韌體的開發與除錯。畢竟USB 多少還是都跟PC 端的應用軟體有關,可以自己
寫軟體是可以很快的驗證自己所定義的通訊協定是否正常,而且現在搞韌體應該沒有人還在用
ICE 那一種一步一步 Trace 程式的方式吧~現在的單晶片常常劈哩啪啦,一下子就跑了一大堆
的東西出來了,除非你是像我以前在幫忙Debug 八核心MCU 開發過程中,還真的需要 Step
by Step 的看東西,否則,現在工程師真的很難有那麼多美國時間跟你這麼玩的。
至於系統應用韌體,最討厭的倒也不是這些東西,而是後來發展過程中,你突然發現,
原來有很多東西可能要做到向前兼容,剛開始也只是覺得反正老闆或長官急著要東西而已,
就隨隨便便的搞個初版就給了,結果沒想到東西後來還需要擴充與升級,結果這下就面臨
命令或通訊協定需要新舊版本兼容,這下就昏倒了。沒辦法,大家都習慣邊上機寫程式,
邊自己定義命令組或通訊協定...沒有養成事先規劃工作,所以啦~如果你要我從這些文章
中,有哪些啟發的教訓?我想最重要的一點就是這一個吧。真的~好技術或好東西是值得
一輩子珍藏的~但先決條件就是要隨時可以升級與維護的...)
>>>>>>>>>>++++++++++++++++++++++++++++++++++
既然上次都提到有關在PC端的驅動程式架構了,我就稍微介紹一下PC端的應用程式吧。
說真的~怎麼寫驅動程式?我不會。但目前我的所有最上層應用程式,可都是我自己寫的。
當然,以我 USB DIY 來說,我是認為這樣子已經可以在USB 世界裡,作我想作的東西了。
以前剛學PC的應用程式時,也是為了利用PC周邊的東西,來作一些東西。只是那時只有
RS232 而已。而我也不會寫 C語言。後來,也是人家給我一個範例程式
(現在要找範例程式就容易多了,因為網路上的東西很多了,只不過是人家講的一句笑話:
網際網路裡,什麼都有,只有您要的沒有?!就算有,您也找不到!!您學USB 是不是
也有這種感覺?!那您來我的網站就對了啊!哈~哈~),自己就一步一腳印慢慢的摸~
雖然寫出來的程式不像專業人是寫得那麼漂亮,卻自己覺得怡然自得了。
畢竟我們寫的還是跟周邊硬體有相關的。重點是在這些周邊控制的東西。
而非是那花俏的程式吧。
首先,我先 說明一下我使用的開發環境吧:這個開發環境也不是我挑的~是人家給我的
範例程式!!因為不會寫 USB 的驅動程式,只好回頭找老同事幫忙(因為當初作計畫時
的團隊已經鳥獸散了,幸好我的人緣還不錯, 我把我的來意與用意說明之後,我們當初寫
驅動程式與軟體的工程師就三兩下給我一版~就說:以後就自求多福了,但對我來說:
已經恩同再造了,又什麼好要求的呢?!)。我的上層應用程式開發環境是 Microsoft Visual
C++ 6.0 ~您要不要用MFC~就看您自己的所好了。在此之前我所曾使用的是 DOS 時代的
Turbo C 。那時也不知道要從何學起?就找一個實例的來親自作一次!就學起來了。
但是,這次接觸 Visual C++ 時,人家可好心的警告我說:MFC 至少要磨個兩三個月以上,
您才會慢慢的進入狀況!年紀一大把,為什麼我還那麼『歹命』啊?但是我很慶幸我還是
走過了!(雖然之前一度還是回到傳統的 C的開發觀念~但是對那些視窗的東西,
實在是喔~ 只能說:年紀真的太大了!)
若是您是用 VB 或其他的,不好意思!真的我已經沒那個體力了。或是,您也覺得人家
都是用 C 語言,前輩也跟我說:對一些有關周邊控制的東西還是也C語言為主~
而我到底要不要換開發環境呢?!您就會跟我上述的心情一樣了。或許,您看了我這篇
文章後,您內心的掙扎會更大吧。
基本的架構跟我前一章節所述的軟體架構有點雷同:
所以,我們的軟體大哥就給我一個 GT68XX.SYS (經千錘百鍊驗證過的驅動程式)配上
一組 GUID 定義檔(好像只要不同的驅動程式搭配不同的GUID定義檔就不怕同一棵IC或
平台會相衝了,這點我也不懂,我大概只知道微軟在視窗操作環境中都是靠GUID再做判別
區分的!),再給個Library 檔 加上一個簡單的 OpenDriver 的原始碼~就教我自求多福了!
唉~這樣子就完全解決我在USB 開發上在PC端的重要瓶頸了。
怎麼用?很簡單,也是看圖:(若不會在Visual C++ 中開 Project 的我也沒辦法教您了!)
這是我做ATMEL ISP 燒錄器的範例程式。
那一個Library到那裡去了?! 也是看圖:
接下來,您就可以大大方方,放心地寫您的上層的應用程式了!啊~寫USB 的應用程式
這麼簡單?!有沒有搞錯?!哈~哈~套一句人家說的:好的老師帶著您上天堂;
不好的老師,帶您住套房!您一定覺得我在乎籠您。但您看了我這麼多文章,您還會這樣子
認為嗎?!所以我說為什麼老是要用那種:用起來總是會有那麼一點提心吊膽的HID 驅動
程式呢? 您一定對我所說的那的 Opendriver.CPP 原始碼很有興趣吧!沒關係,您就用力
下載來看吧!不過,也真的看不出什麼?!我一定要搞得懂嗎?!對我來說:
我沒那個精力。作USB 周邊比較實際呢?還是搞得懂視窗程式來龍去脈比較重要呢?!
對不起!我的網站標榜的是USB DIY 啊!
用力下載--> opendriver.cpp 及 opendriver.h
(PS : 看不懂得不要問我,人家我們軟體大哥不是說了嗎:自求多福!!)
應用程式怎麼寫?那更簡單了:以下就是透過 Endpoint 0 (就是Setup Token )下一組
64 Bytes 資料下去(就是下一個命令兼帶參數,讓韌體去控制LED 的閃爍)!
並讀回韌體的相關數據 :
void CUSBAISPDlg::USB_DEVICE_SET_LED_CONTROLLER(UCHAR BlinkingCNT, UCHAR LEDCR)
{
int i;
hDEV = open_dev();
if(hDEV!=INVALID_HANDLE_VALUE)
{
//for(i=0;i<64;i++) iobuffer[i]=0x00;
//----
//------ LED Controller
//----
//---- Command set = 0x81
//---- arg_0 : Blinking counter , Default = 0x30
//---- arg_1 : LED control
// bit 1: RED ON
// bit 2: GREEN ON
// bit 3: BLUE ON
// bit 4: Global Blinking
// bit 5: RED Blinking
// bit 6: GREEN Blinking
// bit 7: BLUE Blinking
// if Global Blinking is ON, then will ignor the LED ON !!
for(i=0;i<8;i++) STICommandString[i]=0x00; // reset the parameters
STICommandString[0]=0x87; // LED Control Command
STICommandString[1]=BlinkingCNT; // Blinking Speed !
STICommandString[2]=LEDCR; // LED Control Register
USB_DEVICE_SEND_STI_COMMAND(STICommandString);
CloseHandle(hDEV);
hDEV=INVALID_HANDLE_VALUE;
}
}
{
int i;
hDEV = open_dev();
if(hDEV!=INVALID_HANDLE_VALUE)
{
//for(i=0;i<64;i++) iobuffer[i]=0x00;
//----
//------ LED Controller
//----
//---- Command set = 0x81
//---- arg_0 : Blinking counter , Default = 0x30
//---- arg_1 : LED control
// bit 1: RED ON
// bit 2: GREEN ON
// bit 3: BLUE ON
// bit 4: Global Blinking
// bit 5: RED Blinking
// bit 6: GREEN Blinking
// bit 7: BLUE Blinking
// if Global Blinking is ON, then will ignor the LED ON !!
for(i=0;i<8;i++) STICommandString[i]=0x00; // reset the parameters
STICommandString[0]=0x87; // LED Control Command
STICommandString[1]=BlinkingCNT; // Blinking Speed !
STICommandString[2]=LEDCR; // LED Control Register
USB_DEVICE_SEND_STI_COMMAND(STICommandString);
CloseHandle(hDEV);
hDEV=INVALID_HANDLE_VALUE;
}
}
其中:
USB_DEVICE_SEND_STI_COMMAND(STICommandString) 就是:
UCHAR CUSBAISPDlg::USB_DEVICE_SEND_STI_COMMAND(UCHAR *STICommandString)
{
int i;
BOOL success;
iobuffersize = 0x40;
for(i=0;i<8;i++)
iobuffer[i]=STICommandString[i];
// 利用 Endpoint 0 的Setup Out Token 下一組 64 Bytes 的資料給 韌體
success = DeviceIoControl(hDEV,
IOCTL_GrandTech_Scanner_STI_Send_Command,
iobuffer,
iobuffersize,
iobuffer,
iobuffersize,
(unsigned long *)&nBytes,
NULL);
{
int i;
BOOL success;
iobuffersize = 0x40;
for(i=0;i<8;i++)
iobuffer[i]=STICommandString[i];
// 利用 Endpoint 0 的Setup Out Token 下一組 64 Bytes 的資料給 韌體
success = DeviceIoControl(hDEV,
IOCTL_GrandTech_Scanner_STI_Send_Command,
iobuffer,
iobuffersize,
iobuffer,
iobuffersize,
(unsigned long *)&nBytes,
NULL);
// 利用 Endpoint 0 的Setup In Token ! 讀回 USB Device 的 64 Bytes 資料!
success = DeviceIoControl(hDEV,
IOCTL_GrandTech_Scanner_STI_Get_Status,
iobuffer,
iobuffersize,
iobuffer,
iobuffersize,
(unsigned long *)&nBytes,
NULL);
return (iobuffer[1]);
}
success = DeviceIoControl(hDEV,
IOCTL_GrandTech_Scanner_STI_Get_Status,
iobuffer,
iobuffersize,
iobuffer,
iobuffersize,
(unsigned long *)&nBytes,
NULL);
return (iobuffer[1]);
}
很簡單吧~還是老話一句:我為什麼要用HID 驅動程式呢?!哈~哈~
至於 Bulk In 與 Bulk Out 我好像有舉過例子吧?!再寫一次寫沒關係:
Bulk In :
HANDLE hRead=INVALID_HANDLE_VALUE;
hRead = open_file(inPipe);
if(hRead==INVALID_HANDLE_VALUE)
{
///----
MessageBox("Open in pipe Error",NULL,MB_OK);
return ;
}
BOOL success;
success = ReadFile(hRead,
Raw_Buffer,
nLength, // <---- 一次要多少就有多少!!
&nBytesRead,
NULL);
CloseHandle(hRead);
if(hRead==INVALID_HANDLE_VALUE)
{
///----
MessageBox("Open in pipe Error",NULL,MB_OK);
return ;
}
BOOL success;
success = ReadFile(hRead,
Raw_Buffer,
nLength, // <---- 一次要多少就有多少!!
&nBytesRead,
NULL);
CloseHandle(hRead);
Bulk Out :
hWrite = open_file(myoutpipe);
if(hWrite==INVALID_HANDLE_VALUE)
{
MessageBox("Open Out Pipe Error",NULL,MB_OK);
return ;
}
success = WriteFile(hWrite,
fwbuf,
nLength, // <-- 一次要傳多少出去隨您高興!
&nBytesRead,
NULL);
CloseHandle(hWrite);
if(hWrite==INVALID_HANDLE_VALUE)
{
MessageBox("Open Out Pipe Error",NULL,MB_OK);
return ;
}
success = WriteFile(hWrite,
fwbuf,
nLength, // <-- 一次要傳多少出去隨您高興!
&nBytesRead,
NULL);
CloseHandle(hWrite);
好了~您要我寫什麼結論呢?!要不要套個股市名嘴張老師的一段話?
哈~哈~
還是老話一句:多給掌聲鼓勵鼓勵吧!否則,我真的不太想寫有關USB 的東西了。
謝謝您們!下台一鞠躬。
沒有留言:
張貼留言