Platform Builder: The K Flag and Your Driver


One of our engineers was adding a third party driver to system today and had trouble getting it to work. When he installed from the CAB file that was provided, it worked correctly. When he built it into the OS, it wouldn’t work correctly (unfortunately I didn’t discuss it in enough detail to tell you what it was doing.) Just before the end of the day he called out to me and said he left the K flag out.
For those of us who read the Platform Builder newsgroup regularly, we know that this is a common mistake that started with Windows CE 6.0 (yes, the K flag was available prior to CE 6.0 but didn’t affect driver loading.) As Software Engineers, many of first look at the code, and don’t think about the REG and BIB files that also affect the loading of drivers.
What is this K flag that I am writing about? Before I get to that, maybe I should give a quick refresher on MODULES and FILES sections in BIB files. In Platform Builder: Using Bib Files to add files to a Windows CE OS Image I wrote:
FILES Section – the files in the FILES section are put into the OS image without modification. That certainly is a good thing for text files, bitmaps and data.
MODULES Section – file files in the MODULES section are “fixed up” when put into the OS image. That means that the file is modified by romimage so that the executable can be run eXecute In Place (XIP) from the ROM image.   There may be times when you don’t want it to be run XIP, like if you want to reduce the image size, but want the same DLL to be run from both Kernel space and User space.
My description of “fixed up” might have been a little vague. Since the K flag directly affects how the files are fixed up, let’s dig deeper. From your first computer or programming course, you may know that executable files targeting most modern operating systems are relocateable. That is the addresses are variables that are relocated when the OS loads the executable. But to save time and possibly space, when creating an OS image, romimage.exe fixes up the addresses of files included in the MODULES section of the BIB files. By default, the addresses are fixed up to user mode addresses.
Starting with Windows CE 6.0, drivers moved to being loaded into kernel mode address space by default. By default, means that unless you tell the system to load the driver into user mode space by setting the DEVFLAGS_LOAD_AS_USERPROC flag in the registry the driver will be loaded by the kernel device manager. But, the addresses are fixed up to user mode addresses by default.
Enter the K flag. The K flag tells romimage to fix up the addresses to kernel mode addresses. So since drivers are loaded into kernel space by default, the K flag must be used for drivers listed under the MODULES section of your BIB files. The following table may be used as a guide for drivers.

 
FILES Section
MODULES Section
K Flag
K Flag not needed because the files are not fixed up
K Flag is needed for Kernel Mode drivers
No K Flag
K Flag not needed because the files are not fixed up
K Flag is not needed for User Mode drivers
 
Note: the table does not apply to applications and DLLs that are to be loaded by applications.
Copyright © 2010 – Bruce Eitman
All Rights Reserved

author: Bruce Eitman | posted @ Thursday, February 04, 2010 1:47 PM | Feedback (0)

Windows CE Chat January 26, 2010


 
Another great opportunity to ask Microsoft engineers your technical questions is coming up on Tuesday, January 26th.  These chats are your opportunity to get advice and answers from the engineers at Microsoft.   You may want to review Transcript Archive to get an idea about what kind of topics are discussed.
Title:    Windows CE Live Chat!
When:  Tuesday, January 26, 2010 9:00 - 10:00 A.M. Pacific Time
 
Description: Do you have tough technical questions regarding Windows CE or Windows Mobile for which you're seeking answers? Do you want to tap into the deep knowledge of the talented Microsoft Embedded Devices Group members? If so, please join us for a live Windows CE chat and bring on the questions! Windows CE is the operating system that is powering the next generation of 32-bit, small-footprint and mobile devices. This chat will cover the tools and technologies used to develop devices using the Windows CE operating system.
To join this chat, please log on via the main MSDN chat page at: Enter Chat Room
Copyright © 2010 – Bruce Eitman
All Rights Reserved

author: Bruce Eitman | posted @ Monday, January 25, 2010 2:08 PM | Feedback (0)

Platform Builder: Changing the Driver Prefix


A reader recently asked me the following:
“What do you need to do exactly to change the legacy namespace of an existing driver? I have a serial port driver (for an expansion card with 4 serial ports) which works and uses the COM-prefix, but I want to change the COM-prefix to something else, so that it's easier to distinguish between onboard COM-ports and the ports on the expansion card...
I've changed the prefix in the registry and also in the .def-files. But when I try to compile it, I get LNK2001-errors (Unresolved external symbol). The driver that I'm working with is a MDD/PDD-driver.”
I found this to be an interesting question on a few levels; why does the linker error happen and what needs to happen to change the prefix? I gave him a short answer in the comments, but thought that it deserves a more prominent answer as a separate article.
Why does the linker error happen?
To understand the linker error we need to understand what the DEF file does.   The DEF file tells the linker that it should find a set of functions and expose those functions to the outside world. The functions are exposed outside of the DLL so that when an application or another DLL loads this DLL it can call the function(s). With that we know that by changing the set of functions to be functions that don’t exist, we should get linker errors, why because the functions don’t exist and we told the linker that they do.
What needs to happen to change the prefix?
I know you are sitting there thinking that the answer is obvious, and certainly one answer is obvious. I came up with three solutions:
1.       The obvious answer is to change the functions in the driver to match the DEF file. Done, simple and quick – but wait, what if the functions aren’t in the code because the driver is made up of an MDD and PDD? Now it gets more complicated, we could clone the MDD just to be able to change the prefix. Not a real good reason to go to that effort and then need to maintain the MDD.
2.       We could create wrapper functions in the driver to call the original functions. Something like:
DWORD NEW_Init(ULONG   RegistryPath)
{
return XXX_Init( RegistryPath );
}
Repeat for each function and I suppose you could even expose both sets of functions, the XXX_ and the NEW_ functions.
3.       We can use the DEF file to rename the functions. 
LIBRARY       Sample Driver
 
