??xml version="1.0" encoding="utf-8" standalone="yes"?>777午夜精品久久av蜜臀,国产精品一区二区久久精品无码 ,久久国产成人亚洲精品影院http://www.shnenglu.com/zjj2816/zh-cnThu, 08 May 2025 20:59:03 GMTThu, 08 May 2025 20:59:03 GMT60Write HBITMAP Object in to BMP File ?/title><link>http://www.shnenglu.com/zjj2816/archive/2009/02/16/73921.html</link><dc:creator>井泉</dc:creator><author>井泉</author><pubDate>Mon, 16 Feb 2009 03:32:00 GMT</pubDate><guid>http://www.shnenglu.com/zjj2816/archive/2009/02/16/73921.html</guid><wfw:comment>http://www.shnenglu.com/zjj2816/comments/73921.html</wfw:comment><comments>http://www.shnenglu.com/zjj2816/archive/2009/02/16/73921.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.shnenglu.com/zjj2816/comments/commentRss/73921.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/zjj2816/services/trackbacks/73921.html</trackback:ping><description><![CDATA[<font face=Arial size=2>void WriteBMPFile(HBITMAP bitmap, LPTSTR filename, HDC hDC)<br>{<br>BITMAP bmp; <br>PBITMAPINFO pbmi; <br>WORD cClrBits; <br>HANDLE hf; // file handle <br>BITMAPFILEHEADER hdr; // bitmap file-header <br>PBITMAPINFOHEADER pbih; // bitmap info-header <br>LPBYTE lpBits; // memory pointer <br>DWORD dwTotal; // total count of bytes <br>DWORD cb; // incremental count of bytes <br>BYTE *hp; // byte pointer <br>DWORD dwTmp; <br><br>// create the bitmapinfo header information<br><br>if (!GetObject( (bitmap, sizeof(BITMAP), (LPSTR)&bmp)){<br>AfxMessageBox("Could not retrieve bitmap info");<br>return;<br>}<br><br>// Convert the color format to a count of bits. <br>cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel); <br>if (cClrBits == 1) <br>cClrBits = 1; <br>else if (cClrBits <= 4) <br>cClrBits = 4; <br>else if (cClrBits <= 8) <br>cClrBits = 8; <br>else if (cClrBits <= 16) <br>cClrBits = 16; <br>else if (cClrBits <= 24) <br>cClrBits = 24; <br>else cClrBits = 32; </font><br><font face=Arial size=2>// Allocate memory for the BITMAPINFO structure.<br>if (cClrBits != 24) <br>pbmi = (PBITMAPINFO) LocalAlloc(LPTR, <br>sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * (1<< cClrBits)); <br>else <br>pbmi = (PBITMAPINFO) LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER)); <br><br>// Initialize the fields in the BITMAPINFO structure. <br><br>pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); <br>pbmi->bmiHeader.biWidth = bmp.bmWidth; <br>pbmi->bmiHeader.biHeight = bmp.bmHeight; <br>pbmi->bmiHeader.biPlanes = bmp.bmPlanes; <br>pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel; <br>if (cClrBits < 24) <br>pbmi->bmiHeader.biClrUsed = (1<<cClrBits); <br><br>// If the bitmap is not compressed, set the BI_RGB flag. <br>pbmi->bmiHeader.biCompression = BI_RGB; <br><br>// Compute the number of bytes in the array of color <br>// indices and store the result in biSizeImage. <br>pbmi->bmiHeader.biSizeImage = (pbmi->bmiHeader.biWidth + 7) /8 * pbmi->bmiHeader.biHeight * cClrBits; <br>// Set biClrImportant to 0, indicating that all of the <br>// device colors are important. <br>pbmi->bmiHeader.biClrImportant = 0; <br><br>// now open file and save the data<br>pbih = (PBITMAPINFOHEADER) pbmi; <br>lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage);<br><br>if (!lpBits) {<br>AfxMessageBox("writeBMP::Could not allocate memory");<br>return;<br>}<br><br>// Retrieve the color table (RGBQUAD array) and the bits <br>if (!GetDIBits(hDC, HBITMAP(bitmap), 0, (WORD) pbih->biHeight, lpBits, pbmi, <br>DIB_RGB_COLORS)) {<br>AfxMessageBox("writeBMP::GetDIB error");<br>return;<br>}<br><br>// Create the .BMP file. <br>hf = CreateFile(filename, GENERIC_READ | GENERIC_WRITE, (DWORD) 0, <br>NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, <br>(HANDLE) NULL); <br>if (hf == INVALID_HANDLE_VALUE){<br>AfxMessageBox("Could not create file for writing");<br>return;<br>}<br>hdr.bfType = 0x4d42; // 0x42 = "B" 0x4d = "M" <br>// Compute the size of the entire file. <br>hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) + <br>pbih->biSize + pbih->biClrUsed <br>* sizeof(RGBQUAD) + pbih->biSizeImage); <br>hdr.bfReserved1 = 0; <br>hdr.bfReserved2 = 0; <br><br>// Compute the offset to the array of color indices. <br>hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + <br>pbih->biSize + pbih->biClrUsed <br>* sizeof (RGBQUAD); <br><br>// Copy the BITMAPFILEHEADER into the .BMP file. <br>if (!WriteFile(hf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER), <br>(LPDWORD) &dwTmp, NULL)) {<br>AfxMessageBox("Could not write in to file");<br>return;<br>}<br><br>// Copy the BITMAPINFOHEADER and RGBQUAD array into the file. <br>if (!WriteFile(hf, (LPVOID) pbih, sizeof(BITMAPINFOHEADER) <br>+ pbih->biClrUsed * sizeof (RGBQUAD), <br>(LPDWORD) &dwTmp, ( NULL))){<br>AfxMessageBox("Could not write in to file");<br>return;<br>}<br><br><br>// Copy the array of color indices into the .BMP file. <br>dwTotal = cb = pbih->biSizeImage; <br>hp = lpBits; <br>if (!WriteFile(hf, (LPSTR) hp, (int) cb, (LPDWORD) &dwTmp,NULL)){<br>AfxMessageBox("Could not write in to file");<br>return;<br>}<br><br>// Close the .BMP file. <br>if (!CloseHandle(hf)){<br>AfxMessageBox("Could not close file");<br>return;<br>}<br><br>// Free memory. <br>GlobalFree((HGLOBAL)lpBits);<br>}</font> <img src ="http://www.shnenglu.com/zjj2816/aggbug/73921.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/zjj2816/" target="_blank">井泉</a> 2009-02-16 11:32 <a href="http://www.shnenglu.com/zjj2816/archive/2009/02/16/73921.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用VS2008 Feature Pack 修改(zhn)现有的Visual C++的程序界??/title><link>http://www.shnenglu.com/zjj2816/archive/2009/01/09/71593.html</link><dc:creator>井泉</dc:creator><author>井泉</author><pubDate>Fri, 09 Jan 2009 05:51:00 GMT</pubDate><guid>http://www.shnenglu.com/zjj2816/archive/2009/01/09/71593.html</guid><wfw:comment>http://www.shnenglu.com/zjj2816/comments/71593.html</wfw:comment><comments>http://www.shnenglu.com/zjj2816/archive/2009/01/09/71593.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.shnenglu.com/zjj2816/comments/commentRss/71593.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/zjj2816/services/trackbacks/71593.html</trackback:ping><description><![CDATA[上次l大家介l了(jin)Visual C++ 2008 的Feature Pack的界面库新特性。今天给大家介绍一下,怎样用Feature Pack把?zhn)现有的Visual C++ E序界面修改得漂亮些?br> <br>       所需的修改环境:(x)<br>       Visual C++ 2008  (Team Suite版Express版都可以Q但必须是英文版Q否则Feature Pack不支?<br>       正确的安装了(jin)Visual C++ 2008 Feature Pack beta<br>       (zhn)要修改的Visual C++ 的程序源代码工程<br> <br>       具备?jin)以上三点就可以开始进行修Ҏ(gu)作了(jin)。但是有一Ҏ(gu)h意,那就是?zhn)E序中是否用C(jin)MS C++ 9.0 ~译器不再支持的语法Ҏ(gu)?如果有,那很不幸Q我个h不推荐?zhn)升?zhn)的E序界面Q毕竟程序运行的E_性才是最重要的。ؓ(f)?jin)漂亮的界面修改已经试qƈE_ q行的代码,可不是一个明智的选择?br> <br>       下面我就用一个Visual C++的入门Demo <a target="_blank">Scribble</a> 来修攏V这个Scribble(zhn)可以在MSDN|站上下载到Q但h注意Q我l出的这个下载工E是VS2005 for x64的。下载后Q?zhn)需要进行以下改动:(x)<br>        1) Scribble工程属性中QC/C++~译器的Treat Warnings as error 关闭Q否则?zhn)的工E将?x)因Z个Warning没有解决Q导致整个程序编译失败。如图:(x)<br>         <img src="http://images.cnblogs.com/cnblogs_com/michaellee/disable_WX.jpg" alt="" border="0" height="530" width="762"><br> <br>       2) ~译ӞTarget 改ؓ(f)Win32;<br> <br>       |嗦?jin)这么多Q开始修改吧Q?br> <br>       W一? L(fng)定CScribbleApp::InitialInstance() Ҏ(gu)中已l调用了(jin)AfxOleInit();<br>       W二? 在stdafx.h文g中加?#include"afxcontrolbars.h" ,q头文g包含?jin)Feature Pack新增的界面类声明;<br>       W三步:(x)修改CScribbleAppcȝ承的父类Q由CWinApp改ؓ(f)CWinAppEx;q个CWinAppExcLCWinApp? 加了(jin)很多的功能,说个单的QCWinAppEx提供?jin)一个SetRegistryBaseҎ(gu)Q这个方法可以用来设定当前App所使用的注册表的根?br>       W四步:(x)修改L架类Q将CMainFrame的父cȝCMDIFrameWnd改ؓ(f)CMDIFrameWndEx;q个修改设计到类声明? IMPLEMENT_DYNAMIC宏、MESSAGE_MAP宏、OnCreate函数{调用到?rn)态方法的地方、以?qing)其它等{。最好是直接? Replace all文本替换?<br>       W五步:(x)CMDIChildWndcL换ؓ(f)CMDIChildWndEx,L架换?jin),子窗体也要?<br>       W六步:(x)替换CTooBar为CMFCTooBarQ替换CStatusBar为CMFCStatusBar;是修改一下m_wndStatusBar和m_wndToolBar两个变量的声明处;<br>       W七步:(x)替换CMainFrame::OnCreate()函数中m_wndToolBar 和m_wndStatusBar停靠的相关代?Set/Get BarStyle改ؓ(f)Set/Get PaneStyle 也是文本替换一下,很简单。将DockControlBar(&m_wndStatusBar);改ؓ(f) DockPane(&m_wndStatusBar);<br>       完成以上七步,基本攚w就完成了(jin)。但是如果?zhn)现在~译(zhn)的E序Q?zhn)会(x)发现Scribble界面基本上没有Q何改变。下面的才是更重要的Q我们要dRibbonBar?jin)?x)<br> <br>       W一步:(x)在CMainFramecM声明一个CMFCRibbonBarcd的变量m_wndRibbonBar。这个变量就代表Office2007界面里面那个替代?jin)菜单的东?<br>       W二步:(x)在CMainFramecM声明一个CMFCRibbonApplicationButton的变量m_MainButton。这个变量代表了(jin)Office2007界面左上角那个Home按钮;<br>       W三步:(x)在CMainFrame::OnCreate函数中添加代码。首先是创徏RibbonBar对象Q老规矩:(x)<br>       if(!m_wndRibbonBar.Create(this))<br>       {<br>           return -1;<br>       }<br>       W四步:(x)讑֮m_MainButton对象Q?br>       m_MainButton.SetImage(……);   //讑֮图标<br>       m_MainButton.SetToolTipText(……); //讑֮提示文本<br>       m_MainButton.SetText(……);   //讑֮按钮文本<br>       W五步:(x)在CMainFrame::OnCreate函数中添加代码,通过RibbonBar对象d一个Category:<br>       CMFCRibbonMainPanel *pMainPanel = m_wndRibbonBar.AddMainCategory(_T("File"));<br>       q实际上qg创徏?jin)一个名为File的主菜单?<br>       W六步:(x)l这个Paneld按钮(其实是子菜单项)Q?br>       pMainPanel->Add(new CMFCRibbonButton(ID_FILE_OPEN,_T("打开")));<br>       ……<br>       W七步:(x)<br>       在CMainFrame::OnCreate()函数的最后部?d代码讑֮当前界面的风|(x)<br>       CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerOffice2007));<br>       CMFCVisualManagerOffice2007::SetStyle(CMFCVisualManagerOffice2007::Office2007Luna_Blue);<br>       代码的第一行用来设定可视化理器ؓ(f)Office2007cdQ可供选择的还有OfficXP、Office2003、VS2005 三种,换句话说Q我们可以将我们的程序界面修改ؓ(f)Office2007、Office2003、OfficeXP、VS2005四种风格;<br>       代码的第二行用来讑֮Office2007界面的色?<br>       完成以上步骤后,可以编译运行啦Q看看界面是不是改变?sh)(jin)呢Q?br>       修改前:(x)<br>       <img src="http://images.cnblogs.com/cnblogs_com/michaellee/Scribble1.jpg" alt="" border="0" height="484" width="702"><br> <br>       修改后:(x)<br>       <img src="http://images.cnblogs.com/cnblogs_com/michaellee/Scribble2.jpg" alt="" border="0" height="486" width="705"><br> <br>       我没有找到比较好看的图标Q也没有把菜单都实现出来Q仅仅是作ؓ(f)一个演C。相信在工的帮助下Q我们的MFCE序界面一定会(x)漂亮h的?br> <br>       说到最后,我要提醒大家一下,发布E序前,已经要静(rn)态链接MFC的库。在现在VC8.0 的RTM不普及(qing)的情况下Q就别指望?zhn)的用户安装部|了(jin)支持Feature Packe的FTM库了(jin)。粗_看?jin)一下,一个用向导生成的支持Feature Pack的Application(是的Q安装了(jin)Feature Pack在用AppWizard生新E序的时?可以指定Feature Pack支持?Q什么代码都不加Q静(rn)态编译一般在6M-8M之间(q算可以接受的说)?br>       <img src="http://images.cnblogs.com/cnblogs_com/michaellee/Scribble_3.jpg" alt="" border="0" height="530" width="761"><br>      <img src ="http://www.shnenglu.com/zjj2816/aggbug/71593.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/zjj2816/" target="_blank">井泉</a> 2009-01-09 13:51 <a href="http://www.shnenglu.com/zjj2816/archive/2009/01/09/71593.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>.net制作的wap|站在手Z的测??/title><link>http://www.shnenglu.com/zjj2816/archive/2008/12/31/70830.html</link><dc:creator>井泉</dc:creator><author>井泉</author><pubDate>Wed, 31 Dec 2008 02:46:00 GMT</pubDate><guid>http://www.shnenglu.com/zjj2816/archive/2008/12/31/70830.html</guid><wfw:comment>http://www.shnenglu.com/zjj2816/comments/70830.html</wfw:comment><comments>http://www.shnenglu.com/zjj2816/archive/2008/12/31/70830.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.shnenglu.com/zjj2816/comments/commentRss/70830.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/zjj2816/services/trackbacks/70830.html</trackback:ping><description><![CDATA[<p style="text-align: left;">讉Ka(chn)sp站点的时候会(x)Ҏ(gu)讉K的设?输出不同的内?如果用IE讉Kp出的是html,手机讉K,输出是WML。是什么让他这么智能化呢?关键之处在配置文g?span style="color: #0000ff;"><</span><span style="color: #800000;">browserCaps</span><span style="color: #0000ff;">>节!</span></p> <p style="text-align: left;"><span style="color: #0000ff;">在webconfig中加上这个,他可以强制输出wmlQ还有其他的Ud讄属性都在这?/span></p> <p style="text-align: left;"><span style="color: #0000ff;"><span style="color: #0000ff;"><</span><span style="color: #800000;">browserCaps</span><span style="color: #0000ff;">></span><span style="color: #000000;"><br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            </span><span style="color: #0000ff;"><</span><span style="color: #800000;">result </span><span style="color: #ff0000;">type</span><span style="color: #0000ff;">="System.Web.Mobile.MobileCapabilities, System.Web.Mobile, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"</span><span style="color: #0000ff;">/></span><span style="color: #000000;"><br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            </span><span style="color: #0000ff;"><</span><span style="color: #800000;">use </span><span style="color: #ff0000;">var</span><span style="color: #0000ff;">="HTTP_USER_AGENT"</span><span style="color: #0000ff;">/></span><span style="color: #000000;"><br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11"><br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            browser=Unknown<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            version=0.0<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            majorversion=0<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            minorversion=0<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            frames=false<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            tables=false<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            cookies=false<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            backgroundsounds=false<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            vbscript=false<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            javascript=false<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            javaapplets=false<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            activexcontrols=false<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            win16=false<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            win32=false<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            beta=false<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            ak=false<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            sk=false<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            aol=false<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            crawler=false<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            cdf=false<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            gold=false<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            authenticodeupdate=false<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            tagwriter=System.Web.UI.Html32TextWriter<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            ecmascriptversion=0.0<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            msdomversion=0.0<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            w3cdomversion=0.0<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            platform=Unknown<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            css1=false<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            css2=false<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            xml=false<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11"><br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            mobileDeviceManufacturer = "Unknown"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            mobileDeviceModel = "Unknown"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11"><br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            gatewayVersion = "None"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            gatewayMajorVersion = "0"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            gatewayMinorVersion = "0"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11"><br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">           preferredRenderingType = "wml11"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">           preferredRenderingMime = "text/vnd.wap.wml"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">           preferredImageMime = "image/vnd.wap.wbmp"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11"><br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            defaultScreenCharactersWidth = "12"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            defaultScreenCharactersHeight = "6"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            defaultScreenPixelsWidth = "96"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            defaultScreenPixelsHeight = "72"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            defaultCharacterWidth = "8"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            defaultCharacterHeight = "12"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            screenBitDepth = "1"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            isColor = "false"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            inputType = "telephoneKeypad"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11"><br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            numberOfSoftkeys = "0"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            maximumSoftkeyLabelLength = "5"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11"><br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            canInitiateVoiceCall = "false"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11"><br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            canSendMail = "true"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            hasBackButton = "true"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            rendersWmlDoAcceptsInline = "true"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            rendersWmlSelectsAsMenuCards = "true"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            rendersBreaksAfterWmlAnchor = "false"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            rendersBreaksAfterWmlInput = "false"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            rendersBreakBeforeWmlSelectAndInput = "true"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            requiresAttributeColonSubstitution = "true"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            requiresPhoneNumbersAsPlainText = "false"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            requiresUrlEncodedPostfieldValues = "false"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            requiredMetaTagNameValue = ""<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            rendersBreaksAfterHtmlLists = "true"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            requiresUniqueHtmlCheckboxNames = "true"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            requiresUniqueHtmlInputNames = "true"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            requiresUniqueFilePathSuffix = "true"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            supportsCss = "false"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            hidesRightAlignedMultiselectScrollbars = "false"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            canRenderAfterInputOrSelectElement = "true"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            canRenderInputAndSelectElementsTogether = "true"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            canRenderOneventAndPrevElementsTogether = "true"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            canCombineFormsInDeck = "true"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            canRenderMixedSelects = "true"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            canRenderPostBackCards = "true"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            canRenderSetvarZeroWithMultiSelectionList = "true"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            supportsImageSubmit = "true"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            supportsSelectMultiple = "true"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            requiresHtmlAdaptiveErrorReporting = "false"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            requiresContentTypeMetaTag = "false"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            requiresDBCSCharacter = "false"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            requiresOutputOptimization = "false"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            supportsAccesskeyAttribute = "false"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            supportsInputIStyle = "false"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            supportsInputMode = "false"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            supportsIModeSymbols = "false"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            supportsJPhoneSymbols = "false"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            supportsJPhoneMultiMediaAttributes = "false"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            maximumRenderedPageSize = "2000"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            requiresSpecialViewStateEncoding = "false"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            requiresNoBreakInFormatting = "false"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            requiresLeadingPageBreak = "false"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            supportsQueryStringInFormAction = "true"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            supportsCacheControlMetaTag = "true"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            supportsUncheck = "true"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            canRenderEmptySelects = "true"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            supportsRedirectWithCookie = "true"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            supportsEmptyStringInCookieValue = "true"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            cachesAllResponsesWithExpires = "false"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            requiresNoSoftkeyLabels = "false"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            defaultSubmitButtonLimit = "1"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            <br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            supportsBold = "false"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            supportsItalic = "false"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            supportsFontSize = "false"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            supportsFontName = "false"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            supportsFontColor = "true"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            supportsBodyColor = "true"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            supportsDivAlign = "true"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            supportsDivNoWrap = "false"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            supportsCharacterEntityEncoding = "true"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11"><br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">            isMobileDevice="false"<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11"></span><span style="color: #0000ff;"></</span><span style="color: #800000;">browserCaps</span><span style="color: #0000ff;">></span> </span><span style="color: #000000;"><br> </span>另外通过讄<br>          Page.Response.Expires <span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #000000;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br> <img src="http://www.aspxclub.com/UploadFile/Material/1/3974.gif" alt="" align="top" height="16" width="11">   Response.CacheControl </span><span style="color: #000000;">=</span><span style="color: #000000;"> </span><span style="color: #000000;">"</span><span style="color: #000000;">Public</span><span style="color: #000000;">"</span><span style="color: #000000;">;</span> <br> 可以<strong>取消Ud讑֤~存Qƈ通过</strong>RedirectToMobilePage函数q行重定向?/p><img src ="http://www.shnenglu.com/zjj2816/aggbug/70830.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/zjj2816/" target="_blank">井泉</a> 2008-12-31 10:46 <a href="http://www.shnenglu.com/zjj2816/archive/2008/12/31/70830.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>WINCE Driver and BSP Develop Blog ?/title><link>http://www.shnenglu.com/zjj2816/archive/2008/12/24/70243.html</link><dc:creator>井泉</dc:creator><author>井泉</author><pubDate>Wed, 24 Dec 2008 07:12:00 GMT</pubDate><guid>http://www.shnenglu.com/zjj2816/archive/2008/12/24/70243.html</guid><wfw:comment>http://www.shnenglu.com/zjj2816/comments/70243.html</wfw:comment><comments>http://www.shnenglu.com/zjj2816/archive/2008/12/24/70243.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/zjj2816/comments/commentRss/70243.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/zjj2816/services/trackbacks/70243.html</trackback:ping><description><![CDATA[<h3 class="post-title"> 开发优U的驱动程? </h3> <div id="ndn7n3f" class="post-body"> <div> <p class="MsoNormal" style="text-indent: 21pt;"><span style="font-family: ?hu)?">作ؓ(f)驱动开发工E师</span><span lang="EN-US">,</span><span style="font-family: ?hu)?">我们需要在每一行代码上下功?/span><span lang="EN-US">,</span><span style="font-family: ?hu)?">因ؓ(f)驱动E序的效率直接媄(jing)响着pȝ的性能</span><span lang="EN-US">.</span><span style="font-family: ?hu)?">而新手往往不会(x)注意到这些细节。以为功能实C后就万事大吉?jin),其实不然Q好的驱动程序不只是能实现预期的功能。它同样需要高的效率与规范的风根{用戯׃我们pȝ是给?/span><span lang="EN-US">/</span><span style="font-family: ?hu)?">她做事的Q而不是给我们做测试的Q所以我们要可能提高效率。同时好的代码风D大大降低我们自己的维护成本?/span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span></span><span style="font-family: ?hu)?">高效率看似容易,但要注意到每个细节还是挺隄Q我们可以从以下几点L意这个问题:(x)</span></p> <p class="MsoNormal" style="margin-left: 18pt; text-indent: -18pt;"><!--[if !supportLists]--><span lang="EN-US"><span>1Q?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> </span></span></span><!--[endif]--><span style="font-family: ?hu)?">不要使用无关的代码,q点Ҏ(gu)理解Q尤其是调试代码Q?/span><span lang="EN-US">RELEASE</span><span style="font-family: ?hu)?">时一定要去除q些代码?/span></p> <p class="MsoNormal" style="margin-left: 18pt; text-indent: -18pt;"><!--[if !supportLists]--><span lang="EN-US"><span>2Q?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> </span></span></span><!--[endif]--><span style="font-family: ?hu)?">L多余的函数调用,可能的保存?sh)些数据。即使是最快的函数Q调用它时也?x)引发压栈与出栈Q所以要量做函数调用。当然如果一个函数返回的数据比较大,保存那些数据占用比较多的内在空_(d)保存q回值就得不偿失?jin)。比如,看到有的人每ơ在使用一个地址时就调用</span><span lang="EN-US">MmmapIoSpace</span><span style="font-family: ?hu)?">这个地址映射到程序地址I间Q用完以后又立即</span><span lang="EN-US">Unmap</span><span style="font-family: ?hu)?">q个地址Q下ơ用时又做</span><span lang="EN-US">MAP</span><span style="font-family: ?hu)?">Q这是一U及(qing)不好的方法,每次需要多调用两个pȝ函数?/span></p> <p class="MsoNormal"><span lang="EN-US">3</span><span style="font-family: ?hu)?">Q如果可行,不要在@环中使用条g判断Q尤其在一个次数很多的循环中更应该如此?/span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span></span><span style="font-family: ?hu)?">比如Q?/span></p> <p class="MsoNormal" style="text-indent: 21.75pt;"><span lang="EN-US">For( i=0; i<1000;></span></p> <p class="MsoNormal" style="text-indent: 21.75pt;"><span lang="EN-US"><span> </span>If( m==1)<span> </span>..</span></p> <p class="MsoNormal" style="text-indent: 21.75pt;"><span lang="EN-US"><span> </span>Else if (m==2 )….</span></p> <p class="MsoNormal" style="text-indent: 21.75pt;"><span lang="EN-US"><span> </span>Else …..</span></p> <p class="MsoNormal" style="text-indent: 21.75pt;"><span lang="EN-US">}</span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span></span><span style="font-family: ?hu)?">q种代码Q我们可以把</span><span lang="EN-US">If </span><span style="font-family: ?hu)?">写在</span><span lang="EN-US">for </span><span style="font-family: ?hu)?">之外Q即Q每一U不同的条g写一个@环体?/span></p> <p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p> <p class="MsoNormal" style="text-indent: 21.75pt;"><span lang="EN-US"><span> </span>If( m==1)<span> </span>for ...</span></p> <p class="MsoNormal" style="text-indent: 21.75pt;"><span lang="EN-US"><span> </span>Else if (m==2 )<span> </span>for ….</span></p> <p class="MsoNormal" style="text-indent: 21.75pt;"><span lang="EN-US"><span> </span>Else<span> </span>for …..</span></p> <p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p> <p class="blogger-labels">标签Q?<a rel="tag">E序技?/a></p> </div> </div> <p class="post-footer"> <em>张脓(chung)者:(x)Blog by Braden @ <a title="permanent link">5/07/2007 07:56:00 上午</a></em>   <a class="comment-link" location.><span style="text-transform: lowercase;">0 条评?/span></a> <a class="comment-link"><span style="text-transform: lowercase;">指向此帖子的链接</span></a> <span id="nhzzd1v" class="item-action"><a title="以电(sh)子邮件发送帖?><img src="http://www.blogger.com/img/icon18_email.gif" class="icon-action" alt="" height="13" width="18"></a></span><span id="xzpzjlx" class="item-control blog-admin pid-2106978906"><a style="border: medium none ;" title="修改帖子"><img src="http://www.blogger.com/img/icon18_edit_allbkg.gif" class="icon-action" alt="" height="18" width="18"></a></span> </p> <!-- End .post --> <!-- Begin #comments --> <!-- End #comments --> <h2 class="date-header">2007-03-10</h2> <!-- Begin .post --> <div id="jnvx9pf" class="post"><a name="216214469836542308"></a> <h3 class="post-title"> 开发DMA驱动 </h3> <div id="135r7fd" class="post-body"> <div> <span lang="EN-US"><span> </span></span><span style="font-family: ?hu)?">使用</span><span lang="EN-US">DMA</span><span style="font-family: ?hu)?">的好处就是它不需?/span><span lang="EN-US">CPU</span><span style="font-family: ?hu)?">的干预而直接服务外设,q样</span><span lang="EN-US">CPU</span><span style="font-family: ?hu)?">可以去处理别的事务Q从而提高系l的效率Q对于慢速设备,?/span><span lang="EN-US">UART</span><span style="font-family: ?hu)?">Q其作用只是降低</span><span lang="EN-US">CPU</span><span style="font-family: ?hu)?">的用率Q但对于高速设备,如硬盘,它不只是降低</span><span lang="EN-US">CPU</span><span style="font-family: ?hu)?">的用率Q而且能大大提高硬件设备的吞吐量。因为对于这U设备,</span><span lang="EN-US">CPU</span><span style="font-family: ?hu)?">直接供应数据的速度太低?/span> <p class="MsoNormal"><span lang="EN-US"><span> </span></span><span style="font-family: ?hu)?">?/span><span lang="EN-US">CPU</span><span style="font-family: ?hu)?">只能一个ȝ周期最多存取一ơȝQ而且对于</span><span lang="EN-US">ARM</span><span style="font-family: ?hu)?">Q它不能把内存(sh)</span><span lang="EN-US">A</span><span style="font-family: ?hu)?">地址的值直接搬?/span><span lang="EN-US">B</span><span style="font-family: ?hu)?">地址。它只能先把</span><span lang="EN-US">A</span><span style="font-family: ?hu)?">地址的值搬C个寄存器Q然后再从这个寄存器搬到</span><span lang="EN-US">B</span><span style="font-family: ?hu)?">地址。也是_(d)对于</span><span lang="EN-US">ARM</span><span style="font-family: ?hu)?">Q要p两个ȝ周期才能?/span><span lang="EN-US">A</span><span style="font-family: ?hu)?">地址的值送到</span><span lang="EN-US">B</span><span style="font-family: ?hu)?">地址。?/span><span lang="EN-US">DMA</span><span style="font-family: ?hu)?">׃同了(jin)Q一般系l中?/span><span lang="EN-US">DMA</span><span style="font-family: ?hu)?">都有H发Q?/span><span lang="EN-US">Burst</span><span style="font-family: ?hu)?">Q传输的能力Q在q种模式下,</span><span lang="EN-US">DMA</span><span style="font-family: ?hu)?">能一ơ传输几个甚臛_十个字节的数据,所以?/span><span lang="EN-US">DMA</span><span style="font-family: ?hu)?">能讑֤的吞吐能力大为增强?/span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span></span><span style="font-family: ?hu)?">使用</span><span lang="EN-US">DMA</span><span style="font-family: ?hu)?">时我们必要注意如下事实Q?/span></p> <p class="MsoNormal" style="margin-left: 18pt; text-indent: -18pt;"><!--[if !supportLists]--><span lang="EN-US"><span>1Q?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> </span></span></span><!--[endif]--><span lang="EN-US">DMA</span><span style="font-family: ?hu)?">使用物理地址Q程序是使用虚拟地址的,所以配|?/span><span lang="EN-US">DMA</span><span style="font-family: ?hu)?">时必d虚拟地址转化成物理地址?/span></p> <p class="MsoNormal" style="margin-left: 18pt; text-indent: -18pt;"><!--[if !supportLists]--><span lang="EN-US"><span>2Q?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> </span></span></span><!--[endif]--><span style="font-family: ?hu)?">因ؓ(f)E序使用虚拟地址Q而且一般?/span><span lang="EN-US">CACHED</span><span style="font-family: ?hu)?">地址Q所以虚拟地址中的内容与其物理地址上的内容不一定一致辞Q所以在启动</span><span lang="EN-US">DMA</span><span style="font-family: ?hu)?">传输之前一定要该地址?/span><span lang="EN-US">CACHE</span><span style="font-family: ?hu)?">hQ即写入内存?/span></p> <p class="MsoNormal" style="margin-left: 18pt; text-indent: -18pt;"><!--[if !supportLists]--><span lang="EN-US"><span>3Q?span style="font-family: "Times New Roman"; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> </span></span></span><!--[endif]--><span lang="EN-US">OS</span><span style="font-family: ?hu)?">q不能保证每ơ分配到的内在空间在物理上是q箋(hu)的。尤其是在系l用过一D|间而又分配?jin)一块比较大的内存时?/span></p> <p class="MsoNormal" style="margin-left: 18pt;"><span style="font-family: ?hu)?">所以每ơ都需要判断地址是不是连l的Q如果不q箋(hu)需要把q段内存分成几段?/span><span lang="EN-US">DMA</span><span style="font-family: ?hu)?">完成传输?/span></p> <p class="MsoNormal" style="margin-left: 18pt;"><span lang="EN-US"><o:p> </o:p></span></p> <p class="blogger-labels">标签Q?<a rel="tag">BaseKnowledge</a></p> </div> </div> <p class="post-footer"> <em>张脓(chung)者:(x)Blog by Braden @ <a title="permanent link">3/10/2007 09:44:00 下午</a></em>   <a class="comment-link" location.><span style="text-transform: lowercase;">0 条评?/span></a> <a class="comment-link"><span style="text-transform: lowercase;">指向此帖子的链接</span></a> <span id="ttxzdhl" class="item-action"><a title="以电(sh)子邮件发送帖?><img src="http://www.blogger.com/img/icon18_email.gif" class="icon-action" alt="" height="13" width="18"></a></span><span id="jf31rtr" class="item-control blog-admin pid-2106978906"><a style="border: medium none ;" title="修改帖子"><img src="http://www.blogger.com/img/icon18_edit_allbkg.gif" class="icon-action" alt="" height="18" width="18"></a></span> </p> </div> <!-- End .post --> <!-- Begin #comments --> <!-- End #comments --> <h2 class="date-header">2007-03-03</h2> <!-- Begin .post --> <div id="tfjv9fr" class="post"><a name="5156944094587713279"></a> <h3 class="post-title"> WINCE下USBFN驱动E序的一些概? </h3> <div id="rtxlt7x" class="post-body"> <div> <p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p> <p class="MsoNormal"><span lang="EN-US">USBFN</span><span style="font-family: ?hu)?">Q即</span><span lang="EN-US">USB</span><span style="font-family: ?hu)?">客户端驱动,用来一?/span><span lang="EN-US">WINCE</span><span style="font-family: ?hu)?">讑֤模拟成一定的</span><span lang="EN-US">USB</span><span style="font-family: ?hu)?">讑֤Q让L端(?/span><span lang="EN-US">PC</span><span style="font-family: ?hu)?">Q访问。目?/span><span lang="EN-US">WINCE</span><span style="font-family: ?hu)?">提供?/span><span lang="EN-US">USB</span><span style="font-family: ?hu)?">客户端有存储讑֤Q串口设备,?/span><span lang="EN-US">RNDIS</span><span style="font-family: ?hu)?">|络接口讑֤?/span></p> <p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p> <p class="MsoNormal" style="text-indent: 21pt;"><span style="font-family: ?hu)?">存储讑֤用来?/span><span lang="EN-US">WINCE</span><span style="font-family: ?hu)?">讑֤上的存储I间Q例?/span><span lang="EN-US">FLASH</span><span style="font-family: ?hu)?">Q当作一块存储介质给L讉KQ即?/span><span lang="EN-US">WINCE</span><span style="font-family: ?hu)?">讑֤模拟成一?/span><span lang="EN-US">U</span><span style="font-family: ?hu)?">盘?/span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span></span><span style="font-family: ?hu)?">串口讑֤设备与L?/span><span lang="EN-US">USB</span><span style="font-family: ?hu)?">q线模拟成串口,</span><span lang="EN-US">WINCE</span><span style="font-family: ?hu)?">和主机端都认为它们之前连接上?jin)一根串口线Q它们之间可以做串口通信Q典型的应用是用来实?/span><span lang="EN-US">WINCE</span><span style="font-family: ?hu)?">?/span><span lang="EN-US">PC</span><span style="font-family: ?hu)?">机的同步q接?/span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span>RNDIS</span><span style="font-family: ?hu)?">讑֤使两端认为它们之间徏立了(jin)|络q接Q通过注册表设|可以让L通过</span><span lang="EN-US">WINCE</span><span style="font-family: ?hu)?">讑֤上网或者</span><span lang="EN-US">WINCE</span><span style="font-family: ?hu)?">讑֤通过L上网?/span></p> <p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span>WINCE</span><span style="font-family: ?hu)?">已经提供?jin)以上三U设备的驱动E序Q在同一时刻只能使用一个设备。而我们需要做的只是提?/span><span lang="EN-US">USBFN</span><span style="font-family: ?hu)?">ȝ控制器的驱动E序?/span><span lang="EN-US">USBFN</span><span style="font-family: ?hu)?">pȝ各个模块的关pd下:(x)</span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span>USBFN</span><span style="font-family: ?hu)?">总\U控制器作ؓ(f)一个ȝ驱动E序Q被讑֤理器加载,Ҏ(gu)注册表设|加载相应的客户驱动E序Q即存储讑֤Q串口设备或?/span><span lang="EN-US">RNDIS</span><span style="font-family: ?hu)?">讑֤。客户驱动程序即启动</span><span lang="EN-US">USBFN</span><span style="font-family: ?hu)?">Q引发主机配|设备,配置完成以后卛_开始工作?/span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span></span><span style="font-family: ?hu)?">?/span><span lang="EN-US">USBFN</span><span style="font-family: ?hu)?">总\U控制器驱动?/span><span lang="EN-US">MDD</span><span style="font-family: ?hu)?">部分</span><span lang="EN-US">WINCE</span><span style="font-family: ?hu)?">本n已经提供Q?/span><span lang="EN-US">PDD</span><span style="font-family: ?hu)?">只需初始化硬件设备,提供传输卛_?/span><span lang="EN-US">MDD</span><span style="font-family: ?hu)?">在初始化时调?/span><span lang="EN-US">UfnPdd_Init</span><span style="font-family: ?hu)?">函数得到</span><span lang="EN-US">PDD</span><span style="font-family: ?hu)?">层的函数表,之后?x)根据需要调用各个函数?/span><span lang="EN-US">PDD</span><span style="font-family: ?hu)?">q需要提?/span><span lang="EN-US">IST</span><span style="font-family: ?hu)?">Q用以处理各个中断。需要注意的?/span><span lang="EN-US">USBFN</span><span style="font-family: ?hu)?">有一个与其它讑֤不同之处Q它的注册表需要这样一个设|:(x)</span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span>"BusIoctl"=dword:<st1:chmetcnv unitname="a" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" st="on">2a</st1:chmetcnv>0048</span><span style="font-family: ?hu)?">Q用以让pȝ加蝲完设备之后调用gؓ(f)</span><span lang="EN-US">0x<st1:chmetcnv unitname="a" sourcevalue="2" hasspace="False" negative="False" numbertype="1" tcsc="0" st="on">2a</st1:chmetcnv>0048</span><span style="font-family: ?hu)?">?/span><span lang="EN-US">IOCTL</span><span style="font-family: ?hu)?">代码d成初始化Q其定义?/span><span style="font-size: 12pt; font-family: ?hu)?" lang="EN-US">IOCTL_BUS_POSTINIT</span><span style="font-size: 12pt; font-family: ?hu)?">?span lang="EN-US"><o:p></o:p></span></span></p> <p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p> <p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p> <p class="blogger-labels">标签Q?<a rel="tag">BaseKnowledge</a></p> </div> </div> <p class="post-footer"> <em>张脓(chung)者:(x)Blog by Braden @ <a title="permanent link">3/03/2007 06:56:00 下午</a></em>   <a class="comment-link" location.><span style="text-transform: lowercase;">2 条评?/span></a> <a class="comment-link"><span style="text-transform: lowercase;">指向此帖子的链接</span></a> <span id="7rnzrxh" class="item-action"><a title="以电(sh)子邮件发送帖?><img src="http://www.blogger.com/img/icon18_email.gif" class="icon-action" alt="" height="13" width="18"></a></span><span id="lrfjx9v" class="item-control blog-admin pid-2106978906"><a style="border: medium none ;" title="修改帖子"><img src="http://www.blogger.com/img/icon18_edit_allbkg.gif" class="icon-action" alt="" height="18" width="18"></a></span> </p> </div> <!-- End .post --> <!-- Begin #comments --> <!-- End #comments --> <h2 class="date-header">2007-02-28</h2> <!-- Begin .post --> <div id="n7fzf5j" class="post"><a name="990238142699354822"></a> <h3 class="post-title"> SOURCES文g详解 </h3> <div id="jr1ht9x" class="post-body"> <div> <p class="MsoNormal"><span lang="EN-US">SOURCES</span><span style="font-family: ?hu)?">文g?/span><span lang="EN-US">WINCE</span><span style="font-family: ?hu)?">底层开发中最重要的文件之一</span><span lang="EN-US">,</span><span style="font-family: ?hu)?">主要的配|项如下</span><span lang="EN-US">:</span></p> <p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p> <p class="MsoNormal"><span lang="EN-US"><o:p></o:p>TARGETNAME,</span><span style="font-family: ?hu)?">定义模块名称</span><span lang="EN-US">.<br>TARGETTYPE,</span><span style="font-family: ?hu)?">模块的种c?/span><span lang="EN-US">,</span><span style="font-family: ?hu)?">可以?/span><span lang="EN-US">DYNLINK, LIBRARY,EXE.<br></span><span style="font-family: ?hu)?">如果</span><span lang="EN-US">TARGETTYPE</span><span style="font-family: ?hu)?">?/span><span lang="EN-US">DLL,</span><span style="font-family: ?hu)?">则可以定?/span><span lang="EN-US">DLLENTRY,</span><span style="font-family: ?hu)?">?/span><span lang="EN-US">Dll</span><span style="font-family: ?hu)?">入口定义成别的不?/span><span lang="EN-US">DLLMain</span><span style="font-family: ?hu)?">的函?/span><span lang="EN-US">,</span><span style="font-family: ?hu)?">如果</span><span lang="EN-US">DLL</span><span style="font-family: ?hu)?">的入口是</span><span lang="EN-US">DllMain</span><span style="font-family: ?hu)?">Q则不需要别的定义?/span><span lang="EN-US"><br></span><span style="font-family: ?hu)?">如果</span><span lang="EN-US">TARGETTYPE</span><span style="font-family: ?hu)?">?/span><span lang="EN-US">EXE,</span><span style="font-family: ?hu)?">则可以定?/span><span lang="EN-US">EXEENTRY,</span><span style="font-family: ?hu)?">用于指定</span><span lang="EN-US">EXE</span><span style="font-family: ?hu)?">的入口函?/span><span lang="EN-US">. </span></p> <p class="MsoNormal"><span style="font-family: ?hu)?">如果</span><span lang="EN-US">TARGETTYPE</span><span style="font-family: ?hu)?">?/span><span lang="EN-US">LIBRARY,</span><span style="font-family: ?hu)?">则不需要定义入口函数?/span></p> <p class="MsoNormal"><span lang="EN-US"><o:p> </o:p><br>INCLUDES</span><span style="font-family: ?hu)?">Q如果一个模块需要用非标准路径下的头文件时</span><span lang="EN-US">,</span><span style="font-family: ?hu)?">需要定?/span><span lang="EN-US">INCLUDES,</span><span style="font-family: ?hu)?">用于包含更多的头文g路径</span><span lang="EN-US">,</span><span style="font-family: ?hu)?">用法如下</span><span lang="EN-US">:<br><br>INCLUDES=$(INCLUDES);\new directory\...,</span><span style="font-family: ?hu)?">注意定义新的</span><span lang="EN-US">INCLUDES</span><span style="font-family: ?hu)?">?/span><span lang="EN-US">,</span><span style="font-family: ?hu)?">需要包?/span><span lang="EN-US">INCLUDES</span><span style="font-family: ?hu)?">原来的|否则需要包含所有可能的目录?/span><span lang="EN-US"><br><br>TARGETLIBS,SOURCELIBS</span><span style="font-family: ?hu)?">用于定义该模块需要链接哪些库文g</span><span lang="EN-US">.</span></p> <p class="MsoNormal"><span lang="EN-US"><o:p> </o:p><br>TARGETLIBS</span><span style="font-family: ?hu)?">Q如果一个库?/span><span lang="EN-US">DLL</span><span style="font-family: ?hu)?">的Ş式提供给调用者,需要用</span><span lang="EN-US">TARGETLIBS</span><span style="font-family: ?hu)?">Q它只链接一个函数地址Q系l执行时?x)将被链接的库加载。比?/span><span lang="EN-US">coredll.lib</span><span style="font-family: ?hu)?">是q样的库文g。即动态链接?/span></p> <p class="MsoNormal"><span lang="EN-US">SOURCELIBS</span><span style="font-family: ?hu)?">Q将库中的函数实体链接进来。即?rn)态链接,用到的函C(x)在我们的文g中Ş成一份拷贝?/span></p> <p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span><br><span style="font-family: ?hu)?">注意Q内核这个执行文件是没有</span><span lang="EN-US">TARGETLIBS</span><span style="font-family: ?hu)?">的,</span><span lang="EN-US">GIISR.DLL</span><span style="font-family: ?hu)?">也不能有</span><span lang="EN-US">TARGETLIBS</span><span style="font-family: ?hu)?">?/span></p> <p class="MsoNormal"><span lang="EN-US"><br>WINCECOD,</span><span style="font-family: ?hu)?">如果其定义?/span><span lang="EN-US">1,</span><span style="font-family: ?hu)?">则编译器?x)?f)每一个文件生?/span><span lang="EN-US">.cod</span><span style="font-family: ?hu)?">文g</span><span lang="EN-US">,</span><span style="font-family: ?hu)?">它是一个汇~文Ӟ调试时查看汇~代码也是一U很好的办法?/span><span lang="EN-US"><br><br>SOURCES,</span><span style="font-family: ?hu)?">定义该模块需要哪些源文g</span><span lang="EN-US">.</span></p> <p class="blogger-labels">标签Q?<a rel="tag">BaseKnowledge</a></p> </div> </div> <p class="post-footer"> <em>张脓(chung)者:(x)Blog by Braden @ <a title="permanent link">2/28/2007 09:09:00 下午</a></em>   <a class="comment-link" location.><span style="text-transform: lowercase;">1 条评?/span></a> <a class="comment-link"><span style="text-transform: lowercase;">指向此帖子的链接</span></a> <span id="1bhl1vz" class="item-action"><a title="以电(sh)子邮件发送帖?><img src="http://www.blogger.com/img/icon18_email.gif" class="icon-action" alt="" height="13" width="18"></a></span><span id="1f7dhnv" class="item-control blog-admin pid-2106978906"><a style="border: medium none ;" title="修改帖子"><img src="http://www.blogger.com/img/icon18_edit_allbkg.gif" class="icon-action" alt="" height="18" width="18"></a></span> </p> </div> <!-- End .post --> <!-- Begin #comments --> <!-- End #comments --> <h2 class="date-header">2007-02-17</h2> <!-- Begin .post --> <a name="8604944099509790452"></a> <h3 class="post-title"> 多个讑֤׃n同一个硬件中? </h3> <span lang="EN-US"><o:p></o:p></span><span style="font-family: ?hu)?">g中断UL有限的,我们可能需要在已有的系l上做一些扩展,比如串口扩展成好几个,有些g本np计成多个讑֤׃n一条中断线Q比如我的系l中两个串口共享同一?/span><span lang="EN-US">CPU</span><span style="font-family: ?hu)?">中断QQ何一个串口发生中断以后都?x)触?/span><span lang="EN-US">CPU</span><span style="font-family: ?hu)?">的同一条中断线Q需要判断别的寄存器来确定是哪个串口发生?jin)什么中断?/span> <p class="MsoNormal"><span style="font-family: ?hu)?">我们可以?/span><span lang="EN-US">OAL</span><span style="font-family: ?hu)?">中分析各个中断源Q然后返回不同的</span><span lang="EN-US">SYSINTR</span><span style="font-family: ?hu)?">|但这U做法扩展性不好。例如,</span><span lang="EN-US">OAL</span><span style="font-family: ?hu)?">中设值某个中断源最多会(x)产生三个</span><span lang="EN-US">SYSINTR</span><span style="font-family: ?hu)?">Q但以后扩展成了(jin)四个讑֤Q有一个设备就无法正常工作?jin)?/span></p> <p class="MsoNormal"><span lang="EN-US">WINCE</span><span style="font-family: ?hu)?">引入?jin)可装蝲中断处理例程的概c(din)即在需要与别的讑֤׃n中断的驱动程序中加蝲一?/span><span lang="EN-US">ISR</span><span style="font-family: ?hu)?">Q一般?/span><span lang="EN-US">WINCE</span><span style="font-family: ?hu)?">提供?/span><span lang="EN-US">GIISR</span><span style="font-family: ?hu)?">x(chng)满需求。将其安装到内核?/span><span lang="EN-US">OAL</span><span style="font-family: ?hu)?">中发生中断时调用</span><strong><span style="font-size: 8.5pt; color: black; letter-spacing: 1.2pt;" lang="EN-US">NKCallIntChain</span></strong><span style="font-family: ?hu)?">来得?/span><span lang="EN-US">SYSINTR</span><span style="font-family: ?hu)?">Q这个函C(x)引vpȝ逐个调用在该</span><span lang="EN-US">IRQ</span><span style="font-family: ?hu)?">上加载的所有可装蝲?/span><span lang="EN-US">ISR</span><span style="font-family: ?hu)?">Q当某个</span><span lang="EN-US">ISR</span><span style="font-family: ?hu)?">认ؓ(f)q个中断是由它引发的时就q回?/span><span lang="EN-US">SYSINTR</span><span style="font-family: ?hu)?">Q否则就q回</span><span style="font-size: 8.5pt; font-family: verdana; color: black;" lang="EN-US">SYSINTR_CHAIN</span><span style="font-size: 8.5pt; font-family: ?hu)? color: black;">Q?/span><span style="font-family: ?hu)?">pȝ׃(x)接着调用其它?/span><span lang="EN-US">ISR</span><span style="font-family: ?hu)?">Q甚x(chng)有的</span><span lang="EN-US">ISR</span><span style="font-family: ?hu)?">都被调用或者有一?/span><span lang="EN-US">ISR</span><span style="font-family: ?hu)?">q回?jin)正?/span><span lang="EN-US">SYSINTR</span><span style="font-family: ?hu)?">?/span></p> <p class="MsoNormal"><span style="font-family: ?hu)?">驱动E序中的调用办法如下Q?/span><span lang="EN-US">CE</span><span style="font-family: ?hu)?">帮助文档Q:(x)</span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span>if (InstallIsr) {</span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span>// Install ISR handler</span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span>g_IsrHandle = LoadIntChainHandler(IsrDll, IsrHandler, (BYTE)Irq);</span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span>if (!g_IsrHandle) {</span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span>DEBUGMSG(ZONE_ERROR, (L"WAVEDEV: Couldn't install ISR handler\r\n"));</span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span>} else {</span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span>GIISR_INFO Info;</span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span>PVOID PhysAddr;</span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span>DWORD inIoSpace = 1;<span> </span>// io space</span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span><span> </span>PHYSICAL_ADDRESS PortAddress = {ulIoBase, 0}; </span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span></span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span>if (!TransBusAddrToStatic(PCIBus, 0, PortAddress, ulIoLen, &inIoSpace, &PhysAddr)) {</span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span>DEBUGMSG(ZONE_ERROR, (L"WAVEDEV: Failed TransBusAddrToStatic\r\n"));</span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span>return FALSE;</span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span>}</span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span></span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span>DEBUGMSG(ZONE_PDD, (L"WAVEDEV: Installed ISR handler, Dll = '%s', Handler = '%s', Irq = %d, PhysAddr = 0x%x\r\n", IsrDll, IsrHandler, Irq, PhysAddr));</span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span></span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span>// Set up ISR handler</span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span>Info.SysIntr = ulSysIntr;</span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span>Info.CheckPort = TRUE;</span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span>Info.PortIsIO = TRUE;</span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span>Info.UseMaskReg = FALSE;</span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span>Info.PortAddr = (DWORD)PhysAddr + ES1371_dSTATUS_OFF;</span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span>Info.PortSize = sizeof(DWORD);</span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span>Info.Mask = ES1371_INTSTAT_PENDING;</span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span></span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span>if (!KernelLibIoControl(g_IsrHandle, IOCTL_GIISR_INFO, &Info, sizeof(Info), NULL, 0, NULL)) {</span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span>DEBUGMSG(ZONE_ERROR, (L"WAVEDEV: KernelLibIoControl call failed.\r\n"));</span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span>}</span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span>}</span></p> <p class="MsoNormal"><span lang="EN-US"><span> </span>}</span></p> <p class="MsoNormal"><span lang="EN-US"><o:p> </o:p></span></p> <p class="MsoNormal"><span style="font-family: ?hu)?">q里需要注意一下,因ؓ(f)</span><span lang="EN-US">ISR</span><span style="font-family: ?hu)?">在内核态运行,</span><span lang="EN-US">Info.PortAddr</span><span style="font-family: ?hu)?">必须是系l最原始的虚拟地址Q即没有?/span><span lang="EN-US">VirtualCopy</span><span style="font-family: ?hu)?">映射q的Q从</span><span lang="EN-US">OEMAddressTable</span><span style="font-family: ?hu)?">中计出来的虚拟地址。在q个例子中用</span><span lang="EN-US">TransBusAddrToStatic</span><span style="font-family: ?hu)?">函数可以直接把物理地址转换成这U地址。?/span><strong><span style="font-size: 8.5pt; color: black; letter-spacing: 1.2pt;" lang="EN-US">MmMapIoSpace</span></strong><span style="font-family: ?hu)?">得到是在当前E序I间中的地址</span><span lang="EN-US">,</span><span style="font-family: ?hu)?">不能使用。而且</span><span lang="EN-US">GIIR</span><span style="font-family: ?hu)?">要被加蝲到内核空_(d)所以在加入?/span><span lang="EN-US">OS</span><span style="font-family: ?hu)?">包中旉要加?/span><span lang="EN-US">K</span><span style="font-family: ?hu)?">标志Q否?/span><span lang="EN-US">LoadIntChainHandler</span><span style="font-family: ?hu)?">函数?x)失败?/span></p><img src ="http://www.shnenglu.com/zjj2816/aggbug/70243.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/zjj2816/" target="_blank">井泉</a> 2008-12-24 15:12 <a href="http://www.shnenglu.com/zjj2816/archive/2008/12/24/70243.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> 如何使用CeLog调试Windows mobile讑֤驱动 ?/title><link>http://www.shnenglu.com/zjj2816/archive/2008/12/19/69830.html</link><dc:creator>井泉</dc:creator><author>井泉</author><pubDate>Fri, 19 Dec 2008 06:07:00 GMT</pubDate><guid>http://www.shnenglu.com/zjj2816/archive/2008/12/19/69830.html</guid><wfw:comment>http://www.shnenglu.com/zjj2816/comments/69830.html</wfw:comment><comments>http://www.shnenglu.com/zjj2816/archive/2008/12/19/69830.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/zjj2816/comments/commentRss/69830.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/zjj2816/services/trackbacks/69830.html</trackback:ping><description><![CDATA[<div style="margin-left: 21pt; text-indent: -21pt;"><span>一.<span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">     </span></span>介绍</div> <div>本文主要介绍在不q入KITL模式, 使用CeLog工具来调试Windows mobile讑֤的方法,该方法可以抓C用DEBUGMSG打出的log信息Q注意:(x)本方法只在RETAIL版本上实验通过?/div> <div style="margin-left: 21pt; text-indent: -21pt;"><span>?<span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">     </span></span>工具</div> <div style="margin-left: 21pt; text-indent: -21pt;">Platform Builder</div> <div style="margin-left: 21pt; text-indent: -21pt;"><span><span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;"> </span></span>Readlog.exe</div> <div style="margin-left: 21pt; text-indent: -21pt;">CeLogStopFlush.exe</div> <div>Readlog.exe可以在\径:(x)_WINCEROOT\SDK\BIN\I386下面扑ֈQCeLogStopFlush.exe</div> <div>的源代码可以在_WINCEROOT\Public\Common\SDK\Samples\CeLog\Flush\Stopflush扑ֈ,使用build –c可以生成CeLogStopFlush.exe?/div> <div style="margin-left: 21pt; text-indent: -21pt;"><span>?<span style="font-family: 'Times New Roman'; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">     </span></span>步骤</div> <div>1Q徏立一个Start Log的快h式,具体新徏一个文Ӟ复制下面的语句:(x)</div> <pre style="background: white none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><span style="font-size: 10.5pt;">83#\Windows\<span style="color: red;">celogflush</span>.exe -buf 0x100000 -time 60000 -n \celog.clg -z 0x00800000 -ui 1</span></pre> <pre style="background: white none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><span style="font-size: 10.5pt;">其重命名ؓ(f)Start Log.lnk</span></pre> <pre style="background: white none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><span style="font-size: 10.5pt;">2</span><span style="font-size: 10.5pt;">Q检查手机的\Windows目录是否有以下两个文?/span><span style="font-size: 10.5pt;">CeLog.dll and CeLogFlush.exe</span><span style="font-size: 10.5pt;">Q如果没有的话,它们拷贝到</span><span style="font-size: 10.5pt;">\Windows</span><span style="font-size: 10.5pt;">目录Q?/span><span style="font-size: 10.5pt;">release</span><span style="font-size: 10.5pt;">目录可以扑ֈQ?/span></pre> <pre style="background: white none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><span style="font-size: 10.5pt;">3</span><span style="font-size: 10.5pt;">Q拷贝Start Log.lnk和CeLogStopFlush.exe到开始菜单中Q修Ҏ(gu)册表Q增加或修改下面的键倹{(注意</span>ZoneCE?6q制的)(j)</pre> <pre>[HKEY_LOCAL_MACHINE\System\CeLog]</pre> <pre><span>    "Transport"="LocalFile"</span></pre> <pre><span>    "FileName"="celog.clg"</span></pre> <pre><span>    "ZoneCE"=dword:800000</span></pre> <pre style="background: white none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><span style="font-size: 10.5pt;">4</span><span style="font-size: 10.5pt;">Q点击Start Log开始抓log</span></pre> <div>5Q点击CeLogStopFlush.exe停止抓log</div> <div>6Q将根目录下生成?strong><span style="font-weight: normal;">celog.clg</span></strong><strong><span style="font-weight: normal;">文g拯?/span></strong><strong><span style="font-weight: normal;">PC</span></strong><strong><span style="font-weight: normal;">Z</span></strong>Readlog同一U目?strong><span style="font-weight: normal;">?/span></strong></div> <div><strong><span style="font-weight: normal;">7</span></strong><strong><span style="font-weight: normal;">Q打开</span></strong><strong><span style="font-weight: normal;">DOS</span></strong><strong><span style="font-weight: normal;">命o(h)行,转到</span></strong><strong><span style="font-weight: normal;">Readlog.exe</span></strong><strong><span style="font-weight: normal;">目录中,输入下面的命令:(x)</span></strong></div> <pre><span style="font-size: 10.5pt;">Readlog.exe celog.clg celog.log</span></pre> <div>8Q用文本工h?strong><span style="font-weight: normal;">celog.log</span></strong><strong><span style="font-weight: normal;">中的</span></strong><strong><span style="font-weight: normal;">log</span></strong><strong><span style="font-weight: normal;">信息Q下面是一?/span></strong><strong><span style="font-weight: normal;">log</span></strong><strong><span style="font-weight: normal;">的实例?/span></strong></div><img src ="http://www.shnenglu.com/zjj2816/aggbug/69830.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/zjj2816/" target="_blank">井泉</a> 2008-12-19 14:07 <a href="http://www.shnenglu.com/zjj2816/archive/2008/12/19/69830.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux应用E序安装与管??/title><link>http://www.shnenglu.com/zjj2816/archive/2008/12/16/69559.html</link><dc:creator>井泉</dc:creator><author>井泉</author><pubDate>Tue, 16 Dec 2008 03:34:00 GMT</pubDate><guid>http://www.shnenglu.com/zjj2816/archive/2008/12/16/69559.html</guid><wfw:comment>http://www.shnenglu.com/zjj2816/comments/69559.html</wfw:comment><comments>http://www.shnenglu.com/zjj2816/archive/2008/12/16/69559.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/zjj2816/comments/commentRss/69559.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/zjj2816/services/trackbacks/69559.html</trackback:ping><description><![CDATA[<strong>Linux应用E序安装与管?/strong>        <br>         <br> 目标Q?br>         ?jin)解linux应用E序的组成部?br>         掌握使用RPM工具理软g包的Ҏ(gu)<br>         掌握应用E序源代码包的编译安装方?br>         掌握囑Ş界面下应用程序管理工L(fng)使用<br> 1、Linux应用E序基础<br> 2、RPM包管?br>         包管理系l初步:(x)<br>         RPM:RPM Package Manager        <br>         <br> <a target="_blank"><font color="#0000ff">http://www.rpm.org</font></a><br>         RPM包管理系l:(x)<br>                 $ rpm<br>         RPPM包的文g名称Q?br>            bash-3.0-19.2.i386.rpm<br>                 bash:软g名称?br>                 3.0-19.2:软g的版本号?br>                 i386:软g所q行的最低硬件^台?br>                 rpm:文g的扩展名,用来标识当前文g是rpm格式的Y件包?br>         RPM包管理功能:(x)<br>             rpm命o(h)配合不同的参数可以实C下的rpm包的理功能:<br>                 查询已安装在linuxpȝ中的RPM软g包的信息?br>                 查询RPM软g包安装文件的信息?br>                 安装RPM软g包到当前linuxpȝ?br>                 从当前linuxpȝ中卸载已安装的RPM软g包?br>                 从当前linuxpȝ中升U已安装的RPM软g包?br> 使用rpm命o(h)查询软g包:(x)<br>         1、查询系l中安装的所有RPM?br>                 $ rpm  -qa                                      查询当前linuxpȝ中已l安装的软g包?br>                 例:(x)$ rpm -qa | grep -i x11 | head -3  察看pȝ中包含x11字符串的?行Y件包?br>         2、查询Y件包是否安装<br>                 $ rpm –q rpm包名U?nbsp;                       察看pȝ中指定Y件包是否安?br>                 ? $ rpm -q bash                            察看pȝ中bash软g包是否安装?br>            "rpm -q"命o(h)中指定的软g包名U需要准的拼写Q该命o(h)不会(x)在Y件包的名UCq行局部匹配的查询?br>         3、查询已安装软g包详l信?br>                 $ rpm –qi RPM包名U?nbsp;                      查询linuxpȝ中指定名UY件包的详l信息?br>                 例:(x)$ rpm -qi bash                          察看bash软g包的详细信息?br>            "rpm -qi"命o(h)的执行结果中包含较详l的信息Q包括:(x)软g名称Q版本信息,包大,描述Q等?br>         4、查询已安装软g包中的文件列?br>                 $ rpm –ql RPM包名U?nbsp;                      查询已安装Y件包在当前系l中安装?jin)哪些文件?br>                 例:(x)$ rpm -ql bash | head -3            查看bash软g在系l中已安装文件的?行文件列表?br>                     $ rpm -ql bash | grep bin             用过滤方式察看bash中包含bin字符串的文g列表?br>         5、查询系l中文g所属的软g?br>                 $ rpm –qf 文g名称    查询linuxpȝ中指定文件所属的软g包?br>                 例:(x)$ rpm -qf /bin/bash                   察看bash文g所属的软g包?br>                     bash-3.0-19.2      昄l果?br>         6、查询RPM安装包文件中的信?<br>                 $ rpm –qpi RPM包文件名                  察看RPM包未安装前的详细信息?br>                 $ rpm –qpl RPM包文件名                  察看RPM包未安装前的文g列表?br>            "rpm -qpi和rpm -qpl q两条命令可作ؓ(f)在安装Y件包之前对其的了(jin)解?br>         7、rpm命o(h)查询实例<br>                 $ which mount                               获得mount命o(h)的可执行文g路径?br>                 $ rpm –qf  /bin/mount                     查询/bin/mount所属的软g包?br>                 $ rpm –qi util-linux                           查询/bin/mount所属Y件包的详l信息?br>                 $ rpm –qf util-linux | grep mount       查询/bin/mount所属Y件包中包括mount相关所有文件?br> 使用rpm命o(h)安装软g?br>         1、rpm软g包地基本安装<br>                 $ rpm –i  rpm安装包文件名                安装该Y件包中的文g到当前系l,安装q程不提CZQ何信息?br>         2、在安装软g包的同时昄详细信息<br>                 $ rpm –ivh rpm安装包文?nbsp;                安装该Y件包中的文g到当前系l,安装q程?x)以癑ֈ比的形?br>                                                                     昄安装的进度和一些其他信息?br>         3、RPM软g包安装的依赖关系<br>                 强制安装Q? rpm  --force  –i  rpm包文件名<br>             注:(x)要先满软g包的依赖关系后再q行软g包的安装Q用强制安装命令安装不能保证Y件安装到pȝ后一定能<br>                   正常q行Q因此徏议慎重用?br> 使用rpm命o(h)卸蝲软g包:(x)<br>         1、RPM软g包的卸蝲<br>                 $ rpm  -e  软g包名U?nbsp;                      软g包的卸蝲Q在卸蝲时不昄M信息?br>             注:(x)RPM软g包的卸蝲同样存在依赖关系Q只有在没有依赖关系存在时才能对其进行卸载?br>         2、rpm软g包卸载的依赖关系<br>                   在用RPM命o(h)q行卸蝲ӞRPM命o(h)?x)分析要卸蝲的Y件包的依赖关p,当存在依赖关pL?x)自动停止,q显?nbsp;   <br>                   哪个软g造成的卸载失败。根据RPM提示的错误信息,定先卸载的软g包,再卸载被依赖的Y件包?br> 使用rpm命o(h)升软g包:(x)<br>         $ rpm  - U  rpm安装包文件名<br>             注:(x)"rpm -u"命o(h)中用的升软g包文件最好用RED HAT公司针对当前的linux版本官方推出的升U文Ӟ不要  <br>                   使用W三Ҏ(gu)供的升包?br>    <br> 应用E序~译<br>         开放源代码应用E序的编译安?br>         Q下面以多线E下载Y?prozilla"的源代码~译安装Z来说明源代码~译安装的整个过E)(j)<br>         ~译应用E序前的准备工作Q?br>         1、确认系l中已经安装?jin)编译环?br>                 $ rpm  -qa  | grep gcc                       定当前pȝ中安装了(jin)gcc~译器环境?br>         2、下载prozillaE序的源代码安装包文?br>                  ?br>         3、释攑ַ下蝲的源代码软g包文?br>                 $ tar jxf prozilla-2.0.4.tar.bz2              释放以下载的源代码Y件包文g到当前目录。解压后的文?br>                                                                      名:(x)prozilla-2.0.4<br>            扩展Qtar的xzvf参数用于释放以tar.gz格式的压~包?br>         4、进入源代码目录<br>                 $ cd prozilla-2.0.4                             q入目录?br>                 $ pwd                                            昄当前目录路径?br>                 /home/teacher/download/prozilla-2.0.4      昄l果?br>            ~译软g安装的\径:(x)<br>                 $ ./configure --prefix=/home/teacher/proz  <br>                 在prozillaE序的配|中Q?--prdfix"选项可以指定应用E序~译后的安装路径Q如果不使用"--prefix"<br>                 选项指定安装路径QconfigureE序配|prozilla的默认安装\径ؓ(f)"/usr/local/bin"目录?br>          5、程序编译过E?br>                 $ make                                           使用make命o(h)q行E序的二q制~译?br>         6、程序安装过E?br>                 $ make install<br>                 "make install"命o(h)按照configuer命o(h)?--prefix"选项中设定的安装路径已~译完成的应用程序安?br>                  到目标目录?br>         7、验证编译安装的E序<br>                 $ ls /home/teacher/proz                    察看proz文g夹中的文件?br>                 bin  include lib man share<br>         <br>         <br>         ~译前的配置<br>                 $ ./configure  - - help                    <br>         ~译与安装:(x)<br>         1、程序编译过E?br>                 $ make <br>         2、程序安装过E?br>                 $ make install<br>         3、验证编译安装的E序<br> 使用囑Ş界面pȝ工具完成RPM保的安装<br>          ?img src ="http://www.shnenglu.com/zjj2816/aggbug/69559.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/zjj2816/" target="_blank">井泉</a> 2008-12-16 11:34 <a href="http://www.shnenglu.com/zjj2816/archive/2008/12/16/69559.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Windows CE usb驱动E序http://www.shnenglu.com/zjj2816/archive/2008/12/03/68441.html井泉井泉Wed, 03 Dec 2008 02:35:00 GMThttp://www.shnenglu.com/zjj2816/archive/2008/12/03/68441.htmlhttp://www.shnenglu.com/zjj2816/comments/68441.htmlhttp://www.shnenglu.com/zjj2816/archive/2008/12/03/68441.html#Feedback0http://www.shnenglu.com/zjj2816/comments/commentRss/68441.htmlhttp://www.shnenglu.com/zjj2816/services/trackbacks/68441.html上述讲了(jin)堆理论,可能读者脑袋都已经大了(jin)Qؓ(f)此,我们举个单的例子来详l说明一下驱动程序的开发过E?

