织梦CMS - 轻松建站从此开始!

罗索实验室

当前位置: 主页 > 嵌入式开发 > Windows CE >

Wince下读取SD卡ID

落鹤生 发布于 2012-02-16 10:26 点击:次 
对于SD卡信息读取,我们只需要把精力放在客户端驱动层就可以,尤其需要关注Sdmemmain文件,Sdmemmain提供了为系统提供SMC_Init、SMC_Open和SMC_IOControl等函数进行系统调用。
TAG:

1.SD卡驱动架构

1.1Wince 下SD卡驱动协议栈
•  OST硬件底层部分 (主控制端驱动)      SDHC_XXX.DLLl
•  BUS 中间逻辑命令层 (总线驱动)        DBUS.DLL
•  CLIENT上层(客户端驱动)               SDMEMORY.DLL

1.1.1主控制端驱动
主控制端驱动控制包含主控制器硬件,遵循主控制端驱动接口,它被用于总线驱动通信和设置操作参数。主控制器驱动接口 提供一个硬件提取层,在总线和主控制端执行之间。即:SDHC_XXX.DLL是最底层,因为这层是硬件关联层,因此取名XXX便是为了对应的具体的硬件 BSP包(如本项目的硬件平台是ZYLONITE,其硬件供应商给的BSP包名即为ZYLONITE,在实际项目中我们便将SDHC_XXX.DLL取代 为SDHC_ZYLONITE.DLL),它负责具体的发命令,大多数情况下都需要修改。

1.1.2 总线驱动
总线驱动作为提取和管理层处于主控制驱动和客户端驱动之间。它包括在SDbus.dll文件。为客户端驱动提供了标准 的API,允许运行在任何的基于windows ce设备。总线驱动将是独立于应用程序和主控制端驱动,在不同的处理器之间移植,并不需要改动。SDBus.dll是中间层,负责整合命令和管理。

1.1.3 客户端驱动
客户端驱动和SD客户端驱动通信接口允许客户端驱动去和SD设备通信。客户端驱动接口是有计划地抽象SD总线物理设 备的执行,提供了客户端驱动最大的弹性。客户端驱动接口允许客户端驱动去衡量一个单一的,同步的访问存储卡驱动使用一个线程,异步通信设备驱动。 SDMemory.dll是最高层,类似于应用层。

对于SD卡信息读取,我们只需要把精力放在客户端驱动层就可以,尤其需要关注Sdmemmain文件,Sdmemmain提供了为系统提供SMC_Init、SMC_Open和SMC_IOControl等函数进行系统调用。

2.SD卡信息读取程序分析
2.1图形界面
•RegisterClass注册窗口
•CreateWindowEx 创建窗口
•ListBox控件
•Size位置设置
2.1.1RegisterClass 注册窗口

  1. // Register application main window class. 
  2. wc.style = 0;  // Window style 
  3. wc.lpfnWndProc = MainWndProc;    // Callback function 
  4. wc.cbClsExtra = 0;      // Extra class data 
  5. wc.cbWndExtra = 0;      // Extra window data 
  6. wc.hInstance = hInstance;        // Owner handle 
  7. wc.hIcon = NULL,        // Application icon 
  8. wc.hCursor = LoadCursor (NULL, IDC_ARROW);// Default cursor 
  9. wc.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); 
  10. wc.lpszMenuName = NULL; // Menu name 
  11. wc.lpszClassName = szAppName;    // Window class name 
  12.  
  13. if (RegisterClass (&wc) == 0) return 0; 

2.1.2 CreateWindowEx 创建窗口

  1. hWnd = CreateWindow (szAppName, // Window class 
  2. TEXT("SdInfo"),     // Window title 
  3. // Style flags 
  4. WS_VISIBLE | WS_CAPTION | WS_SYSMENU, 
  5. CW_USEDEFAULT,       // x position 
  6. CW_USEDEFAULT,       // y position 
  7. CW_USEDEFAULT,       // Initial width 
  8. CW_USEDEFAULT,       // Initial height 
  9. NULL,                // Parent 
  10. NULL,                // Menu, must be null 
  11. hInstance,           // Application instance 
  12. NULL);               // Pointer to create 
  13.  // parameters 
  14. if (!IsWindow (hWnd)) return 0;  // Fail code if not created.  

