67
Copyright reserved© Witech Co., Ltd. Website: http://www.arm9board.net OK6410 Users Manual Part 2 – Windows CE Copyright@2010-2011 http://www.arm9board.net Email: [email protected] Tel: +86-871-5899845

OK6410 Wince

Embed Size (px)

Citation preview

Page 1: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

OK6410 Users Manual

Part 2 – Windows CE

Copyright@2010-2011 http://www.arm9board.net

Email: [email protected] Tel: +86-871-5899845

Page 2: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net Email: [email protected] Tel: +86-871-5899845

COPYRIGHT STATEMENT Contents (content being images, text, programs and scripts) of

this manual is copyright © Witech Co., Ltd. All rights expressly

reserved.

Any content of the manual printed or downloaded may not be sold,

licensed, transferred, copied or reproduced in whole or in part in any

manner or in or on any media to any person without the prior written

consent of Witech Systems Ltd. including but not limited to:

transmission by any method

storage in any medium, system or program

display in any form

performance

hire, lease, rental or loan

Requests for permission to reproduce material from this manual

should be addressed to Witech Systems Ltd.

Page 3: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net Email: [email protected] Tel: +86-871-5899845

About Windows CE

WinCE is an open 32bit embedded operating system developed by Microsoft on the basis of

Windows 95 for minimalistic computers and embedded systems. Windows CE is a distinctly

different operating system and kernel, rather than a trimmed-down version of desktop Windows.

Though having its user interface succeeded from Windows 95/98, Windows CE is a new

information device platform developed on the basis of Win32 API.

Microsoft has stated that the ‘CE’ is not an intentional initialism, but many people believe CE

stands for ‘Consumer Electronics’ or ‘Compact Edition’. Microsoft says it implies a number of

Windows CE design precepts, including “Compact, Connectable, Compatible, Companion, and

Efficient.” The first version, known during development under the code name “Pegasus”, featured

a Windows-like GUI and a number of Microsoft's popular applications, all trimmed down for

smaller storage, memory, and speed of the palmtops of the day.

Windows CE is optimized for devices that have minimal storage—a Windows CE kernel may

run in under a megabyte of memory. Devices are often configured without disk storage, and may

be configured as a “closed” system that does not allow for end-user extension (for instance, it can

be burned into ROM). Windows CE conforms to the definition of a real-time operating system,

with deterministic interrupt latency. From version 3 and onward, the system supports 256 priority

levels and uses priority inheritance for dealing with priority inversion.

Features of Windows CE include:

1) Flexible power management, including sleeping/weakup function.

2) Using object streo technology, including filesystem, registry and database, and also

many other high performance, high efficiency operating system features.

3) Enhanced communications. WindowsCE widely supports various kinds of

communication hardware devices, as well as direct LAN connection and dial-up

connection. WinCE also provides connection to PC, intranet and internet.

4) Support for nested interrupts. Support has been added for nested interrupts, which

allows interrupts that are at higher priority levels to be serviced immediately, instead of

having them wait for a lower priority ISR to complete.

5) Better thread response. The upper bound on scheduling latencies for high-priority

ISTs (interrupt service threads) has been tightened. This improvement in thread response

allows developers to know specifically when the thread transitions occur and aids in the

creation of new embedded applications by increasing the capabilities of monitoring and

controlling hardware in Windows CE.

6) 256 priority levels allow developers more flexibility in controlling the scheduling of

embedded systems.

7) The ability to control the quantum of any thread in the system allows greater control

over the scheduler.

Page 4: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net Email: [email protected] Tel: +86-871-5899845

Table Of Contents Chapter One: Developing WinCE6.0 .........................................................6

1.1 Building Development Environment ..................................................................................6 1.1.1 Required Software....................................................................................................6 1.1.2 Installing Required Software....................................................................................6

1.2 Installing BSP for OK6410 ...............................................................................................10 1.3 Compiling WinCE 6.0 Project........................................................................................... 11

Chapter Two: Burning WinCE6.0 to OK6410..........................................13 2.1 Fusing SDboot to SD card.................................................................................................13 2.2 Setting Boot Mode ............................................................................................................13 2.3 Installing USB Driver .......................................................................................................15 2.4 Burning stepldr.bin to NAND Flash..................................................................................15 2.5 Burning eboot.bin to NAND Flash ...................................................................................17 2.6 Setting Nand Flash Boot ...................................................................................................17 2.7 Setting Display Resolution................................................................................................18 2.8 Burning nk.bin to NAND Flash ........................................................................................18

Chapter Three: Functions and Operations ................................................20 3.1 Interfaces & Peripherals Test ............................................................................................20

3.1.1 LED Test ................................................................................................................20 3.1.2 ADC Test ................................................................................................................21 3.1.3 Temperature Sensor Test ........................................................................................21 3.1.4 Buzzer Test.............................................................................................................22 3.1.5 Audio Test ..............................................................................................................22 3.1.6 Seiral Test...............................................................................................................23 3.1.7 USB Host Test........................................................................................................24 3.1.8 Touch Screen Calibration .......................................................................................25 3.1.9 SD Card Test ..........................................................................................................26 3.1.10 Real Time Clock...................................................................................................26 3.1.11 Ethernet Test.........................................................................................................27 3.1.12 Camera Test..........................................................................................................27 3.1.13 SDIO WIFI Test ...................................................................................................28 3.1.14 TV Test .................................................................................................................29 3.1.15 NAND Flash Partitioning.....................................................................................29

3.2 Hardware Acceleration......................................................................................................29 3.2.1 JPEG Decoding Test...............................................................................................29 3.2.2 MFC Test................................................................................................................30 3.2.3 OPENGLE Test ......................................................................................................31

Chapter Five: Developing WinCE Applications.......................................32 4.1 Synchronizing WinCE with WinXP..................................................................................32

4.1.1 Installing ActiveSync Driver..................................................................................32 4.1.2 Synchronizing with ActiveSync .............................................................................33

Page 5: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net Email: [email protected] Tel: +86-871-5899845

4.2 Exporting SDK..................................................................................................................34 4.3 Installing SDK...................................................................................................................36 4.4 Sample Application ...........................................................................................................36

4.4.1 Creating Application Project ..................................................................................36 4.4.2 Debugging Sample Application .............................................................................41

Appendix I: Windows CE .NET Advanced Memory Management (from MSDN)......................................................................................................44

Page 6: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net Email: [email protected] Tel: +86-871-5899845

About this manual This manual illustrates developing Windows CE 6.0 for and running Windows CE 6.0 on the

OK6410. Procedures in this manual are tested under Windows XP SP2 and Windows XP SP3.

Chapter One: Developing WinCE6.0 1.1 Building Development Environment 1.1.1 Required Software

Unlike the previous versions, the platform builder for WinCE6.0 is no longer independent

program but a plug-in in the Visual Studio 2005. That is to say, the VS2005 is now the

development environment for Windows CE 6.0.

Trial edition of VS2005 and WinCE6.0 can be downloaded from the MSDN website, or we

can buy an installation DVD from a Microsoft distributor. Service Packs and updates can be

downloaded from the MSDN website.

1) Visual Studio 2005

2) Visual Studio 2005 Service Pack 1

3) MSDN (optional)

4) Windows Embedded CE6.0

5) Windows Embedded CE 6.0 Platform Builder Service Pack 1

6) WINCE6.0R2

7) Microsoft Device Emulator 2.0(optional)

8) Virtual Machine Network Driver for Microsoft Device Emulator (optional)

9) WINCE6.0 Updates

10) WINCE6.0R3

11) WINCE6.0R3 Update-Rollup

1.1.2 Installing Required Software

1. Installing Visual Studio 2005

The VS2005 installer can be found in the folder “VS2005\VSTS\vs”, namely the “setup.exe”.

Double click the installer to install it.

In the setup wizard, click “Install Visual Studio 2005”:

Page 7: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

Email: [email protected] Tel: +86-871-5899845

Page 8: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

Make sure that Visual C++ and Visual C# is to be installed, as shown below:

Email: [email protected] Tel: +86-871-5899845

Page 9: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

Wait until the setup completes:

Email: [email protected] Tel: +86-871-5899845

Page 10: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

2. Installing Visual Studio 2005 Service Pack 1

The service pack 1, named as “VS80sp1-KB926601-X86-ENU.exe” is essential for the

development of WinCE6.0.

3. Installing Windows Embedded CE 6.0

When installing the WinCE 6.0, one thing that requires our attention is that the item

“ARMV4I” CPU support has to be included in the platform, as shown below:

4. Installing WinCE 6.0 Updates

The following three updates have to be installed in sequence:

WinCEPB60-061231-Product-Update-Rollup-Armv4I.msi

WinCEPB60-071231-Product-Update-Rollup-Armv4I.msi

WinCEPB60-081231-Product-Update-Rollup-Armv4I.msi

Latest updates can be found in the Microsoft website:

http://www.microsoft.com/downloads/details.aspx?familyid=D80C5227-B45B-48A3-BF0A-

CAC98AE07A99&displaylang=en

1.2 Installing BSP for OK6410 The WinCE BSP for OK6410, named as “OK6410_BSP.msi”, can be found in the folder

“WINCE6.0\BSP” in the DVD. Double click it to install it to “X:\WINCE600” (“X” refers to the

driver where you installed the CE6.0).

Email: [email protected] Tel: +86-871-5899845

Page 11: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

1.3 Compiling WinCE 6.0 Project A sample WinCE project named as “S3C6410_CE6_DEMO” has already been installed

