Download pdf - Tai Lieu Huong Dan USBp3

Transcript
Page 1: Tai Lieu Huong Dan USBp3

Nguy n Ng c H ng L p TKTL 40 HVKTQS

- 1 -

Ph n 3:Vi t Ch ng Trình C# giao ti p v i thi t b USB

1. T o Driver cho thi t b và t o các th vi n hàm giao ti p USB:Công vi c u tiên mà b n ph i làm v i WinDriver t o Driver và các

th vi n ph n m m cho ch ng trình PC c a b n. Các b c ti n hành bao g m:

1. n thi t b c a b n vào c ng USB trên máy tính computer:2. Ch y DriverWizard và ch n thi t b c a b n:

hình 1: M ho c t o m t WinDriver ProjectCh n thi t b c a b n trong list c a WinDriver:

Page 2: Tai Lieu Huong Dan USBp3

Nguy n Ng c H ng L p TKTL 40 HVKTQS

- 2 -

Ch n phát ra file Driver và ánh tên cho thi t b c a b n:

Ti p t c ch n next ta c:

i ây b n có th ki m tra vi c truy n nh n qua USB xem thi t b c a b n ãho t ng ch a. Vi c ti p theo là t o ra giao di n ban u và th vi n trên C#.Click và bi u t ng Generate Code và ch n ngôn ng mà b n s d ng, hi n nayngôn ng C# thông d ng v i nhi u ng i và có nhi u ti n ích h n so v i VBnên ây tôi ch n nh sau:

Công vi c còn l i ch là OK và ch máy ch y hihi.

Page 3: Tai Lieu Huong Dan USBp3

Nguy n Ng c H ng L p TKTL 40 HVKTQS

- 3 -

Ch y Project trên Visual Studio 2005 b n có th th y WinDriver ã t o cho tat giao di n ban u s d ng các giao ti p USB, b n có th s d ng luôn

giao di n này th c hi n theo Project c a b n:

Chú ý r ng b n ph i Project/ Set as Startup Project tr c ã.Nh ng giúp cho ng i m i h c có th hi u c m t cách nhanh chóng tôixin t t o m t giao di n khác n gi n ng n g n h n b ng vi c s d ng các thvi n mà WinDriver v a t o ra cho chúng ta. ó là hai th vi nproject_usb_4550_lib.dll (th vi n này do ta t nó cùng v i tên Project khi t ora) và wdapi_dotnet921.dll hai th viên này ch a các l p và các y quy n r t

u ích giúp cho vi c qu n lý và th c hiên giao ti p b ng USB.

Công vi c ti p theo c a chúng ta là hãy tam quên i cái giao di n mà WinDrivera t o ra trên, và b t tay vào t o m t giao di n c a chính chúng ta. V i

ph ng châm càng n gi n càng t t nên h ng d n này tôi ch t o m t giaodi n ch v i 2 Button và 2 textBox dùng u khi n nh sau:

Page 4: Tai Lieu Huong Dan USBp3

Nguy n Ng c H ng L p TKTL 40 HVKTQS

- 4 -

y là song b c u tiên, b c ti p theo là add 2 th vi n trên vào trongproject c a mình và nghiên c u cách s d ng chúng. N u b n add thành công thì

n s th y chúng nh sau:

Ta hãy xem chúng có nh ng gì ( vi c s d ng ch y u trên th vi nproject_usb_4550_lib.dll):

Th vi n này ch a 4 u quy n (delegates) dành t o các s ki n quan tr ngi bus USB và 4 l p, trong ó 3 l p u khi n thi t b USB và m t l p

Page 5: Tai Lieu Huong Dan USBp3

Nguy n Ng c H ng L p TKTL 40 HVKTQS

- 5 -