2.1.3ListBox控件

  1. hwndChild = CreateWindowEx (WS_EX_CLIENTEDGE, TEXT ("listbox"), 
  2. TEXT (""), WS_VISIBLE | WS_CHILD | WS_VSCROLL | 
  3. LBS_USETABSTOPS | LBS_NOINTEGRALHEIGHT, 0, 0, 
  4. 100, 100,hWnd, (HMENU)IDC_RPTLIST, hInst, NULL); 
  5.   
  6. // Destroy frame if window not created. 
  7. if (!IsWindow (hwndChild)) { 
  8.         DestroyWindow (hWnd); 
  9.         return 0; 
  10.   
  11. // Set tab-stop i to listbox 
  12. int i = 24; 
  13. SendMessage (hwndChild, LB_SETTABSTOPS, 1, (LPARAM)&i); 
  14. return 0;  

2.1.4 Size位置设置

  1. nWidth = LOWORD (lParam); 
  2. nHeight = HIWORD (lParam); 
  3.   
  4. x =  0; 
  5. y =  20; 
  6. cx = nWidth; 
  7. cy = nHeight - y; 
  8.   
  9. GetClientRect (hWnd, &rect); 
  10. //set listbox size 
  11. SetWindowPos (GetDlgItem (hWnd, IDC_RPTLIST), 0, x,y,cx,cy,SWP_NOZORDER); 

3.SD卡信息读取程序
3.1思路
SD卡事件–->读取信息-–>字符处理—>发送到Listbox并显示

SD卡事件
         SD卡事件很好解决,至于发送WM_DEVICECHANGE事件消息给程序就可以,依赖的头文件是<dbt.h>。

  1. const struct decodeUINT MainMessages[] = { 
  2. WM_CREATE,DoCreateFrame, 
  3. WM_SIZE, DoSizeFrame, 
  4. WM_DEVICECHANGE, DoSdbianren, 
  5. WM_DESTROY, DoDestroyMain, 
  6. };  

读取信息
         利用DeviceIoControl发送相关CTL命令来控制需要读取的信息,CTL命令依赖的头文件是diskio.h,如果SDK不包含,可以到WINCE6000下的Public的INC文件夹里面查找相关的定义。

  1. HANDLE FileHandle = CreateFile (TEXT("DSK2:"), GENERIC_READ|GENERIC_WRITE
  2. , 0, NULL, OPEN_EXISTING, 0, NULL); 
  3. if (FileHandle == INVALID_HANDLE_VALUE){ 
  4. Display(hWnd,L"-----------------------------------"); 
  5. Display(hWnd,L"DSK2 Load Faild"); 
  6. return 0; 
  7.   
  8. int Res = DeviceIoControl(FileHandle, IOCTL_DISK_GET_STORAGEID, NULL
  9. , 0, SDIdent, BufferLength, &ReturnedBytes, NULL); 

字符处理
         这个步骤是我卡壳最久的地方,参考网上的程序写,发现老是读不出,最后,看到一篇文章说,SD卡的ID号是char型的,而不是WCHAR,两者间需要进行转换,不然无法显示。

  1. WCHAR WBuffer1[BufferLength]; 
  2. memset(WBuffer1, 0,BufferLength); 
  3. char * SerialNo = (char *)((DWORD)SDIdent + SDIdent->dwManufactureIDOffset); 
  4. int nLen = strlen(SerialNo) +1; 
  5. int nwLen =  MultiByteToWideChar(CP_ACP, 0,SerialNo,nLen,   NULL, 0);  
  6. MultiByteToWideChar(CP_ACP, 0, SerialNo, nLen, WBuffer1, nwLen);//change char * to PWCHAR 
  7.  
  8. wsprintf(WBuffer,L"Serial=%s",WBuffer1); 
  9. Display(hWnd,WBuffer);  

发送到Listbox并显示

  1. void Display(HWND hWnd,PWCHAR Str) 
  2.          TCHAR szOut[128]; 
  3.          INT i; 
  4.   
  5.          wsprintf(szOut,TEXT("%s"),(LPTSTR)Str); 
  6.          i= SendDlgItemMessage (hWnd, IDC_RPTLIST, LB_ADDSTRING, 0, 
  7.                             (LPARAM)(LPCTSTR)szOut); 
  8.          if (i != LB_ERR) 
  9.         SendDlgItemMessage (hWnd, IDC_RPTLIST, LB_SETTOPINDEX,i, 
  10.                             (LPARAM)(LPCTSTR)szOut); 



 

(youyudehexie)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www1.rosoo.net/a/201202/15719.html]
本文出处:CSDN博客 作者:youyudehexie 原文
顶一下
(1)
100%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容