EXPORTS NEW_Init=XXX_Init
                NEW_Deinit=XXX_Deinit
                NEW_Open=XXX_Open
                NEW_Close=XXX_Close
                NEW_Read=XXX_Read
                NEW_Write=XXX_Write
                NEW_Seek=XXX_Seek
                NEW_IOControl=XXX_IOControl
This exports the NEW_ functions which refer to the XXX_ functions when called.  This solution is similar to solution #2, but without needing to write code to do it. With this we can do very little work and expose the functions with new prefixes without needing to clone the MDD. Try this then run “Dumpbin /EXPORTS MyDriver.dll” to see the names of the exported functions.
 
Copyright © 2010 – Bruce Eitman
All Rights Reserved

author: Bruce Eitman | posted @ Monday, January 11, 2010 12:54 PM | Feedback (1)

Windows CE: Killing an Application


In Windows CE: Using ToolHelpAPI to list running processes, I showed how to use the ToolHelpAPI to get a list of running processes or applications. Someone recently asked in one of the newsgroups how to kill an application. The question included code using ToolHelpAPI to find a process, but the code had some problems.
ToolHelpAPI does provide information about the processes, but the function for killing a process, TerminateProcess(), needs a HANDLE to the process.   OpenProcess() can be used to get a HANDLE using a Process ID (PID) of the process. The PID is available in the information from ToolHelpAPI.
The following function, KillProcess(), takes a PID as an argument. KillProcess() then gets the HANDLE to the process and terminates the process.
DWORD KillProcess( DWORD PID )
{
                HANDLE hApp ;
                DWORD ReturnValue = FALSE;
 
                hApp = OpenProcess(PROCESS_TERMINATE, FALSE, PID);
                if( hApp )
                {
                                if( !TerminateProcess( hApp, 999 ) )
                                                RETAILMSG( 1, (TEXT("KillApp: Failed to kill app, error %d\n"), GetLastError() ));
                                else
                                                ReturnValue = TRUE;
                }
                else
                                RETAILMSG( 1, (TEXT("KillApp: %X is not currently running\n"), PID ) );
 
                CloseHandle(hApp);
                return ReturnValue;
}
The second argument to TerminateProcess() is the exit code. I randomly selected 999 as that value, you could of course use any value that you want to use.
Keep in mind that killing a process with TerminateProcess() is a very harsh way to end a process. This does not allow a process to end gracefully; it just kills the main thread – no main thread, no process.   So use this with caution an only if you don’t have a more graceful way to request that the process exit gracefully.
 
Copyright © 2009 – Bruce Eitman
All Rights Reserved

author: Bruce Eitman | posted @ Monday, December 14, 2009 1:30 PM | Feedback (0)

Windows CE Chat December 15, 2009


 Another great opportunity to ask Microsoft engineers your technical questions is coming up on Tuesday, November 24th.  These chats are your opportunity to get advice and answers from the engineers at Microsoft.   You may want to review the transcript from previous months to get an idea about what kinds of topics are discussed.

 

Title:    Windows CE Live Chat

When:  Tuesday, December 15, 2009 9:00 - 10:00 A.M. Pacific Time

 Add to Calendar

 

Description: Do you have tough technical questions regarding Windows CE or Windows Mobile for which you're seeking answers? Do you want to tap into the deep knowledge of the talented Microsoft Embedded Devices Group members? If so, please join us for a live Windows CE chat and bring on the questions! Windows CE is the operating system that is powering the next generation of 32-bit, small-footprint and mobile devices. This chat will cover the tools and technologies used to develop devices using the Windows CE operating system.

To join this chat, please log on via the main MSDN chat page at: http://msdn.microsoft.com/chats/

Join the chat room on the day of the chat: www.microsoft.com/communities/chats/chatrooms/msdn.aspx

 

Copyright © 2009 – Bruce Eitman
All Rights Reserved

author: Bruce Eitman | posted @ Saturday, December 12, 2009 8:00 AM | Feedback (0)

Platform Builder: Communicating Between the Bootloader and the OS


In the article Platform Builder: Setting Default Memory Divisions, I discussed using pOEMCalcFSPages() or pfnCalcFSPages() to set the memory division between storage and program memory. In that article I presented the following function:
DWORD OEMCalcFSPages(DWORD dwMemPages, DWORD dwDefaultFSPages)
{
                DWORD Percent = 50;
                return ( dwMemPages * Percent ) / 100;
}
Then I suggested that with enough knowledge of your BSP and an imagination, you could dynamically set the percent value instead of using a hardcoded value. In this article, I thought that I would explore how this could be handled in a BSP to allow the bootloader to pass a percent value to the OS.
If the bootloader is going to pass a value to the OS we need a method to do this. Now if these were applications running within the OS we might think about using  sockets, message queues or maybe a memory mapped file. But these tools aren’t available if for no other reason when the bootloader is running, the OS isn’t. We can think about memory mapped files though, but in a simpler form which would be just memory mapped data.
To understand this better, let’s look at the CEPC BSP. The CEPC BSP already memory maps data to communicate between the bootloader and the OS. CEPC does this with a data structure, BSP_ARGS, which it allocates space in RAM to use. The following explains how CEPC sets up the memory mapping:
·         The BSP_ARGS structure is defined in the CSP in bootargs.h.
·         The address of BSP_ARGS is defined in the CSP in bootargs.h as BOOT_ARG_PTR_LOCATION
·         In config.bib the BSP_ARGS address space is documented by establishing a RESERVED section
·         The boot.bib files don’t documented the BSP_ARGS address space, which would be good to do
·         The bootloaders (BIOSLoader, EBoot and Sboot) initialize a pointer to the address that will be used
·         The kernel reads the data from BOOT_ARGS when OEMInitDebugSerial() runs
BSP_ARGS is used primarily to pass display and debug information from the bootloader to the kernel. But that doesn’t mean that it cannot be extended to do more.
Other BSPs may use a structure with a different name, or not have a structure for this purpose at all.
In the case of setting the memory division percent, we could add a member to the BSP_ARGS structure and provide a mechanism in the bootloader to initialize the value. When changing BSP_ARGS, it is important to watch the size of the structure. CEPC maps 256 bytes for the structure, so if the structure becomes larger than 256 bytes the data would be in memory space that is being used for other purposes.
BSP_ARGS can also be used for the kernel to communicate to the bootloader. A member could be included in BSP_ARGS that tells the bootloader how to behave on the next boot. This only works for soft resets though and the bootloader must not clear BSP_ARGS before the member is read. For this to work well, BSP_ARGS must have some value in it that can be used to verify that values in BSP_ARGS are valid.
 