例如我们有个USB Mouse讑֤Q设备信息描q如下:(x)
Device Descriptor:
bcdUSB: 0x0100
bDeviceClass: 0x00
bDeviceSubClass: 0x00
bDeviceProtocol: 0x00
bMaxPacketSize0: 0x08 (8)
idVendor: 0x05E3 (Genesys Logic Inc.)
idProduct: 0x0001
bcdDevice: 0x0101
iManufacturer: 0x00
iProduct: 0x01
iSerialNumber: 0x00
bNumConfigurations: 0x01

ConnectionStatus: DeviceConnected
Current Config value: 0x01
Device Bus Speed: Low
Device Address: 0x02
Open Pipes: 1

Endpoint Descriptor:
bEndpointAddress: 0x81
Transfer Type: Interrupt
wMaxPacketSize: 0x0003 (3)
bInterval: 0x0A

可以看出上述讑֤有一个中断PIPEQ包的最大gؓ(f)3。可能有人问上述的值怎么得到的,win2k 的DDK中有个usbview的例E,~译一下,你的USB讑֤插到PC机的USB口中Q运行usbview.exe卛_看得相应的设备信息?

有了(jin)q些基本信息Q就可以~写USB讑֤?jin),首先声明一下,下面的代码取自微软的USB鼠标hE序Q版权归微Y所有,此处仅仅借用来描qC下USB鼠标驱动的开发过E,读者如需要引用此代码Q需要得到微软的同意?