together with the BSP; we can find its shortcut on the desktop. Double click on the shortcut to

open the project in the Visual Studio 2005.

In the VS2005 window, choose the configuration “Samsung_SMDK6410Release”.

Then click the menu “Build” and select the item “Advanced Build Commands-->Clean

Sysgen” to start compiling the project. When the compilation completes, we will find the binaries

in the folder

“\WINCE600\OSDesigns\S3C6410_DEMO\S3C6410_DEMO\RelDir\Samsung_SMDK6410_Rel

ease”.

Email: [email protected] Tel: +86-871-5899845

Page 12: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

We can also create our own project, please refer to the PDF file

“SMDK6410_WinCE6.0_FMD_InstallationManual.pdf” in the folder

“\WINCE600\PLATFORM\SMDK6410\” for detailed guides.

Email: [email protected] Tel: +86-871-5899845

Page 13: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

Chapter Two: Burning WinCE6.0 to OK6410 2.1 Fusing SDboot to SD card

Insert a SD card formatted as FAT32 to a card reader and connect the card reader to the PC.

Find the IROM_Fusing_Tool.exe in the folder “Tools\SDboot” in the DVD, double click to run it.

In the IROM_Fusing_Tool window, click “Browse” and open the file “OK6410_SDboot.nb0”

in the folder “Tools\SDboot”, select the SD drive and then click the “START” button to start

fusing the SDboot image to the SD card. A dialog box as shown in the picture below indicates that

the fusing is done.

2.2 Setting Boot Mode 1) Insert the SD card to the SD card slot on the OK6410.

2) Set up the toggle switch SW2 to SD card boot mode.

Pins Pin 8 Pin 7 Pin 6 Pin 5 Pin 4 Pin 3 Pin 2 Pin 1

Layout SELNAND OM4 OM3 OM2 OM1 GPN15 GPN14 GPN13

NAND Flash 1* 0 0 1 1 X X X

NOR Flash X 0 1 0 1 X X X

SD card X 1 1 1 1 0 0 0

NOTE: “0” indicates OFF while “1” refers to ON.

3) Connect the serial port cable, USB cable, power supply on the OK6410. Find the DNW

program in the DVD folder “Tools”, copy it to a local folder and run it.

In the DNW window, click the menu item “Serial Port->Connect” to connect to the OK6410

via serial port, when it is connected, we will see something like “COM1, 115200bps” on the DNW

title bar. As shown below:

Email: [email protected] Tel: +86-871-5899845

Page 14: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

4) Power on the OK6410, we will see the SDboot message in the DNW window:

Email: [email protected] Tel: +86-871-5899845

Page 15: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

2.3 Installing USB Driver We will get Found New Hardware Wizard if it is the first time that we run the SDboot,

Follow the wizard to install the USB driver for DNW (DVD:\Drivers\USB Driver\USB Driver for

DNW).

As soon as the USB driver is installed, we will see the information like [USB:OK] on the

DNW title bar, as shown below:

2.4 Burning stepldr.bin to NAND Flash

1) Click the DNW menu “Configuration->Options” and configure the download address to

“0x50030000”, as shown in the picture below:

Email: [email protected] Tel: +86-871-5899845

Page 16: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

2) Click “USB Port->Transmit->Transmit”, and open the file “eboot.nb0” in the folder

“WINCE6.0\demo” in the DVD, the “eboot.nb0” will be downloaded to the OK6410 and booted

as soon as it is downloaded. Press the Space Bar during the boot delay to enter the eboot

configuration menu. As shown below:

In the eboot menu,

3) Press A to erase all the blocks in the NAND Flash.

4) Press 6 to enable programming disk image into Smart Media card. (no need if it is already

enabled)

5) Press 5 to switch the Startup image to LAUNCH EXISTING.

6) Press W to save the configurations.

7) Press U, then click the DNW menu “USB Port->UBOOT->UBOOT”, and open the file

“stepldr.bin” in the folder “WINCE6.0\demo” to download the stepldr image to the OK6410

NAND Flash.

Email: [email protected] Tel: +86-871-5899845

Page 17: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

8) Restart the OK6410.

2.5 Burning eboot.bin to NAND Flash 1) Repeat the step1 and step2 in the chapter 2.4.

2) Press U, then click the DNW menu “USB Port->UBOOT->UBOOT”, and open the file

“eboot.bin” in the folder “WINCE6.0\demo” to download the eboot image to the OK6410 NAND

Flash.

2.6 Setting Nand Flash Boot

Pins Pin 8 Pin 7 Pin 6 Pin 5 Pin 4 Pin 3 Pin 2 Pin 1

Layout SELNAND OM4 OM3 OM2 OM1 GPN15 GPN14 GPN13

NAND Flash 1* 0 0 1 1 X X X

NOR Flash X 0 1 0 1 X X X

SD card X 1 1 1 1 0 0 0

NOTE: “0” indicates OFF while “1” refers to ON.

Email: [email protected] Tel: +86-871-5899845

Page 18: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

2.7 Setting Display Resolution

The option “S” in the eboot menu sets the display resolution in the WinCE6.0. As shown

below, we can choose the resolution for our display by pressing the corresponding number in front

of the listed resolution:

After choosing the resolution, we have to press W to save the configuration and reset the

OK6410 to take the configuration into effect.

2.8 Burning nk.bin to NAND Flash After doing these above we have burnt the stepldr and eboot to the NAND Flash and set the

OK6410 boot from the NAND Flash, the next thing to do is to burn the WinCE kernel image:

nk.bin.

1) Restart the OK6410, press the Space Bar during the boot delay to enter the Eboot menu.

2) Press F to erase the NAND Flash. (the boot partition will be reserved)

3) Press 9 to format the NAND Flash.

4) Press U, then click the DNW menu “USB Port->UBOOT->UBOOT”, and open the file

“nk.bin” in the folder “WINCE6.0\demo” to download the WinCE kernel image to the OK6410

Email: [email protected] Tel: +86-871-5899845

Page 19: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

NAND Flash.

5) The Windows CE 6.0 will be started automatically as soon as the kernel image is

dow oaded.

nl

Email: [email protected] Tel: +86-871-5899845

Page 20: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

Chapter Three: Functions and Operations

h the OK6410 and can be found in the folder

“\Wi

e note that the files can be kept permanently only when they are copied to the

“Nan

can be found in the folder

“\Wi

de of drivers can be found at

“X:\WINCE600\PLATFORM\SMDK6410\SRC\DRIVERS”, “X” referring to the drive where

WinCE6 is installed.

3.1 Interfaces & Peripherals Test Several test programs are provided wit

nCE6.0\TestApps” in the shipped DVD. Copy the exe files to the folder “NandFlash” on the

OK6410 so that we can run the test programs.

Pleas

dFlash” folder. Files copied to other folders will be erased when we reset or power-off the

OK6410.

Source code of the test programs

nCE6.0\TestApps\SourceCode”. Some of the programs are downloaded from internet and

thus source code for these programs is not provided.

Source co

3.1.1 LED Test

Run the LED_Test.exe and click the Start button, we will see the LEDs blinking, which

indicates that the LEDs are working well, otherwise they are out of order.

Email: [email protected] Tel: +86-871-5899845

Page 21: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

3.1.2 ADC Test

Run the ADC_Test.exe to test the A/D conversion. Value of the A/D conversion will be

shown in the program interface; we can change the value by adjusting the CN3 resistance on the

OK6410 board.

NOTE: the ADC_Test program conflicts with the touch screen driver, before you run the

ADC_Test, insert an USB mouse and use it.

3.1.3 Temperature Sensor Test

The Temp_Sensor.exe tests the temperature sensor, run it and we will see the current

temperature in the window.

Email: [email protected] Tel: +86-871-5899845

Page 22: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

3.1.4 Buzzer Test

BEE_Test.exe controls the buzzer. Click the Start button to start the buzzer and “+” “-” to

change the frequency.

3.1.5 Audio Test

Audio_Test.exe tests the audio functions. Connect an earphone and a MIC to the audio

sockets on the OK6410 and run the Audio_Test.exe, then click StartRec to record the found from

MIC, upon clicking Stop button the recorded sound will be saved as wav file in the folder

“\FlashDisk\Rec”, which will be erased when the OK6410 gets reset or powered off.

Email: [email protected] Tel: +86-871-5899845

Page 23: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

3.1.6 Seiral Test

With the Serial_Test.exe we can test the serial port communication. Before running the

Serial_Test.exe program, connect the serial port cable between the OK6410 and PC, and start the

Hyper-Terminal in Windows.

Email: [email protected] Tel: +86-871-5899845

Page 24: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

Click the menu “Configuration-> Options” in the Serial_Test menu bar, select the serial port

and baud rate in the coming pop-up window:

Then click “Serial Port-> Connect”, something like “COM2,115200” will be shown on the

title bar, which indicates that COM1 is connected with the baud rate of 115200, now if we enter

some characters in the Hyper-Terminal, the characters entered will be shown in the Serial_Test

program; we can also enter characters in the program, they will be printed in the Hyper-Terminal.

NOTE: We can not connect COM1, since it has been used by the system as debug port.

3.1.7 USB Host Test

USB mouse, USB keyboard and USB storage devices are supported by WinCE, simply plug

these devices to the USB Host interface then we will be able to use them.

Email: [email protected] Tel: +86-871-5899845

Page 25: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

3.1.8 Touch Screen Calibration

To calibrate the touch screen, double click the “Stylus” icon in the Control Panel. In the

coming Stylus window, click the Recalibrate button in the calibrate tab. A cross will be shown on

the four corners and the center of the LCD, click the center of the cross to calibrate to touch screen.

The calibration data will be saved when we suspend the WinCE system (Start-> Suspend).

In our own applications we can call the TouchCalibrate() function to open the calibration

interface. The TouchCalibrate() function is defined in the file “coredll.dll”.

Email: [email protected] Tel: +86-871-5899845

Page 26: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

3.1.9 SD Card Test

Theoretically the WinCE6 on the OK6410 supports upto 32GB SD card, so far we have test

1G, 2G, 4G and 8GB ones, Plug-and-Playable.

3.1.10 Real Time Clock

RTC is supported by WinCE6. A battery is used on the OK6410 to provide power to the Real

Time Clock so that the RTC can keep working when the board is powered off. We can double click

the clock in the task bar to change the RTC time.

Email: [email protected] Tel: +86-871-5899845

Page 27: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

3.1.11 Ethernet Test

DM9000 is used as 10/100M auto-adaptive Ethernet chip on the OK6410. Before testing the

Ethernet function, connect a direct Ethernet cable to a modem or router, or a cross-over Ethernet

cable to the PC.

Open the Control Panel and double click the Network icon, setup the IP address, sub-net

mask, gateway and DNS. Upon doing these we should be able to browse web pages on the internet.

3.1.12 Camera Test

Insert the CMOS camera to the CAM interface on the OK6410, then power up the board. DO

NOT connect or disconnect the CMOS camera when the power is on.

Run the Camera_Test.exe in the TestApps folder, we can take pictures and photos from the

camera.

Email: [email protected] Tel: +86-871-5899845

Page 28: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

3.1.13 SDIO WIFI Test

Connect the SDIO WIFI module to the SD1 socket on the OK6410, then power up the board.

DO NOT connect or disconnect the SDIO WIFI when the power is on. Make sure that you have a

wireless router running around the WIFI module

The SDIO8681 property window will be shown as soon as the WinCE system is started, we

can also double click the network icon in the task bar to open it if it did not start automatically.

Find the router information in the Wireless panel and double click it to setup wireless network.

Email: [email protected] Tel: +86-871-5899845

Page 29: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

3.1.14 TV Test

Connect the TV interface to a TV via a video cable then run the TV_test.exe program, the

WinCE interface will be shown on the TV.

3.1.15 NAND Flash Partitioning

NAND Flash partition is supported by the OK6410. Files stored in the NANDFlash folder

(drive) can be stored permanently. Files in other folders will be erased upon powering-off or

resetting. We can check the volume information of NAND Flash by right clicking the NandFlash

drive and then selecting Property.

3.2 Hardware Acceleration

Test programs mentioned in this chapter can be found in the folder “TestApps”. At this

moment these programs work only with 7” LCD (800*480 resolution).

3.2.1 JPEG Decoding Test

This test decodes the JPEG images with different resolutions and formats in the folder

“\JPEGtest\testVectors\testInp”.

Copy the folder “JPEGtest” to the NandFlash drive and run the program “jpg_test.exe” in this

Email: [email protected] Tel: +86-871-5899845

Page 30: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

folder. Decoded images will be shown on the LCD, we can also see debugging information printed

via the serial port.

3.2.2 MFC Test

MFC is short for Multi Format CODEC, it supports various of formats like H.263、H.264、

VC-1(WM V9) 、MPEG-4.

Copy the folder “MFCtest” to the NandFlash drive and run the program “mfc_demo.exe” in

this folder. The program window will be shown as below, click the file name to start playing the

video:

Email: [email protected] Tel: +86-871-5899845

Page 31: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

3.2.3 OPENGLE Test

Copy the folder “OPENGLEStest” to the NandFlash folder, and the

“OPENGLEStest\windows” to the folder “\windows” in WinCE, run the programs “glapp1_1.exe”

and “glapp2_0.exe”, we will see OPENGLE demostration on the LCD.

Email: [email protected] Tel: +86-871-5899845

Page 32: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

Chapter Five: Developing WinCE Applications 4.1 Synchronizing WinCE with WinXP

The ActiveSnyc program provided by Windows provides synchronization between Windows

CE and Desktop Windows, with which we can download/upload files conveniently and debug

applications remotely.

4.1.1 Installing ActiveSync Driver

Start the WinCE system on the OK6410, then connect the USB OTG interface to a USB port

on the Host PC via the USB cable, we will see the Found New Hardware wizard a few seconds

after connecting the USB interfaces. Follow the wizard to install the ActiveSync Driver

(DVD:\Driver\USB Drivers\ActiveSync Driver).

Email: [email protected] Tel: +86-871-5899845

Page 33: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

4.1.2 Synchronizing with ActiveSync

The ActiveSync installer can be found in the folder “Tools” in the DVD, double click it to

install ActiveSync. We need to set it up after the installation.

As shown in the picture below, click the menu item “File->Connection Settings”,

And configure as shown below:

Email: [email protected] Tel: +86-871-5899845

Page 34: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

Thereafter the WinCE will be synchronized with Desktop Windows automatically upon its

start up.

4.2 Exporting SDK A SDK (Software Development Kit) is a kit which includes header files, libraries, documents

that related to the platform, which helps application developers to develop applications for the

specific target platform.

To create a SDK for the OK6410:

Start the VS2005 and open the S3C6410_demo project.

Select the item “Add New SDK” in the VS2005 menu “Project”, then configure the SDK

properties as shown in the pictures below:

Email: [email protected] Tel: +86-871-5899845

Page 35: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

Then build the SDK:

Email: [email protected] Tel: +86-871-5899845

Page 36: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

The SDK will be created in the folder

“\WINCE600\OSDesigns\S3C6410_DEMO\S3C6410_DEMO\SDKs\SDK1\MSI”.

4.3 Installing SDK As described in the chapter above, the Software Development Kit (SDK) is necessary for

developing applications. The SDK has to be installed before we can develop applications for the

OK6410 platform.

Double click the OK6410_CE6_SDK.msi to install the SDK, also we can find a ready-made

SDK in the DVD.

4.4 Sample Application 4.4.1 Creating Application Project

Create a new project in the VS2005. Select the “Project Type” as “Visvual C++”-->“Smart

Device” --> “MFC Smart Device Application” and name it as “HelloWorld”, as shown below:

Email: [email protected] Tel: +86-871-5899845

Page 37: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

Upon pressing OK we will get the “MFC Smart Device Applilcation Wizard”, follow the

wizard and configure the project as shown in the pictures below:

Email: [email protected] Tel: +86-871-5899845

Page 38: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

Email: [email protected] Tel: +86-871-5899845

Page 39: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

Email: [email protected] Tel: +86-871-5899845

Page 40: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

Edit the file “HelloWorld.rc” a little bit as you wish, then click the menu “Build” and select

the item “Build Solution” to compile the HelloWorld project.

Email: [email protected] Tel: +86-871-5899845

Page 41: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

4.4.2 Debugging Sample Application

Start WinCE6.0 on the OK6410 and synchronize it with desktop windows.

Click the VS2005 menu item “Tools->Options” and select “Device Tools->Devices”, select

the item “OK6410 Board ARMV4I Device” then click the “Properties…” button. Configure the

properties as shown in the picture below:

Email: [email protected] Tel: +86-871-5899845

Page 42: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

Then, click the VS2005 menu “Tools” and select the item “Connect to Device…”

Email: [email protected] Tel: +86-871-5899845

Page 43: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

When the device is connected, we can click “Build->Deploy Solution” to debug the

HelloWorld application.

Email: [email protected] Tel: +86-871-5899845

Page 44: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

Appendix I: Windows CE .NET Advanced Memory Management (from MSDN)

Douglas Boling, Windows Embedded MVP Boling Consulting Abstract

One of the advantages of Microsoft® Windows® CE is its Microsoft Win32® application programming interface (API) support. The hundreds of thousands of Windows programmers can leverage their knowledge of the Win32 API and MFC to move to Windows CE with relatively little difficulty. Windows CE can implement a subset of the Win32 API, but programmers should never forget that Windows CE is a completely different operating system from Windows XP with different requirements and a different implementation. Knowing how Windows CE implements its Win32 compatibility can make all the difference when designing applications or diagnosing problems.

Memory management is one of the places in which the difference in the implementation between Windows CE and Windows XP is most apparent. Although Windows CE supports almost every Win32 memory management function, with the exception of deprecated global heap functions the implementation of these memory management APIs is completely different. These differences can hinder those unfamiliar with the subtle differences between Windows CE and the desktop versions of Windows. To understand where these problems are located you must first understand how Windows CE manages memory.

System Memory Map

Both Windows XP and Windows CE are 32 bit operating systems, and as such support a 4-gigabyte (GB) virtual address space. Windows XP divides the address space into two 2 GB areas. The top half of the address space is reserved for the system. The bottom 2 GB of the address space is replicated for each running application.

Figure 1. The Windows XP virtual memory space

The virtual address space of Windows CE is at first glance, organized in a similar fashion with an area reserved for the system and replicated application spaces. Figure 2 shows the Windows CE address space. In this case the top 2 gigabytes (GB) of the address space are also reserved by the system. The lower half of the address space is divided into many regions. The majority of this area, almost half of the space, is defined as the Large Memory Area. This area is used to allocate large blocks of memory space typically used for memory-mapped files.