Copyright © 2009 – Bruce Eitman
All Rights Reserved

author: Bruce Eitman | posted @ Friday, December 11, 2009 12:34 PM | Feedback (0)

Windows CE: Using RAPI to Run Applications (Part 3)


The CERunApp application can be downloaded from: 

 
 The CERunApp source code can be downloaded from: 

 
In Windows CE: Using RAPI to Run Applications (Part 1) and Windows CE: Using RAPI to Run Applications (Part 2) I wrote about using RAPI remotely start applications on a Windows CE device from a workstation. In Windows CE: Using RAPI to Run Applications (Part 2) I presented an application, CERunApp.exe, that downloads an application from the workstation to the Windows CE device and then starts the application.   A reader responded to that article by asking about running an MP3 file using the CERunApp.exe. I responded that the CERunApp.exe starts applications, not MP3 files. This article will correct that by extending the CERunApp.exe to download a file and run a resident application on the Windows CE device with the name of the file as a command line argument.
I am not going to go into great detail about the changes to CERunApp, but to get started, I added a tab control so that the app can have two ways of being used. The original application is in the first tab, labeled Application. It looks like:
Not much of a change to this part of the application, but the new tab labeled Parameter adds the new functionality. This new tab looks like:
In this new tab there are:
·         A drop down list of EXE files in the \Windows folder on the Windows CE device
This list is populated when the user clicks on the Parameter tab from the Application tab.
·         A text box to enter command line parameters
·         A browse button to select a file to be downloaded and include in the command line
When the user clicks on the Run Application button, the file is downloaded, then the application is started with the command line with the file name added to it.
Since I covered most of the RAPI code in the previous articles, I am going to focus on the changes that I made. The fist change was to add code to get the list of EXE files in the \Windows folder. This was done using CeFindFirstFile(), CeFindNextFile(), and CeFindClose().   These functions work much like their counterparts that would be used on the device itself. To use these, I added FindFirstFile(), FindNextFile() and FindClose() the the CRapi class as follows.
    public System.IntPtr FindFirstFile(string FolderName, ref string FileName)
    {
        System.IntPtr ReturnValue = System.IntPtr.Zero;
        CE_FIND_DATA FindData = new CE_FIND_DATA();
 
        if (IsConnected())
        {
            ReturnValue = CeFindFirstFile(FolderName, ref FindData);
            if (ReturnValue != System.IntPtr.Zero)
            {
                FileName = FindData.cFileName;
            }
        }
        return ReturnValue;
    }
    public bool FindNextFile(System.IntPtr hFind, ref string FileName)
    {
        bool ReturnValue = false;
        CE_FIND_DATA FindData = new CE_FIND_DATA();
 
        if (IsConnected() && hFind != System.IntPtr.Zero)
        {
            ReturnValue = CeFindNextFile(hFind, ref FindData);
            if (ReturnValue != false)
            {
                FileName = FindData.cFileName;
            }
        }
        return ReturnValue;
    }
 
    public bool FindClose(System.IntPtr hFind)
    {
        bool ReturnValue = false;
        if (IsConnected() && hFind != System.IntPtr.Zero)
            ReturnValue = CeFindClose(hFind);
        return ReturnValue;
    }
 
If your read the previous article closely, you would have noticed that at that time I chose to make the connection and end the connecting in the functions as they were called. Using 20/20 hindsight I have change this so that the connection is made when the CRapi class is instantiated and closed with a call to Disconnect() which I added to CRapi. Disconnect() is also closed when the CRapi is destructor is called, but of course that is up to the garbage collector. I recommend closing when finished rather than letting the destructor do it. This change was clearly necessary when using the find file functions.
The code that handles the click on the Parameter tab looks like:
        private void FileCopyTab_Click(object sender, EventArgs e)
        {
            CRapi RAPI = new CRapi();
            String FoundFile = "No Files Found";
            System.IntPtr hFind;
            string[] FileNames;
            uint Index = 0;
            uint LoopCount = 0;
 
            Cursor.Current = Cursors.WaitCursor;
 
            FileAppName.Items.Clear();
 
            do
            {
                FileNames = new string[Index];
                Index = 0;
                hFind = RAPI.FindFirstFile("\\Windows\\*.exe", ref FoundFile);
                if (hFind != System.IntPtr.Zero)
                {
                    do
                    {
                        if (LoopCount > 0)
                            FileNames[Index] = FoundFile;
                        Index++;
                    } while (RAPI.FindNextFile(hFind, ref FoundFile));
 
                    RAPI.FindClose(hFind);
                }
                else
                {
                    if( LoopCount > 0 )
                        FileNames[Index] = FoundFile;
                    Index++;
                }
            }
            while (LoopCount++ < 1);
 
            CaseInsensitiveComparer Comparer = CaseInsensitiveComparer.Default;
            Array.Sort(FileNames, Comparer);
            LoopCount = Index;
            for (Index = 0; Index < LoopCount; Index++)
            {
                FileAppName.Items.Add(FileNames[Index]);
            }
 
            RAPI.Disconnect();
            Cursor.Current = Cursors.Default;
        }
This code finds the EXE files in the \Windows folder, then sorts them alphabetically.
The rest uses code similar to or included in the original application.
Copyright © 2009 – Bruce Eitman
All Rights Reserved

author: Bruce Eitman | posted @ Thursday, December 10, 2009 3:06 PM | Feedback (1)