首先Q必输出USBD要求调用的三个函敎ͼ首先到设备插入到USB端口ӞUSBD?x)调用USBDeviceAttach()函数Q相应的代码如下Q?
extern "C" BOOL
USBDeviceAttach(
USB_HANDLE hDevice, // USB讑֤句柄
LPCUSB_FUNCS lpUsbFuncs, // USBDI的函数集?
LPCUSB_INTERFACE lpInterface, // 讑֤接口描述信息
LPCWSTR szUniqueDriverId, // 讑֤ID描述字符丌Ӏ?
LPBOOL fAcceptControl, // q回TRUEQ标识我们可以控制此讑֤Q?反之表示不能控制
DWORD dwUnused)
{
*fAcceptControl = FALSE;
// 我们的鼠标设备有特定的描qC息,要检是否是我们的设备?
if (lpInterface == NULL)
return FALSE;
// 打印相关的USB讑֤接口描述信息?
DEBUGMSG(ZONE_INIT,(TEXT("USBMouse: DeviceAttach, IF %u, #EP:%u, Class:%u, Sub:%u,Prot:%u\r\n"), lpInterface->Descriptor.bInterfaceNumber,lpInterface->Descriptor.bNumEndpoints, lpInterface->Descriptor.bInterfaceClass,lpInterface->Descriptor.bInterfaceSubClass,lpInterface->Descriptor.bInterfaceProtocol));
// 初试数据USB鼠标c,产生一个接受USB鼠标数据的线E?
CMouse * pMouse = new CMouse(hDevice, lpUsbFuncs, lpInterface);
if (pMouse == NULL)
return FALSE;

if (!pMouse->Initialize())
{
delete pMouse;
return FALSE;
}

// 注册一个监控USB讑֤事g的回调函敎ͼ用于监控USB讑֤是否已经拔掉?
(*lpUsbFuncs->lpRegisterNotificationRoutine)(hDevice,
USBDeviceNotifications, pMouse);

*fAcceptControl = TRUE;
return TRUE;
}

W二个函数是 USBInstallDriverQ)(j)函数Q?
一些基本定义如下:(x)
const WCHAR gcszRegisterClientDriverId[] = L"RegisterClientDriverID";
const WCHAR gcszRegisterClientSettings[] = L"RegisterClientSettings";
const WCHAR gcszUnRegisterClientDriverId[] = L"UnRegisterClientDriverID";
const WCHAR gcszUnRegisterClientSettings[] = L"UnRegisterClientSettings";
const WCHAR gcszMouseDriverId[] = L"Generic_Sample_Mouse_Driver";

函数接口如下Q?
extern "C" BOOL
USBInstallDriver(
LPCWSTR szDriverLibFile) // @parm [IN] - Contains client driver DLL name
{
BOOL fRet = FALSE;
HINSTANCE hInst = LoadLibrary(L"USBD.DLL");

// 注册USB讑֤信息
if(hInst)
{
LPREGISTER_CLIENT_DRIVER_ID pRegisterId = (LPREGISTER_CLIENT_DRIVER_ID)
GetProcAddress(hInst, gcszRegisterClientDriverId);

LPREGISTER_CLIENT_SETTINGS pRegisterSettings =
(LPREGISTER_CLIENT_SETTINGS) GetProcAddress(hInst,
gcszRegisterClientSettings);

if(pRegisterId && pRegisterSettings)
{
USB_DRIVER_SETTINGS DriverSettings;

DriverSettings.dwCount = sizeof(DriverSettings);

// 讄我们的特定的信息?
DriverSettings.dwVendorId = USB_NO_INFO;
DriverSettings.dwProductId = USB_NO_INFO;
DriverSettings.dwReleaseNumber = USB_NO_INFO;

DriverSettings.dwDeviceClass = USB_NO_INFO;
DriverSettings.dwDeviceSubClass = USB_NO_INFO;
DriverSettings.dwDeviceProtocol = USB_NO_INFO;

DriverSettings.dwInterfaceClass = 0x03; // HID
DriverSettings.dwInterfaceSubClass = 0x01; // boot device
DriverSettings.dwInterfaceProtocol = 0x02; // mouse

fRet = (*pRegisterId)(gcszMouseDriverId);

if(fRet)
{
fRet = (*pRegisterSettings)(szDriverLibFile,
gcszMouseDriverId, NULL, &DriverSettings);

if(!fRet)
{
//BUGBUG unregister the Client Driver’s ID
}
}
}
else
{
RETAILMSG(1,(TEXT("!USBMouse: Error getting USBD function pointers\r\n")));
}
FreeLibrary(hInst);
}
return fRet;
}
上述代码主要用于产生USB讑֤驱动E序需要的注册表信息,需要注意的是:(x)USB讑֤驱动E序不用标准的注册表函敎ͼ而是使用RegisterClientDriverIDQ)(j)和RegisterClientSettings来注册相应的讑֤信息?