qu n lý danh sách các thi t b USB khác nhau c gán vào PC. Chúng ta hãyquan sát c th h n v i các u quy n và các l p này:- quy n D_USER_ATTACH_CALLBACK d ng gán s ki n cóthi t b USB thích h p g n vào bus USB v i m t hàm callback do b n t o rath ng là kh i t o vi c truy n nh n d li u.- quy n D_USER_DETACH_CALLBACK c s d ng gán ski n thi t b USB ã c tháo ra v i m t hàm g i l i do b n xây d ng th nglà thông báo cho ngu i s d ng v vi c Disconnect và k t thúc vi c truy n nh n- quy n D_USER_TRANSFER_COMPLETION khá h u ích vì nó sgán s ki n truy n nh n k t thúc vào m t hàm x lý c vi t d li u usb do b nxây d ng.- quy n D_USER_POWER_CHANGE_CALLBACK ít c s d ng

n vì nó liên quan n vi c báo ng thay i ngu n trên bus USB, b n có thn d ng th c hi n các bi n pháp b o m c t ngu n bus USB khi có s c .

- p KEY_USB_Device ch a các hàm th c hi n vi c cài t c u hìnhkhác nhau cho thi t b USB hay hàm c các s hi u VP, IP và hàm theo dõitr ng thái truy n nh n c a thi t b :

- p KEY_USB_DeviceManager th c hi n vi c qu n lý thi t b USB và s l ng thi t b USB c g n vào:

- p KEY_USB_Pipe có s l ng hàm t ng i l n và chuyên d ng c vi t d li u ki m tra tr ng thái truy n nh n, ki m soát vi c kh i ng vàng các ng ng…

- L p Pipe_list th c hi n qu n lý các ng ng vào ra c a thi t b .p các hàm này khá linh ho t và y cho m i ng d ng USB và b n c ng

không c n ph i tìm hi u k t t c các hàm ó vì chúng ta ch c n làm vi c v it s hàm nh t nh là giao ti p.

Bây gi là n công vi c khó nh t ây, ta ph i vi t code làm sao cho khi g nthi t b vào thì nó ph i nh n c và th c hi n truy n phát d li u.

Page 6: Tai Lieu Huong Dan USBp3

Nguy n Ng c H ng L p TKTL 40 HVKTQS

- 6 -

Ý t ng c a tôi là dùng Button1(tên là btwrite) th c hi n vi c truy n d li uc l y trong textBox1(tên là txttrans) t PC xu ng V K, Button2(btread)

dùng l y d li u t V K lên PC hi n th textBox2(txtLog). thu t toán th c hi n ch ng trình chúng ta ch h n ch 3 ch c n ng c b n

là c, vi t d li u và phát hi n thi t b gán vào hay tháo ra (hai s ki n nh nbi t thi t b u c hi n th trên txtLog).Ph n khai báo USING c a ch ng trình chúng ta c n m t s khai báo nh sau:using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;using System.Runtime.InteropServices;using System.Runtime.CompilerServices;

using Jungo.wdapi_dotnet; //s d ng th vi n wdapi_dotnetusing Jungo.project_usb_4550_lib; //s d ng th vi n project_usb_4550_libusing wdu_err=Jungo.wdapi_dotnet.WD_ERROR_CODES;//s d ng vi c khai báo l i

using DWORD = System.UInt32;using WORD = System.UInt16;using UCHAR = System.Byte;

ph n khai báo các bi n c a form chính chúng ta th c hi n m t s khai báo hàngbi n và t o các i t ng sau:private const string DEFAULT_LICENSE_STRING ="6C3CC2CFE89E7AD04238DF2EF24449E848CDC187.NguyenNgocHung";// TODO: If you have renamed the WinDriver kernel module (windrvr6.sys),// change the driver name below accordinglyprivate const string DEFAULT_DRIVER_NAME = "windrvr6";private const WORD DEFAULT_VENDOR_ID = 0x04D8;private const WORD DEFAULT_PRODUCT_ID = 0x0101;public const DWORD TIME_OUT = 30000;