Platform Builder: Setting Default Memory Divisions


Windows CE divides the system RAM into two parts; storage memory and program memory. These two parts are equally divided by default. The problem with that is that some systems need to store files than they need program space, and some systems need more program space than storage. The division can be changed dynamically at run time, which I discussed in Windows CE: Automatically setting the Object Store Size But the device OEM can change the division default in two ways:
1.       FSRAMPERCENT in config.bib
2.       pOEMCalcFSPages() in the kernel
 
FSRAMPERCENT in config.bib
FSRAMPERCENT is used to set the percent of RAM should be used for the storage memory. Setting FSRAMPERCENT looks like:
CONFIG
    FSRAMPERCENT=0x40404040
FSRAMPERCENT is difficult or at least awkward to set because each byte represents a different amount of RAM. Each byte represents the number of 4 KB blocks per megabyte, not the percent as the name would suggest.
·         Byte 0 is the number of 4 KB blocks per megabyte in the first two megabyte of RAM
·         Byte 1 is the number of 4 KB blocks per megabyte in the second two megabyte of RAM
·         Byte 2 is the number of 4 KB blocks per megabyte in the third two megabyte of RAM
·         Byte 3 is the number of 4 KB blocks per megabyte in rest of RAM
Sounds goofy, but there is an historical reason. This allowed for early very much RAM restricted devices to set up FSRAMPERCENT for various RAM configurations. A device with just 2 MB would use the first byte for its configuration, then if there were 3 MB more it would use the next byte which might be set up different and so on.
pOEMCalcFSPages()/pfnCalcFSPages() in the kernel
Then in Windows CE 4.0 it became easier to set up the RAM divisions. The kernel now calls a function in the OAL code to determine how many pages should be in the storage memory. This only happens if the OAL provides a function and initializes the pOEMCalcFSPages() or pfnCalcFSPages() function pointers. In Windows CE 6.0 the function pointer pfnCalcFSPages is a member of g_pOemGlobal, while previous version pOEMCalcFSPages was a standalone variable. So the code for CE 6.0 looks like this:
DWORD OEMCalcFSPages( DWORD dwMemPages, DWORD dwDefaultFSPages);
 
OEMInit()
{
                …
                g_pOemGlobal->pfnCalcFSPages = OEMCalcFSPages;
                …
}
 
DWORD OEMCalcFSPages(DWORD dwMemPages, DWORD dwDefaultFSPages)
{
                DWORD Percent = 50;
                return ( dwMemPages * Percent ) / 100;
}
 
And in previous version, the function would be the same, but the initialization of the pointer could be:
DWORD OEMCalcFSPages( DWORD dwMemPages, DWORD dwDefaultFSPages);
extern DWORD (*OEMCalcFSPagesPtr)( DWORD dwMemPages, DWORD dwDefaultFSPages) pOEMCalcFSPages=OEMCalcFSPages;
This example uses a hardcode percent, but with some imagination and a good understanding of your BSP, you can probably come up with a way to make this more dynamic.
 
With these three ways to change the configuration of RAM, the question now is which one wins? If you use FSRAMPERCENT and pOEMCalcFSPages/pfnCalcFSPages the function pointers will win and set the RAM percent. Of course the code to change it at run time will then override both.
Copyright © 2009 – Bruce Eitman
All Rights Reserved

author: Bruce Eitman | posted @ Wednesday, December 09, 2009 2:37 PM | Feedback (3)

Windows CE Chat Transcript (November 24, 2009)


For those of you who missed the chat today, here is the raw transcript.   By raw, I mean that I copied and pasted the discussion without any edits. This is divided into two parts, the top part is the answers from the Microsoft Experts and the bottom part is the questions from the audience.
Answers from Microsoft:
 
msft_davbo (Moderator): Our chat today covers the topic of Windows Embedded CE!

1. This chat will last for one hour. During this hour, our Experts will respond to as many questions as they can. Please understand that there may be some questions we cannot respond to due to lack of information or because the information is not yet public.

2. We encourage you to submit questions for our Experts. To do so, type your questions in the send box, select the “ask the Experts” box and click SEND. Questions sent directly to the Guest Chat room will not be answered by the Experts, but we encourage other community members to assist.

3. We ask that you stay on topic for the duration of the chat. This helps the Guests and Experts follow the conversation more easily. We invite you to ask off topic questions after this chat is over, but not during.

4. Please abide by the Chat Code of Conduct.

Chat code of conduct: <http://msdn.microsoft.com/chats/chatroom.aspx?ctl=hlp#Conduct>;
msft_davbo (Moderator): We are pleased to welcome our Experts for today’s chat. I will have them introduce themselves now.

Chat will begin in a couple of minutes.

<http://www.Microsoft.com/Embedded>;