另外一个函数是USBUninstallDriver()函数Q具体代码如下:(x)
extern "C" BOOL
USBUnInstallDriver()
{
BOOL fRet = FALSE;
HINSTANCE hInst = LoadLibrary(L"USBD.DLL");

if(hInst)
{
LPUN_REGISTER_CLIENT_DRIVER_ID pUnRegisterId =
(LPUN_REGISTER_CLIENT_DRIVER_ID)
GetProcAddress(hInst, gcszUnRegisterClientDriverId);

LPUN_REGISTER_CLIENT_SETTINGS pUnRegisterSettings =
(LPUN_REGISTER_CLIENT_SETTINGS) GetProcAddress(hInst,
gcszUnRegisterClientSettings);

if(pUnRegisterSettings)
{
USB_DRIVER_SETTINGS DriverSettings;

DriverSettings.dwCount = sizeof(DriverSettings);
// 必须填入与注册时相同的信息?
DriverSettings.dwVendorId = USB_NO_INFO;
DriverSettings.dwProductId = USB_NO_INFO;
DriverSettings.dwReleaseNumber = USB_NO_INFO;

DriverSettings.dwDeviceClass = USB_NO_INFO;
DriverSettings.dwDeviceSubClass = USB_NO_INFO;
DriverSettings.dwDeviceProtocol = USB_NO_INFO;

DriverSettings.dwInterfaceClass = 0x03; // HID
DriverSettings.dwInterfaceSubClass = 0x01; // boot device
DriverSettings.dwInterfaceProtocol = 0x02; // mouse

fRet = (*pUnRegisterSettings)(gcszMouseDriverId, NULL,
&DriverSettings);
}

if(pUnRegisterId)
{
BOOL fRetTemp = (*pUnRegisterId)(gcszMouseDriverId);
fRet = fRet ? fRetTemp : fRet;
}
FreeLibrary(hInst);
}
return fRet;
}
此函C要用于删除USBInstallDriver()时创建的注册表信息,同样的它使用自己的函数接口UnRegisterClientDriverIDQ)(j)和UnRegisterClientSettingsQ)(j)来做相应的处理?

