Friday, November 28, 2008

Buona Fortuna - Good Luck Ankit

Yesterday was the last day for my team mate Ankit in Accord.

He is all set to start off a new career and may be even in a new path in his new company - MindTree. All the best for you Ankit




Saturday, November 22, 2008

Dynamically Changing USB Client Function

Hi guys,

Here is a code for changing the current usb client function from Serial to Mass storage dynamically.



/*
* #FUNCTION
*
* @Function: GetUfnController
* @Return: INVALID_HANDLE_VALUE - USB Function device was not found
* Otherwise, if found
* @Parameters:
* @Description:
* Function to get the handle of a USB Client device.
*/
HANDLE GetUfnController()
{
HANDLE hUfn = NULL;
// Get a handle to the bus driver
DEVMGR_DEVICE_INFORMATION di;
memset(&di, 0, sizeof(di));
di.dwSize = sizeof(di);

#ifdef _SEARCH_WITH_GUID_
BYTE rgbGuidBuffer[sizeof(GUID) + 4]; // +4 because scanf writes longs
memset(&rgbGuidBuffer[0],0,sizeof(GUID) + 4);
LPGUID pguidBus = (LPGUID) rgbGuidBuffer;
LPCTSTR pszBusGuid = _T("E2BDC372-598F-4619-BC50-54B3F7848D35");
// Parse the GUID
if (FALSE == ConvertStringToGuid(&pszBusGuid[0],pguidBus) )
return INVALID_HANDLE_VALUE;
HANDLE hf = FindFirstDevice(DeviceSearchByGuid, pguidBus, &di);
#else
HANDLE hf = FindFirstDevice(DeviceSearchByLegacyName, L"UFN1:", &di);
#endif /* _SEARCH_WITH_GUID_ */
if (hf != INVALID_HANDLE_VALUE) {
hUfn = CreateFile(di.szBusName, GENERIC_READ, FILE_SHARE_READ,NULL, OPEN_EXISTING, 0, NULL);
CloseHandle(hf);
}
else {
hUfn = INVALID_HANDLE_VALUE;
}
return hUfn;
} /* GetUfnController */

/*
* #FUNCTION
*
* @Function: ChangeClient
* @Return: TRUE - Client Function change was succesful
* FALSE - Client Function change failed
* @Parameters:
* hUfn - Handle to the USB client device
* pszNewClient - New usb function to be loaded
* @Description:
* Function to switch the active usb client function driver
*/
BOOL ChangeClient(HANDLE hUfn, LPCTSTR pszNewClient)
{
if(hUfn == INVALID_HANDLE_VALUE || pszNewClient == NULL)
return ERROR_INVALID_PARAMETER;
DWORD dwRet = ERROR_SUCCESS;
UFN_CLIENT_NAME ucn;
_tcscpy(ucn.szName, pszNewClient);
BOOL fSuccess = DeviceIoControl(hUfn,
IOCTL_UFN_CHANGE_CURRENT_CLIENT, &ucn, sizeof(ucn), NULL, 0, NULL, NULL);
return fSuccess;
} /* ChangeClient */


/*
* #FUNCTION
*
* @Function: ConnectionStatus
* @Return: TRUE - Active sync session is active
* FALSE - Active sync session is not detected
* @Parameters:
* @Description:
* Function to Check the connection status of ActiveSync
*/
BOOL ConnectionStatus(VOID)
{
RASCONN rsconn[10];
DWORD dwcb, dwConnections;
RASCONNSTATUS rasStatus;
BOOL bConnected = FALSE;

// Enumerate active connections
dwcb = sizeof(rsconn);
rsconn[0].dwSize = sizeof(RASCONN);
if(RasEnumConnections(rsconn, &dwcb, &dwConnections) == 0) {
if(dwConnections == 0 || rsconn[0].hrasconn == NULL) {
DBG_PRINT ("No current connections\r\n");
}
else{
// Get first RAS connection status
rasStatus.dwSize = sizeof(rasStatus);
if(RasGetConnectStatus(rsconn[0].hrasconn, &rasStatus) != 0) {
DBG_PRINT ("Could not get RAS connection status\r\n");
}
else{
// Is it connected?
if(rasStatus.rasconnstate != RASCS_Connected) {
DBG_PRINT("Not connected\r\n");
}
else {
if ((0 == wcscmp(L"direct",rasStatus.szDeviceType)) &&
(0 == wcscmp(L"Serial on USB",rasStatus.szDeviceName))) {
DBG_PRINT(TEXT("Got an activesync connection..\r\n"));
bConnected = TRUE;
}
}
}
}
}
else {
DBG_PRINT ("Could not enumerate RAS connections\r\n");
}
return bConnected;
} /* ConnectionStatus */

