How to make winCE see an SD / MMC card after startup

I am working on software for a new tool that interacts with some kind of scientific equipment. The user interface is implemented through a Windows CE Pocket PC (Windows CE 600 V3.01 Build 195). The instrument is configured using one end of the flexible cable, which is always connected to the SD card slot on the PC. A cable enters the instrument and the other end connects to the installed SD card when it is present. The SD card contains a chip for use with the tool, as well as software / firmware updates as necessary, and a data file related to the chip. I have C # software that starts when WinCE loads. This application checks for the presence of an SDMMC card, because it depends on the data related to the accompanying chip for certain functions.

My problem. If an SD card is inserted at the other end of the flex cable when WinCE boots up, winCE detects the presence of the card and the \ SDMMC folder is created, allowing the software to read the data. If only a flexible cable is connected, but the SDMMC card is not present at the other end, Windows does not create a folder. This is what I expect. But our field engineers change the map for various reasons to replace the chip while the software is active. This is a problem if the windows load before the card is inserted. Due to the flexible cable, WinCE never detects that a card is inserted. He also never discovers that he has been deleted.

The software checks the SD card every 5 seconds. The firmware can determine through bits if a card is inserted, and it transfers this information to the software. If the card was previously missing, now it is detected, but the \ SDMMC folder is missing, I would like the software to call WinCE in order to try to detect again. I was thinking about using registry values, but it is not clear what the value of HKEY_LOCAL_MACHINE SDMMc can be written. I'm also not quite sure what the meanings mean. Can they be reset? I see that the Storage Manager registry will detect this, as shown below:

[HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\SDMMC] "Name"="SD MMC device" "Folder"="SD Card 

Is there any way to read / write this registry in order to click winCE to see that the card is inserted on the other end of the cable? AM I totally disagree with this thought? Is there any other way to do this?

Sorry for the long question. I usually play at the application level. The population of this problem did not give me the answers that I need, although perhaps I do not know enough to ask the right questions. Thanks for any help you can give me.

UPDATE: I am still trying to find a solution to this problem. My current thought is to get Windows CE to re-enumerate the device when my device firmware detects that a card is inserted. MY code is requesting firmware to receive a notification about this in my C # application. For my tool / application, the SD card is always in "Dsk2:". When a C # application receives a notification about inserting an SD card, it calls a method that performs the following actions:

