2009年7月24日 星期五

[轉貼] Qt4.4.3 在s3c2440平台的移植

Qt4.4.3 在s3c2440平台的移植      版本1.0
首先,從http://trolltech.com/downloads下載針對嵌入式設備的Device Creation版,目前最新穩定版是
qt-embedded-linux-opensource-src-4.4.3。下面是詳細的移植步驟:

1.解壓縮
  tar zxf qt-embedded-linux-opensource-src-4.4.3.tar.gz
   cd qt-embedded-linux-opensource-src-4.4.3

2.編譯,使用系統默認的圖片庫,保留大部分常用功能,並加入tslib觸摸屏校驗的支持
./configure \
  -prefix /new_disk/weiyan/qt/build/ \  //指定安裝的目錄,與開發板上運行的目錄一致
  -release -shared \
  -fast \
  -pch \
  -no-qt3support \
  -qt-sql-sqlite \
  -no-libtiff -no-libmng \
  -qt-libjpeg \
  -qt-zlib \
  -qt-libpng \
  -qt-freetype \
  -no-openssl \
  -nomake examples -nomake demos -nomake tools\
  -optimized-qmake \
  -no-phonon \
  -no-nis \
  -no-opengl \
  -no-cups \
  -no-xcursor -no-xfixes -no-xrandr -no-xrender -no-xkb -no-sm\
  -no-xinerama -no-xshape \
  -no-separate-debug-info \
  -xplatform qws/linux-arm-g++ \
  -embedded arm \
  -depths 16 \
  -no-qvfb \
  -qt-gfx-linuxfb \
  -no-gfx-qvfb  -no-kbd-qvfb  -no-mouse-qvfb\
  -qt-kbd-usb \
  -confirm-license \
  -qt-mouse-tslib

make (或者gmake)
make install (或者gmake install)

3.設置Qt4應用程序的編譯環境
  cp bin/qmake /usr/bin

4.製作Qt4的文件系統,進行適當的裁減
  只複製必須的Qt庫
  cd $rootfs  #$rootfs 為文件系統的目錄
  mkdir new_disk/weiyan/qt/build –p && cd new_disk/weiyan/qt/build
  cp /new_disk/weiyan/qt/build/lib/libQtCore.so ./
  cp /new_disk/weiyan/qt/build/lib/libQtGui.so.4 ./
  cp /new_disk/weiyan/qt/build/lib/libQtNetwork.so.4 ./
  mkdir fonts
  只複製支持中文顯示的文泉驛字體
  cp /mnt/qt/build/lib/fonts/wenquanyi_120_50.qpf fonts

5.編譯內置的測試程序
cd $QTDIR/examples/qws/mousecalibration
qmake && make
cp mousecalibration $rootfs/new_disk/weiyan/qt/build/

6.在wy2440開發板上運行QT4測試程序
   重新生成yaffs2文件系統
   mkyaffs $rootfs rootfs.yaffs2

   已生成的文件系統大小為24M
   ll rootfs.yaffs -h
   -rw------- 1 root root  24M 2008-11-02 03:09 rootfs.qt4

在wy2440開發板上重新燒寫文件系統,進入到U-Boot
WEIYAN # run uprootfs  自動升級文件系統
WEIYAN # boot   啟動內核

設置QT4運行的環境變量
export QTDIR=/new_disk/weiyan/qt/build
export LD_LIBRARY_PATH=$QTDIR/lib:$OPIEDIR/lib
export PATH=$QTDIR/bin:$OPIEDIR/bin:$PATH
export QWS_MOUSE_PROTO=tslib:/dev/event1
export TSLIB_ROOT=/usr
export TSLIB_TSDEVICE=/dev/event1
export TSLIB_CALIBFILE=/etc/pointercal
export TSLIB_PLUGINDIR=$TSLIB_ROOT/lib/ts
export TSLIB_CONFFILE=/etc/ts.conf

執行基於Qt4的觸摸屏校驗
[root@WEIYAN /]$ ./new_disk/weiyan/qt/build/mousecalibration

2009年6月9日 星期二