Monday, November 17, 2008

Remote Tools and CETK over activesync

I will explain on how to connect development pc to a board running windows ce 6.0 os image using Activesync. The development board that I used is similar to the Mainstone III development platform (based on a Marvell PXA 270 processor) and activesync is configured to connect over the USB client port.

Previously when I was trying to connect to my development board using activesync from remote tools, i was getting error message that " Unable to load device side components". The samething happens while I was using CETK. But Sctivesync was connceting properly. Then I started digging into discussion forums for finding a solution to this problem. Here is what I found:

  1. Open C:\Program Files\Common Files\Microsoft Shared\Windows CE Tools\Platman\target\wce600.
  2. Create a folder armV4 and copy the contents of armV4i into this one.
  3. Now Open Kernel Tracker or any remote tools.
  4. Then follow the same steps specified by Sue in her blog post.
Presto!!!... There you have your remote tools working over Activesync.

NOTE: Special Thanks to Sue Loh (Windows CE Base Team Blog) and Yan Sun (CE 6.0 and PlatMan remote tools)

Tuesday, November 11, 2008

Debugging a booting problem

In this post, I will explain about how I debugged a problem in which our development board was taking a lot of time to completly boot up into Windows CE.


The usual bootup time for the development board was around 30-35 seconds, but as we were adding new drivers , the bootup time went up by minutes. The booting was really slow. So I took up this issue.

As i analyzed the booting up process, it was clear that the Boot phase 1 (loading of FMD) was getting over without any hickups. And slow down seems to have been occuring while drivers are getting loaded and initialized.

We can follow two strategies for pin pointing this issue:

Remove each driver one-by-one.
If we are not clear with the source of the problem, then individually eliminating each component one-by-one and observing the behaviour is a straight forward but time consuming way.


Using Celog
In one of my earlier posts, I have mentioned about a cab file that I created with all the celog settings and files. I installed this file on to the development board and configured the registry to launch 'CeLogFlush.exe' during bootup. Also Celog was configured to dump the data into a local file.

[HKEY_LOCAL_MACHINE\init]
"Launch05"="CeLogFlush.exe" -- include celog.dll

[HKEY_LOCAL_MACHINE\System\CeLog]
"Transport"="LocalFile"
"FileName"="celog.clg"
"BufferSize"=dword:100000 // 1MB
"ZoneCE"=dword:815263
"FlushTimeout"=dword:1388 // 5 seconds
"FileFlags"=dword:1 // Keep file open
"ThreadPriority"=dword:C8 // Priority increased to 200
After the complete system was up, I killed the CeLogFlush.exe using ITaskMgr (a really good task manager application) and took the Celog.clg from the device. This output file will contain only the thread IDs, we need to fix this up using readlog (http://devwince.blogspot.com/2008/10/fixing-thread-names-in-celog-output.html).

Now we can view this file in Windows CE Remote Kernel tracker.

Image1


According the Celog data, the booting process went normally till the 7th second since celogflush was started and all the drivers till that point was loaded and threads have been started (that means the XXX_Init routine was completed successfully). But after that the next thread start only at the 52 seconds mark, which was the battery monitor thread. And according the driver loading order in registry, the drivers were the power button monitor and battery driver.

Image2


When I analyzed the XXX_Init of battery driver, I found out that there was a t_printf statement in the init routine. According to the MSDN documentation t_printf will dump the data onto a console, which is again a driver and is not started yet. So when I removed the t_printf statements, the booting speed was back to normal.

:)

Tuesday, November 4, 2008

Another nice article about booting

Here is another really informative article by the Windows CE Base team.:)

http://blogs.msdn.com/ce_base/archive/2007/11/26/How-does-Windows-Embedded-CE-6.0-start_3F00_.aspx