Below the Large Memory Area is another large area, referred to in this paper as reserved. Below the reserved area, at the extreme low end of the memory space, is a 64-megabyte (MB) area. This 64 MB area, more precisely the lowest 32 MB of the area, is replicated for each running

Email: [email protected] Tel: +86-871-5899845

Page 45: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

application.

Figure 2. The Windows CE virtual memory space

Windows CE Application Memory Map

The lowest 64 MB of the virtual address space is where Windows CE applications are. Figure 3 shows this application virtual address space. The application code is loaded starting at virtual address 0x10000, like it is in Windows XP applications. When the application is launched, enough space for all the code is reserved in the address space. The actual code is then demand paged into the address space as it is needed.

Above the area reserved for the code, pages are reserved for the read-only and read/write static data areas. In addition, regions are reserved for the local heap and for a stack for each thread running in the application. The size of the region reserved for each stack is fixed when the thread is launched. The actual RAM is only committed as the stack grows. The heap, on the other hand, reserves an area that can be grown as necessary as blocks of RAM are allocated in the heap.

When execute in place (XIP) DLLs are loaded, they are loaded from the top of the 64 MB space down. Each XIP DLL is based (positioned in the address space) when the ROM is created. When a non XIP DLL is loaded, it is positioned below the 32 MB boundary. Non-XIP DLLs, also called RAM-based DLLs, are those that are loaded from the object store, decompressed from ROM or loaded from an external file system such as a Compact Flash card. The upper 32 MB of the applications virtual memory space is only used for XIP DLLs.

Email: [email protected] Tel: +86-871-5899845

Page 46: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

Figure 3. A Windows CE .NET application virtual memory space Any additional memory allocated by the application by either creating separate heaps or by

directly calling the VirtualAlloc API is allocated from the bottom up with the system finding the first free region that is large enough to satisfy the allocation.

Living Within the Box

Although one limiting factor of a Windows CE application is the amount of RAM available to the application, another major limitation is the application's relatively small 32 MB virtual address space. Although XIP DLLs are loaded above the 32 MB space, all other memory allocations and any RAM-based DLLs all must fit in the 32 MB memory space of the application. This 32 MB "box" is not as much a problem for the Windows CE programmer as it is a challenge to be overcome.

To understand how this seeming large memory space is constraining, you must understand the operation of the VirtualAlloc API. VirtualAlloc is the most fundamental memory allocation call in any Microsoft Win32 operating system. It allocates memory at the page level; the page being the smallest unit of memory that can be allocated or freed by the CPU. The page size of a Windows CE .NET CPU is either 1024 or 4096 bytes depending on the CPU. The 4 KB page size is the most widely used.

The VirtualAlloc call allocates memory in two steps. First, a region of the virtual memory space is reserved. This reservation does not consume any RAM; it simply prevents a portion of the virtual address space from being used for other reasons. After the memory space is reserved, portions or the entire region can be committed, which maps actual physical memory into the reserved region. The VirtualAlloc function is used for both reserving memory space and committing memory. The prototype for the VirtualAlloc function is shown below. LPVOID VirtualAlloc (LPVOID lpAddress, DWORD dwSize, DWORD flAllocationType, DWORD flProtect);

The first parameter to VirtualAlloc is the virtual address of the region of memory to allocate. The lpAddress parameter is used to identify the previously reserved memory block when you use VirtualAlloc to commit a block of memory previously reserved. If this parameter is NULL, the system determines where to allocate the memory region, rounded to a 64 KB boundary. The second parameter is dwSize, the size of the region to allocate or reserve. Because this parameter is specified in bytes, not pages, the system rounds the requested size up to the next page boundary.

The flAllocationType parameter specifies the type of allocation. You can specify a combination of the following flags: MEM_COMMIT, MEM_AUTO_COMMIT and

Email: [email protected] Tel: +86-871-5899845

Page 47: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net Email: [email protected] Tel: +86-871-5899845

MEM_RESERVE. The MEM_COMMIT flag allocates the memory to be used by the program. MEM_RESERVE reserves the virtual address space to be later committed. Reserved pages cannot be accessed until another call is made to VirtualAlloc specifying the region and using the MEM_COMMIT flag. The MEM_AUTO_COMMIT flag is unique to Windows CE and is quite handy but not a subject for this article.

Therefore, to use VirtualAlloc to allocate usable RAM, an application must either call VirtualAlloc twice, once to reserve memory space and again to commit the physical RAM, or call it once, combining both the MEM_RESERVE and MEM_COMMIT flags in the flAllocationType parameter.

Combining the reserve and commit flags uses less code, and is quicker and simpler. This technique is used often in Windows XP applications but is not a good idea in Windows CE applications. The problem is illustrated with the following code fragment. INT i; PVOID pMem[512]; for (i = 0; i < 512; i++) { pMem[i] = VirtualAlloc (0, PAGE_SIZE, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); }

The key to avoiding this problem is knowing about it. This is only one of a number of places where the issue of only 512 regions in a Windows CE application's address space impacts the application.

Allocating Large Memory Blocks Another issue with living within the 32 MB address space of a Windows CE .NET

application is how to allocate huge blocks of memory. If an application needs a block of 8, 16, or 32 megabytes of RAM for a specific need, how can it allocate this memory when the entire address space of the application is limited to 32 MB? The answer is to apply a fix that was first used in earlier versions of Windows CE .NET for video drivers. It works out that if Windows CE .NET detects a call to VirtualAlloc that reserves address space of larger than 2 MB, the address space is not reserved in the 32 MB box. Instead, the block is reserved in the Large Memory Area that is positioned in the global memory space just below the 2 GB system reserved space.

When the memory space has been reserved, the application can commit specific pages within the reserved space with calls to VirtualAlloc. This allows huge memory blocks to be available to the application, or driver, even though it lives within the constraints of the 32 MB box. The code below shows a simple allocation of a 64 MB block, and then commits one page of the reserved area. PVOID ptrVirt, ptrMem; ptrVirt = VirtualAlloc (0, 1024 * 1024 * 64, MEM_RESERVE, PAGE_NOACCESS); if (!ptrVirt) return 0; ptrMem = VirtualAlloc ((PVOID)((int)ptrVirt+4096), 4096, MEM_COMMIT, PAGE_READWRITE); if (!ptrMem) { VirtualFree (ptr, 0, MEM_RELEASE); return 0; } return ptrMem;

The preceding code also shows one of the features of dealing directly with the virtual memory API. You can create large sparse arrays without consuming large amounts of RAM. In the code above, the 64 MB region reserved does not consume any physical RAM. In this example, the only RAM consumed is one page, 4096 bytes, when the page is committed with the second call to VirtualAlloc.

Page 48: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

DLL Load Problem There are currently a large number of Windows CE programmers that are programming on

the Pocket PC 2002. Despite being fixed by a change to the Windows CE .NET memory architecture, there is a significant problem that is impacting Pocket PC 2002 programmers concerning the loading of DLLs by applications. To understand this problem, you first must understand one of the major differences between how Windows CE .NET differs from Windows CE 3.0 and how both versions of Windows CE load and manage DLLs.

One of the new features of Windows CE .NET is the expansion of an application's virtual address space from 32 MB, in earlier versions of Windows CE, to 64 MB. The upper 32 MB of the virtual space that is available for XIP DLLs is not available in Windows CE 3.0. Because of this, applications running on Windows CE 3.0-based systems must load their XIP DLLs, their code and all their data into a 32 MB virtual address space. Figure 4 shows the application memory space of a Windows CE 3.0 application. A diagram of the Windows CE 3.0 application memory space is shown in Figure 4.

Figure 4. A Windows CE 3.0 application virtual memory space Because the Pocket PC 2002 is based on Windows CE 3.0, this limitation of the virtual

memory space applies to applications running on that platform.

DLL Loading The technique that Windows CE uses to load DLLs is the same for Windows CE .NET in

addition to earlier versions of Windows CE with the exception of the extra 32 MB of space on Windows CE .NET where XIP DLLs are loaded.

When a request is made to load a DLL the kernel first checks to see if the DLL has been previously loaded by another application, if not, and the DLL is not an XIP DLL, the kernel uses a modified top-down search to find the first available space in the 32 MB virtual memory map. The search is considered to be modified because the kernel avoids any address that is used by another DLL even if the DLL is not loaded by the current process. This search technique ensures that every DLL in the system is loaded at a unique, non-overlapping address.

The unique address is necessary because if a DLL is loaded by more than one process, it must be located at the same virtual address in all processes. By loading different DLLs each at a unique address, the kernel ensures that if an application wants to load a DLL previously loaded by another process, the virtual address where the DLL is mapped in the other process is available in the process requesting the DLL. Figure 5 shows a diagram of three processes each loading a series of DLLs. In this figure, DLL A is loaded by all three processes at the same address. Process 2 loads DLL C, which is lower in the address space than DLL B and DLL A, which were loaded by

Email: [email protected] Tel: +86-871-5899845

Page 49: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

Process 1. Process C later loads DLL A and its own DLL D. Notice that in each of the processes the same DLLs are loaded at identical addresses while each different DLL is loaded at a unique address.

Figure 5. Three processes loading a series of DLLs Now consider what to do if you encounter a potential problem. Suppose Process 2 loaded

DLL C that was quite large as shown in Figure 6. Note that process 3 has the bad luck of being both a large .exe file and loading a DLL after process 2 had loaded its rather immense DLL C. Clearly, process 3 is close to trouble if it attempted to load any more DLLs that had not been loaded already by other processes. This is a somewhat contrived example because the size of DLL C would have to be incredibly large, or Process 2 would have to load a large number of DLLs for this problem to occur naturally.