另外一个需要处理的注册的监控通知函数USBDeviceNotificationsQ)(j)Q?
extern "C" BOOL USBDeviceNotifications(LPVOID lpvNotifyParameter, DWORD dwCode,
LPDWORD * dwInfo1, LPDWORD * dwInfo2, LPDWORD * dwInfo3,
LPDWORD * dwInfo4)
{
CMouse * pMouse = (CMouse *)lpvNotifyParameter;

switch(dwCode)
{
case USB_CLOSE_DEVICE:
//删除相关的资源?
delete pMouse;
return TRUE;
}
return FALSE;
}


USB鼠标的类的定义如下:(x)
class CMouse
{
public:
CMouse::CMouse(USB_HANDLE hDevice, LPCUSB_FUNCS lpUsbFuncs,
LPCUSB_INTERFACE lpInterface);
~CMouse();

BOOL Initialize();
private:
// 传输完毕调用的回调函?
static DWORD CALLBACK MouseTransferCompleteStub(LPVOID lpvNotifyParameter);
// 中断处理函数
static ULONG CALLBACK CMouse::MouseThreadStub(PVOID context);
DWORD MouseTransferComplete();
DWORD MouseThread();

BOOL SubmitInterrupt();
BOOL HandleInterrupt();

BOOL m_fClosing;
BOOL m_fReadyForMouseEvents;

HANDLE m_hEvent;
HANDLE m_hThread;

USB_HANDLE m_hDevice;
USB_PIPE m_hInterruptPipe;
USB_TRANSFER m_hInterruptTransfer;

LPCUSB_FUNCS m_lpUsbFuncs;
LPCUSB_INTERFACE m_pInterface;

BOOL m_fPrevButton1;
BOOL m_fPrevButton2;
BOOL m_fPrevButton3;

// 数据接受~冲区?
BYTE m_pbDataBuffer[8];
};

具体实现如下Q?

// 构造函敎ͼ初始化时调用
CMouse::CMouse(USB_HANDLE hDevice, LPCUSB_FUNCS lpUsbFuncs,
LPCUSB_INTERFACE lpInterface)
{
m_fClosing = FALSE;
m_fReadyForMouseEvents = FALSE;
m_hEvent = NULL;
m_hThread = NULL;

m_hDevice = hDevice;
m_hInterruptPipe = NULL;
m_hInterruptTransfer = NULL;

m_lpUsbFuncs = lpUsbFuncs;
m_pInterface = lpInterface;

m_fPrevButton1 = FALSE;
m_fPrevButton2 = FALSE;
m_fPrevButton3 = FALSE;

memset(m_pbDataBuffer, 0, sizeof(m_pbDataBuffer));
}

// 析构函数Q用于清除申L(fng)资源?
CMouse::~CMouse()
{
// 通知pȝd闭相关的函数接口?
m_fClosing = TRUE;

// Wake up the connection thread again and give it time to die.
if (m_hEvent != NULL)
{
// 通知关闭数据接受U程?
SetEvent(m_hEvent);

if (m_hThread != NULL)
{
DWORD dwWaitReturn;

dwWaitReturn = WaitForSingleObject(m_hThread, 1000);
if (dwWaitReturn != WAIT_OBJECT_0)
{
TerminateThread(m_hThread, DWORD(-1));
}
CloseHandle(m_hThread);
m_hThread = NULL;
}
CloseHandle(m_hEvent);
m_hEvent = NULL;
}

if(m_hInterruptTransfer)
(*m_lpUsbFuncs->lpCloseTransfer)(m_hInterruptTransfer);

if(m_hInterruptPipe)
(*m_lpUsbFuncs->lpClosePipe)(m_hInterruptPipe);
}


// 初始化USB鼠标驱动E序
BOOL CMouse::Initialize()
{
LPCUSB_DEVICE lpDeviceInfo = (*m_lpUsbFuncs->lpGetDeviceInfo)(m_hDevice);

// (g)配|:(x)USB鼠标应该只有一个中断管?
if ((m_pInterface->lpEndpoints[0].Descriptor.bmAttributes & USB_ENDPOINT_TYPE_MASK) != USB_ENDPOINT_TYPE_INTERRUPT)
{
RETAILMSG(1,(TEXT("!USBMouse: EP 0 wrong type (%u)!\r\n"),
m_pInterface->lpEndpoints[0].Descriptor.bmAttributes));
return FALSE;
}
DEBUGMSG(ZONE_INIT,(TEXT("USBMouse: EP 0:MaxPacket: %u, Interval: %u\r\n"),
m_pInterface->lpEndpoints[0].Descriptor.wMaxPacketSize,
m_pInterface->lpEndpoints[0].Descriptor.bInterval));

m_hInterruptPipe = (*m_lpUsbFuncs->lpOpenPipe)(m_hDevice,
&m_pInterface->lpEndpoints[0].Descriptor);

if (m_hInterruptPipe == NULL) {
RETAILMSG(1,(TEXT("Mouse: Error opening interrupt pipe\r\n")));
return (FALSE);
}
m_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (m_hEvent == NULL)
{
RETAILMSG(1,(TEXT("USBMouse: Error on CreateEvent for connect event\r\n")));
return(FALSE);
}
// 创徏数据接受U程
m_hThread = CreateThread(0, 0, MouseThreadStub, this, 0, NULL);
if (m_hThread == NULL)
{
RETAILMSG(1,(TEXT("USBMouse: Error on CreateThread\r\n")));
return(FALSE);
}

return(TRUE);
}

// 从USB鼠标讑֤中读出数据,产生相应的鼠标事件?
BOOL CMouse::SubmitInterrupt()
{
if(m_hInterruptTransfer)
(*m_lpUsbFuncs->lpCloseTransfer)(m_hInterruptTransfer);

// 从USB鼠标PIPE中读数据
m_hInterruptTransfer = (*m_lpUsbFuncs->lpIssueInterruptTransfer)
(m_hInterruptPipe, MouseTransferCompleteStub, this,
USB_IN_TRANSFER | USB_SHORT_TRANSFER_OK, // 表示L?
min(m_pInterface->lpEndpoints[0].Descriptor.wMaxPacketSize,
sizeof(m_pbDataBuffer)),
m_pbDataBuffer,
NULL);

if (m_hInterruptTransfer == NULL)
{
DEBUGMSG(ZONE_ERRORQ(L "!USBMouse: Error in IssueInterruptTransfer\r\n"));
return FALSE;
}
else
{
DEBUGMSG(ZONE_TRANSFER,(L"USBMouse::SubmitInterrupt,Transfer:0x%X\r\n",
m_hInterruptTransfer));
}
return TRUE;
}

// 处理鼠标中断传输的数?
BOOL CMouse::HandleInterrupt()
{
DWORD dwError;
DWORD dwBytes;

DWORD dwFlags = 0;
INT dx = (signed char)m_pbDataBuffer[1];
INT dy = (signed char)m_pbDataBuffer[2];

BOOL fButton1 = m_pbDataBuffer[0] & 0x01 ? TRUE : FALSE;
BOOL fButton2 = m_pbDataBuffer[0] & 0x02 ? TRUE : FALSE;
BOOL fButton3 = m_pbDataBuffer[0] & 0x04 ? TRUE : FALSE;

if (!(*m_lpUsbFuncs->lpGetTransferStatus)(m_hInterruptTransfer, &dwBytes,&dwError))
{
DEBUGMSG(ZONE_ERROR,(TEXT("!USBMouse: Error in GetTransferStatus(0x%X)\r\n"),
m_hInterruptTransfer));
return FALSE;
}
else
{
DEBUGMSG(ZONE_TRANSFER,(TEXT("USBMouse::HandleInterrupt, hTransfer 0x%X complete (%u bytes, Error:%X)\r\n"),
m_hInterruptTransfer,dwBytes,dwError));
}

if (!SubmitInterrupt())
return FALSE;

if(dwError != USB_NO_ERROR)
{
DEBUGMSG(ZONE_ERROR,(TEXT("!USBMouse: Error 0x%X in interrupt transfer\r\n"),dwError));
return TRUE;
}

if(dwBytes < 3)
{
DEBUGMSG(ZONE_ERROR,(TEXT("!USBMouse: Invalid byte cnt %u from interrupt transfer\r\n"),dwBytes));
return TRUE;
}

if(dx || dy)
dwFlags |= MOUSEEVENTF_MOVE;

if(fButton1 != m_fPrevButton1)
{
if(fButton1)
dwFlags |= MOUSEEVENTF_LEFTDOWN;
else
dwFlags |= MOUSEEVENTF_LEFTUP;
}

if(fButton2 != m_fPrevButton2)
{
if(fButton2)
dwFlags |= MOUSEEVENTF_RIGHTDOWN;
else
dwFlags |= MOUSEEVENTF_RIGHTUP;
}

if(fButton3 != m_fPrevButton3)
{
if(fButton3)
dwFlags |= MOUSEEVENTF_MIDDLEDOWN;
else
dwFlags |= MOUSEEVENTF_MIDDLEUP;
}

m_fPrevButton1 = fButton1;
m_fPrevButton2 = fButton2;
m_fPrevButton3 = fButton3;

DEBUGMSG(ZONE_EVENTS,
(TEXT("USBMouse event: dx:%d, dy:%d, dwFlags:0x%X (B1:%u, B2:%u, B3:%u)\r\n"),
dx,dy,dwFlags,fButton1,fButton2,fButton3));

// 通知pȝ产生鼠标事g
if (m_fReadyForMouseEvents)
mouse_event(dwFlags, dx, dy, 0, 0);
else
m_fReadyForMouseEvents = IsAPIReady(SH_WMGR);

return TRUE;
}