mskim_MSFT (Expert)[12:01]: Hello, this is mskim from Windows CE JDP team.
RajeevDubey[MS] (Expert)[12:01]: Hi, this is Rajeev Dubey, Program Manager for Bluetooth.
mikehall_ms (Moderator)[12:02]: Hi, I'm Mike Hall, Software Architect
Sing Wee [MS] (Expert)[12:05]: Hello, I'm Sing Wee, member of the CoreOS/BSP Test Team.
FBlanq_MSFT (Expert)[12:05]: Hi, I'm Francisco Blanquicet, SDET with CoreOS/WinCE
msft_davbo (Moderator)[12:05]: Chat is started so ask any questions you may have about Windows CE.
rajran[MSFT] (Expert)[12:06]: Hi , I'm Rajeev Rangappa, PM in Core Team
Q: [1] hi experts, is there any way to provide debug information for assembler files (.s) to the debugger so that i can step through the sources? currently only exported symbols are visible to the debugger
A: As far as I know, the only way to step into and through assembler sources is to either (1) first switch to the 'disassembly' pane of the debugger, then either set a breakpoint on a CPU instruction, or (2) switch to the disassembly view in the source view and "step into" a function call. (bl on ARM, call on X86)
Q: [6] [1] so there is no way to get debug info for assembler files into the pdb files?
A: What kind of info are you wanting to get into the PDB files? What is missing and what way are you accessing information?
Q: [11] [6] i know i can step i the disassembler view, but it is somewhat painful without the coments of the sourcefile. So I would like to see and step in the assembler sourcefile while debugging like when debugging c or cpp files
A: ah, so what you're wanting is a mixed assembler/code bytes view. I do not thing our tools currently have such a view for the Windows CE debugger. You would have to open a source code window side-by-side in platform builder to see the comments.
Q: [12] [6] also local (not exported] labels are not known to the debugger
A: No, unfortunately local assembler labels are not accounted for in the debugging information.
Q: [13] [11] well thats the way i spend most of my time
A: We can give this feedback to our tool chain developers. Thanks for the input.
Q: [15] XAML + Other Windows: I have an MFC app which contains window based user draw controls (caches and draws bitmaps and overlays data on them). I want to update the UI to use XAML. How can I embed some of these existing controls in the XAML app?
A: Here is MSDN link regarding Win32Control in Silverlight for Windows Embedded.
Q: [15] XAML + Other Windows: I have an MFC app which contains window based user draw controls (caches and draws bitmaps and overlays data on them). I want to update the UI to use XAML. How can I embed some of these existing controls in the XAML app?
A: Yes, you can use Win32Control in Silverlight for Windows Embedded. Here is the link on msdn regarding Win32Contro. http://msdn.microsoft.com/en-us/library/ee502772.aspx
Q: [2] hi experts, i have integrated lint in the build prrocess. to see the output i have used the build_markers for C files, so they are also shown as c files in the summary. is there any way to show them with the "other files", in other words which build marker
A: Drivers should get notifications when suspend is happening if there's a driver that's not responding to a notification properly (in this case the driver for the RAM file system), you can definitely expect resource leaks or other bad behavior. Since this problem occurs only after a few suspends/resumes, I suspect that a very large amount of memory is being leaked - much more than the size of the file you're opening and closing. To debug this, I think you will want to instrument your app. As a next step, can you track the available object store space in your thread and try to understand more deeply how the memory is being used? See GetStoreInformation (http://msdn.microsoft.com/en-us/library/aa916952.aspx). After that, it may be worthwhile to turn on DEBUGZONEs in filesys.dll to see if there are any useful messages that can help you understand the situation.
Travis Hobrla [MS] (Expert)[12:25]: Answered the wrong question, one moment!
Q: [10] I'm creating the file in RAMFS, and I don't believe my thread can have any leak considering it's just opening and closing the same file. Do you have any idea what could go wrong ? Thank you.
A: Drivers should get notifications when suspend is happening if there's a driver that's not responding to a notification properly (in this case the driver for the RAM file system), you can definitely expect resource leaks or other bad behavior. Since this problem occurs only after a few suspends/resumes, I suspect that a very large amount of memory is being leaked - much more than the size of the file you're opening and closing. To debug this, I think you will want to instrument your app. As a next step, can you track the available object store space in your thread and try to understand more deeply how the memory is being used? See GetStoreInformation (http://msdn.microsoft.com/en-us/library/aa916952.aspx). After that, it may be worthwhile to turn on DEBUGZONEs in filesys.dll to see if there are any useful messages that can help you understand the situation.
Q: [13] [11] well thats the way i spend most of my time
A: I just tried something similar to this. In a debug build, I break into my C code, and go to disassembly view. I see the assembly code inline with my C code and my comments, so I would expect you should be able to see your assembly code inline with your comments as well.
Q: [16] XAML + Other Windows: Effectively I want to skin the current app using XAML. Maybe there are some examples shipped with R3?
A: In R3, there is a IEsample_exr in public\ie\oak you can reference. How to skin the existing application with Silverlight for Windows Embedded.
Travis Hobrla [MS] (Expert)[12:27]: @winceLover: use "Ask the Experts"
Q: [18] hi experts, is there an easy way to enable debug zones in advance for dlls that haven't been loaded yet? Some dlls only get loaded while an application is running and by the time I get to click on Target->CE Debug Zones-><module name> it's already too late
A: I would recommend the "Host side (desktop) registry" method outlined here: http://blogs.msdn.com/ce_base/archive/2006/12/18/debug-messages-and-debug-zones-in-windows-ce.aspx
Q: [20] [10] - I will try to track the memory used in my thread more thoroughly. It's too bad I can't use KITL at that point as I'm doing suspend/resumes tests. So Travis, you're saying that there might be a leak in the RAM file system (which is public code) ?
A: It's certainly possible, but there is more investigation which is required before you can be sure.
Q: [19] Sing Wee [13] well that doesn't work for assembler files, at least in my environment, although I have to say I use trace32 vom lauterbach most of the time. But this is the behaviour i would wish for .s files.
A: It's a good feature request for the tools but I don't think we have any support for it right now. Sorry!
Q: [17] hi experts, is there a way to put additional items to the clean target without modifying makefile.def?
A: I believe the only way is during the WINCETARGETFILES or WINCETARGETFILES0 phase, you could completely override the clean rule in your own makefile.inc.
Q: [20] [10] - I will try to track the memory used in my thread more thoroughly. It's too bad I can't use KITL at that point as I'm doing suspend/resumes tests. So Travis, you're saying that there might be a leak in the RAM file system (which is public code) ?
A: I haven't tried this over suspend/resume cycles, but have you by any chance tried using AppVerifier to see if you can catch where memory may be leaking from?
Q: [23] Sing Wee [19] well, perhaps there are not much assembler junkies out there , thank you any way
A: No worries. Out of curiosity, are you doing this in CE6 or CE5? My observations were based on CE6.
Q: [22] We need to give camera data to the appln for displaying it on the WINCE 6.0 device LCD or we need to send the camera frames to the device USB video class for displaying at the desktop PC app.IS both my requirement will be acheived by DSHOW camera driver?
A: Yes DirectShow is the best place to build your camera application. Check Mike Hall's blog for a USB Camera Driver download http://blogs.msdn.com/mikehall/archive/2007/06/07/download-ce-6-0-usb-camera-driver.aspx. This driver allows you to pull in frames into DirectShow from a USB attached camera on Windows CE. For communicating to a Desktop you'd need to build a custom communication sink filter to send the frames from Windows CE to a corresponding custom source filter on the Desktop. If interested can post a sample on codeplex w/ details on setting up the filters send email to davbo@microsoft.com.
Q: [21] What is the best way to setup a filesystem storing hive registry ? In our system, the SD card will be the storage holding it. Should we setup the SD card as MountPermanent, and are there other registry keys worth setting ?
A: Is the SD card fixed in place in your unit? If so, you should be safe to mount the card permanently. Also, make sure it is set to mount at boot time. For reference, examine some existing drivers that use persistent store for their registry
Q: Prabu, what's UVC stack?
Q: [20] [10] - I will try to track the memory used in my thread more thoroughly. It's too bad I can't use KITL at that point as I'm doing suspend/resumes tests. So Travis, you're saying that there might be a leak in the RAM file system (which is public code) ?
A: And which public code RAMFS driver are you using? The RAMDISK, RAMFMD or?
Q: [21] What is the best way to setup a filesystem storing hive registry ? In our system, the SD card will be the storage holding it. Should we setup the SD card as MountPermanent, and are there other registry keys worth setting ?
A: In addition to what Kurt said, http://msdn.microsoft.com/en-us/library/aa914710.aspx gives you a good introduction. Basically you need to make sure the registry for your SD driver is wrapped in ;HIVE BOOT SECTION tags, as well as anything that driver depends on, so that it can get loaded in phase 0.
Q: [27] Sing Wee [23] i am doing CE6, porting to a OMAP platform, currently working on the bootloader, but work is proceeded to jump to BootloaderMain
A: Understood - thanks.
Q: [26] [20] Sing Wee : I haven't tried using AppVerifier, does it support well checking leaks while suspending/resuming the system ?
A: That's the part I haven't tried. AppVerifier keeps track of memory by monitoring calls to allocate/deallocate memory on processes/DLLs you point it at. *If* it works over suspend/resume, the checkpoint/delta feature might help you narrow down the problem more quickly. I'm having difficulty finding my original posting, but a copy of it has apparently made it here: http://www.pocketpcjunkies.com/Uwe/Forum.aspx/wince-test/481/Can-app-verifier-detect-memory-leak-in-a-driver
Q: [28] [21] - yes, this is setup correctly and works fine, until going to suspend/resume, where the SD gets unmounted and remounted. My question is : should we absolutely keep the power on to the SD card (it's never removed), and set it as MountPermanent ?
A: You should be able to call RegFlushKey (http://msdn.microsoft.com/en-us/library/aa917036.aspx) during your power-down code and unmount / remount.
Q: [24] Using DSHOW layer can we give the camera frames to the client UVC stack?
A: Is you question about around if you have a Windows CE Web Camera and plug into a Desktop Machine how to provide the frames from Windows CE to the Desktop UVC Stack? Desktop MSDN info for UVC Stack http://msdn.microsoft.com/en-us/library/ee349147.aspx.
Q: [28] [21] - yes, this is setup correctly and works fine, until going to suspend/resume, where the SD gets unmounted and remounted. My question is : should we absolutely keep the power on to the SD card (it's never removed), and set it as MountPermanent ?
A: In addtion to keep the power (or handle the power cycle correctly), MountPermanent , you SD Host controller driver should never simulate a card replug after suspend/resume.
Q: [30] Travis [17] I am not sure if i understand you right, the WINCETARGETFILES targets are executed after building so not really good for cleaning, WINCETARGETFILE0 are executed before compiling, but what if only the clean target is performed?
A: Do you mean by calling 'nmake clean' ?
Q: [33] Travis [17] yes, for example, or clicking Build - Clean in VS2005
A: Unforunately I don't think there is a way to handle 'nmake clean' without modifying makefile.def. Build - Clean I believe executes "build -c" which would execute the WINCETARGETFILES0 pass - you could do cleanup at that point, before things get compiled.
Q: [34] Travis [33] ok, are there "best practices" for modifying makefile.def?
A: The 'best practice' is to make a backup, change as little as possible, and do so at your own risk! What exactly are you trying to accomplish?
Q: [31, 29] Can you point me to the KB entry or tell us what exactly has to be adapted in the OAL Cache routine?
In a previous QFE adressing the L2 cache it is documented that one has to adapt the OAL Cache routines. To found out how we were hoping for more information from the KB entry which however does not seem to exist. Question following.
A: Title: FIX: Kernel does not properly handle BSPs that distinguish between L1 and L2 cache flushing in Windows Embedded CE 6.0.

Symptoms:
A performance problem was found in Cortex-A8 based processors due to excessive PSL API call overhead caused by unnecessary L2 cache flush operations.

With the code changes included in this QFE, the kernel now maintains proper L2 cache coherence so that the system can benefit from performance enhancements obtained by separating L1/L2 cache flushing in the OAL. To take advantage of this performance improvement, the OAL should be modified to flush L1 and L2 cache only when necessary.

This QFE may also address L2 caching issues in other CPU architectures whose OEMCacheRangeFlush implementations properly respect L2 cache flags:
• CACHE_SYNC_WRITEBACK: write back L1 data cache to L2 data cache
• CACHE_SYNC_DISCARD: write back L1 data cache to L2 data cache and discard L1 data cache
• CACHE_SYNC_L2_WRITEBACK: write back L2 data cache to memory
• CACHE_SYNC_L2_DISCARD: write
Q: [32] Multiple Displays: One of our projects requires two displays with independent content. Under CE6 is it possible using direct show to display different media (ie. different videos) on each of the display and two channels of Audio? We will write custom app.
A: Check out Microsoft Embedded Automotive who has support for up to 10 zones of AV content: http://www.microsoft.com/auto/ma.mspx. Typically they are just using 1-2 zones for front and rear AV zone control in the vehicle.
Q: [31] Can you point me to the KB entry or tell us what exactly has to be adapted in the OAL Cache routine?
A: Damian, can you please send me your email in a private message? I'll see if I can dig up the KB number for you.
Q: [31] Can you point me to the KB entry or tell us what exactly has to be adapted in the OAL Cache routine?
A: Looks like there was a limit to how much I could put in my response. Here's the final line in it's entirety:
• CACHE_SYNC_L2_DISCARD: write back L2 data cache to memory and discard L2 data cache
Q: [35] Travis [33] i am integrating lint, doxygen and some other tools (see previous question about build marker). so there are some non standard files to clean
A: I see. Well, the clean rules in makefile.def are pretty straightforward, so you should be able to alter them without affecting too much. I'd recommend adding a 'cleanlint' target to the clean rule, and implementing that.
Q: [31] Can you point me to the KB entry or tell us what exactly has to be adapted in the OAL Cache routine?
A: Basically, the OAL's OEMCacheRangeFlush implmentation needs to follow the guideline in http://msdn.microsoft.com/en-us/library/ee478186.aspx
msft_davbo (Moderator)[13:00]: Hello everyone, we are just about out of time.

Thank you for joining us for our Windows Embedded CE 6.0 chat today!

<http://www.Microsoft.com/Embedded>;

A special thank you to the product group members for coming out.

The transcript of today’s chat will be posted online as soon as possible, to <http://msdn.microsoft.com/en-us/chats>;. We’ll see you again for another chat next month. Please check <http://msdn.microsoft.com/en-us/chats>; for the list of upcoming chats.

If you still have unanswered questions, let me suggest that you post them on one of our newsgroups on
<http://msdn.microsoft.com/en-us/windowsembedded/ce/default.aspx>

-Windows
Embedded CE 6.0 R3 Now Available! <http://msdn.microsoft.com/windowsembedded/ce/dd630616.aspx>;
 
 
The Questions
 
msft_davbo (Moderator)[12:05]: Chat is now started.
Andrew Scholan MCTS[12:05]: Hello, this is Andrew Scholan from Plextek in Cambridge, UK.
wolfelectronic[12:06] asked the experts: hi experts, is there any way to provide debug information for assembler files (.s) to the debugger so that i can step through the sources? currently only exported symbols are visible to the debugger
wolfelectronic[12:09] asked the experts: hi experts, i have integrated lint in the build prrocess. to see the output i have used the build_markers for C files, so they are also shown as c files in the summary. is there any way to show them with the "other files", in other words which build marker
wolfelectronic[12:09] asked the experts: should i use for other files?
Sebastien[12:11] asked the experts: Hello everyone, I am currently testing my WinCE 6 iMX31 based platform and doing automated suspend/resume stress testing. My application first sends a message to a PIC to ask the PIC to resume the processor later, then my application goes to suspend.
Sebastien[12:12] asked the experts: After ten seconds, the PIC wakes up the system and the process repeats.
wolfelectronic[12:12] asked the experts: [1] so there is no way to get debug info for assembler files into the pdb files?
Sebastien[12:12] asked the experts: After making this work properly, I added a thread in my test application which does nothing more than opening a file and closing it in a loop.
Sebastien[12:12] asked the experts: After a few suspend/resumes, a message box appears in CE telling me that the program memory is very low and the system becomes unresponsive.
Sebastien[12:12] asked the experts: When I'm not executing this thread, my system can suspend/resume up to a thousand times or more.
Sebastien[12:13] asked the experts: I'm creating the file in RAMFS, and I don't believe my thread can have any leak considering it's just opening and closing the same file. Do you have any idea what could go wrong ? Thank you.
wolfelectronic[12:15] asked the experts: [6] i know i can step i the disassembler view, but it is somewhat painful without the coments of the sourcefile. So I would like to see and step in the assembler sourcefile while debugging like when debugging c or cpp files
wolfelectronic[12:16] asked the experts: [6] also local (not exported] labels are not known to the debugger
wolfelectronic[12:17] asked the experts: [11] well thats the way i spend most of my time
Bruce Eitman[12:17]: Sebastian - does your question have anything to do with the suspend/resume? What happens if you just run your file access thread without suspending?
wolfelectronic[12:18] asked the experts: [12] ok, thankyou kurtken
Andrew Scholan MCTS[12:19] asked the experts: XAML + Other Windows: I have an MFC app which contains window based user draw controls (caches and draws bitmaps and overlays data on them). I want to update the UI to use XAML. How can I embed some of these existing controls in the XAML app?
Andrew Scholan MCTS[12:22] asked the experts: XAML + Other Windows: Effectively I want to skin the current app using XAML. Maybe there are some examples shipped with R3?
wolfelectronic[12:23] asked the experts: hi experts, is there a way to put additional items to the clean target without modifying makefile.def?
Sebastien[12:23]: Bruce: sorry I didn't see you message until now. If I don't suspend/resume, I don't have this problem
winceLover[12:26]: hi experts, is there an easy way to enable debug zones in advance for dlls that hasn't been loaded yet? Some dlls only get loaded while an application is running and by the time I get to click on Target->CE Debug Zones-><module name> it's already too late
PaulT[12:27]: winceLover: Don't forget to check the Ask the Experts checkbox. This puts your question in a queue from which it is answered...
winceLover[12:28] asked the experts: hi experts, is there an easy way to enable debug zones in advance for dlls that haven't been loaded yet? Some dlls only get loaded while an application is running and by the time I get to click on Target->CE Debug Zones-><module name> it's already too late
wolfelectronic[12:29] asked the experts: Sing Wee [13] well that doesn't work for assembler files, at least in my environment, although I have to say I use trace32 vom lauterbach most of the time. But this is the behaviour i would wish for .s files.
Sebastien[12:30] asked the experts: [10] - I will try to track the memory used in my thread more thoroughly. It's too bad I can't use KITL at that point as I'm doing suspend/resumes tests. So Travis, you're saying that there might be a leak in the RAM file system (which is public code) ?
Andrew Scholan MCTS[12:31]: XAML + Other Windows: Thanks.
Sebastien[12:32] asked the experts: What is the best way to setup a filesystem storing hive registry ? In our system, the SD card will be the storage holding it. Should we setup the SD card as MountPermanent, and are there other registry keys worth setting ?
Prabu[12:33] asked the experts: We need to give camera data to the appln for displaying it on the WINCE 6.0 device LCD or we need to send the camera frames to the device USB video class for displaying at the desktop PC app.IS both my requirement will be acheived by DSHOW camera driver?
Sebastien[12:33]: Thanks Travis
wolfelectronic[12:36] asked the experts: Sing Wee [19] well, perhaps there are not much assembler junkies out there , thank you any way
Prabu[12:37] asked the experts: Using DSHOW layer can we give the camera frames to the client UVC stack?
Sebastien[12:40]: [20] Sing Wee : I haven't tried using AppVerifier, does it support well checking leaks while suspending/resuming the system ?
Prabu[12:41] asked the experts: USB Video Class
Sebastien[12:41] asked the experts: [20] Sing Wee : I haven't tried using AppVerifier, does it support well checking leaks while suspending/resuming the system ?
wolfelectronic[12:41] asked the experts: Sing Wee [23] i am doing CE6, porting to a OMAP platform, currently working on the bootloader, but work is proceeded to jump to BootloaderMain
Sebastien[12:43] asked the experts: [21] - yes, this is setup correctly and works fine, until going to suspend/resume, where the SD gets unmounted and remounted. My question is : should we absolutely keep the power on to the SD card (it's never removed), and set it as MountPermanent ?
Damian Barnett[12:46] asked the experts: In a previous QFE adressing the L2 cache it is documented that one has to adapt the OAL Cache routines. To found out how we were hoping for more information from the KB entry which however does not seem to exist. Question following.
wolfelectronic[12:46] asked the experts: Travis [17] I am not sure if i understand you right, the WINCETARGETFILES targets are executed after building so not really good for cleaning, WINCETARGETFILE0 are executed before compiling, but what if only the clean target is performed?
Damian Barnett[12:47]: Can you point me to the KB entry or tell us what has to be adapted in OAL Cache routine?
Damian Barnett[12:47] asked the experts: Can you point me to the KB entry or tell us what exactly has to be adapted in the OAL Cache routine?
Sebastien[12:49]: [26] Thank you Sing
Andrew Scholan MCTS[12:51] asked the experts: Multiple Displays: One of our projects requires two displays with independent content. Under CE6 is it possible using direct show to display different media (ie. different videos) on each of the display and two channels of Audio? We will write custom app.
Sebastien[12:51]: [28] - Thank you Travis
wolfelectronic[12:51] asked the experts: Travis [17] yes, for example, or clicking Build - Clean in VS2005
wolfelectronic[12:55] asked the experts: Travis [33] ok, are there "best practices" for modifying makefile.def?
wolfelectronic[12:57] asked the experts: Travis [33] i am integrating lint, doxygen and some other tools (see previous question about build marker). so there are some non standard files to clean
Damian Barnett[12:59]: Thanks Sing!
msft_davbo (Moderator)[13:00]: Hello everyone, we are just about out of time.

Thank you for joining us for our Windows Embedded CE 6.0 chat today!

<http://www.Microsoft.com/Embedded>;

A special thank you to the product group members for coming out.

The transcript of today’s chat will be posted online as soon as possible, to <http://msdn.microsoft.com/en-us/chats>;. We’ll see you again for another chat next month. Please check <http://msdn.microsoft.com/en-us/chats>; for the list of upcoming chats.

If you still have unanswered questions, let me suggest that you post them on one of our newsgroups on
<http://msdn.microsoft.com/en-us/windowsembedded/ce/default.aspx>

-Windows
Embedded CE 6.0 R3 Now Available! <http://msdn.microsoft.com/windowsembedded/ce/dd630616.aspx>;
Chat Topic: Open Peer-to-Peer Technical Chat in Progress
 
Copyright © 2009 – Bruce Eitman
All Rights Reserved
 

author: Bruce Eitman | posted @ Tuesday, November 24, 2009 1:40 PM | Feedback (0)

Platform Builder: Cleaning Non-Standard Files


During today’s chat with Microsoft’s Windows CE Team, someone asked “is there a way to put additional items to the clean target without modifying makefile.def?”   So I decided to see if I could come up with a way.
It can’t be done using a sources file. Sources files are only used to set environment variable prior to nmake being called and we need a target named “clean” to handle cleaning the additional files.
That leaves makefile.inc and makefile. I tried it in makefile.inc with a WINCETARGETFILES set for a different target than clean. It didn’t work.
I added a clean as a target in the makefile after including makefile.def, that didn’t work either. On a whim, I put it before including makefile.def and it worked. The following is my test makefile.
clean:
                -@del /q file.txt
 
!INCLUDE $(_MAKEENVROOT)\makefile.def
 
This successfully deletes file.txt and the clean target in makefile.def is still functioning to clean obj and cod files.
An alternative to this would be to create your own makefile.def and include it. For this, I put a makefile.def in the root of my platform (_TARGETPLATROOT) which is an exact copy of the makefile above. Then I modified my makefile to be:
!INCLUDE $(_TARGETPLATROOT)\makefile.def
This method allow me to have a common makefile.def for my platform which will make maintenance easier in the future.
Copyright © 2009 – Bruce Eitman
All Rights Reserved

author: Bruce Eitman | posted @ Tuesday, November 24, 2009 1:34 PM | Feedback (0)