Figure 6. Three processes loading a series of DLLs with Process 2 loading a huge DLL From general loading of DLLs, now it is time to add the complication of dealing with XIP

Email: [email protected] Tel: +86-871-5899845

Page 50: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net Email: [email protected] Tel: +86-871-5899845

and non-XIP DLLs. Each execute in place DLL is based at a unique address when the ROM image is created by the OEM. This way, all XIP DLLs can be loaded without any conflicts among them. Because they are XIP, the ROM containing the DLL code can be mapped directly into the virtual address space of any application that requests it. XIP DLLs cannot be rebased at another address when they are loaded by a process, because changing the base would involve modifying the read-only code.

When the kernel looks for free virtual addresses for non-XIP DLLs, it begins its search for a free virtual address below the lowest based XIP DLL. This is not the lowest based XIP DLL your application has loaded, rather it is the lowest based XIP DLL in the entire system whether it is loaded by any applications or not. Here again this technique insures that every DLL currently loaded can be loaded by other processes. Although this system works quite well, there are times when a DLL won't load due to the unique implementation of Windows CE .NET on the Pocket PC 2002.

The implementation of Windows CE .NET on the Pocket PC 2002 takes advantage of a feature in Windows CE 3.0 that allows for more than one ROM to be used on a device. This feature allows more than one ROM to be used in a system even if they do not have contiguous physical addresses.

As mentioned above, DLLs require special processing to be XIP. Because the basing of a DLL requires changing the code of the DLL, a DLL has to be based when the image of a ROM is created. When the first ROM is created, the ROM creation tool bases each DLL so that it does not overlap any other DLL in the ROM.

The use of multiple XIP regions meant that the DLL load issue needed to be revisited by the kernel designers. To ensure that the XIP DLLs never overlap on a multiple XIP region system, the DLLs in the second ROM had to be based at a virtual address lower than the lowest DLL of the first ROM image. If other ROMs were used, the DLLs in those XIP regions also had to be based lower than the previous ROM.

The use of multiple ROM images is handy for other reasons. If an OEM or Microsoft wanted to update part of a Windows CE image, they could send out an update for a specific ROM without having to update the entire system. To insure that an update of one ROM does not require changes to another, Microsoft encourages that the DLLs based in a lower image be based not at the address of the lowest DLL in the previous image but at a lower address to artificially introduce a virtual memory gap between set of DLLs and another.

The developers inside Microsoft responsible for the Pocket PC 2002, which is based on Windows CE 3.0, took advantage of multiple XIP regions to the extreme. Most Pocket PC implementations have five or more XIP regions. The problem is that the gaps between the regions are far too large. The lowest based XIP DLL in a Pocket PC 2002 image is typically based below 0x0100000. Because Windows CE places RAM based DLLs below the lowest XIP DLL, the space available for RAM based DLLs, the application code, its heaps and stacks is not limited to the 32 MB virtual address space but the space below the lowest XIP DLL, which is less than 16 megabytes.

In Figure 7, the problem of the Pocket PC 2002 is illustrated. Notice that the area in the virtual memory space for the XIP DLLs is rather large. In reality, this figure is quite conservative because it does not show the XIP region taking over half the virtual memory space, which it typically does on a Pocket PC 2002. Notice that the loading of the RAM-based DLLs; A, B, C, and D takes place much lower in the virtual address space.

Page 51: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

Figure 7. DLL loading on the Pocket PC 2002 where a large part of the virtual address space is used by XIP DLLs

With corporate applications processing vast amounts of data, corporate developers are forced to use large databases in their Windows CE applications. Usually the database engine is implemented as a DLL and it is usually quite large. In the example above, the database DLL is the troublemaking DLL C. With the combination of less than 16 megabytes of virtual memory space available for a Pocket PC 2002 application and the requirements of large, RAM-based DLLs, many developers are discovering that their applications will not run due to lack of space—not RAM, but virtual memory space.

Combining DLLs

Various techniques are available to alleviate this problem on the Pocket PC 2002. First, developers should reduce the number of DLLs by combining their small DLLs into larger ones. Each DLL takes up at least one 64-kilobyte region. If an application has 4 DLLs each 20 kilobytes in size, the total memory space used by the DLLs is 256 kilobytes. By combining the four DLLs, the resulting large DLL will consume only 64 kilobytes of virtual memory space—the code takes up only 60 kilobytes, but the minimum footprint is 64 kilobytes. As a general rule, combine DLLs into sizes up to, but not over, multiples of 64 kilobytes. In some applications with an excessive number of small DLLs, the simple act of combining the DLLs into a few large ones will solve the DLL load problem for their application.

Moving DLL Code into the Application

Another method of reducing the problem of DLLs in the Pocket PC 2002 is to move code based in DLLs into the application. Even if the code is shared among more than one process, sometimes is advantageous to duplicate the code in both processes because different processes load independently from other applications.

At first, moving code into the application seems like it will not help—the code still is in the 32 MB virtual space of the application. However, the key here is to make some a large application that doesn't need the large, RAM based DLLs and other small application that loads and uses the RAM based DLL. In this technique, the large application performs most of the business logic and small application that loads the large DLL. If the large application needs the services of the large DLL, it must use interprocess communication to have the smaller process make the call to the DLL and return the data to the large process again by using interprocess communication.

Defining the DLL Load Order

Email: [email protected] Tel: +86-871-5899845

Page 52: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net Email: [email protected] Tel: +86-871-5899845

When reducing the number of DLLs or relaying out the application's code isn't enough, it is time for a more radical method: manually specifying the load order of the DLLs. The load order is important because if a large DLL is loaded early, it pushes down the load address of all subsequent small DLLs. Typically, the large DLL is used by a single application. But if it is loaded early, it can impact the other application by pushing down the load address of the other applications DLLs to the point where they cannot be loaded.

The solution is to load the small DLLs first, and then have the offending large DLL loaded later or even last. This raises the issue of how to force the load order of the DLLs. One way is to sequence the startup of the different processes in the application suite but this sometimes can be problematic.

Another way to define the DLL load order is to write a small application that runs before the primary application that loads the RAM based DLLs in a defined order by repeatedly calling the Win32 function LoadLibrary. The DLL loader stays running for the life of the primary application and then terminates. It can even launch the primary application by calling CreateProcess and wait until the primary application terminates by blocking on the process handle returned by CreateProcess. The DLL load application does not use a lot of RAM because the loaded DLLs will all be loaded eventually by the other processes.

All of the solutions discussed for solving the DLL load problem on the Pocket PC 2002 are hacks of one way or another. None are elegant, nor that maintainable. However, these are the solutions that developers are using to develop their products. Future releases of the Pocket PC should solve this problem, but for developers working on Pocket PC 2002 products, improvisation is the key.

By knowing how Windows CE manages memory, developers can avoid pitfalls and diagnose problems more quickly. Understanding how DLLs are managed by Windows CE helps avoid potential problems in Pocket PC 2002 applications. Even when future releases of the Pocket PC appear that solve this problem, the millions of devices already in the field will need applications. Knowing where to look for the problem is the first step in finding, and then solving the problem.

Page 53: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

Appendix II: Interrupt Architecture in Microsoft Windows CE .NET (from MSDN)

Nat Frampton, Windows Embedded MVP President, Real Time Development Corp. Overview

With Microsoft Windows CE .NET, Microsoft has advanced the interrupt architecture of Windows CE. The operating system's (OS) ability to deal with shared interrupts greatly extends the ability of Windows CE .NET to support many interrupt architectures. This article explores the scenarios for dealing with interrupts from both the original equipment manufacturer (OEM) and application developers. OEM adaptation layer (OAL) interrupt service routine (ISR) Handling is explored. Installable ISRs are presented, including a simple shell to get started. Interrupt service thread (IST) interrupt handling is presented along with a template for initialization and execution. Finally, sources of latencies for both ISR and ISTs are examined. (14 printed pages)

Interrupt Architecture

The first step in exploring the interrupt architecture of Microsoft® Windows® CE .NET is defining an overall model of the hardware, kernel, OAL and thread interactions during an interrupt. The following diagram is an overall picture of these different levels of responsibility and the transitions that cause changes of state.

Figure 1. The diagram represents the major transitions during an interrupt with time increasing to the

right of the diagram. The bottom most layer of the diagram is the hardware and the state of the interrupt controller. The next layer is the kernel interactions during interrupt servicing. The OAL describes the board support package (BSP) responsibilities. The top most layer represents the application or driver thread interactions needed to service an interrupt. The diagram represents the interactions during a single interrupt; representing the new ability of Windows CE .NET to have shared interrupts.

The activity starts with an interrupt represented by the line at the left most section of the chart. An exception is generated causing the kernel ISR vector to be loaded onto the processor. The kernel ISR interacts with the hardware disabling all equal and lower priority interrupts on all processors except for the ARM and Strong ARM architectures. The kernel then vectors to the OAL ISR that has been registered for that particular interrupt. The OAL ISR then can either directly handle the interrupt or can use NKCallIntChain to walk a list of installed ISRs. The main ISR or any of the installed ISRs then performs any work and returns the mapped interrupt called SYSINTR for that device. If the ISR determines that its associated device is not causing the

Email: [email protected] Tel: +86-871-5899845

Page 54: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net Email: [email protected] Tel: +86-871-5899845