MFC 學習筆記,Invalidate()、RedrawWindow()、UpdateWindow()的差異

Invalidate()是強制系統進行重繪,但是不一定就馬上進行重繪。因為Invalidate()只是通知系統,此 時的視窗已經變為無效。強制系統調用WM_PAINT,而這個消息只是Post(寄送)就是將該消息放入訊息佇列。當執行到WM_PAINT消息時才會對視窗進行重繪。

  UpdateWindow只向表單發送WM_PAINT消息,在發送之前判斷GetUpdateRect(hWnd,NULL,TRUE)看有無可繪製的 用戶端區域,如果沒有,則不發送WM_PAINT。發送即不經過訊息佇列,直接發送到對應視窗,因此此函數可以立即更新視窗。

  RedrawWindow()則是具有Invalidate()和UpdateWindow()的雙特性。聲明視窗的狀態為無效,並立即更新視窗,立即調用WM_PAINT消息處理。

MFC 學習筆記,改變Static Text的顏色、背景色

在類別,右鍵,選擇屬性

image

在屬性視窗 的訊息 WM_CTLCOLOR 加入消息函數

OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)

WMCTLCOLOR

在函數中加入對應程式碼:

if (pWnd->GetDlgCtrlID()==IDC_STATIC_S_TEXT)
{
pDC->SetTextColor(m_textColor); //設置字體顏色
pDC->SetBkMode(TRANSPARENT); //設置字體背景為透明
// TODO: Return a different brush if the default is not desired
return (HBRUSH)::GetStockObject(WHITE_BRUSH); // 設置背景色
}
else
return hbr;
其中,m_textColor是全域變數,要動態更改的方法為,在Button Click時加入:
SetDlgItemText(IDC_STATIC_S_TEXT,"OPENED");
m_textColor = RGB(255, 0, 0) ;
GetDlgItem(IDC_STATIC_S_TEXT)->RedrawWindow();
//GetDlgItem(IDC_STATIC_S_TEXT)->InvalidateRect(NULL);
設定全域變數m_textColor新的顏色, 然後呼叫RedrawWindow()或是InvalidateRect(NULL)重繪。

2009年6月3日 星期三

OpenCV 擷取Webcam

轉灰階

IplImage * GRAY = 0;
GRAY = cvCreateImage(cvSize(frame1->width,frame1->height),IPL_DEPTH_8U,1);
cvCvtColor(frame1, GRAY, CV_RGB2GRAY);
cvCvtColor(GRAY, frame1, CV_GRAY2RGB);
cvReleaseImage(&GRAY);

啟動WebCam,並指定handle給 Panel

int ncams = cvcamGetCamerasCount();
int width=640;
int height=480;
Panel1->Width = width;
Panel1->Height = height;

HWND hwnd = Panel1->Handle;

cvcamSetProperty(0, CVCAM_PROP_ENABLE, CVCAMTRUE);
cvcamSetProperty(0, CVCAM_PROP_CALLBACK,CaptureCallback);
cvcamSetProperty(0, CVCAM_PROP_WINDOW, &hwnd);
cvcamSetProperty(0,CVCAM_RNDWIDTH,&width);
cvcamSetProperty(0,CVCAM_RNDHEIGHT,&height);


cvcamGetProperty(0,CVCAM_CAMERAPROPS,NULL); // 開啟webcam設定介面

cvcamInit();
cvcamStart();

關閉WebCam

cvcamStop();

cvcamExit();

2008年9月8日 星期一

Opensource SIP Stak compared

Martin van den Berg, August 2004.
I've spend some time looking at open-source SIP stacks. There are more open-source SIP stacks on the net than described here! I was only looking at those having a LGPL alike license and written in C or C++.
The information presented on this page are my personal findings, syntisized from the resp. websites, mailing lists and sources. If you find an error or have comments or additions, please let me know: martinvdberg@gmail.com
The candidate stacks, documented in following subsections are:
* OPAL As a dual stack SIP and OpenH323, OPAL is the successor of OpenH323.
* VOCAL A stack primary used in servers - has a relationship with Cisco.
* sipX Pingtel its SIP stack, contributed to the SIPfoundry.
* reSIProcate A object oriented SIP library, written in C++. Spin-off of the VOCAL project.
* oSIP An ANSI C library, leaves control to the application.