private PROJECT_USB_4550_DeviceManager uDevManager; //khai báo kh i t ovi c qu n lý i t ng USBprivate PROJECT_USB_4550_Device usb_device; //khai báo i t ng USBprivate PROJECT_USB_4550_Pipe usb_pipe_trs; //khai báo i t ng ng truy nprivate PROJECT_USB_4550_Pipe usb_pipe_rev; //khai báo i t ng ng nh nprivate delegate void D_ATTACH_GUI_CALLBACK(PROJECT_USB_4550_Device pDev);//khai báo y quy n thông báo thi t b g n vàoprivate delegate void D_DETACH_GUI_CALLBACK(PROJECT_USB_4550_Device pDev);//khai báo y quy n thông báo thi t b tháo radelegate void safeLogTextCallBack(string sMsg); //khai báo y quy n ph c vhi n th

Chúng ta ã có 1 i t ng qu n lý USB, 1 i t ng thi t b USB, 2 i t ngng ng TRANSFER và RECEIVER, các k t n i, khai báo driver u khi n

và các u quy n c n thi t. Ti p theo chúng ta s xây d ng các hàm c a formtheo các s ki n chính. S ki n u tiên chúng ta c n quan tâm là “form load”vì nó x y ra u tiên trong chu i s ki n vì v y có th t n d ng kh i t o m t

bi n, i t ng cho ch ng trình.