interrupt the ISR returns SYSINTR_CHAIN, which causes NKCallIntChain( ) to walk the ISR list to the next interrupt in the chain. The ISRs are called in the order that they were installed creating a priority on the calling list.

Once the single ISR or its associated chain of ISRs has been called the return values can be one of the following:

Return Value Action

SYSINTR_NOP Interrupt is not associated with any registered ISR for a device. Kernel enables all other interrupts.

SYSINTR Interrupt is associated with a known registered ISR and device.

SYSINTR_RESCHED Interrupt was the result of a timer expiration requesting an OS reschedule.

The SYSINTR return value is of highest interest to our discussion. Upon completion of the ISR the kernel re-enables all interrupts on the processor except for the identified interrupt. The kernel then signals the event that has been associated with the SYSINTR value.

The IST of a driver or application is then able to run assuming that it is the highest priority thread that is ready to run. The IST communicates with the associated device and reads any necessary data from the device completing its interrupt interaction. The IST then signals its completion with a call to InterruptDone( ) with the associated SYSINTR value.

The kernel, upon receiving the InterruptDone for the SYSINTR value, then re-enables the designated interrupt. This is the first point at which another interrupt for this device can be received.

This is a fast and furious look through the interrupt sequence of activities inside Windows CE .NET. We will now examine each of these components and their responsibilities in detail.

OAL ISR Handling

The OAL ISR is the basic interrupt handler that is part of the platform. The following is an actual ISR for an X86 platform. Profiling and ILTiming support has been removed. The X86 ISR is representative of all of the Windows CE-based platforms. It demonstrates a single ISR that handles all interrupts on the system.

The ISR's goal is to hand back to the kernel a SYSINTR number for the associated device that has caused the interrupt. The ISR performs the following sequence of activities.

• Gets the current hardware interrupt from the PICGetCurrentInterrupt ( PIC)

• If the interrupt is INTR_TIMER0 (System Timer)

1. Updates the CurMSec keeping time for the OS

2. Check to see if a reboot address has been registered (RebootHandler)

• If the interrupt is INTR_RTC

1. The ISR checks to see if an alarm has expired (SYSINTR_RTC_ALARM)

• If the Interrupt is less that the INTR_MAXIMUM

1. Call the Interrupt chain (NKCallIntrChain)

2. Sets the return value from the NKCallIntrChain to the return value

3. If the interrupt chain did not claim the interrupt: (SYSINTR_CHAIN)

Map the current hardware interrupt (OEMTranslateIRQ)

Page 55: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net Email: [email protected] Tel: +86-871-5899845

If the interrupt was registered with HookInterrupt in OEMInit

Return the SYINTR value from OEMTranslateIRQ

If the interrupt was not registered return SYSINTR_NOP

4. Enables all but the current interrupt. (PICEnableInterrupt)

5. Does the proper end of interrupt to signal the PIC that the interrupt is done (EOI)

• The ISR returns one of the following:

1. SYSINTR_NOP—No ISR claimed the interrupt

2. SYSINTR_RESCHED—Reschedule Timer has expired

3. SYSINTR—ISR has claimed the interrupt

4. SYSINTR_RTC_ALARM—Alarm has expired

ULONG PeRPISR(void) { ULONG ulRet = SYSINTR_NOP; UCHAR ucCurrentInterrupt; ucCurrentInterrupt = PICGetCurrentInterrupt(); if (ucCurrentInterrupt == INTR_TIMER0) { CurMSec += SYSTEM_TICK_MS; CurTicks.QuadPart += TIMER_COUNT; if ((int) (CurMSec - dwReschedTime) >= 0) ulRet = SYSINTR_RESCHED; } // // Check if a reboot was requested. // if (dwRebootAddress) { RebootHandler(); } } else if (ucCurrentInterrupt == INTR_RTC) { UCHAR cStatusC; // Check to see if this was an alarm interrupt cStatusC = CMOS_Read( RTC_STATUS_C); if((cStatusC & (RTC_SRC_IRQ)) == (RTC_SRC_IRQ)) ulRet = SYSINTR_RTC_ALARM; } else if (ucCurrentInterrupt <= INTR_MAXIMUM) { // We have a physical interrupt ID, return a SYSINTR_ID // Call interrupt chain to see if any installed ISRs handle this // interrupt ulRet = NKCallIntChain(ucCurrentInterrupt); if (ulRet == SYSINTR_CHAIN) { ulRet = OEMTranslateIrq(ucCurrentInterrupt);

Page 56: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net Email: [email protected] Tel: +86-871-5899845

if (ulRet != -1) PICEnableInterrupt(ucCurrentInterrupt, FALSE); else ulRet = SYSINTR_NOP; } else { PICEnableInterrupt(ucCurrentInterrupt, FALSE); } } if (ucCurrentInterrupt > 7 || ucCurrentInterrupt == -2) { __asm { mov al, 020h ; Nonspecific EOI out 0A0h, al } } __asm { mov al, 020h ; Nonspecific EOI out 020h, al } return ulRet; }

If an ISR has not been installed for an interrupt that has been initialized with HookInterrupt in OEMInit in the OAL, the ISR will return the proper SYSINTR value.

Note: You are not required to install an installable ISR for an interrupt if the device can be serviced through IST interactions only. Enabling the interrupt through a call to HookInterrupt in the OAL's OEMInit is sufficient.

The ISR code is a very small and fast piece of code. Its execution time will directly affect the latencies for interrupts throughout the system. A change to the Interrupt architecture that was introduced in Windows CE 3.0 was the ability to Nest Interrupts. At the point that the OAL ISR is entered, all higher priority interrupts have been enabled. The ISR may be preempted. Scenarios where timing within the ISR is critical may require interrupts to be disabled for that period of time. As with ISR execution time, this time when interrupts are turned off will increase the worst-case latencies for your platform.

At the point the ISR has handed back a SYSINTR associated with a particular device, the kernel then signals the IST to wake up. The IST interrupt handling code within a driver or application is responsible for concluding the interrupt interaction.

Installable ISRs

Installable ISRs were created in response to the openness that Windows CE .NET has brought to the embedded space. No longer is the OEM completely responsible for the platform and the application code. The embedded space now contains platform providers and application developers. If a new device were added to an open bus by an application developer on a platform using Windows CE 3.0, the OEM would have to convince the OEM to add the ISR to the platform.

To install an ISR into a platform there are two required steps: 1. Call the LoadIntChainHandler function to load the DLL containing the ISR code. 2. The ISR must be coded to respond with a SYSINTR_ . . . response as in the OAL ISR. The LoadIntChainHandler function loads the ISR dynamic-link library (DLL) into the

kernel's address space. This implies that the code cannot call any non-kernel functions including any C-language runtime library functions. Remember that some structure-to-structure assignments degrade into a memcpy call and all code must be reviewed to ensure that no requirements of external libraries, even if they are created by the compiler, are necessary.

The following source code example demonstrates a basic shell for creating an installable ISR. There are four functions:

• DLLEntry—Receives the process and thread attach messages • InfoCopy—A copy routine that is used when doing any structure assignments

Page 57: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net Email: [email protected] Tel: +86-871-5899845

• IOControl—Handler for any IST calls with KernelLibIOControl • ISRHandler—Actual ISR

BOOL __stdcall DllEntry( HINSTANCE hinstDll, DWORD dwReason, LPVOID lpReserved ) { if (dwReason == DLL_PROCESS_ATTACH) {} if (dwReason == DLL_PROCESS_DETACH) {} return TRUE; } // The compiler generates a call to memcpy() for assignments of large objects. // Since this library is not linked to the CRT, define our own copy routine. void InfoCopy( PVOID dst, PVOID src, DWORD size ) { while (size--) { *((PBYTE)dst)++ = *((PBYTE)src)++; } } BOOL IOControl( DWORD InstanceIndex, DWORD IoControlCode, LPVOID pInBuf, DWORD InBufSize, LPVOID pOutBuf, DWORD OutBufSize, LPDWORD pBytesReturned ) { switch (IoControlCode) { case IOCTL_DEMO_DRIVER: // Your I/O Code Here return TRUE; break; default: // Invalid IOCTL return FALSE; } return TRUE; } DWORD ISRHandler( DWORD InstanceIndex ) { BYTE Value; Value = READ_PORT_UCHAR((PUCHAR)IntrAddress ); // If interrupt bit set, return corresponding SYSINTR if ( Value & 0x01 )

Page 58: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net Email: [email protected] Tel: +86-871-5899845

{ return SYSINTR_DEMO; } else { return SYSINTR_CHAIN; } }

The ISR handler code uses a port I/O call to check the status of the device. Your scenario may require a much more complex interrogation. If the device is not the source of the interrupt, the return value will be SYSINTR_CHAIN. This return value tells the NKChainIntr function that our device was not the source of the interrupt and that other ISRs in the chain should be evaluated. If a valid SYSINTR is returned by the ISR, then NKChainIntr will immediately return and not call any other ISRs on the list. This provides a priority ordering. The first loaded installable ISR is loaded first on the list, or highest priority, subsequent installable ISRs are then added to the bottom of the list. The highest priority installable ISR in the chain should be installed first for both priority and speed of execution.

IST Interrupt Handling

Dealing with interrupts from either an application or driver, requires a two-step process. First, the interrupt must be initialized with an associated event. Second, the IST must wait on the interrupt event in response to interrupts from the kernel.

Interrupt Initialization

