Phần quản lý kết nối USB giữa reader và máy tính, ta sẽ tích hợp nó vào bên trong phần mềm quản lý của ta ở trên. Chỉ đơn giản là ta sẽ thực hiện gọi các hàm giao tiếp với thiết bị ngoại vi , mà hãng Microsoft đã cung cấp sẵn trong các lớp thư viện WINDOWS API của hệ điều hành windows. Bây giờ ta sẽ đi tìm hiểu qua về chúng.
API bao gồm các hàm, các thông báo, các cấu trúc dữ liệu, các kiểu dữ liệu, mà chúng ta có thể sử dụng để tạo ra các ứng dụng chạy trên hệ điều hành Windows. Các phần của API mà ta hay sử dụng nhất , đó là các mã phục vụ cho việc gọi các hàm API từ Windows. Cái này bao gồm, phần khai báo các thủ tục, phần định nghĩa các kiểu dữ liệu của người dùng, và phần khai báo các hằng số.
Trước khi một ứng dụng có thể trao đổi dữ liệu với một HID, thì nó phải nhận dạng được thiết bị và lấy được các thông tin về các report của thiết bị đó. Đầu tiên ứng dụng sẽ tìm ra các HID được gắn vào hệ thống là gì. Sau đó, nó kiểm tra thông tin về mỗi HID đó cho đến khi nó tìm thấy được một trong các thuộc tính mong muốn. Với các thiết bị truyền thống, ứng dụng có thể tìm kiếm các thông tin về mã số nhà phát hành và mã số sản phẩm. Hoặc ứng dụng có thể tìm ra thiết bị đó là thuộc kiểu HID đặc biệt nào, chẳng hạn như HID mouse hay là HID joystick. Sau khi đã tìm ra được thiết bị, ứng dụng có thể trao đổi thông tin với thiết bị đó bằng cách gửi hoặc nhận các report.
Dưới đây là bảng danh sách các hàm API được sử dụng để thiết lập liên lạc thông tin và trao đổi dữ liệu với một HID.
Bảng2.2 Danh sách các hàm API dùng cho kết nối usb trong windows
Các hàm API DLL Mục đích
HidD_GetHidGuid hid.dll Lấy GUID cho lớp HID
SetupDiGetClassDevs setupapi.dll Trả về thông tin của một thiết
bị từ một tập hợp chứa tất cả các thiết bị trong một lớp đặc biệt.
SetupDiEnumDeviceInterfaces setupapi.dll Trả về thông tin một thiết bị trong tập hợp thông tin thiết bị.
CreateFile kernel32.dll Mở một kết nối truyền thông
tới thiết bị.
HidD_GetAttributes hid.dll Trả về mã số nhà sản xuất, mã
số sản phẩm, và số phiên bản của sản phẩm.
HidD_GetPreparsedData hid.dll
HidP_GetCaps hid.dll Trả về một cấu trúc mô tả các
thiết bị.
ReadFile kernel32.dll Đọc một report đầu vào từ
thiết bị.
HidD_SetFeature hid.dll Gửi một Feature report tới
thiết bị.
HidD_GetFeature hid.dll Đọc một Feature report từ
thiết bị.
CloseHandle kernel32.dll
2.4 Kết Luận
Như vậy ở chương này chúng ta đã đi thiết kế một hệ thống quản lý bệnh nhân bằng công nghệ RFID hoàn chỉnh một cách chi tiết từ việc thiết kế reader đến thiết kế phần mềm chạy trên máy tính. Ở đây tôi xin phép được lưu ý rằng, trong quá trình thiết kế chúng ta cần đặc biệt chú ý tới anten cho reader. Tuy cách chế tạo nó khá đơn giản, chỉ là quấn dây đông theo một hình tròn, hay hình vuông,...Nhưng nếu tính toán sai dẫn đến sai số quá lớn , có thể khiến cho reader không thể đọc được thẻ. Vì vậy khi chế tạo anten cần có các máy đó cần thiết để biết được một cách chính nhất có thể giá trị độ tự cảm của cuộn dây anten.
TÀI LIỆU THAM KHẢO
[1] Sandip Lahiri, RFID Sourcebook. Upper Saddle River, NJ: Prentice Hall PTR, 2005.
[2] Himanshu Bhatt, Bill Glover, RFID Essentials. Sebastopol, CA: O'Reilly, 2006. [3] Patrick J.Sweeney II, RFID For Dummies. Hoboken, NJ: Wiley, 2005.
[4] V.Daniel Hunt, Albert Puglia, Mike Puglia, RFID A Guide To Radio Frequence Identification. Hoboken, NJ: Wiley, 2007.
[5] Frank Thornton, Brad Haines, Anand M Das, Hersh Bhargava, RFID Security.
Rockland, Massachusetts: Syngress Publishing, 2006.
[6] http://www.rfdesignline.com/howto/202101579 ,truy nhập cuối cùng ngày 10/5/2010.
[7] http://www.usb.org/ ,truy nhập cuối cùng ngày 10/5/2010.
[8] http://www.emmicroelectronic.com/Line.asp?IdLine=3/,truy nhập cuối cùng ngày 1/5/2010.
[9] http://wikipedia.org/ ,truy nhập cuối cùng ngày 10/5/2010.
[10] http://www.microchip.com/ ,truy nhập cuối cùng ngày 10/5/2010. [11] http://www.mysql.com/ ,truy nhập cuối cùng ngày 10/4/2010. [12] http://php.net/index.php/ ,truy nhập cuối cùng ngày 12/4/2010.
[13] http://msdn.microsoft.com/en-us/vcsharp/default.aspx,truy nhập cuối cùng ngày 12/4/2010.
BẢNG ĐỐI CHIẾU CÁC THUẬT NGỮ VIỆT- ANH
Khả năng đánh địa chỉ Addressability Dòng điện xoay chiều Alternating Current
Điều chế biên độ Amplitude Modulation
Khóa dịch biên Amplitude Shift Key
Các tiêu chuẩn cỡ dây của Hoa Kỳ American Wire Gauge
Giao diện lập trình ứng dụng Application Programming Interface
Tán xạ ngược Backscatter
Mã vạch Bar Code
Hai pha Biphase
Thẻ chặn (được sử dụng các thẻ
RFID khác) Blocker Tag
Đốt cháy (để thao tác ghi lên chip) Burn
Phân cực tròn Circular Polarization
Khối tách xung Clock Extractor
Lớp Class
Một loại công nghệ để chế tạo vi mạch tích hợp
Complementary Metal Oxide Semiconductor
Sóng liên tục Continuous Wave
Kiểm tra độ dư vòng Cyclic Redundancy Check
Bộ mô tả Descriptor
Bộ mô tả thiết bị (usb) Descriptor Device Bộ mô tả các báo cáo (usb) Descriptor Report Bộ mô tả chuỗi (usb) Descriptor String Bộ mô tả các giao diện (usb) Descriptor Interface Bộ mô tả các đặc tính vật lý (usb) Descriptor physical
Lưỡng cực Dipole
Dòng điện một chiều Direct Current
Lưỡng cực đôi Dual Dipole
Công xuất bức xạ đẳng hướng Equivalent Isotropic Radiated Power
Hiệu suất bức xạ Effective Radiated Power Được lập trình sẵn bởi nhà sản xuất Factory Programmed
Phần mềm nhỏ được cài đặt trên vi điều khiển để nó có thể chạy ngay khi khởi động
Firmware
Lưỡng cực gấp Folded Dipole
Điều chế tần số (hay Điều tần) Frequency Modulation
Khóa dịch tần Frequency Shift Key
Tốc độ đầy đủ (usb) Full Speed
Giao diện đồ họa người dùng Graphical User Interface
Tần số cao High Frequency
Thiết bị giao tiếp với con người Human Interface Device Thiết bị chuột được hỗ trợ bởi lớp
HID
HID Mouse Thiết bị cần điều khiển được hỗ trợ
bởi lớp
HID HID Joystick
Danh mục Item
Phân cực tuyến tính Linear Polarization
Mạng nội bộ Local Area Network
Tần số thấp Low Frequency
Tốc độ thấp (usb) Low Speed
Phần mềm chịu trách nhiệm kết nối
phần cứng RFID vào hệ thống Midleware
Điều biên Modulator
Khóa on – off On Off Keying
Mạng cá nhân Personal Area Network
Vòng khóa pha Phase Locked Loop
Điều chế pha Phase Modulation
Khóa dịch pha Phase Shift Key
Cắm là chạy (usb) Plug And Play
Phân cực Polarization
Điều khiển / chỉnh lưu nguồn Power control/rectifier
Bảng mạch in Printed circuit board
Mã số sản phẩm Product
Mã hóa khoảng xung Pulse Interval Encoding
Nhận dạng tần số vô tuyến Radio Frequency Identification
Thiết bị đọc thẻ Reader
Bộ nhớ chỉ đọc Read Only Memory
Chỉ đọc Read Only
Đọc – ghi Read -Write
Hệ thống quản lý dữ liệu cơ sở
(trong hệ điều hành windows) Relational Database Management System
Đoạn thông tin Segment
Giao thức quản lý mạng đơn giản Simple Network Management Protocol
Phân lớp Subclass
Đa truy nhập phân chia theo thời
gian Time Division Multiple Access
Máy phát tín hiệu Transmitter
Bộ phát đáp Transponder
Tần số siêu cao Ultra High Frequency
Buýt nối tiếp đa năng Universal Serial Bus Mã số thế hệ sản phẩm Version
Mã số nhà sản xuất Vendor
Bộ dao động được khống chế bằng điện áp
Voltage Controlled Oscillator
Mạng không dây Wireless
Ghi một lần – đọc nhiều lần Write Once - Read Many Anten lưỡng cực gấp 2 dây 2-Wire Folded Dipole Antenna Anten lưỡng cực gấp 3 dây 3-Wire Folded Dipole Antena
PHỤ LỤC A : MỘT SỐ MÃ NGUỒN
Trong phần phụ lục này tôi chỉ xin phép trích dẫn một số phần mã nguồn chương trình quan trọng. Trong đó phải kể đến là phần mã điều khiển đọc thẻ EM4100 và descriptor mô tả thiết bị trong kết nối USB. Đó là hai tệp em4100.c và
usb_descriptor.h Em4100.c :
// Purpose: Reads the ID number and data number // Inputs: A pointer to a 5 byte array to fill // * The first byte will have the ID // * The last 4 bytes will have the data
// Outputs: TRUE if read successful, FALSE if read failed int1 read_em4100(int8* data)
{ int8 i;
RF_get(sizeof(RFbuffer)*8, TRUE); // Fill the buffer with data for(i=0; i<2; ++i)
{
while(!END_OF_RFBUFFER) {
if(header_search_em4100()) // Try to find 9 consecutive 1s {
if(decode_data_em4100(data)) // Try to decode the data after the header {
RFbuffer_fill(0xAA); // Prevents false detection return TRUE; // Return sucessful read }
} }
RFbuffer_invert(); // Invert the buffer because the } // Manchester encoded data could have // been read starting at the wrong edge RFbuffer_fill(0xAA); // Prevents false detection return FALSE; // Return error
// Purpose: Search for the header consisting of 9 ones // Inputs: None
// Outputs: TRUE if the header was found, FALSE if it was not found int1 header_search_em4100()
{
int bitCounter = 0;
// Loops until 9 consecutive 1s are found // or the end of the receive buffer is reached while(!END_OF_RFBUFFER) { if(RFbuffer_getBit() == 1) { if(++bitCounter == 9) { return TRUE; } } else { bitCounter = 0; } } return FALSE; }
// Purpose: Decodes the ID number and data number // Inputs: A pointer to a 5 byte array to fill
// * The first byte will have the ID // * The last 4 bytes will have the data
// Outputs: TRUE if read successful, FALSE if read failed int1 decode_data_em4100(int8* data)
{ int1 bit = 0; int8 count = 1; int1 parity = 0; int1 colParity1 = 0; int1 colParity2 = 0;
int1 colParity3 = 0; int1 colParity4 = 0;
// Loop until 40 bits of data and 10 bits of parity are received for(count=1; count <= 50; ++count)
{ bit = RFbuffer_getBit(); if(END_OF_RFBUFFER) { return FALSE; } if(count % 5 == 0) {
// Check for row parity if(parity != bit) { return FALSE; } parity = 0; } else {
// Store a bit of data shift_right(data, 5, bit); // Calculate row parity parity ^= bit;
// Calculate column parity switch (count % 5) {
case 1: colParity1 ^= bit; break; case 2: colParity2 ^= bit; break; case 3: colParity3 ^= bit; break; case 4: colParity4 ^= bit; break; }
} }
// Check for column parity
if(colParity1 != RFbuffer_getBit() || colParity2 != RFbuffer_getBit() || colParity3 != RFbuffer_getBit() || colParity4 != RFbuffer_getBit() ) {
return FALSE; }
// Check for stop bit if(RFbuffer_getBit() != 0) {
return FALSE; }
// Prevents reading all zeros for customer ID and tag ID for(count=0; count<5 && data[count] == 0; ++count); if(count == 5)
{
return FALSE; }
// Return TRUE if no errors in decoding received transponder data return TRUE;
}
Usb_descriptor.h :
////////////////////////////////////////////////////////////////// ///
/// start config descriptor
/// right now we only support one configuration descriptor. /// the config, interface, class, and endpoint goes into this array. ///
//////////////////////////////////////////////////////////////////
#DEFINE USB_TOTAL_CONFIG_LEN 32 //config+interface+class+endpoint //configuration descriptor
char const USB_CONFIG_DESC[] = { //config_descriptor for config index 1
USB_DESC_CONFIG_LEN, //length of descriptor size
USB_TOTAL_CONFIG_LEN,0, //size of all data returned for this config 1, //number of interfaces this device supports
0x01, //identifier for this configuration. (IF we had more than one configurations)
0x00, //index of string descriptor for this configuration
0xC0, //bit 6=1 if self powered, bit 5=1 if supports remote wakeup (we don't), bits 0-4 reserved and bit7=1
0x32, //maximum bus power required (maximum milliamperes/2) (0x32 = 100mA)
//interface descriptor 0 alt 0
USB_DESC_INTERFACE_LEN, //length of descriptor
USB_DESC_INTERFACE_TYPE, //constant INTERFACE (0x04)
0x00, //number defining this interface (IF we had more than one interface) 0x00, //alternate setting
2, //number of endpoints, not counting endpoint 0. 0xFF, //class code, FF = vendor defined 0xFF, //subclass code, FF = vendor 0xFF, //protocol code, FF = vendor
0x00, //index of string descriptor for interface //endpoint descriptor
USB_DESC_ENDPOINT_LEN, //length of descriptor
USB_DESC_ENDPOINT_TYPE, //constant ENDPOINT (0x05) 0x81, //endpoint number and direction (0x81 = EP1 IN)
0x02, //transfer type supported (0 is control, 1 is iso, 2 is bulk, 3 is interrupt) USB_EP1_TX_SIZE & 0xFF,USB_EP1_TX_SIZE >> 8, //maximum packet size supported
0x01, //polling interval in ms. (for interrupt transfers ONLY) //endpoint descriptor
USB_DESC_ENDPOINT_LEN, //length of descriptor
USB_DESC_ENDPOINT_TYPE, //constant ENDPOINT (0x05) 0x01, //endpoint number and direction (0x01 = EP1 OUT)
0x02, //transfer type supported (0 is control, 1 is iso, 2 is bulk, 3 is interrupt) USB_EP1_RX_SIZE & 0xFF,USB_EP1_RX_SIZE >> 8, //maximum packet size supported
0x01, //polling interval in ms. (for interrupt transfers ONLY) };
// a specific descriptor in the above table.
//NOTE: DO TO A LIMITATION OF THE CCS CODE, ALL HID INTERFACES MUST START AT 0 AND BE SEQUENTIAL
// FOR EXAMPLE, IF YOU HAVE 2 HID INTERFACES THEY MUST BE INTERFACE 0 AND INTERFACE 1
#define USB_NUM_HID_INTERFACES 0
//the maximum number of interfaces seen on any config
//for example, if config 1 has 1 interface and config 2 has 2 interfaces you must define this as 2
#define USB_MAX_NUM_INTERFACES 1
//define how many interfaces there are per config. [0] is the first config, etc. const char USB_NUM_INTERFACES[USB_NUM_CONFIGURATIONS]={1}; #if (sizeof(USB_CONFIG_DESC) != USB_TOTAL_CONFIG_LEN)
#error USB_TOTAL_CONFIG_LEN not defined correctly #endif
////////////////////////////////////////////////////////////////// ///
/// start device descriptors ///
////////////////////////////////////////////////////////////////// //device descriptor
char const USB_DEVICE_DESC[] ={
USB_DESC_DEVICE_LEN, //the length of this report 0x01, //constant DEVICE (0x01)
0x10,0x01, //usb version in bcd
0x00, //class code (if 0, interface defines class. FF is vendor defined) 0x00, //subclass code
0x00, //protocol code
USB_MAX_EP0_PACKET_LENGTH, //max packet size for endpoint 0. (SLOW SPEED SPECIFIES 8)
0xd8,0x04, //vendor id (0x04D8 is Microchip) 0x11,0x00, //product id
0x00,0x01, //device release number
0x01, //index of string description of manufacturer. therefore we point to string_1 array (see below)
0x02, //index of string descriptor of the product 0x00, //index of string descriptor of serial number
USB_NUM_CONFIGURATIONS //number of possible configurations };
////////////////////////////////////////////////////////////////// ///
/// start string descriptors
/// String 0 is a special language string, and must be defined. People in U.S.A. can leave this alone.
///
/// You must define the length else get_next_string_character() will not see the string /// Current code only supports 10 strings (0 thru 9)
///
////////////////////////////////////////////////////////////////// //the offset of the starting location of each string.
//offset[0] is the start of string 0, offset[1] is the start of string 1, etc. const char USB_STRING_DESC_OFFSET[]={0,4,12};
#define USB_STRING_DESC_COUNT sizeof(USB_STRING_DESC_OFFSET) char const USB_STRING_DESC[]={
//string 0
4, //length of string index
USB_DESC_STRING_TYPE, //descriptor type 0x03 (STRING) 0x09,0x04, //Microsoft Defined for US-English