⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 windowsce_net 420串口驱动分析(2)--jesse.htm

📁 WinCE下串口编程应用实例
💻 HTM
📖 第 1 页 / 共 5 页
字号:
                        lang=EN-US>MDD</SPAN></B><B 
                        style="mso-bidi-font-weight: normal"><SPAN 
                        style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">部分</SPAN><SPAN 
                        lang=EN-US><O:P></O:P></SPAN></B> 
                  </P></TD></TR></TBODY></TABLE>
                  <P class=MsoNormal><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">由于串口驱动由</SPAN><SPAN 
                  lang=EN-US>Device.exe</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">直接调用,所以</SPAN><SPAN 
                  lang=EN-US>MDD</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">部分是以完整的</SPAN><SPAN 
                  lang=EN-US>Stream</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口给出的</SPAN><SPAN 
                  lang=EN-US>. </SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">也就具备基于</SPAN><SPAN 
                  lang=EN-US>Stream</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接口的驱动程序所需的函数实现,包括</SPAN><SPAN 
                  lang=EN-US>COM_Init</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,</SPAN><SPAN 
                  lang=EN-US>COM_Deinit</SPAN> </P>
                  <P class=MsoNormal><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,</SPAN><SPAN 
                  lang=EN-US>COM_Open,COM_Close ,COM_Read ,COM_Write, COM_Seek,, 
                  COM_PowerUp, COM_PowerDown, COM_IOControl</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">几个基本实现。由于串口发送</SPAN><SPAN 
                  lang=EN-US>/</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">接收的信息并不能定位,而仅仅是简单的传送,所以</SPAN><SPAN 
                  lang=EN-US>COM_Seek</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">仅仅是形式上实现了一下。</SPAN> 
                  </P>
                  <P class=MsoNormal><SPAN lang=EN-US><O:P>&nbsp;</O:P></SPAN> 
                  </P>
                  <P class=MsoNormal><B 
                  style="mso-bidi-font-weight: normal"><SPAN 
                  lang=EN-US>COM_Init<O:P></O:P></SPAN></B> </P>
                  <P class=MsoNormal><SPAN lang=EN-US>COM_Init</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是该驱动的初始化函数</SPAN><SPAN 
                  lang=EN-US>,</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在设备管理器加载该驱动后首先调用,用于初始化所需的变量,硬件设备等资源。该过程分配代表设备硬件实例的数据结构,并通过硬件抽象接口</SPAN><SPAN 
                  lang=EN-US>HWInit</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">初始化硬件。同时该函数会调用</SPAN><SPAN 
                  lang=EN-US>InterruptInitialize</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">为接收内核中的逻辑中断创建相应事件并初始化临界区。该函数还需要得到硬件缓冲器的物理地址和获知该缓冲器的大小</SPAN><SPAN 
                  lang=EN-US>(</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">该冲器最小为</SPAN><SPAN 
                  lang=EN-US>2K)</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。最后它将建立相应的缓冲作为接收的中介。下面我们来看这个函数的实现过程。</SPAN> 
                  </P>
                  <P class=MsoNormal><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在函数中定义了两个重要的变量。</SPAN><SPAN 
                  lang=EN-US>pSerialHead</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">和</SPAN><SPAN 
                  lang=EN-US>pHWHead.</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">前者用于描述相应的串口的状态,后者则是对应硬件的数据抽象。首先为</SPAN><SPAN 
                  lang=EN-US>pSerialHead</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">分配空间和初始化链表和临界区等数据并同时为接收和发送中断创建事件。然后再从注册表中获得当前的注册项值</SPAN><SPAN 
                  lang=EN-US>(</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">由于</SPAN><SPAN 
                  lang=EN-US>device.exe</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">是根据注册表键值来调用驱动的,当前键注册表项指的就是与上述键值在同一根下的注册项</SPAN><SPAN 
                  lang=EN-US>)</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。得到</SPAN><SPAN 
                  lang=EN-US>DeviceArrayIndex</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、</SPAN><SPAN 
                  lang=EN-US>Priority256</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">键下的具体值后就可以调用</SPAN><SPAN 
                  lang=EN-US>GetSerialObject(</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</SPAN><SPAN 
                  lang=EN-US>PDD</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中实现</SPAN><SPAN 
                  lang=EN-US>)</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">来获得具体的</SPAN><SPAN 
                  lang=EN-US>HWObj</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对象,并通过该对象来调用硬件初始化函数了。</SPAN><SPAN 
                  lang=EN-US>(</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">由于在这里已经对硬件进行了初始化,之后的返回都需要调用</SPAN><SPAN 
                  lang=EN-US>COM_Deinit</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">来完成。</SPAN><SPAN 
                  lang=EN-US>)</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">由于硬件初始化</SPAN><SPAN 
                  lang=EN-US>(</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">实际的驱动初始化代码</SPAN><SPAN 
                  lang=EN-US>)</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">已经得到执行这个时候就只有分配和初始化缓冲的工作需要做了。所以调用</SPAN><SPAN 
                  lang=EN-US>HWGetRxBufferSize(PDD</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">代码</SPAN><SPAN 
                  lang=EN-US>)</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">来获取</SPAN><SPAN 
                  lang=EN-US>PDD</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中设定的缓冲大小,并根据返回的具体值分配缓冲。最后如果</SPAN><SPAN 
                  lang=EN-US>BindFlags</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">被设定为</SPAN><SPAN 
                  lang=EN-US>THREAD_AT_INIT</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">就再调用</SPAN><SPAN 
                  lang=EN-US>StartDispatchThread</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">启动分发线程</SPAN><SPAN 
                  lang=EN-US>(</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">实际的</SPAN><SPAN 
                  lang=EN-US>IST)</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">。这样就完成了系统初始化的操作。</SPAN> 
                  </P>
                  <P class=MsoNormal><SPAN lang=EN-US><O:P>&nbsp;</O:P></SPAN> 
                  </P>
                  <P class=MsoNormal><B 
                  style="mso-bidi-font-weight: normal"><SPAN 
                  lang=EN-US>COM_Deinit<O:P></O:P></SPAN></B> </P>
                  <P class=MsoNormal><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">当驱动被称被卸下的时候该事件启动,用作与</SPAN><SPAN 
                  lang=EN-US>COM_Init</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">相反的操作。这个过程大致会释放驱动中所使用的资源,停止期间创建的线程等操作。具体说来,大致为停止在</SPAN><SPAN 
                  lang=EN-US>MDD</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中的所有</SPAN><SPAN 
                  lang=EN-US>IST</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">,和释放内存资源和临界区等系统资源。同时还需调用</SPAN><SPAN 
                  lang=EN-US>HWDeinit</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">来释放</SPAN><SPAN 
                  lang=EN-US>PDD</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">中所使用到的系统资源。</SPAN> 
                  </P>
                  <P class=MsoNormal><SPAN lang=EN-US><O:P>&nbsp;</O:P></SPAN> 
                  </P>
                  <P class=MsoNormal><B 
                  style="mso-bidi-font-weight: normal"><SPAN 
                  lang=EN-US>COM_Open<O:P></O:P></SPAN></B> </P>
                  <P class=MsoNormal><SPAN lang=EN-US>COM_Oepn</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</SPAN><SPAN 
                  lang=EN-US>CreateFile</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">后被调用,用于以读</SPAN><SPAN 
                  lang=EN-US>/</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">写模式打开设备,并初始化所需要的空间</SPAN><SPAN 
                  lang=EN-US>/</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">资源等,创建相应的实例,为后面的操作做好准备。这里的代码相对比较容易,下面就简单讲一下。既然是初始化,肯定就免不了对参数的检查。首先检查通过</SPAN><SPAN 
                  lang=EN-US>COM_Init</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">返回的</SPAN><SPAN 
                  lang=EN-US>pHead</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">结构是否有效,这里虽然没有显式的在这两个函数之间传递参数,而是在设备管理器的内部传递这个参数的。<IMG 
                  height=254 
                  src="windowsCE_net 420串口驱动分析(2)--jesse.files/o_image010.gif" 
                  width=372></SPAN><SPAN lang=EN-US></SPAN> </P>
                  <P class=MsoNormal><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">之后是检查文件系统传递过来的</SPAN><SPAN 
                  lang=EN-US>Open</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">句柄中的</SPAN><SPAN 
                  lang=EN-US>Open</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">模式是否有效,这个参数由应用程序产生,通过文件系统直接传递到驱动。之后就开始初始化的操作,在这里将会建立相应的</SPAN><SPAN 
                  lang=EN-US>HW_OPEN_INFO</SPAN><SPAN 
                  style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">实体。下面和为该结构的定义。</SPAN> 
                  </P>
                  <P class=MsoNormal><SPAN lang=EN-US>typedef struct 
                  __HW_OPEN_INFO {</SPAN> </P>
                  <P class=MsoNormal><SPAN lang=EN-US><SPAN 
                  style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; 
                  </SPAN>PHW_INDEP_INFO<SPAN style="mso-spacerun: yes">&nbsp; 
                  </SPAN>pSerialHead;<SPAN 
                  style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>// @field 
                  Pointer back to our HW_INDEP_INFO</SPAN> </P>
                  <P class=MsoNormal><SPAN lang=EN-US><SPAN 
                  style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp; </SPAN>DWORD<SPAN 
                  style="mso-tab-count: 1">&nbsp;&nbsp;&nbsp; </SPAN><SPAN 
                  style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
                  </SPAN>AccessCode;<SPAN 
                  style="mso-spacerun: yes">&nbsp;&nbsp;&nbsp;&nbsp; </SPAN>// 
                  @field What permissions was this opened with</SPAN> </P>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -