2008年11月7日 星期五

如何籍由MinGW編譯可以正確存取libusb-win32的程式?

先前在Linux上有了libusb的Library,讓Linux的使用者在發展需要存取USB裝置的應用程式時,免除了撰寫Kernel Device Driver的困擾;同樣地,在Windows上也有個libusb-win32的專案,可以至http://libusb-win32.sourceforge.net/取得,在依照其說明的安裝流程安裝後,您即可以透過libusb-win32這個Library來存取USB Device。

只是如小弟我是個Linux的愛好者,還是想擺脫Windows的牽絆,於是找到了MinGW這個專案,這是一個cross-compiler的專案,使用者可以用它在Linux平台上編譯出Windows程式,此時小弟進一步妄想:「如果可以在Linux平台上寫個程式,並且不用寫Windows Driver,那該有多好?」

為此,我抄習並略為修改libusb的測試程式,欲籍由MinGW進行編譯,結果.........找不到Device?
而libusb-win32所附的測試程式卻可以正常work?在百思不解之際,經由Jserv的協助,發現需有以下參數,方足以成功產出可以透過libusb-win32存取USB Device的程式,特此將其記錄於此....

i686-mingw32-gcc -O2 -Wall -mno-cygwin -o DLSPD.exe -I./src  DLSPD_test.c -s -mno-cygwin -L. -lusb -lgdi32 -luser32 -lcfgmgr32 -lsetupapi -lcomctl32

2008年10月27日 星期一

如何在數行內容中,插入/移除字元?

一般我們在編輯文件時,偶爾會需要對數行的內容插入或移除一些字元或符號,此時我們可以以下列的動作來完成:
1. )在vim的一般模式下,按「Ctrl + v」,此時會進入區塊選取模式。
2. )利用游標的方向鍵,選取適當的區塊。
3. )按「Shift + i」,進入插入模式。
4. )進行所需的修改。
5. )修改完後,按「ESC」結束區塊編輯模式。

2008年10月23日 星期四

How to drive usb device with libusb?

想要寫程式控制USB Device,又不想去碰Linux Driver的人有福了!您可以使用libusb來達成您的需求!

1.要透過libusb來操控USB Device,首先您需要安裝libusb。Debian的使用者操作指令如下:
-先尋找適當的usb套件。
$apt-cache search libusb
libftdi0 - Library to control and program the FTDI USB controller
libhid-dev - userspace USB HID development files
libhid0 - userspace USB HID access library
libusb++-0.1-4c2 - userspace C++ USB programming library
libusb++-dev - userspace C++ USB programming library development files
libusb-0.1-4 - userspace USB programming library
libusb-dev - userspace USB programming library development files
python-hid - Python wrapper for USB HID access library
sulu - File Mananger for Samsung Uproar and YEPP

-安裝libusb開發版本(Note:開發版才會有header file可供連結參考)
$apt-get install libusb-dev

2.撰寫程式尋找您要的USB Device。
#include

usb_dev_handle *dev_handle;

// Search device and open it
int devopen(void)
{
struct usb_bus *busses, *bus;
int c, i, a;
struct usb_device *dev;
usb_init();
usb_find_busses();
usb_find_devices();
busses = usb_get_busses();
for (bus = busses; bus; bus = bus->next) {
for (dev = bus->devices; dev; dev = dev->next) {
struct usb_device_descriptor *desc;
desc = &(dev->descriptor);
printf("Vendor/Product ID: %04x:%04x\n", desc->idVendor,
desc->idProduct);
if ((desc->idVendor == 0x1234) && (desc->idProduct == 0x4321)) {
goto a;
}
}
}
if ((bus == NULL) || (dev == NULL))
return -1;
a:
dev_handle = usb_open(dev);

if (dev_handle == NULL) {
printf("USB IO open failed.\n");
return -1;
}
usb_reset(dev_handle);
return 0;
}

// Output interface
// 0x02 is (Output direction | endpoint address).
// 2000 is time out value.
int devwrite(char *buffer, int len)
{
return usb_bulk_write(dev_handle, 0x02, buffer, len, 2000);
}

// Input interface
// 0x86 is (Input direction | endpoint address).
int devread(char *buffer, int len)
{
return usb_bulk_read(dev_handle, 0x86, buffer, len, 2000);
}