private void form_main_Load(object sender, EventArgs e) {

// ng ký hai hàm s ki n ATTACH_CALLBACK & DETACH_CALLBACK

Page 7: Tai Lieu Huong Dan USBp3

Nguy n Ng c H ng L p TKTL 40 HVKTQS

- 7 -

D_USER_ATTACH_CALLBACK dDeviceAttachCb = newD_USER_ATTACH_CALLBACK(UserDeviceAttach);

D_USER_DETACH_CALLBACK dDeviceDetachCb = newD_USER_DETACH_CALLBACK(UserDeviceDetach);

//kh i t o i t ng qu n lý thi t b USB uDevManager = newPROJECT_USB_4550_DeviceManager(dDeviceAttachCb, dDeviceDetachCb, DEFAULT_VENDOR_ID, DEFAULT_PRODUCT_ID, DEFAULT_DRIVER_NAME, DEFAULT_LICENSE_STRING); }

Hàm 2 callback x lý 2 s ki n Attacth và Detach theo c c u trung gian ci n 2 hàm UserDeviceAttach & UserDeviceDetach kh i t o các ing AttachCb và DetachCb . Trong hàm này còn th c hi n vi c kh i t o thi t b

USB và hai ng ng TRANSFER & RECEIVER.private void UserDeviceAttach(PROJECT_USB_4550_Device pDev) {

D_ATTACH_GUI_CALLBACK AttachCb = newD_ATTACH_GUI_CALLBACK(DeviceAttachGuiCb);

// kh i t o thi t b USB usb_device = pDev;

// kh i t o ng ng nh n và truy n usb_pipe_rev =(PROJECT_USB_4550_Pipe)usb_device.GetpPipesList()[1]; usb_pipe_trs =(PROJECT_USB_4550_Pipe)usb_device.GetpPipesList()[2];

Invoke(AttachCb, new object[] {pDev}); }

Và:private void UserDeviceDetach(PROJECT_USB_4550_Device pDev) {

D_DETACH_GUI_CALLBACK DetachCb = newD_DETACH_GUI_CALLBACK(DeviceDetachGuiCb);

Invoke(DetachCb, new object[] { pDev }); }

Các hàm DeviceAttachGuiCb & DeviceDetachGuiCb ch là các hàm hi n th tr ngthái thi t b g n vào hay tháo ra.

private void DeviceAttachGuiCb(PROJECT_USB_4550_Device pDev) { TraceMsg("Found new device\r\n"); TraceMsg("Your new device is installed and ready to use\r\n"); }private void DeviceDetachGuiCb(PROJECT_USB_4550_Device pDev) { TraceMsg("Your device has detached\r\n"); }

thu n l i cho vi c hi n th tr ng thái ch ng trình chúng ta nên b xung m t hàm u khi n vi c xu t thông báo ví d 3 hàm d i ây:

private void SafeLogText(string sMsg) {

// InvokeRequired compares the thread ID of the// calling thread to the thread ID of the creating thread.// If these threads are different, it returns true.if (txtLog.InvokeRequired)

{

Page 8: Tai Lieu Huong Dan USBp3

Nguy n Ng c H ng L p TKTL 40 HVKTQS

- 8 -

safeLogTextCallBack cb = newsafeLogTextCallBack(SafeLogText);

this.Invoke(cb, new object[] { sMsg }); }

else { txtLog.AppendText(sMsg); } }

public void TraceMsg(string sMsg) { SafeLogText(sMsg); }

Bây gi ta b t tay vào vi c xây d ng hàm dùng truy n nh n d li u. Khi nh nvào button write thì th c hi n truy n m t byte xu ng V K:private void btwrite_Click(object sender, EventArgs e) { SingleTransfer(); }

Hàm SingleTransfer(); th c hi n vi t s l y 1 byte ã nh p vào txttrans vàchuy n sang d ng byte trong buffer sau ó g i hàm truy n không ng b :usb_pipe_trs.UsbPipeTransferAsync(false, 0, buffer, dwBuffSize, TIME_OUT, newD_USER_TRANSFER_COMPLETION(Transfer_trs_Completion));

Khi nh n vào button read thì th c hi n nh n m t byte t V K lên PC và hi nth ra txtLog.private void btread_Click(object sender, EventArgs e) { SingleReceiver(); }

Hàm SingleReceiver(); t ng t nh hàm SingleTransfer(); th c hi n vi cnh n d li u vào b m:usb_pipe_rev.UsbPipeTransferAsync(true, 0, buffer, dwBuffSize, TIME_OUT, newD_USER_TRANSFER_COMPLETION(Transfer_rev_Completion));

Các hàm Transfer_trs_Completion & Transfer_rev_Completion th c hi n vi cthông báo hoàn thành truy n ho c nh n. Hàm DisplayHexBuffer h tr vi chi n th giá tr thâp l c phân.Sau ây là toàn b mã c a ch ng trình:using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;using System.Runtime.InteropServices;using System.Runtime.CompilerServices;

using Jungo.wdapi_dotnet;using Jungo.project_usb_4550_lib;using wdu_err = Jungo.wdapi_dotnet.WD_ERROR_CODES;

using DWORD = System.UInt32;

Page 9: Tai Lieu Huong Dan USBp3

Nguy n Ng c H ng L p TKTL 40 HVKTQS

- 9 -

using WORD = System.UInt16;using UCHAR = System.Byte;

namespace project_usb_4550{

public partial class form_main : Form {

private const string DEFAULT_LICENSE_STRING ="6C3CC2CFE89E7AD04238DF2EF24449E848CDC187.NguyenNgocHung";

private const string DEFAULT_DRIVER_NAME = "windrvr6";private const WORD DEFAULT_VENDOR_ID = 0x04D8;private const WORD DEFAULT_PRODUCT_ID = 0x0101;public const DWORD TIME_OUT = 30000;

private PROJECT_USB_4550_DeviceManager uDevManager;private PROJECT_USB_4550_Device usb_deviceprivate PROJECT_USB_4550_Pipe usb_pipe_trs;private PROJECT_USB_4550_Pipe usb_pipe_rev;private delegate void D_ATTACH_GUI_CALLBACK(PROJECT_USB_4550_Device

pDev);private delegate void D_DETACH_GUI_CALLBACK(PROJECT_USB_4550_Device

pDev);delegate void safeLogTextCallBack(string sMsg);public form_main()

{ InitializeComponent(); }

private void form_main_Load(object sender, EventArgs e) {

D_USER_ATTACH_CALLBACK dDeviceAttachCb = newD_USER_ATTACH_CALLBACK(UserDeviceAttach);

D_USER_DETACH_CALLBACK dDeviceDetachCb = newD_USER_DETACH_CALLBACK(UserDeviceDetach);

uDevManager = newPROJECT_USB_4550_DeviceManager(dDeviceAttachCb, dDeviceDetachCb, DEFAULT_VENDOR_ID, DEFAULT_PRODUCT_ID, DEFAULT_DRIVER_NAME, DEFAULT_LICENSE_STRING); }

private void UserDeviceAttach(PROJECT_USB_4550_Device pDev) {

D_ATTACH_GUI_CALLBACK AttachCb = newD_ATTACH_GUI_CALLBACK(DeviceAttachGuiCb);

usb_device = pDev; usb_pipe_rev =(PROJECT_USB_4550_Pipe)usb_device.GetpPipesList()[1]; usb_pipe_trs =(PROJECT_USB_4550_Pipe)usb_device.GetpPipesList()[2];

Invoke(AttachCb, new object[] {pDev}); }

private void DeviceAttachGuiCb(PROJECT_USB_4550_Device pDev) { TraceMsg("Found new device\r\n"); TraceMsg("Your new device is installed and ready to use\r\n"); }

private void UserDeviceDetach(PROJECT_USB_4550_Device pDev) {

D_DETACH_GUI_CALLBACK DetachCb = newD_DETACH_GUI_CALLBACK(DeviceDetachGuiCb);

Invoke(DetachCb, new object[] { pDev }); }

Page 10: Tai Lieu Huong Dan USBp3

Nguy n Ng c H ng L p TKTL 40 HVKTQS

- 10 -

private void DeviceDetachGuiCb(PROJECT_USB_4550_Device pDev) { TraceMsg("Your device has detached\r\n"); }

private void SafeLogText(string sMsg) {

// InvokeRequired compares the thread ID of the// calling thread to the thread ID of the creating thread.// If these threads are different, it returns true.if (txtLog.InvokeRequired)

{safeLogTextCallBack cb = new

safeLogTextCallBack(SafeLogText);this.Invoke(cb, new object[] { sMsg });

}else

{ txtLog.AppendText(sMsg); } }

public void TraceMsg(string sMsg) { SafeLogText(sMsg); }

private void btwrite_Click(object sender, EventArgs e) { SingleTransfer(); }

private void SingleTransfer() {

DWORD dwBuffSize = 1;byte[] buffer = new byte[1];string txt = txttrans.Text;

buffer[0] = Convert.ToByte(txt[0]); usb_pipe_trs.UsbPipeTransferAsync(false, 0, buffer, dwBuffSize, TIME_OUT, newD_USER_TRANSFER_COMPLETION(Transfer_trs_Completion)); }

private void Transfer_trs_Completion(PROJECT_USB_4550_Pipe pipe) {

if (pipe.GetTransferStatus() ==(DWORD)wdu_err.WD_STATUS_SUCCESS) { TraceMsg("Transfer completed successfully!\r\n "); }

else { TraceMsg("tranfer fail\r\n"); } }

private void btread_Click(object sender, EventArgs e) { SingleReceiver(); }

private void SingleReceiver() {

DWORD dwBuffSize = 1;byte[] buffer = new byte[1];

usb_pipe_rev.UsbPipeTransferAsync(true, 0, buffer,

Page 11: Tai Lieu Huong Dan USBp3

Nguy n Ng c H ng L p TKTL 40 HVKTQS

- 11 -

dwBuffSize, TIME_OUT, newD_USER_TRANSFER_COMPLETION(Transfer_rev_Completion)); }

private void Transfer_rev_Completion(PROJECT_USB_4550_Pipe pipe) {

if (pipe.GetTransferStatus() ==(DWORD)wdu_err.WD_STATUS_SUCCESS) { TraceMsg(DisplayHexBuffer(pipe.GetBuffer(),1)); }

else { TraceMsg("receiver failure!\r\n"); } }

private string DisplayHexBuffer(byte[] buff, DWORD dwBuffSize) {

string display = "";for (DWORD i = 0; i < dwBuffSize; i++)

display = string.Concat(display, buff[i].ToString("X")," ");

display = string.Concat(display, Environment.NewLine);return display;

} }}