OPAL

OPAL is the Open Phone Abstraction Library, and is the successor to OpenH323. There were a couple of architectural issues in OpenH323, especially in the area of the codecs and media channels, that required a major rewrite. OPAL is designed to be an infrastructure for any protocol, not just H.323. It enables normalized interfaces so an application can quickly use a range of "call protocols", be it H.323, SIP, PSTN hardware, PC sound cards, MGCP or whatever proprietary protocol might exist. They all look the same to the application. OPAL and OpenH323 under Mozilla Public License (MPL). A prototype SIP implementation is also included.
The long-term goal is to use OPAL instead of openH323 as primary development library. A release with verified working SIP and OpenH323 was planned in mid June 2004. At this point OPAL is in an experimental phase.
OpenH323 is big in footprint and code. A lot of functionality is covered, especially for H.323 but codecs, RTP and SDP are also included. OPAL is planned to better support re-use or removal of sub-components. The community that uses and supports OpenH323 is large. The mailing list shows a lot of activity but has its focus primarily at H.323 instead of SIP.
The whole project relies on a platform abstraction layer: the PWLIB. This library is ported (and supported) onto many platforms including VxWorks, Linux, Win32 etc...
Although the structure of the library is complex, the quality of the code looks good. It is coded in C++ and depends mainly on class hierarchies. The OPAL library is designed to realize either User Agents (endpoints), proxies (gateways) or registrars, any other than that will result in modifications.
VOCAL
VOCAL is an open-source VoIP project, hosted en contributed by Vovida.org. Vovida.org is a communications community site dedicated to providing a forum for open source software used in datacom and telecom environments. Vovida.org is a unit of Cisco.
VOCAL is not just a stack; it provides the building blocks for a VoIP system. The focus is mainly on servers such as proxy servers, redirect servers, H323-SIP translators etc... Supported platforms are Lunix and Solaris. The SIP stack however is available as a C++ object oriented library. At this moment, the stack is only partially RFC3261 compliant. The latest VOCAL version (v.1.5.0) dates from April 2003. Although not up to date, a little bit of documentation is available.
Support is available via mailing lists, which is moderated and low volume. Questions like "what features does the stack support" are unfortunately blocked. Therefore, not all facts of this stack are known.
SipX
SipX is a family of SIP related projects, hosted by SIPFoundry. SipX is completely separate from reSIProcate (also hosted by the SIPfoundry). Pingtel contributed SipX to the SIPFoundry (Feb 2004). Actually, Pingtel formed the SIPfoundry nonprofit organization to shepherd efforts to create open-source IP telephony, messaging, presence and collaboration software. Pingtel is a commercial company that makes VOIP softphones and PBX software.
The sipXtacklib is a C++ object oriented SIP stack library, licensed under LGPL. Stable releases are available.
The SipX stack is small but functional and is being used in commercial products. The stack is also designed to function in an embedded environment. The open source software however, does not include the VxWorks port. Within the SipX family a registrar, proxy and softphone are available that use the sipXtacklib. The total footprint size is approx. 4Mb, excluding features can reduce this and stripping libraries like glib.
SipX is likely to be more portable than reSIProcate since it doesn't use advanced C++ features. Like other open source projects, the libraries looked at (sipXtacklib and sipXportLib) are poorly documented. Help however is available via the mail list.
ReSIProcate
Around 2 years ago, some people got together to write a C++ SIP stack that was supposed to be a clean slate 3261-based design. This lead to vocal2, hosted within the VOCAL project (but it has never shared any core design with the VOCAL code-base). One thing led to another and the project left the VOVIDA SCM umbrella and was reborn at www.resiprocate.org using sourceforge's project tools, but independent SCM (CVS). Time passed and PingTel announced their Open Source initiative, inviting other VoIP (and specifically SIP) related projects to participate. The reSIProcate team decided, in favour of visibility to be a part of the SipFoundry - as a separate project under the SipFoundry umbrella.
reSIProcate is a high performance, object-oriented, C++ sip stack that is compliant with RFC 3261. It includes support for a wide variety of operating systems, including Windows and Linux. It has full support for UDP, TCP, and TLS transports on both IPv4 and IPv6. It also implements the full set of specifications for DNS usage in SIP, including NAPTR and SRV lookups (RFCs: 3263, 2915, 2782) using an asynchronous DNS library (ares).
The reSIProcate project (at this time) is really mostly a stack and not a set of applications & stack like some other SIP projects. reSIProcate is currently used in commercial products and is quite stable. reSIProcate is suitable for implementing one of the following SIP applications:
* Phones (e.g. embedded);
* Softphones (any platform);
* Gateways;
* Proxies;
* B2buas, or;
* IM / Presence Servers or Clients.
Commercial deployments are:
* PurpleComm (
www.purplecomm.com)
o SipDragon: Proxy, Registrar, Voicemail, Presence Server
o Windows Softphone (
http://meet2talk.com)
* Jasomi Networks (
www.jasomi.com)
o PeerPoint * CSP - Italy (
www.csp.it)
o IM/Audio/Video UA for Windows
o Conference Server and h.323 gateway in development
* Computer Talk Technology (
www.computer-talk.com)
o Evaluating use of resiprocate for Contact Center product
A reSIProcate VxWorks port is not available. It is possible to port the library under the condition that a modern compiler is used that complies with the "ANSI 2000 C++" standard since not all compilers (fully) support the partial specializations and template operations used. E.g. it is reported to be build by gcc-2.95 and VC7.0 but cannot be build by VC6.0.
The library relies of two other open source initiatives: Ares (DNS resolver) and openssl (TLS). ReSIProcate is poorly documented but has a relatively active mail list. At first glance, the library does not seem to be designed for embedded systems.
oSIP
(from http://www.gnu.org/software/osip/)
The oSIP project has started in July 2000. The first official and public release was published in May 2001.
The oSIP library is at first a free software project. In the context of the third generation network, more and more telecom operators will use IP technology, the favorite land of Linux. One aspect of this evolution is that the future of Linux is highly dependent on the multimedia tools that will be available. oSIP, as a SIP implementation, will allow building interoperable registrar, user-agent (software phones), and proxy thus giving more chance to Linux to be part of the next generation telephony products.
But oSIP is not only targeted towards PC applications. oSIP is enough flexible and tiny to be used on small OS with low requirements. From the 0.7.0 release, the thread support is now optional and the design of the application is entirely chosen by the end-developer. oSIP will fit embedded systems. oSIP is known to run on the real time OS VxWorks and other ports should be simple.
The oSIP stack is a flat ANSI-C library. Its footprint is less than 400kb for a win32 compile. The oSIP stack doesn't offer a full-blown SIP solution. Instead it provides a message parser and API only. It has no OS dependencies. Creation of threads, sockets etc... are left to the application. In other words, oSIP doesn't force a specific architecture, threading- or socket usage.
oSIP, in fact, is made up out of three separate libraries. First, there is the parser, capable of reading and writing SIP and SDP messages. The second is a transaction/session manager, which provides state machines. The API of the latter is low-level so a third library is provided that provides a higher-level API but has a GPL license.
Open-source implementations based upon oSIP are:
* linphone - a linux softphone
* partysip - SIP proxy/registrar/redirect server
* siproxd - simple linux SIP proxy
從最後的comparision看來,他是推薦osip: 又小,功能又齊,u又os independent.

2008年8月27日 星期三

[轉貼]BCB 控制 USB

#include <vcl.h>
#include <dir.h>
#include <setupapi.h>
#include "C:/WINDDK/3790/inc/ddk/w2k/usbdi.h"
#include "C:/WINDDK/3790/inc/ddk/w2k/devioctl.h"
#include <initguid.h>
//---------------------------------------------------------------------------
// 下面必須為驅動程式的 GUID 值, 這裡我亂寫的數
DEFINE_GUID(USB_DRIVER_GUID, 0x12345678,0xabcd,0x1122,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0x00);
//---------------------------------------------------------------------------
HANDLE OpenOneDevice(HDEVINFO hDvcInfo, PSP_INTERFACE_DEVICE_DATA DvcInfoData, char *sDevNameBuf)
{
  HANDLE hOut = INVALID_HANDLE_VALUE;

  ULONG  iReqLen = 0;
  SetupDiGetInterfaceDeviceDetail(hDvcInfo, DvcInfoData, NULL, 0, &amp;iReqLen, NULL);

  ULONG iDevDataLen = iReqLen; //sizeof(SP_FNCLASS_DEVICE_DATA) + 512;
  PSP_INTERFACE_DEVICE_DETAIL_DATA pDevData = (PSP_INTERFACE_DEVICE_DETAIL_DATA)malloc(iDevDataLen);

  pDevData-&gt;cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
  if(SetupDiGetInterfaceDeviceDetail(hDvcInfo, DvcInfoData, pDevData, iDevDataLen, &amp;iReqLen, NULL))
   {
     strcpy(sDevNameBuf, pDevData-&gt;DevicePath);
     hOut = CreateFile(pDevData-&gt;DevicePath, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
   }

  free(pDevData);
  return hOut;
}
//---------------------------------------------------------------------------
HANDLE OpenUsbDevice(const GUID *pGuid, char *sDevNameBuf)
{
  HANDLE hOut = INVALID_HANDLE_VALUE;

  HDEVINFO hDevInfo = SetupDiGetClassDevs(pGuid, NULL, NULL, DIGCF_PRESENT|DIGCF_INTERFACEDEVICE);

  SP_INTERFACE_DEVICE_DATA deviceInfoData;
  deviceInfoData.cbSize = sizeof (SP_INTERFACE_DEVICE_DATA);

  ULONG nGuessCount = MAXLONG;
  for(ULONG iDevIndex=0; iDevIndex
   {
     if(SetupDiEnumDeviceInterfaces(hDevInfo, 0, pGuid, iDevIndex, &amp;deviceInfoData))
      {
        if((hOut=OpenOneDevice(hDevInfo, &amp;deviceInfoData, sDevNameBuf)) != INVALID_HANDLE_VALUE)
          break;
      }
     else if(GetLastError() == ERROR_NO_MORE_ITEMS) //No more items
      {
        break;
      }
   }
  SetupDiDestroyDeviceInfoList(hDevInfo);
  return hOut;
}
//---------------------------------------------------------------------------
bool GetUsbDeviceFileName(const GUID *pGuid, char *sDevNameBuf)
{
  HANDLE hDev = OpenUsbDevice(pGuid, sDevNameBuf);
  if(hDev != INVALID_HANDLE_VALUE)
   {
     CloseHandle(hDev);
     return true;
   }
  return false;
}
//---------------------------------------------------------------------------
HANDLE OpenMyDevice()
{
  char DeviceName[MAXPATH] = "";
  return OpenUsbDevice(&amp;USB_DRIVER_GUID, DeviceName);
}
//---------------------------------------------------------------------------
HANDLE OpenMyDevPipe(const char *PipeName)
{
  char DeviceName[MAXPATH] = "";
  if(GetUsbDeviceFileName(&amp;USB_DRIVER_GUID, DeviceName))
   {
     strcat(DeviceName,"\\");
     strcat(DeviceName,PipeName);
     return CreateFile(DeviceName, GENERIC_WRITE|GENERIC_READ, FILE_SHARE_WRITE|FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
   }
  return INVALID_HANDLE_VALUE;
}
//---------------------------------------------------------------------------


//打開 USB 口讀寫, 由驅動程式的 Pipe 名確定 

HANDLE hPipe = OpenMyDevPipe("MyPipe1"); //驅動程式裡面的 Pipe 名, 對應訪問某個端點的 I/O, 這裡我亂寫的, 需要與驅動一致
if(hPipe != INVALID_HANDLE_VALUE) //打開 Pipe 成功
 {
   ReadFile(hPipe, Buffer, BufSize, &amp;nBytesRead, NULL); //從 hPipe 裡讀取數據到 Buffer 裡
   //WriteFile(hPipe, Buffer, BytesToWrite, &amp;nBytesWritten, NULL); //把 Buffer 裡面的 BytesToWrite 位元組寫入 hPipe
   CloseHandle(hPipe);
 }

//使用 DeviceIoControl 訪問 USB 設備

HANDLE hDevice = OpenMyDevice();
if(hDevice != INVALID_HANDLE_VALUE) //打開設備成功
 {
   //這些 DeviceIoControl 功能都是由設備定義的, 具體看設備和驅動的資料
   if(DeviceIoControl(hDevice, IOCTL_READ_xxxx, &amp;IOBlock, sizeof(IOBLOCK), &amp;c, 1, &amp;nBytes, NULL))
    {
      //成功
    }
   CloseHandle(hDevice);
}

USB 設備、USB 驅動、USB 應用程式

1.USB 設備硬體部分
  a.這個硬體的標識是用的 Vender ID 和 Product ID, 即“廠家標識”和“產品標識”
  b.這個硬體規定了各個 End Point (端點) 的性質, 讀/寫 及 類型 (Control/Interrupt/Bulk/Isochronous)
  c.這個硬體的固件裡面有 DeviceIoControl 的實現部分, 規定了這個函數的具體參數和動作
2.USB 設備驅動
①硬體介面
  a.需要識別 Vender ID 和 Product ID
  b.對每個 EndPoint 的每個 I/O 分配一個 Pipe, 並且起一個名字作為軟體介面
  c.做 DeviceIoControl 的介面
②軟體介面
  a.GUID, 驅動程式的標識, 每個驅動程式使用不同的 GUID, GUID 是識別驅動的, 與硬體無關 (驅動程式升級版本 GUID 不能修改)
  b.硬體介面裡面的 b: Pipe 名字是軟體介面, 這個 Pipe 名字純粹由驅動定義的, 和硬體無關, 升級驅動不能改 Pipe 的名字
  c.硬體介面裡面的 c 的各個參數也是軟體的介面, 這些參數是由硬體帶來的, 不是驅動規定的, 當然也可以在驅動裡面轉義, 隱藏設備的真實情況
③這個驅動程式是用 WinDDK 編譯的, 可以用文字編輯器或其他開發工具的編輯器編程式碼, 然後調用 WinDDK 編譯
3.讀寫 USB 口的程式
①與驅動的介面
  a.利用驅動程式裡面的 GUID 找出設備的檔案名, 用 CreateFile 函數打開設備。我前面的程式裡面的 OpenUsbDevice 就是這個作用
  b.通過 a.得到的設備檔案名和驅動程式裡面的 Pipe 名打開 Pipe, 訪問這個 Pipe 對應的 USB 端點 (讀寫資料)
  c.使用 a.的 CreateFile 得到的控制碼, 通過 DeviceIoControl 實現設備規定的動作
②有關需要的資料
  a.Vender ID, Product ID 和 GUID 一般在驅動程式的 .inf 檔裡面能看到, 如果找不到就需要和廠家聯繫
  b.Pipe 的名字是驅動程式規定的, 需要有驅動程式的資料才能知道
  c.DeviceIoControl 的參數需要有驅動程式的資料或者硬體資料才能知道
③這個程式一般用 C/C++ 直接編寫, 如果使用其他語言(VB/PB等)需要調用 C/C++ 編的 DLL


其他相關內容:

USB 驅動程式可以到註冊表裡面找到:
"HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Enum\\USB\\Vid_廠家標識&amp;Pid_產品標識\\驅動程式"

裡面的 ClassGUID 就是驅動程式的 GUID 標識, 例如 {36FC9E60-C465-11CF-8056-444553540000}
相當於程式的: DEFINE_GUID(USB_DRIVER_GUID, 0x36FC9E60,0xC465,0x11CF,0x80,0x56,0x44,0x45,0x53,0x54,0x00,0x00);
另外在這個註冊表鍵裡面還可找到有關設備的其他描述, 例如 DeviceDesc = "USB Mass Storage Device" 等