The following is example code for setting up and associating an IST with a particular interrupt. The key steps in initialising an interrupt are: • Creating an Event • Getting the System Interrupt number for your IRQ • Creating an interrupt thread (IST) that is suspended • Calling InterruptInitialize to create an association of the IRQ->Event 1. Creating an IST that is not suspended may cause InterruptInitialize to fail

because the event is already being waited on • Set the thread priority to the appropriate priority • Resuming the IST Void SetupInterrupt( void ) { // Create an event // g_hevInterrupt = CreateEvent(NULL, FALSE, FALSE, NULL); if (g_hevInterrupt == NULL) { RETAILMSG(1, (TEXT("DEMO: Event creation failed!!!\r\n"))); return; } // Have the OAL Translate the IRQ to a system irq // fRetVal = KernelIoControl( IOCTL_HAL_TRANSLATE_IRQ, &dwIrq, sizeof( dwIrq ), &g_dwSysInt, sizeof( g_dwSysInt ), NULL ); // Create a thread that waits for signaling //

Page 59: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net Email: [email protected] Tel: +86-871-5899845

g_fRun = TRUE; g_htIST = CreateThread(NULL, // Security 0, // No Stack Size ThreadIST, // Interrupt Thread NULL, // No Parameters CREATE_SUSPENDED, // Create Suspended &dwThreadID // Thread Id ); // Set the thread priority – arbitrarily 5 // m_nISTPriority = 5; if( !CeSetThreadPriority( g_htIST, m_nISTPriority )) { RETAILMSG(1,(TEXT("DEMO: Failed setting Thread Priority.\r\n"))); return; } // Initialize the interrupt // if ( !InterruptInitialize(g_dwSysInt,g_hevInterrupt,NULL,0) ) { RETAILMSG (1, (TEXT("DEMO: InterruptInitialize failed!!!\r\n"))); return; } // Get the thread started // ResumeThread( g_htIST ); }

It is important to note that the call to InterruptInitialize takes only the SYSINTR value and the event. The kernel does not know or care about the thread that will be waiting on the event. This allows for a variety of application and driver architectures. A simple main loop of an application could initialize an interrupt and then immediately wait on the event. Only a single event can be associated with an interrupt. The event cannot be used in a call to WaitForMultipleObjects. We will look at a simple thread to service the interrupt. This is the standard solution for most implementations.

IST-Interrupt Service Routine

Example code for an IST is presented in this section. The key components to this IST interrupt handling thread are:

• Waiting for the Interrupt Event. • Confirming that we have a pulsed event from the OS. • Do any board level interrupt processing necessary to complete the interrupt. In our

example we confirm the interrupt. • Handling the interrupt in the shortest time possible. • Create CELOGDATA to be viewed in Kernel Tracker. • Check to see if the g_fPRRunning flag is set and then set the g_hevPRStart Event. • Call InterruptDone(). 1. The OS will not provide another interrupt on this IRQ until InterruptDone is

called. • Waiting for the Interrupt Event again.

DWORD WINAPI ThreadIST( LPVOID lpvParam )

Page 60: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net Email: [email protected] Tel: +86-871-5899845

{ DWORD dwStatus; BOOL fState = TRUE; // Always chec the running flag // while( g_fRun ) { dwStatus = WaitForSingleObject(g_hevInterrupt, INFINITE); // Check to see if we are finished // if(!g_fRun ) return 0; // Make sure we have the object // if( dwStatus == WAIT_OBJECT_0 ) { // Do all interrupt processing to complete the interaction // with the board so we can receive another interrupt. // if (!( READ_REGISTER_ULONG(g_pBoard Register) & INTR_MASK)) { RETAILMSG(1, (TEXT("DEMO: Interrupt..."))); g_dwInterruptCount ++; } // Finish the interrupt // InterruptDone( g_dwSysInt ); } } return 0; }

This sample reads a ULONG register to determine the interrupt state. You can simply replace this section of code with your code. It is very critical that the IST process be as simple as possible. If future processing on the data from the device needs to be done:

• Get the data from the device as quickly as possible in the IST. • Create an event to signal a lower priority thread to do the work. • Immediate return, with InterruptDone, from the IST. • Have the lower priority thread process the data further. • Place FIFOs between the IST and the lower priority thread to handle overruns.

Contributors to Latencies

From the diagram of the interrupt architecture in Windows CE .NET, the interactions of the hardware, kernel, OAL and driver/application threads are demonstrated. Microsoft has provided several tools including ILTiming, CEBench and Kernel Tracker, to help you evaluate the performance of Windows CE .NET on your platform. An understanding of the contributions to both ISR and IST latency help to target areas of investigation.

ISR Latencies

As can be seen in the Interrupt Architecture Diagram earlier in this paper, the ISR latency is defined as the time from when an interrupt occurred to the time the OAL ISR first executes. Since

Page 61: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net Email: [email protected] Tel: +86-871-5899845

the interrupt does not cause an exception into the processor if interrupts are turned off, the first contributor to latency is the total time interrupts are turned off in the system. Interrupts for a processor are checked at the beginning of each machine instructions. If a long string move instruction is called, this can lock out interrupts, causing the second source of latency, which is the amount of time a BUS access locks out the processor. The third contributor is the amount of time it takes the kernel to vector to the OAL ISR handler. This is a process context switch. ISR Latency Contributors are:

• Time Interrupts are turned off. • Time BUS Instructions lockout the processor. • Execution time of the Kernel ISR plus Vector Time to OAL ISR.

IST Latencies The IST latency as shown in the architecture diagram earlier in this paper is the amount of

time from when an interrupt occurs to the time when the first line of code in the IST is executed. This differs from the output of the Microsoft measurement tools in Windows CE .NET. The Microsoft tools have the IST latency as the time from the end of the OAL ISR execution to the beginning of the IST. Since the standard ISR takes very little time you will need to add the ISR and IST latencies from the Microsoft measurement tools to get the IST latencies as defined in the Interrupt Architecture Diagram.

The first contributor to IST latencies is the ISR latencies as defined earlier in this paper. The second contributor is the ISR execution time. This time can be a variable based on the length of the calling chain for shared interrupts. For low latency scenarios it is not necessary to call the NKCallIntChain on interrupts that will never be shared.

The kernel functions in Windows CE, such as the scheduler, are called KCALLS. During these KCALLs a software flag is set to let the scheduler know that it cannot be interrupted at this time. ISRs will still be called but return values to reschedule the OS or schedule an IST are delayed until the KCALL is completed. The non-preemptable time is the third contributor to IST latency. Finally the kernel must schedule the IST. This context switch is the last contributor to latency. IST Latency Contributors are:

• ISR Latency Time • OAL ISR Execution Time • Time when the OS is in a KCALL • Time to schedule the IST

Conclusions With Windows CE .NET, Microsoft has advanced the Windows CE interrupt architecture.

The ability of the OS to deal with shared interrupts greatly extends the ability of Windows CE .NET to support many interrupt architectures. Knowledge of this interrupt architecture greatly speeds up the investigation times into driver and latency issues. A model of the operating system interaction is the key to this understanding. Shared interrupts have greatly increased the openness of Windows CE .NET supporting the platform provider and application developer scenarios that are pervasive from company to company or within companies. Understanding latency sources will help in diagnosis of driver and real-time issues. The interrupt structure in Windows CE .NET is well defined and understandable. In short, "No, it's not magic!"

Page 62: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net Email: [email protected] Tel: +86-871-5899845

Appendix III: Understanding the File System Architecture in Windows CE .NET (from MSDN)

Mike Hall Microsoft Corporation Steve Maillet Entelechy Consulting Summary

The Windows CE .NET file system is a flexible modular design that allows for custom file systems, filters, and a variety of different block device types. The file systems and all file-related APIs are managed by the FileSys.exe process. This module implements the object store and Storage Manager (we'll look into the object store in a little bit) and unifies all of the file systems into a single system under one root, "\". In Windows CE .NET, all files and file systems exist in a single namespace starting from "\" as the root. All files are identified with a unique path from the root in a hierarchal tree. This is similar to Windows for the desktop, except that there are no drive letters. In Windows CE, drives are mounted as folders under the root. Thus, a new storage card added into the system is mounted in the root of the tree with a path like "\Storage Card".

FileSys.exe consists of several components: • ROM File System • Storage Manager • Object Store The object store is a memory heap, controlled by FileSys.exe. The Object Store contains the

RAM system registry, the RAM file system, and the property database. Each of these is an optional component of the FileSys.exe module. The RAM file system and property database are completely optional and may not exist at all in some systems. The registry is required in some form for each Windows CE device. Until version 4.0 of Windows CE, it always resided in the object store. With Windows CE .NET, it can exist as a file on an externally mounted file system such as a disk. We'll get into how this is hooked up later.

The RAM-based files system is normally connected to the root of the unified file system presented to applications. That is, a file "\MyFile.txt" is located in the root of the unified system and in the root of the RAM file system. The ROM file system is connected to the "\Windows" folder in the unified file system. This means that all files in the ROM are accessible as read-only files from the "\Windows" folder.

The Storage Manager is new to Windows CE .NET. As the name implies, it is responsible for managing the storage devices in the system, and the file systems for accessing them. There are 4 primary things the Storage Manager deals with:

• Storage drivers. These are the device drivers for the physical storage mediums. They are sometimes called "block drivers," since they provide access to randomly addressable blocks of data storage.

• Partition drivers. These provide management of multiple partitions on a single storage device. Windows CE .NET allows a physical disk to contain multiple partitions formatted for different file systems on each partition. The partition driver is effectively a storage driver translator. It exposes the same interface as a storage driver, and translates block addresses for a partition into the true address of the block on the storage device. It then passes the call off to the storage driver.

• File system drivers. These drivers organize the data on a storage device as files and folders. Windows CE .NET ships with a few different systems, including UDFS for CDs and DVDs, as well as FATFS (including FAT32 support). With version 4.2 there is a new system called transaction safe FAT file system (TFAT). (We may cover that in a future article; as always if you are interested let us know.)

• File system filters. File system filters process calls for a file system before the file system gets them. This allows for some specialized handling of file access for data encryption, compression, and statistical usage monitoring.

Page 63: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

As the old saying goes, a picture is worth a thousand words, so the following diagram illustrates the relationships between the various components of the file system.

Figure 1. Overview of the Windows CE file system

An important thing to notice about this structure is that file system filters operate under the Storage Manager and cannot be applied to the ROM file system or the RAM file system in the object store. At this point in time, Microsoft does not provide a mechanism for filtering access to either of those systems. As a result, in this article we'll be focusing on the right side of the picture. The following diagram zooms in on that area for a closer look.

Figure 2. Storage Manager and related components

As you can see in this diagram, not all file system drivers use a physical device, and even if they do, they may not use a partition driver. This allows for a great deal of flexibility. For instance, the network redirector, responsible for providing access to network shares, uses WinSock to communicate across the network to a remote server, and it has no physical disk on the Windows CE device.

Now that we can see what most of the pieces are and how they relate to one another, we'll look at how the system gets it all loaded up. When the operating system boots, NK.exe loads FileSys.exe directly from the ROM files system. FileSys.exe then initializes the registry from the default registry in the ROM file system. (There is a bit of a chicken and egg problem here in using the hive registry where the registry is in a file on a disk for a file system not yet mounted. We'll look into how the operating system solves that problem when we cover the hive registry in a later

Email: [email protected] Tel: +86-871-5899845

Page 64: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net

article.) FileSys.exe will then read the registry entries to start various applications. One of the first

applications listed in the registry is normally Device.exe, the Device Manager. Device Manger loads drivers from the HKEY_LOCAL_MACHINE\Driver\BuiltIn key. Normally, any built-in disk devices, such as hard disks, are listed under this key so the block driver is loaded. The block drivers advertise a specific device class identifier, BLOCK_DRIVER_GUID {A4E7EDDA-E575-4252-9D6B-4195D48BB865}.

The Storage Manager built into FileSys.exe registers with the Device Manager notification system to receive notifications about block drivers loading and unloading. The Storage Manager then opens the block driver and queries it for a profile name. Each block device type has a profile associated with it. The PROFILE is a registry key that specifies, among other things, the partition driver and default file system for a particular type of device. (We'll get into the details of the registry entries for a profile in just a bit.)

The Storage Manager reads the information about the partition driver for the device and loads the appropriate driver. (Microsoft provides one partition driver called "mspart" that is used for standard hard disk partitioning through the partition table in the master boot record of the disk. You are of course free to create your own if needed, or not use any at all.)

Once the partition driver is loaded, the Storage Manager will then ask the partition driver to enumerate the partitions on the disk and to identify the file system on each. The partition driver will read the information about partitions and file systems from the Master Boot Record (MBR) and provide that information to the Storage Manager, which then uses it to load the file system drivers for each partition and mount the file system into the root of the unified file system. While that may seem like a lot of steps, it allows for the flexibility to support network redirector FATFS and DVD ROMs all within the same framework.

Now that we understand the steps FileSys.exe goes through to get the various components loaded, we'll take a closer look at the file system driver and the role of the File System Driver Manager (FSDMGR). FSDMGR is the part of the Storage Manager (in previous versions of the operating system it was part of the Device Manager) responsible for providing services to file system drivers. Because a file system should not need to know if the data is coming from a partition on a disk, or from the disk directly, the FSDMGR wraps the file system driver providing interfaces for the upper and lower edges on the driver. The following diagram illustrates how this works.

Figure 3. Storage Manager

Email: [email protected] Tel: +86-871-5899845

Page 65: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net Email: [email protected] Tel: +86-871-5899845

The Storage Manager calls the file system driver (FSD), and the FSD uses the FSDMGR_ APIs to retrieve data from the device. In the case of a CD that does not have partitions, the device communicates through the FSDMGR to the block driver. If it is a hard disk with multiple partitions, then it uses the FSDMGR_ APIs in the same way. However, the FSDMGR then hands off the work to the appropriate partition driver.

We have looked at how the Storage Manager, FSDMGR, FSDs, partition drivers and block drivers interact and interoperate. Let's return to the details of how they are loaded, and examine the details of the profiles in the registry. A profile, as previously mentioned, is just a set of registry values defining information about a block device and how it should be used in the system. Profiles are located under: HKEY_LOCAL_MACHINE\System\StorageManager\Profiles

Each profile is a key with the name of the profile under the base profile key. For example, if we have a hard disk on a Windows CE .NET device, and it identifies that it uses the hard disk profile, then the profile is located at HKEY_LOCAL_MACHINE\System\StorageManager\Profiles\Hard Disk. All of the profile information is contained in named values under this profile key. The various values and their purpose are listed in the following table.

Table 1. Profile registry keys

Value Type Description

Folder REG_SZ Name of the folder as it appears to the user in Windows Explorer. An integer is automatically appended for multiple instances. (For example, Storage Card, Storage Card2, and so on.)

FileSystem REG_SZ Name of the file system to use as a default for the disk. (Normally not used if a partition driver is used.)

PartitionDriver REG_SZ Lists the partition driver to use if the default driver is inappropriate. If this string is empty, no partition driver is loaded. If this value is not present, then the default partition driver is used.

AutoFormat REG_DWORD If the disk is not formatted, automatically format

AutoPart REG_DWORD If the disk is not partitioned, automatically partition it with one partition occupying the largest amount of available disk space.

AutoMount REG_DWORD Automatically mount the file system when the storage device driver is loaded.

Name REG_SZ Name of the profile to display

Page 66: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net Email: [email protected] Tel: +86-871-5899845

in the Control Panel UI.

MountFlags REG_DWORD Flags for determining how the file system is mounted. (See below for details.)

The MountFlags value requires some special attention. It is a bit mask of the values in the following table.

Table 2. Flags for the MountFlags registry key

Flag Description

1 Hidden file system.

2 May contain hive registry.

4 Mount as root of file system ("\").

8 Hide ROM file system. (Used only with [4].)

Marking a file system as hidden prevents it from being found by any normal enumeration of files and folder. (Such as FindFirstFile, and so on.) The Storage Manager does this for itself so that device drivers and applications can detect if a particular system is using the Storage Manger. (Since older versions of the operating system don't have it, some driver may need compatibility with the old LoadFSD(Ex) mechanism for loading file systems.) While you can't use FindFirstFile to enumerate arbitrary hidden systems, if you know the name of the file system, you can use it anywhere you would use a file path. The following example shows how to detect whether or not the Storage Manager is in use a system. BOOL IsStorageManagerRunning() { DWORD attr = GetFileAttributes( _T("\\StoreMgr") ); if( (attr != -1) && (attr & FILE_ATTRIBUTE_TEMPORARY) ) return TRUE; return FALSE; }

The next bit in the MountFlags indicates whether the file system may contain the hive-based registry. This allows FileSys.exe to manage the chicken and egg problem mentioned previously. (Since the registry is needed to load the components needed to access the registry hive files that may be on a disk...) We'll see how this bit is used in a later article on the hive registry.

The next two bits are related and are used when you wish to mount the external file system as the root of the unified file system. Recall that normally the root of the unified system is the RAM file system. This is great for battery-powered handheld devices, but doesn't work for A/C line-powered devices that are turned off sometimes, as the RAM contents are lost each time. The mount file system as root flag allows you to get around this by connecting the external storage as the root, so that the file \MyDataFile.TXT will reside in the root of the external storage device. The hide ROM file system will hide the ROM files system data files (but not execute in place EXEs and DLLs) to allow you to update all files in the ROM. This allows you to use a very small operating system image in FLASH with the majority of the executable on the disk and loaded only as needed. (Much like the desktop systems do now.)

If any of the values for a particular profile are not present, the Storage Manager will use the defaults from the HKEY_LOCAL_MACHINE\System\StorageManager\Profiles key. The defaults you can override are located in COMMON.REG. You should override using your PLATFORM.REG or PROJECT.REG. (Remember, you shouldn't alter the COMMON.REG!) The following table shows the defaults from COMMON.REG.

Table 3. COMMON.REG defaults

Page 67: OK6410 Wince

Copyright reserved© Witech Co., Ltd.

Website: http://www.arm9board.net Email: [email protected] Tel: +86-871-5899845

Value Default Value

Folder LOC_STORE_DEFAULT_FOLDER (Identifier for a string in the .STR file for the device; usually "Storage Card" in English builds.)

FileSystem FATFS

PartitionDriver Mspart.dll

AutoFormat 0

AutoPart 0

AutoMount 1

MountFlags 0

Summary

The Windows CE file system architecture is flexible and extensible, and supports: • Multiple block devices. • Multiple partitions per block device. • Different file systems per partition. • Mounting external device file systems as root of system. The registry is key to getting correct (expected) behavior for loading and running a file

system. The hive-based registry throws a twist into the mix. To ease your "mounting" anticipation of that, we will examine the hive registry in detail in a future article with some real world examples. But for now, it's time for us to "dismount" for this month.