Professional Documents
Culture Documents
Developing A Windows CE OAL
Developing A Windows CE OAL
OAL
Mr. Dhiraj Rane
Hardware/Drivers
BSP OEM Hardware and Standard PC
OEM/IHV Supplied
(ARM, SH4, MIPS) Standard Drivers Hardware and Drivers
Windows XP DDK
Device Building
Tools Windows Embedded
Platform Builder
Studio
Lightweight EDB SQL Server 2005 Express Edition
Data
Native Win32
Model
Package
(CEC/MSI)
Boot Loader Architecture
A typical development boot loader
blcommon
OEM code
RTL8139
DP83815
eboot
NE2000
bootpart
…
flash FMD
EDBG drivers
Bootloader Architecture
Blcommon – generic boot loader framework
OEM code – general board init and extensions
Eboot – Ethernet functions (UDP, DHCP, TFTP)
EDBG drivers – Ethernet drivers
3Com 3C90x, AMD AM79C97x, CS8900A, NS
DP83815, NE2000, RealTek RTL8139, SMSC9000 &
SMSC100
Bootpart – storage partition management
FMD – flash management driver
Samsung/Sandisk (NAND), Intel StrataFlash (NOR)
Agenda
Windows CE 5.0 BSPs and Kernels
Development Process
OAL
Architecture and Design
Boot Sequence and Required OAL Functions
Kernel and KITL
Optional OAL Functions
Building
Power Management
OAL Testing – Greg Prier
MEDC Call to Action
Questions?
Additional Information
Best Practices/Recommendations
Windows CE 5.0 BSPs
Reduce OS “bring-up” time on OEM hardware
Avoid changing the "public" OAL interface
Provide production features (power management, performance
optimizations, IOCTLs, etc.)
Maximize code re-use (and testing)
Provide a consistent OAL architecture that can be easily
extended/customized
Increase BSP coverage in-the-box
One BSP for each supported CPU
Integrate BSPs into the IDE Catalog
Integrate BSPs into the Platform Wizard
Enable third parties to create BSPs easily
Ship CSP drivers for many CPUs and SOCs
PB Tools - BSP Wizard and IDE tools
Enables faster, easier porting to OEM devices
PQOAL Design
Collection of OAL software libraries organized by CPU architecture (or
model) and by OAL “function”
Common Code Directory Structure
BSP configuration files are located in a single location
(platform\<BSP>\src\inc)
Chip/set Support Package (CSP) drivers share include files that define
hardware registers and layout
Kernel
OAL
OS Timer
Interrupt
Startup
Library
Library
Library
Library
Library
Library
Library
Cache
IOCTL
KITL
RTC
s3c2410x.h s3c2410x_lcd.h
s3c2410x.inc s3c2410x_memctrl.h
s3c2410x_adc.h s3c2410x_nand.h
s3c2410x_base_regs.h s3c2410x_pwm.h
s3c2410x_base_regs.inc s3c2410x_rtc.h
s3c2410x_clkpwr.h s3c2410x_sdi.h
s3c2410x_dma.h s3c2410x_spi.h
s3c2410x_iicbus.h s3c2410x_uart.h
s3c2410x_iisbus.h s3c2410x_usbd.h
s3c2410x_intr.h s3c2410x_wdog.h
s3c2410x_ioport.h
Creating A BSP
BSP wizard
IDE Tool to clone BSP or create a BSP definition
Can add/remove drivers to a BSP definition
Export wizard
IDE Tool to export feature components from the IDE Catalog to
other PB users
Creates a MS Windows Installer (MSI) file
CEC editor
IDE Tool to create and/or edit .CEC files
A .CEC file defines the properties of an object/component in the
IDE catalog
No more .bsp files
Two methods to create a BSP
Use the command line method
Use the BSP Wizard
Both methods rely on cloning a sample BSP
Creating An OAL
Create directory for OAL code in the BSP
platform\<BSPname>\kernel\oal
Add <dirname> to “dirs” file to build OAL with BSP
Required OAL functions
Startup
Debug serial
OEMInit
System timer
Interrupt processing
Kernel input/output, KITL
Optional OAL functions (Platform Dependent)
Real-time clock and timer
Parallel port I/O code
Ethernet port debug
More information in PB docs
“How-to Create an OEM adaptation layer”
Agenda
Windows CE 5.0 BSPs and Kernels
Development Process
OAL
Architecture and Design
Boot Sequence and Required OAL Functions
Kernel and KITL
Optional OAL Functions
Building
Power Management
OAL Testing – Greg Prier
MEDC Call to Action
Questions?
Additional Information
Best Practices/Recommendations
CE 5.0 Boot Sequence
Boot loader startup sequence Kernel startup sequence
Startup() Startup(
EbootMain() )
BootloaderMain() KernelStart()
OEMDebugInit() ARMInit()
OEMInitDebugSerial()
OEMPlatformInit()
OEMInit()
OEMPreDownload()
KernelInit()
Download Occurs
HeapInit()
OEMLaunch()
InitMemoryPool()
ProcInit()
SchedInit()
FirstSchedule()
SystemStartupFunc()
IOCTL_HAL_POSTINIT
Required OAL Functions
Startup
Debug Serial
OEMInit
System Timer
Interrupt Processing
Kernel Input/Output
Example: Custom Kernel IOCTL
KITL
StartUp
First function called when target device boots
Purpose is to initialize CPU to known state and to
call the kernel initialization function
(KernelInitialize for x86 and KernelStart on all
other platforms)
LEAF_ENTRY
LEAF_ENTRY StartUp
StartUp
.. .. .. ARM
;; Initialize
Initialize CPU
CPU to
to aa known
known state
state example
;; SetSet up
up OEMAddressTable
OEMAddressTable for
for KernelStart
KernelStart
.. .. ..
bl
bl KernelStart
KernelStart
.. .. ..
;; KernelStart
KernelStart should
should never
never return
return
Debug Serial
OEMInitDebugSerial()
Configures Speed, Parity, Stop bit length
OEMReadDebugByte()
Retrieves a byte from the debug monitor
port
OEMWriteDebugByte()
Outputs a byte to the debug monitor port
OEMWriteDebugString()
Writes a string to the debug monitor port
OEMInit
Required task is to set up hardware
and register interrupt for the
system tick
ISRs and HookInterrupt
Setting Up the Interrupt Map
Define a mapping of Interrupt IDs
Mapping can be dynamic at driver load time
Interrupt IDs’ are returned by the ISRs to
the kernel and are used to link an
incoming IRQ with a software IST
OEMInit: An Example
Void
Void OEMInit()
OEMInit() {{
SetUpInterruptMap();
SetUpInterruptMap();
PCIInitBusInfo();
PCIInitBusInfo();
InitDebugEther();
InitDebugEther();
OEMParallelPortInit()
OEMParallelPortInit()
InitPICs();
InitPICs();
InitClock();
InitClock();
if
if (MainMemoryEndAddress
(MainMemoryEndAddress ==== CEPC_EXTRA_RAM_START)
CEPC_EXTRA_RAM_START)
{{
MainMemoryEndAddress
MainMemoryEndAddress +=+= IsDRAM(MainMemoryEndAddress,
IsDRAM(MainMemoryEndAddress,
CEPC_EXTRA_RAM_SIZE);
CEPC_EXTRA_RAM_SIZE);
}}
pKDIoControl
pKDIoControl == OEMKDIoControl;
OEMKDIoControl;
}}
Interrupt Processing
OEMInterruptEnable()
Performs hardware operations necessary to allow
a device to generate the specified interrupt
Includes
Setting a hardware priority for the device
Setting a hardware interrupt enable port
Clearing any pending interrupt conditions from the
device
OEMInterruptDisable()
Disables the specified hardware interrupt
OEMInterruptDone()
Unmasked and reenables of interrupt processing
Interrupt Processing
OEMGetInterrupt()
Used by the any device wanting and IRQ. Example
PCI bus
OEMRequestSysIntr()
Used in the OEMIoControl routine to implement
IOCTL_HAL_TRANSLATE_IRQ and
IOCTL_HAL_REQUEST_SYSINTR
OEMTranslateIrq()
Used by the main ISR to translate a non-shareable
IRQ into a SYSINTR
OEMTranslateSysIntr()
Translates a SYSINTR to its corresponding IRQ
System Timer
Make sure the system timer interrupt is
registered with the ISR
Program the system timer to generate
an interrupt every 1ms
Can also support variable tick
In the system timer ISR, update the
global system tick counter CurMSec
and CurTicks. If reschedule time is
expired then return SYSINTR_Resched
else SYSINTR_NOP
Agenda
Windows CE 5.0 BSPs and Kernels
Development Process
OAL
Architecture and Design
Boot Sequence and Required OAL Functions
Kernel and KITL
Optional OAL Functions
Building
Power Management
OAL Testing – Greg Prier
MEDC Call to Action
Questions?
Additional Information
Best Practices/Recommendations
Kernel Libraries
Library Description
kern.exe kernkitl.exe kernkitlprof.exe
kernel w/ dbg kernel w/
basickernel suppt profiling suppt
Nk.lib Microprocessor-specific
Kernel code that MS supplies X X
Hal.lib OAL that you implement for
target HW X X X
NkProf.lib Profile version of the MS
Kernel code X
KITL.lib Kernel Independent
Transport Layer (KITL)
debugging services X X
SMC9000 Sample Ethernet debugging
driver. Must have for KITL
suppt X X X
FullLibc Microsoft C Run-Time Library X X X
Kernel Input/Output
BOOL
BOOL OEMIoControl(.
OEMIoControl(. .. .).)
{{
switch
switch (dwIoControlCode)
(dwIoControlCode) {{
case
case IOCTL_HAL_SET_DEVICE_INFO
IOCTL_HAL_SET_DEVICE_INFO ::
case
case IOCTL_HAL_REBOOT:
IOCTL_HAL_REBOOT:
.. .. ..
default:
default:
return
return FALSE;
FALSE;
}}
return
return TRUE;
TRUE;
}}
pNKEnumExtensionDRAM AND
OEMEnumExtensionDRAM
Building OAL and Kernel
No longer necessary to SYSGEN OAL libraries
Shared OAL code is built just before the BSP directory
(platform\common)
BSP kernel (kern.exe) sources file:
TARGETLIBS= \
$(_COMMONOAKROOT)\lib\$(_CPUDEPPATH)\nk.lib \
$(_TARGETPLATROOT)\lib\$(_CPUDEPPATH)\oal.lib \
$(_PLATCOMMONLIB)\$(_CPUINDPATH)\oal_startup_s3c2410x.lib \
$(_PLATCOMMONLIB)\$(_CPUINDPATH)\oal_abort_s3c2410x.lib \
$(_PLATCOMMONLIB)\$(_CPUINDPATH)\oal_cache_s3c2410x.lib \
$(_PLATCOMMONLIB)\$(_CPUINDPATH)\oal_memory_s3c2410x.lib \
$(_PLATCOMMONLIB)\$(_CPUDEPPATH)\oal_io_s3c2410x.lib \
$(_PLATCOMMONLIB)\$(_CPUINDPATH)\oal_intr_s3c2410x.lib \
$(_PLATCOMMONLIB)\$(_CPUINDPATH)\oal_timer_s3c2410x.lib \
$(_PLATCOMMONLIB)\$(_CPUINDPATH)\oal_rtc_s3c2410x.lib \
$(_PLATCOMMONLIB)\$(_CPUINDPATH)\oal_ioctl_s3c2410x.lib \
$(_PLATCOMMONLIB)\$(_CPUDEPPATH)\oal_other.lib \
$(_PLATCOMMONLIB)\$(_CPUDEPPATH)\oal_log.lib \
$(_COMMONOAKROOT)\lib\$(_CPUINDPATH)\ddk_io.lib \
$(_COMMONOAKROOT)\lib\$(_CPUDEPPATH)\kitl.lib \
$(_COMMONOAKROOT)\lib\$(_CPUINDPATH)\fulllibc.lib \
$(_PLATCOMMONLIB)\$(_CPUINDPATH)\oal_ethdrv_cs8900a.lib
OAL Power
Management Functions
OAL Power Management Functions
OEMIdle – Puts the CPU in reduced power mode
OEMPowerOff – Puts the CPU in suspend mode
Device Drivers Power Management Functions
xxx_PowerDown, xxx_PowerUp for stream
interface drivers
Device-specific functions for other drivers
SetInterruptEvent
Agenda
Windows CE 5.0 BSPs and Kernels
Development Process
OAL
Architecture and Design
Boot Sequence and Required OAL Functions
Kernel and KITL
Optional OAL Functions
Building
Power Management
OAL Testing – Greg Prier
MEDC Call to Action
Questions?
Additional Information
Best Practices/Recommendations
OAL Tests
Available in CE 5.0
Timers/Clock support
Caches
IOCTLs
Future Tests
Interrupts
Memory Configuration
KITL and VMINI
Bootloader
Etc.
Test Harness
CETK tests
Can also be run from the standard shell
OAL Test Requirements
Booting Tinykern
KITL connection
OAL Timer Tests
Three clocks: GTC, RTC, and QPC
The Test currently checks
Resolution
Always increasing (except rollover)
Clock drift
Compares results against thresholds
Cache Testing
Currently verify correctness,
not performance
Read and write different patterns into
the cache, exercising
boundary conditions
Allow the tester to confirm the
cache parameters
IOCTL Testing
Confirm that an errant call won’t crash
the kernel
IOCTL_HAL_GET_DEVICEID
IOCTL_HAL_GET_UUID
More to come
More Information
PB docs
Source code
Lab
Testing the Windows CE 5.0 OAL
Thursday 11:15 – 12:30
Agenda
Windows CE 5.0 BSPs and Kernels
Development Process
OAL
Architecture and Design
Boot Sequence and Required OAL Functions
Kernel and KITL
Optional OAL Functions
Building
Power Management
OAL Testing – Greg Prier
MEDC Call to Action
Questions?
Additional Information
Best Practices/Recommendations
While at MEDC 2005…
Fill out an evaluation for this session
Randomly selected instant WIN prizes!
Develop
Install Windows Mobile 5.0 Eval Kit including
Visual Studio 2005 Beta 2
Enter Mobile2Market Contest and win up to $25000:
mobile2marketcontest.com
Join Microsoft Solutions Partner Program:
partner.microsoft.com
Tools & Resources
Build Develop
msdn.microsoft.com/ msdn.microsoft.com/
Websites embedded mobility
microsoft.public. microsoft.public.
Newsgroups windowsxp.embedded pocketpc.developer
windowsce.platbuilder smartphone.developer
windowsce.embedded.vc dotnet.framework.compactframework
blogs.msdn.com/ blogs.msdn.com/
Blogs mikehall windowsmobile
vsdteam
netcfteam
Int 1 Int 1 X
X
Int 2 Int 2 X
X = Interrupt Mask
Issue/Concern – Mixing edge and level triggering on shared interrupts may result in missed
interrupts.
Recommendation – Don’t mix edge and level triggering on shared interrupts.
L
Int 1 X Int 1 X Int 1 X
L L
Int 2 X Int 2 X Int 2 X
X = Interrupt Mask
Installable ISR Handler
Recommendation
Use GIISR.dll when sharing interrupts to keep ISR in OAL
simple, which will avoid confusion when
adding/deleting/changing interrupts
GIISR.dll allows drivers to be plugged in dynamically
OAL ISR
Int #1
X UART.dll
Int #n Drivers must
register
Shared Interrupts GIISR.dll X wavedev.dll Address and
Mask to
X GIISR.dll
UHCI.dll
Put highest
priority and most
Generic Installable ISR.
often interrupts
Common code keeps track
at top
of all interrupt devices
associated with IRQ
SYSINTR Design
Issue/Concern
Windows CE provides for 16 reserved and 24 user SYSINTR; As
SOC’s (for example) become more and more prevalent, the need for
more than 24 user SYSINTR is needed
Recommendation
Use IST sharing to minimize the number of SYSINTR needed by
the design
** Current Macallan plans are to support up to 64
Total SYSINTR; TBD on the number of those to be
user SYSINTR
X UART1.dll
IST
SYSINTR ISR X UART2.dll
Sharing
X UART3.dll
IOCTL_HAL_REBOOT
Recommendation
Implement IOCTL_HAL_REBOOT to be able to reset all board logic; Make sure
board level reset reinitializes to boot time state
This IOCTL supports a warm boot of the target device; A request to perform a
warm boot is made by calling the OEMIoControl function with
IOCTL_HAL_REBOOT
If a device calls for a reboot and it uses DMA, IOCTL_HAL_REBOOT takes care of
memory issues to make sure that RAM doesn’t continue to be updated through DMA
from the device
RAM
PCI Bus
DMA
Device
PCI Host Bridge Aperture Registers
Issue/Concern
There is typically not enough space in the memory aperture
range in the host bridge
Recommendation
Use PCI cards with a suitable amount of memory for the for
the system selected
Example – Perm3 requires 128kb of PCI memory from the PCI
bus. Some PCI busses on have 128kb of memory; This
starves all other PCI devices
PCI Bus
Host Bridge
CPU
Device
RAM
Aperture Registers
PCI Bus Mastering (DMA)
Issue/Concern
There are typically issues in the way that the PCI bus arbitrates
devices that are on the bus; Poor arbitration design can lead to
starving other devices, system resources, or hanging the device
Recommendation
Use proper bus arbitration to allow other devices to use system
resources when needed
Example – PCMCIA 802.11b card owning the bus too long can
lead to starving of the LCD because the 802.11b card is taking up
all CPU time
PCI Bus
CPU
LCD Host Bridge
PCI/PCMCIA
Bridge 802.11b
RAM
DMA Routines in CEDDK
Recommendation
Utilize the CEDDK DMA Routines. CEDDK is an essential tool for creating
platform independent device drivers
Abstraction of Bus Architectures
Abstraction of I/O mechanisms
Abstraction of DMA buffer allocation
HalTranslateSystemAddress()
Translates a system wide address to a bus relative address
Default implementation is a 1:1 mapping on PCI only
Assumes PCI buses all have access to full RAM space via host bridge
HalAllocateCommonBuffer()
Allocates a buffer of contiguous physical memory for DMA usage
Does NOT allocate DMA channels
CEDDK does not provide any abstraction for DMA controllers at this point
HalFreeCommonBuffer()
Releases a buffer allocated with HalAllocateCommonBuffer()
Normally only used when the driver is unloading
RAM
DMA
CPU
PCI Bus
Device
Host Bridge
CPU Byte Enable Lines
Issue/Concern
Variable width transfer bus needs to enable byte lines on
reads and writes; Current designs only provide for bytes
lanes on writes, which will cause problems with destructive
read operations
Recommendation
Enable byte lines on buses with variable width transfers for
reads and writes
Byte Enable Lines
PCI Bus
CPU
Host Bridge
PCI/PCMCIA
Bridge Device
Device
Multiple Hardware Timers
Issue/Concern
System that provide a single timer for multiple
functions can lead to clock error issues
Recommendation
Provide a single timer that is used for the system
1ms TIC.
Provide additional timers for profilers and other
OS, Bus, Multimedia needs
Fixed interval timers should be avoided in mobile
battery-powered systems as there is no way for
the kernel to conserve power with OEMIdle
Peripheral Devices
Recommendations
USB Function controller should be able perform disconnect
signal and then connect signal either by reset or by program;
If these signals are not connected, Windows XP may not be
able to determine what state the device is in and ignore the
device during device initialization or suspend/resume; USB
cable may need to be physically disconnect and reconnected
to resolve
Ethernet MAC – Provide a default MAC address for all
peripheral devices and make sure that they all have unique
subnet addresses; MAC addresses located in flash can be
erased; We recommend locating the MAC address in a read
only location
Ethernet MAC – Provide DMA support in Ethernet Controllers
OEMAddressTable
Issue/Concern
Set up the OEMAddressTable efficiently
Recommendation
Don’t overlap Address
Make sure most commonly used components at top of list
Make sure design is consistent with config.bib
he data must be declared in a READONLY section and there must be at least one non-zero
entry for the structure to be valid
For x86 platforms, the first entry must identify RAM, and it must start at 0x80000000
For ARM platforms, 0x80000000 can be mapped to anything
The Size must be a multiple of 4MB for x86 platforms and a multiple of 1MB for ARM; The
last entry of the table must be zeroed. You can leave holes between ranges but you cannot
have overlapping ranges
The only valid virtual memory mapping range is from 0x80000000 to 0x9FFFFFFF; For every
entry created in the table, the kernel creates two virtual address ranges; One exists in the
virtual address range from 0x80000000 to 0x9FFFFFFF and is memory that has caching and
buffering enabled; The second exists in the virtual address range from 0xA0000000 to
0xBFFFFFFF and has caching and buffering disabled
Any memory that is not mapped at boot time cannot be directly accessed by an interrupt
service routine (ISR) without first calling CreateStaticMapping to map the address
OEMCacheRangeFlush
Recommendation
Implement OEMCacheRangeFlush correctly and efficiently
Use pre-configured OEMCacheRangeFlush style
OEMCacheRangeFlush replaces calls to FlushDCache, FlushICache,
and TLBClear in Windows CE .NET 4.2 and later.
If you are implementing this function you should perform TLB
flushes at the end of the function. For example, if
dwFlags==(CACHE_SYNC_DISCARD|CACHE_SYNC_FLUSH_TLB, the
cache discard operation is usually performed before the TLB flush
Some of the CSP routines reference global variables containing
cache and TLB size information; Your platform must resolve these
variables. You can further optimize such CSP implementations by
hard-coding variables in a private implementation of
OEMCacheRangeFlush in your platform; If you want to modify or
override CSP implementations of caching code, you must put the
relevant source files in the Kernel\Buildexe directory and modify
each of the source files in its subdirectories to build the file