DWORD CALLBACK CMouse::MouseTransferCompleteStub(LPVOID lpvNotifyParameter)
{
CMouse * pMouse = (CMouse *)lpvNotifyParameter;
return(pMouse->MouseTransferComplete());
}

// 数据传输完毕回调函数
DWORD CMouse::MouseTransferComplete()
{
if (m_hEvent)
SetEvent(m_hEvent);
return 0;
}


ULONG CALLBACK CMouse::MouseThreadStub(PVOID context)
{
CMouse * pMouse = (CMouse *)context;
return(pMouse->MouseThread());
}

// USB鼠标U程
DWORD CMouse::MouseThread()
{
DEBUGMSG(ZONE_INIT,(TEXT("USBMouse: Worker thread started\r\n")));
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);

if (SubmitInterrupt())
{
while (!m_fClosing)
{
WaitForSingleObject(m_hEvent, INFINITE);

if (m_fClosing)
break;

if ((*m_lpUsbFuncs->lpIsTransferComplete)(m_hInterruptTransfer))
{
if (!HandleInterrupt())
break;
}
else
{
RETAILMSG(1,(TEXT("!USBMouse: Event signalled, but transfer not complete\r\n")));
// The only time this should happen is if we get an error on the transfer
ASSERT(m_fClosing || (m_hInterruptTransfer == NULL));
break;
}
}
}
RETAILMSG(1,(TEXT("USBMouse: Worker thread exiting\r\n")));
return(0);
}

? C(jin)没有Q其实USB的驱动程序编写就q么单,cM的其他设备,例如打印备,有Bulk OUT PIPEQ需要Bulk传输Q那需要了(jin)解一下IssueBulkTransferQ)(j)的应用。当然如果是开发USB Mass Storage Disk的驱动,那就需要了(jin)解更多的协议Q例如Bulk-Only Transport协议{?

微Y的Windows CE.NET的Platform Build中已l带有USB Printer和USB Mass Storage Disk的驱动的源代码了(jin)Q好好研I一下,你一定回受益非浅的?



参考资料:(x)
1Q?微Y出版C?<<Windows Ce Device Driver Kit>>
2Q?<<Universal Serial Bus Specification 1.1>> 来自http:://www.usb.org

井泉 2008-12-03 10:35 发表评论
]]>
Windows CE 6.0中断处理q程 by ninglinghttp://www.shnenglu.com/zjj2816/archive/2008/12/02/68406.html井泉井泉Tue, 02 Dec 2008 09:00:00 GMThttp://www.shnenglu.com/zjj2816/archive/2008/12/02/68406.htmlhttp://www.shnenglu.com/zjj2816/comments/68406.htmlhttp://www.shnenglu.com/zjj2816/archive/2008/12/02/68406.html#Feedback0http://www.shnenglu.com/zjj2816/comments/commentRss/68406.htmlhttp://www.shnenglu.com/zjj2816/services/trackbacks/68406.html

q里我们主要讨论的是CE的中断徏立和中断相应的大概流E以?qing)所涉及(qing)的代码位|。这里所讲述的,是针对ARMq_的。在CE的中断处理里面,有一部分工作是CE Kernel完成的,有一部分工作是要由O(jin)EM完成的?/p>

Kernel代码工作

ExVector.sQ中断向量定义,里面定义的是armtrap.s的函数地址

Armtrap.sQ中断处理定义,最重要是里面的IRQHandler函数Q而其中最重要的是CALL OEMInterruptHandler

Mdarm.cQ中断向量加?/span>

Kdriver.cQ?/span>NKCallIntChain函数Q把IRQ转换?/span>SysIntrQ值得留意的是pIntChainTable[]Q是IRQ所对应?/span>ISR处理E序的入口,其中最主要的是其成员函?/span>pfnHandler?/span>pfnHandler的填充,是在HookIntChain里面Q这个函数是ISR在初始化的时候调用的。在q个函数里面Q如?/span>pIntChainTable为空Q则q回SYSINTR_CHAINQ如?/span>pIntChainTable[]不ؓ(f)I,则调?/span>pfnHandler得到一?/span>sysintr|然后q回之?/span>

 