CODE

  hDevice = CreateFile("\\Dsk2:", (0x80000000) | (0x40000000), 0, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero); if (hDevice == INVALID_HANDLE_VALUE) { int hDeviceError = Marshal.GetLastWin32Error(); // THis is an error - call GetLastERror to find // out what happened. using (StreamWriter bw = new StreamWriter(File.Open(App.chipDebugFile, FileMode.Append))) { String iua = "DevDriverInterface: error from CreateFile: " + hDeviceError.ToString(); bw.WriteLine(iua); } return false; } bResult = DeviceIoControl(hDevice, IOCTL_DISK_UPDATE_PROPERTIES, null, 0, null, 0, ref nBytesReturned, nOverLapped); 

/ CODE

In the above case, the call to CreateFile () failed with error 55: "The specified network resource or device is no longer available."

MY QUESTIONS: Am I trying to make re-enumeration of a device reasonable? Does CreateFile mean that I have to make an ActivateDevice () call? I see an example here: Problems with loading the device driver at startup - WM6.1 of someone calling ActivateDevice () from C # code and wondering if this will take care of the problem of getting WIndows CE to recognize that the SD card now inserted. Can someone help me understand what parameters need to be sent to the ActivateDevice () window? I do not agree with this approach?

This is a new territory for me, and I appreciate any help you can provide. Thanks.

+4
source share
3 answers

See the order of events in a properly functioning system.

  • The device downloads and loads the SD / MMC driver
  • The card is inserted in the card slot.
  • hardware interruption occurs (possibly power detection, possibly data - it depends on the OEM)
  • The interrupt handler notified the SDMMC driver that a card was present.
  • The driver asks for the type of card.
  • The correct function driver (storage, etc.) is loaded (or notified in case of storage).
  • The function driver works to expose hardware for the OS and applications.

The problem for you is that # 3 does not execute correctly when loading if the card is already in the slot. It is not uncommon to develop platforms for SD or USB - the interrupt handler must be functional and open before the slot will be powered.

It is very difficult to create a workaround for this software, especially if OAL (part of the OS developed by the hardware manufacturer, not Microsoft) is a black box. I guess this is the case.

To be clear, this is definitely a platform bug. The first course of action should be to talk to a support group on the OEM device, tell them that they have a bug, and see if you can fix them.

If this does not work (if you do not buy many devices or the device is outdated, getting support is ... difficult), then I would advise digging out the SDMMC platform driver to find out if there could be any way to get to the center of the process. I have never tried (I have always been on the OEM side of this and just fixed the driver or platform code), so I'm not sure if there is even a solution, but it's worth a look.

The source code is freely available if you download and install the evaluation version of Platform Builder (be sure to select the "installation source" option). This is all C, and it’s not a lot of fun to try to browse, but as the saying goes, β€œUse the source, Luke.”

0
source

The problem was solved with some help from my colleagues at Advantech. They provided me with a small C ++ executable, which checked the loading / unloading of the device driver to make it recognize that an SD card was inserted. My problem then began to get this to work in my C # application. Using this thread (my own post):

C # FindFirstDevice Marshaling

I managed to get this to work by calling FindFirstDevice (), using "SDH1" as the string identifying the device, and then calling DeactivateDevice () / ActivateDeviceEX (). If someone is interested in a specific code, I can publish it later (now I'm at home, and the code is on my work laptop).

0
source

For everyone who is interested, here is the code that fixed the problem. This method is called when the firmware detects that an SD card has been inserted or removed after power on. Essentially, it unloads / loads the device driver:

 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct DEVMGR_DEVICE_INFORMATION { public uint dwSize; public IntPtr hDevice; public IntPtr hParentDevice; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)] public string szLegacyName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szDeviceKey; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szDeviceName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szBusName; } public enum DeviceSearchType : int { DeviceSearchByLegacyName = 0, DeviceSearchByDeviceName = 1, DeviceSearchByBusName = 2, DeviceSearchByGuid = 3, DeviceSearchByParent = 4 } class DevDriverInterface { [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct SECURITY_ATTRIBUTES { public int nLength; public IntPtr lpSecurityDescriptor; public bool bInheritHandle; } [DllImport("coredll.dll", SetLastError = true)] public extern static int ActivateDeviceEx(string device, IntPtr regEnts, UInt32 cRegEnts, IntPtr devKey); [DllImport("coredll.dll", SetLastError = true)] public extern static bool DeactivateDevice(int handle); [DllImport("coredll.dll", SetLastError = true)] public static extern int FindFirstDevice(DeviceSearchType searchType, IntPtr searchParam, ref DEVMGR_DEVICE_INFORMATION pdi); // Constructor public DevDriverInterface() { } public bool MountSDCardDrive() { const int INVALID_HANDLE_VALUE = -1; string mRegPath1 = ""; int handle = INVALID_HANDLE_VALUE; DeviceSearchType searchType = DeviceSearchType.DeviceSearchByDeviceName; DEVMGR_DEVICE_INFORMATION di = new DEVMGR_DEVICE_INFORMATION(); di.dwSize = (uint)Marshal.SizeOf(typeof(DEVMGR_DEVICE_INFORMATION)); String searchParamString = "SDH1"; IntPtr searchParam = Marshal.StringToBSTR(searchParamString); handle = FindFirstDevice(searchType, searchParam, ref di); if (handle == INVALID_HANDLE_VALUE) { // Failure - print error int hFindFirstDeviceError = Marshal.GetLastWin32Error(); using (StreamWriter bw = new StreamWriter(File.Open(App.chipDebugFile, FileMode.Append))) { String iua = "DevDriverInterface: error from FindFirstDevice: " + hFindFirstDeviceError.ToString(); bw.WriteLine(iua); } return false; } else { mRegPath1 = di.szDeviceKey; bool deactBool = DeactivateDevice((int) di.hDevice); if (deactBool == false) { using (StreamWriter bw = new StreamWriter(File.Open(App.chipDebugFile, FileMode.Append))) { String iua = "DevDriverInterface: DeactivateDevice: returned false - FAILED"; bw.WriteLine(iua); } return false; } Thread.Sleep(50); // Call ActiveDevice to setup the device driver handle = ActivateDeviceEx(mRegPath1, IntPtr.Zero, 0, IntPtr.Zero); if (handle == INVALID_HANDLE_VALUE) { // Failure - print error int hActivateDeviceError = Marshal.GetLastWin32Error(); using (StreamWriter bw = new StreamWriter(File.Open(App.chipDebugFile, FileMode.Append))) { String iua = "DevDriverInterface: error from ActivateDevice: " + hActivateDeviceError.ToString(); bw.WriteLine(iua); } return false; } } return true; } }; // end class 
0
source

All Articles