int main(void)
{
int result = 0;
char write_buffer[10] = {0};
char read_buffer[10] = {0};

result = devopen();
if (result < 0)
{
printf("Can't open usb device.\n");
} else
{
// send command to usb device.
write_buffer[0] = 0x0B;
write_buffer[1] = 0x01;
write_buffer[2] = 0x02;
result = devwrite(write_buffer, 3);
if (result == 3)
{
// get response from usb device
result = devread(read_buffer, 10);
}
}
return 0;
}

3.編譯上述程式
gcc -g -O0 -o xxx xxx.c -lusb

4.請使用Superuser權限執行它。或者將其檔案屬性進行變更。
chown root xxx
chgrp root xxx
chmod +s xxx

透過上述的機制,您將可以不用撰寫Linux USB Device Driver,即可操作Device Driver。


參考資料:
‧Jollen的Bolg--"libusb 簡介與第一個範例" (http://www.jollen.org/blog/2008/01/libusb_hello_world.html)
‧libusb Developers Guide (http://libusb.sourceforge.net/doc/index.html)
‧testlibusb.c (在libusb的source code中)

感謝Jserv的建議與協助,讓偶有機會做此嘗試。

2008年9月3日 星期三

如何bypass指令給remote target,而不需要修改gdb程式

在使用gdb進行debug時,有時會想對remote端的target下達一些指令,做一些功能的開關,為了達成這個要求,除了修改gdb內部target dependence的檔案remote-target.c外,可以有另一項選擇。
只要您所選擇的target平台有支援qRcmd,您即可使用monitor指令來達成。當user使用monitor指令時,gdb將bypass後面的字串給remote端的target平台,而不做其它額外的處理,使用者可以籍由這個指令,簡單的對target端下達特定的指令,而不需要更動到gdb原有的程式。

2008年7月24日 星期四

如何在stable版的Debian中使用MSN?

雖然MSN不是偶常用的IM,不過由於太多的朋友都使用它,因此也不得不想辦法解決Linux上使用MSN的問題,在早期的Linux上,原本是可以使用gaim這個套件來達成,後來該組織將套件改名為PidGin(詳細改名原因請自行至該網站查詢),PidGin目前僅在Debian testing/unstable版本中存在,在stable版本中使用apt-cache search pidgin會找不到該套件,此時您可以使用下列的步驟來達成:

1.)在/etc/apt/source.list檔案中加入下列一行:
deb http://www.backports.org/debian etch-backports main

2.)存檔後,使用apt-get update來更新套件列表。

3.)再次使用apt-cache search pidgin即可看到
debian:/etc/apt# apt-cache search pidgin
pidgin - graphical multi-protocol instant messaging client for X
pidgin-data - multi-protocol instant messaging client - data files
pidgin-dbg - Debugging symbols for Pidgin
pidgin-dev - multi-protocol instant messaging client - development files

4.)使用apt-get install pidgin即可完成安裝。

5.)別忘了再到/etc/apt/source.list檔中,把加入的位址Disable掉。
#deb http://www.backports.org/debian etch-backports main
(因為這個位址裡的套件尚未達到stable版本的要求,只是為了使用者的需求,使用stable版本的Toolchain及Library重新編譯過而以,並不建議大量使用此處的套件)

2008年7月23日 星期三

Preprocessor Variables of C/C++

下列是C/C++語言標準的前置定義變數,它們在程式編譯的Preprocessing階段,會被置換成特定的字串:
__FILE__:程式所在檔案的名稱。
__LINE__:程式所在檔案內的行號。
__DATE__:程式被編譯的日期(mm dd yyyy)。
__TIME__:程式被編譯的時間(hh:mm:ss)。
__TIMESTAMP__:程式被編譯的日期與時間(mm dd yyyy hh:mm:ss)。
__FUNCTION__:程式所在的函式名稱。(這在C99才有定義,並非所有的編譯器都有支援)

2008年7月22日 星期二

在gdb中如何立即查尋變數的型別?

我們在使用gdb進行trace code時,時常會在過程中想要了解某個變數的型別為何?
此時我們可以利用下列指令來達成:
(gdb)ptype variable