OEM定义工作Q?/span>Oalintr.cQ?/span>OEMInterruptHandler函数Q通过查询g的中断寄存器Q得到硬?/span>IRQ受对?/span>EINT04-23的中断,通过EINTMASK寄存器,得到相对应的pȝIRQ。注意,q里?/span>IRQ?/span>CE定义?/span>IRQQ是pȝgIRQ的扩展。然后调?/span>NKCallIntChain看看q个IRQ是否是一?/span>Chain?/span>Interrupt。如果函数返?/span>SYSINTR_CHAIN或者返回一个不合法?/span>sysintrQ则通过OALIntrTranslateIrq?/span>IRQ转化?/span>sysintr。如果是一个合法的sysintrQ则q回该倹{?/span>

 

单一ISR?/span>DeviceQ主要通过OEMInterruptHandler处理Q在OEMInterruptHandler没有定义?/span>IRQQ可以在OAL里面或者驱动的加蝲里面Q通过HookInterrupt函数q行兌?/span>

多个ISR?/span>DeviceQ通常q是ȝ讑֤的需求,因ؓ(f)ȝ讑֤上面通常串有几个讑֤。这些ȝ上的讑֤Q需要有一?/span>ISR判断I竟是哪个设备发出的中断。这?/span>ISRQ是一?/span>DLL的程序,讑֤驱动必须在初始化的时候通过LoadIntChainHandlerQ文件名Q函数名Q?/span>irqQ加载这?/span>DLLE序?/span>LoadIntChainHandler的定义在kdriver.c?/span>NKLoadIntChainHandler里面。对于大多数的ȝ讑֤Q可以利用微软已l写好的giisr.dll来实现?/span>giisr的实C码在Public\common\oak\drivers下面?/span>

 

对于ȝ讑֤Q如果利?/span>GIISR的话Q原理如下:(x)

ȝ讑֤驱动在初始化的时候,通过LoadIntChainHandler加蝲GIISRQ而加载的时候,LoadIntChainHandler?x)调?/span>GIISR?/span>CreateInstance创徏一个实例,GIISR?x)返回一?/span>index值给LoadIntChainHandlerQ以标示实例Q?/span>LoadIntChainHandler则会(x)q回一?/span>Handlel驱动,驱动则根据这?/span>Handle存取GIISR。得到这?/span>handle之后Q初始化q需要包括从reg表里面读出相关的初始化参敎ͼ?/span>GIISRq行赋|譬如Port AddressQ?/span>Mask AddressQ?/span>SysIntr{?/span>

 

驱动E序在初始化的时候:(x)

1、创Z?/span>EventQ?/span>CreateEventQ?/span>

2、然后用InterruptInitialize函数?/span>sysintr和这?/span>Event相关?/span>

3?/span>Kick-off一?/span>ThreadQ?/span>ISTQ?/span>

4、这?/span>Thread最l是WaitForSingleObjectQ?/span>EventIDQ?/span>

具体的例子,可以参阅USBFN的例子:(x)sc2410pdd.cpp里面Q?/span>UfnPdd_Start函数Q?/span>

Published Sunday, June 10, 2007 7:13 PM by ningling

井泉 2008-12-02 17:00 发表评论
]]>
Windows CE下驱动开发基 付林?/title><link>http://www.shnenglu.com/zjj2816/archive/2008/11/28/68088.html</link><dc:creator>井泉</dc:creator><author>井泉</author><pubDate>Fri, 28 Nov 2008 08:59:00 GMT</pubDate><guid>http://www.shnenglu.com/zjj2816/archive/2008/11/28/68088.html</guid><wfw:comment>http://www.shnenglu.com/zjj2816/comments/68088.html</wfw:comment><comments>http://www.shnenglu.com/zjj2816/archive/2008/11/28/68088.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/zjj2816/comments/commentRss/68088.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/zjj2816/services/trackbacks/68088.html</trackback:ping><description><![CDATA[<span lang="zh-cn"></span>q是我从1?日开始主持天极网论坛嵌入式开发版以来W一ơ发表文章,加上以前琐碎的文章共 ?0。研I的多p感觉自己懂的太少Q其实在驱动开发方面我q是个菜鸟,我是惛_ơ抛砖引玉,让做驱动有Nq经验的人奉献一点出来,让大家减一? 研究驱动源码而又~少注释所带来的痛苦?br> <span lang="zh-cn">  </span>我想即读者看q微软的关于驱动开发的培训教材和CE帮助文档中的驱动部分Q头脑中仍然一片茫然。要想真正了(jin)解驱动程序必ȝ合一些驱动程序源码,在此我以串口驱动E序QCOM16550Q中初始化过Eؓ(f)U烦(ch)单讲一讲驱动开发的基础知识?br> <span lang="zh-cn">  </span>Windows CE下的串口驱动E序能够处理所有I/O行ؓ(f)cM串口的设备,包括Z16450?6550 UARTQ通用异步收发芯片Q的讑֤和一些采用DMA的设备,常见的有9针串口、红外I/O口、Modem{。在%_WINCEROOT%\Public \Common\OAK\Drivers\Serial目录下,COM_MDD2子目录包含新的串口驱动MDD层函C码。COM16550子目录包含串 口驱动PDD层代码。SER16550子目录包含的一pd函数专用于控制与16550兼容的UARTQ这样PDD层的主要工作是调用SER16550? 的函数。还有一个ISR16550子目录包含的是串口驱动程序专用的可安装ISRQ中断服务例E)(j)Q而很多硬件设备驱动程序采用CE默认的可安装ISR giisr.dll。一般串口设备相应的注册表设|例子及(qing)意义如下Q? <table style="border-collapse: collapse;" id="AutoNumber1" border="1" bordercolor="#111111" cellpadding="0" cellspacing="0" width="90%"> <tbody> <tr> <td align="center" width="40%"><strong>?/strong></td> <td align="center" width="60%"><strong>意义</strong></td> </tr> <tr> <td width="40%">"SysIntr"=dword:13</td> <td width="60%">串口1的中断ID为十q制13</td> </tr> <tr> <td width="40%">"IoBase"=dword:02F8</td> <td width="60%">串口1的IOI间首地址为十六进?F8</td> </tr> <tr> <td width="40%">"IoLen"=dword:8</td> <td width="60%">串口1的IOI间长度?个字?/td> </tr> <tr> <td width="40%">"DeviceArrayIndex"=dword:0</td> <td width="60%">串口1的烦(ch)引,?的由?/td> </tr> <tr> <td width="40%">"Order"=dword:0</td> <td width="60%">串口1驱动的加载顺?/td> </tr> <tr> <td width="40%">"DeviceType"=dword:0</td> <td width="60%">串口1的设备类?/td> </tr> <tr> <td width="40%">"DevConfig"=hex: 10,00 ....</td> <td width="60%">串口1在与Modem讑֤通讯时的配置Q如波特率、奇偶校(g){?/td> </tr> <tr> <td width="40%">"FriendlyName"="COM1:"</td> <td width="60%">串口1在拨L(fng)序中昄的名?/td> </tr> <tr> <td width="40%">"Tsp"="Unimodem.dll"</td> <td width="60%">串口1 被用于与Modem讑֤通讯的时候要加蝲的TSPQTAPI Service providerQDLL</td> </tr> <tr> <td width="40%">"Prefix"="COM"</td> <td width="60%">串口1的流接口的前~</td> </tr> <tr> <td width="40%">"Dll"="com16550.Dll"</td> <td width="60%">串口1的驱动程序DLL</td> </tr> </tbody> </table> <p><span lang="zh-cn">  </span>SysIntr 由CE在文件Nkintr.h中预定义Q用于唯一标识中断讑֤。OEM可以在文件Oalintr.h中定义自qSysIntr。常见的预定? SysIntr有SYSINTR_NOPQ中断只由ISR处理QIST不再处理Q,SYSINTR_RESCHEDQ重新调度线 E)(j)QSYSINTR_DEVICESQ由CE预定义的讑֤中断ID的基|(j)QSYSINTR_PROFILE、SYSINTR_TIMING? SYSINTR_FIRMWARE{都是基于SYSINTR_DEVICES定义的。IoBase是串?的IO地址I间的首地址QIoLen是IOI间 的大。IO地址I间只存在于x86q_Q如果在其它q_g寄存器必L到物理地址I间Q那子键的名UCؓ(f)MemBase和MemLen。在x86q_ 更多g的寄存器׃IOI间的局限也映射到物理地址I间。DeviceArrayIndex是设备的索引Q用于区分同cd的设备。Prefix是流驱动 E序的前~Q当应用E序调用CreateFile函数传递COM1:参数Ӟ文gpȝ负责与串口驱动程序通信Q串口驱动程序是在CE启动时由 device.exe加蝲的?br> <br> <span lang="zh-cn">  </span>下面从MDD 层函数COM_Init开始探索串口驱动的初始化过E。COM_Init是在串口讑֤被检后p备管理器device.exe调用的,主要的作用是初始 化设备,它的唯一参数Identifier是由device.exe传递的Q其cd是一个字W串指针Q字W串的内Ҏ(gu)HLM\Drivers \Active\xxQxx是一个十q制敎ͼdevice.exe?x)跟t系l中每个驱动E序Q把加蝲的驱动程序记录在Active键下Q? COM_Init先分配一个HW_INDEP_INFOl构体,q个l构体是独立于串口硬件的头信息(MDD、PDD、SER16550都包含自q特的 l构体,具体的结构体定义请参见串口驱动源码)(j)Q分配之后再初始化结构体中每个成员,初始化结构体后调? OpenDeviceKey((LPCTSTR)Identifier)打开HLM\Drivers\Active\xx\Key包含的注册表路径Q在q? 里\径一般ؓ(f)HLM\Drivers\BuiltIn\SerialQ即串口的驱动程序信息在注册表中所处的位置。COM_Init接着在HLM \Drivers\BuiltIn\Serial下查询DeviceArrayIndex、Priority256的|Priority256指定?jin)? 动程序的优先U,如果没有q默认的优先。接下来调用GetSerialObject(DeviceArrayIndex)Q这个函数由P(pn)DD层定义, q回HWOBJl构体,q个l构体主要包含PDD层和SER16550定义的函数的指针。也是说MDD通过调用q个函数才能调用底层实现的函数。接下来 的大多数工作都是调用底层函数实现初始化。第一个调用的底层函数SerInit主要讄q戯|的g配置Q例如线路控制、L特率。它调用 Ser_GetRegistryData函数得到保存在注册表中的g信息QSer_GetRegistryData在内部调用系l提供的 DDKReg_GetIsrInfoDDK和DDKReg_GetWindowInfo函数得到在HLM\Drivers\BuiltIn\Serial 下保存的IRQ、SysIntr、IsrDll、IsrHandler、IoBase、IoLen。IRQ是逻辑中断PIsrDll表示当前驱动E序? 可安装ISR所在的DLL名称QIsrHandler 表示可安装ISR的函数名U。在q里Z提一下可安装ISRQ读者在我以前发表的关于OAL的文章中可以?jin)解到OEM在OEMInit函数中关联IRQ? SysIntrQ当g讑֤发生中断ӞISR?x)禁止同U和低中断Q然后根据IRQq回兌的SysIntrQ内核根据ISRq回的SysIntr唤醒 相应的ISTQSysIntr与IST创徏的Event兌Q,IST处理中断之后调用InterruptDone解除中断止。在OEMInit中关? 的缺Ҏ(gu)一旦编译了(jin)CE内核后就无法dq种兌?jin),而一些硬件设备会(x)随时插拔或者共享中断,要关联这L(fng)g讑֤解决Ҏ(gu)是可安装ISRQ可安装 ISR专用于处理指定的g讑֤发出的中断,所以如果硬件设备需要可安装ISR必须在注册表中添加I(yng)srDll、IsrHandler。多数硬件设备采? CE默认的可安装ISR giisr.dllQ格式如下:(x)</p> <pre> "IsrDll"="giisr.dll"<br>"IsrHandler"="ISRHandler"</pre> <p><span lang="zh-cn">  </span>如果一个硬仉动程序需要可安装ISR而开发者又不想自己写一个,那么可以利用giisr.dll来实现。除?jin)在注册表中d如上所C外Q还要在驱动E序中调用相兛_数注册可安装ISR。伪代码如下Q?/p> <pre>g_IsrHandle = LoadIntChainHandler(IsrDll, IsrHandler, (BYTE)Irq);<br>GIISR_INFO Info;<br>PHYSICAL_ADDRESS PortAddress = {PhysAddr, 0};<br>TransBusAddrToStatic(BusType, dwBusNumber, PortAddress, dwAddrLen, &dwIOSpace, &(PVOID)PhysAddr)<br>Info.SysIntr = dwSysIntr;<br>Info.CheckPort = TRUE;<br>Info.PortIsIO = (dwIOSpace) ? TRUE : FALSE;<br>Info.UseMaskReg = TRUE;<br>Info.PortAddr = PhysAddr + 0x0C;<br>Info.PortSize = sizeof(DWORD);<br>Info.MaskAddr = PhysAddr + 0x10;<br>KernelLibIoControl(g_IsrHandle, IOCTL_GIISR_INFO, &Info, sizeof(Info), NULL, 0, NULL);</pre> <p><span lang="zh-cn">  </span>LoadIntChainHandler 函数负责注册可安装ISRQ参?为DLL名称Q参?为ISR函数名称Q参?为IRQ。TransBusAddrToStatic函数在后面讲。如? 要利用giisr.dll作ؓ(f)可安装ISRQ必d填充GIISR_INFOl构体,CheckPort=TRUE表示giisr要检指定的寄存器来? 定当前发Z断的是否是这个设备。PortIsIO表示寄存器地址属于哪个地址I间QFALSE表示是内定空_(d)TRUE表示IOI间? UseMaskReg=TRUE表示讑֤有一个掩码寄存器Q专用于指定当前讑֤是否是中断源Q也是发出中断Q而MaskAddr表示掩码寄存器的地址? 如果对Info.Mask赋|那么PortAddr表示一个特D的寄存器地址Q这个寄存器的gMask的?amp;q算的结果如果ؓ(f)真,则证明当? 讑֤是中断源Q否则返回SYSINTR_CHAINQ表C当前ISR没有处理中断Q内核将调用ISR链中下一个ISRQ,如果 UseMaskReg=TRUEQ那么MaskReg寄存器的gPortAddr指定的寄存器的?amp;q算的结果如果ؓ(f)真,则证明当前设备是中断 源?br> <span lang="zh-cn">  </span>函数SerInit接着调用函数 Ser_InternalMapRegisterAddresses转换IO地址q且映射? 址QSer_InternalMapRegisterAddresses在内部调用系l提供的HalTranslateBusAddress(Isa, 0, ioPhysicalBase, &inIoSpace, &ioPhysicalBase)函数与ȝ相关的地址转换为系l地址Q参?为ȝcdQ参?为ȝP参数3转换的地址 QPHYSICAL_ADDRESScdQ实际是LARGE_INTEGER型)(j)Q参?指定寄存器地址属于IO地址I间q是物理地址I间Q参?q回? 换后的物理地址。观察HalTranslateBusAddress的源码得知如果是在x86q_Q这个函数除?jin)把参?赋给?jin)参?其余什么都没有做, 而非x86q_inIoSpace的值置?Q表CZ定是物理地址。在调用HalTranslateBusAddress前要定从注册表中得到的寄存 器地址到底是属于哪个地址I间的,例如Q?/p> <pre>ULONG inIoSpace = 1; ///1表示是IOI间<br>PHYSICAL_ADDRESS ioPhysicalBase = {iobase, 0}; ///相当于ioPhysicalBase.LowPart = iobase</pre> <p><span lang="zh-cn">  </span>在地址转换后就要将转换后的地址映射到驱动程序(一般IST和应用程序一栯行在用户模式Q能够访问的虚拟地址I间Q?x80000000以下Q和ISR能够讉K的静(rn)态虚拟地址I间中(0x80000000以上Q。例如:(x)</p> <pre>////如果地址属于物理地址I间<br>ioPortBase = (PUCHAR)MmMapIoSpace(ioPhysicalBase, Size, FALSE);<br>TransBusAddrToStatic(Isa, 0, ioPhysicalBase, Size, &inIoSpace, ppStaticAddress);</pre> <p><span lang="zh-cn">  </span>MmMapIoSpace函数负责物理地址映射到驱动程序能够访问的虚拟地址I间中,通过源码分析MmMapIoSpace在内部分别调用:(x)</p> <pre>pVirtualAddress =VirtualAlloc(0, SourceSize, MEM_RESERVE, PAGE_NOACCESS);<br>VirtualCopy(pVirtualAddress, (PVOID)(SourcePhys >> 8), SourceSize, PAGE_PHYSICAL | <br>PAGE_READWRITE | (CacheEnable ? 0 : PAGE_NOCACHE));</pre> <p><span lang="zh-cn">  </span>VirtualAlloc 分配一块和MemLen一样大的虚拟地址I间Q因为参??Q所以内核自动分配。一般MemLen于2MBQ所以会(x)在应用程序的地址I间中分配? VirtualCopy负责硬件设备寄存器的物理地址与VirtualAlloc分配的虚拟地址做一个映关p,q样驱动E序讉K PvirtualAddress实际上就是访问第一个寄存器。因为硬件设备寄存器的物理地址一定是?12MBQCE支持RAM的最大|(j)以上Q所以除? 最后的参数要加PAGE_PHYSICAL外,W二个参数物理地址也要右移8位(或者除?56Q。映硬件寄存器当然PAGE_NOCACHE是必d 的。TransBusAddrToStatic函数负责物理地址映射到ISR能够讉K的静(rn)态虚拟地址I间中,当出C断共享时QISR要负责访问硬件设 备的某一个寄存器来判断中断源Q所以将寄存器的物理地址映射到静(rn)态虚拟地址I间中是必要的(ISR只能讉K?rn)态的虚拟地址I间Q。所谓静(rn)态虚拟地址I间? 指在OEMAddressTable中定义的虚拟地址I间Q当然是0x80000000以上Q。在x86q_一般这个表只定义RAM的物理地址与虚拟地址 对应关系Q而硬件设备的寄存器地址q不在该表中定义Q所以如果要创徏一块静(rn)态的虚拟地址I间供ISR讉KQ必d此之前调? CreateStaticMapping函数?xC4000000?xE0000000虚拟地址I间中分配? TransBusAddrToStatic函数在内部就是调用了(jin)CreateStaticMapping函数。注Q硬件设备的寄存器地址也可以在 OEMAddressTable中定义?/p> <pre>////如果地址属于IOI间<br>ioPortBase = (PUCHAR)ioPhysicalBase.LowPart;<br>*ppStaticAddress=ioPortBase</pre> <p>q种情况只属于x86q_Q是IOI间可以直接访问,即是用h式?br> <span lang="zh-cn">  </span>SerInit 函数接着初始化SER_INFOl构体成员,之后调用SL_Init函数Q这个函数在ser16550中定义,负责初始化SER16550_INFOl构 体,在这个结构体中保存(sh)?个寄存器的地址。SerInit函数执行完毕后COM_Init函数创徏接收~冲区,然后调用 StartDispatchThread函数初始化中断ƈ且创建IST。StartDispatchThread函数在内部调? InterruptInitialize函数兌SysIntr和EventQ然后调用InterruptDone函数告诉内核当前串口可以中断处理Q接 着调用CreateThread函数创徏ISTU程。(over吧,再往下说和串口g有关?jin),看多了(jin)没注释的代码我也?ch)Q!Q?/p><img src ="http://www.shnenglu.com/zjj2816/aggbug/68088.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/zjj2816/" target="_blank">井泉</a> 2008-11-28 16:59 <a href="http://www.shnenglu.com/zjj2816/archive/2008/11/28/68088.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Enumhandlehttp://www.shnenglu.com/zjj2816/archive/2008/11/28/68083.html井泉井泉Fri, 28 Nov 2008 08:30:00 GMThttp://www.shnenglu.com/zjj2816/archive/2008/11/28/68083.htmlhttp://www.shnenglu.com/zjj2816/comments/68083.htmlhttp://www.shnenglu.com/zjj2816/archive/2008/11/28/68083.html#Feedback0http://www.shnenglu.com/zjj2816/comments/commentRss/68083.htmlhttp://www.shnenglu.com/zjj2816/services/trackbacks/68083.html
#include "ntdll.h"
#include <stdlib.h>
#include <stdio.h>
#include "ntddk.h"

#define DUPLICATE_SAME_ATTRIBUTES 0x00000004

#pragma comment(lib,"ntdll.lib")

BOOL EnablePrivilege(PCSTR name)
{
TOKEN_PRIVILEGES priv = {1, {0, 0, SE_PRIVILEGE_ENABLED}};
LookupPrivilegeValue(0, name, &priv.Privileges[0].Luid);

HANDLE hToken;
OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);

AdjustTokenPrivileges(hToken, FALSE, &priv, sizeof priv, 0, 0);
BOOL rv = GetLastError() == ERROR_SUCCESS;

CloseHandle(hToken);
return rv;
}

int main(int argc, char *argv[])
{
if (argc == 1) return 0;

ULONG pid = strtoul(argv[1], 0, 0);

EnablePrivilege(SE_DEBUG_NAME);

HANDLE hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, pid);

ULONG n = 0x1000;
PULONG p = new ULONG[n];

while (NT::ZwQuerySystemInformation(NT::SystemHandleInformation, p, n * sizeof *p, 0)
== STATUS_INFO_LENGTH_MISMATCH)

delete [] p, p = new ULONG[n *= 2];

NT::PSYSTEM_HANDLE_INFORMATION h = NT::PSYSTEM_HANDLE_INFORMATION(p + 1);

for (ULONG i = 0; i < *p; i++) {

if (h[i].ProcessId == pid) {
HANDLE hObject;

if (NT::ZwDuplicateObject(hProcess, HANDLE(h[i].Handle), NtCurrentProcess(), &hObject,
0, 0, DUPLICATE_SAME_ATTRIBUTES)
!= STATUS_SUCCESS) continue;

NT::OBJECT_BASIC_INFORMATION obi;

NT::ZwQueryObject(hObject, NT::ObjectBasicInformation, &obi, sizeof obi, &n);

printf("%p %04hx %6lx %2x %3lx %3ld %4ld ",
h[i].Object, h[i].Handle, h[i].GrantedAccess,
int(h[i].Flags), obi.Attributes,
obi.HandleCount - 1, obi.PointerCount - 2);

n = obi.TypeInformationLength + 2;

NT::POBJECT_TYPE_INFORMATION oti = NT::POBJECT_TYPE_INFORMATION(new CHAR[n]);

NT::ZwQueryObject(hObject, NT::ObjectTypeInformation, oti, n, &n);

printf("%-14.*ws ", oti[0].Name.Length / 2, oti[0].Name.Buffer);

n = obi.NameInformationLength == 0
? MAX_PATH * sizeof (WCHAR) : obi.NameInformationLength;

NT::POBJECT_NAME_INFORMATION oni = NT::POBJECT_NAME_INFORMATION(new CHAR[n]);

NTSTATUS rv = NT::ZwQueryObject(hObject, NT::ObjectNameInformation, oni, n, &n);
if (NT_SUCCESS(rv))
printf("%.*ws", oni[0].Name.Length / 2, oni[0].Name.Buffer);

printf("\n");

CloseHandle(hObject);
}
}
delete [] p;

CloseHandle(hProcess);

return 0;
}

井泉 2008-11-28 16:30 发表评论
]]>
ھƷ˾þþþ| þþþƷsmվ | þþþ| þþƷ| þþƷӰԺ| þþƷĻþ| www.þ| þùƷþþ| þùӾƷŮ| Ʒþþþþø69| þþžžƷ99Ʒ| þþƷAVũ帾Ů| ٸ߳ҽоþþþþ| ˾þĻ| þó˹Ʒ| ɫۺϾþþþۺһ | ۺϾþúݺɫ99h| Ʒþøһ| þþavҰһ| 99þþƷ| ŷƷһƷþ| ߳þѹۿ| ɫۺϾþþþۺ99| ھƷ˾þþþø| 㽶þҹɫƷ| 69ۺϾþþƷ| ˾þô߽Ʒ| ɫ͵͵88ŷƷþþ| þþþþþƷ| þþŮһ| þ91ۺϹ91þþƷ| Ʒþþþ| þþþþþ91Ʒѹۿ| ɫþþۺ| һaƬþëƬ| ˹ھƷþþþӰԺVR| ɫ͵͵88ŷƷþþ| þAVӰ| ޹˾þۺ3d | ŷղþ99| 91Ƶ91þþ|