# HG changeset patch # User Graeme Price # Date 1287149538 -3600 # Node ID 307f4279f4331c5425ec21aae4430ff85dead2d3 # Parent 578be2adaf3e0e0cf53c1485f2207e00991cab3e Initial contribution of the Adaptation Documentation. diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-003D2C5B-09DC-5BD1-AF45-A0FCB56F567B.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-003D2C5B-09DC-5BD1-AF45-A0FCB56F567B.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,172 @@ + + + + + +ROMBUILD +

ROMBUILD is the Symbian platform binary XIP (execute-in-place) +ROM builder. It is normally invoked through BUILDROM, +the Symbian platform ROM configuration tool that acts as a front-end +to ROMBUILD.

+
+
ROMBUILD +command syntax

If the OBY files are encoded in UTF-8 with +non-ASCII character support, use the following the ROMBUILD command +syntax:

ROMBUILD [options] [–oby-charset=utf-8 <obyfile>] [-datadrive=<fat.oby>]

If the OBY files are encoded in local character set with non-ASCII +characters support, use the following the ROMBUILD command syntax:

ROMBUILD [options] <obeyfile> [-datadrive=<fat.oby>]

The following command line options are supported:

+ + + +

–argfile=<parameter file>

+

Accepts a parameter file, which contains a list of command-line +parameters specific to the ROM tools, as input.

+
+ +

-?

+

Displays more detailed help for the command.

+
+ +

-coff-header

+

Uses a PE-COFF header instead of a Symbian platform header. PE-COFF is a Portable Executable–Common Object File +Format and is a Microsoft extension to the COFF standard.

+
+ +

-compress

+

Compresses executable files where possible using the inflate +(Deflate, Huffman+LZ77) algorithm unless the -compressionmethod keyword is used to override the default (see below).

+
+ +

-compressionmethod [none | inflate | bytepair]

+

Specifies the compression algorithm to use. Can be used +either with the -compress keyword or alone.

+ + + +

none

+

No compression is used.

+
+ +

inflate

+

Compresses executable files using the default (Deflate, +Huffman+LZ77) algorithm.

+
+ +

bytepair

+

Compresses executable files using the bytepair algorithm. +Bytepair compression allows faster decompression than the default +Deflate, Huffman+LZ77 algorithm and supports demand paging by performing +compression and decompression of code in independent 4 KB pages.

+
+ + +

+ + +

coreimage=<core ROM image file>

+

Uses the specified core image file as the basis for creating +the ROM image extension.

If the given core ROM image file +is invalid or does not exist, an error message is displayed.

+
+ +

-d<bitmask>

+

Sets the trace bitmask; this only applies to debug builds.

The simplest way of specifying this is to use a string of hexadecimal +characters starting with 0x (for example, 0x01234567). However, any +string that can be interpreted and translated into a valid TUint value +may be used. See the standard C function strtoul().

+
+ +

-lowmem

+

Reduces the physical memory consumption during image generation.

+
+ +

-loglevel<level>

+

Level of information to log file. The following valid log +levels are available:

+ + + +

0

+

Default level of information to log file.

+
+ +

1

+

Logs the host or the ROM filenames, the file size, and the +hidden attribute in addition to the loglevel 0 information.

+
+ +

2

+

Logs the E32 file header attributes such as UIDs, data size, +heap size, stack size, VID, SID, and priority in addition to the loglevel 1 information.

+
+ + +

+
+ +

-no-header

+

Suppresses the image loader header.

+
+ +

-no-sorted-romfs

+

Does not add sorted entry arrays (6.1 compatible). It is +a table of offsets for the subdirectories and files which are not +in the sorted order.

+
+ +

-r<fileName>

+

Compares the generated ROM image with the ROM image whose +file name is specified.

+
+ +

-s[log|screen|both]

+

Displays a summary of the size to the specified destination, +that is, to the log, to the screen or to both the log and the screen.

+
+ +

-v

+

Verbose mode.

+
+ +

-wstdpath

+

Displays a warning if a file is placed in a non-standard +directory when PlatSecEnforceSysBin is set to OFF.

For example, the following instruction in +OBY file leads to a warning when -wstdpath is used +and PlatSecEnforceSysBin is OFF:

File=ABI_DIR/BUILD_DIR/hello.exe myfolder/bin/hello.exe

+
+ +

-j<NUM_OF_WORKING_THREADS>

+

Specifies the number of working threads that can run concurrently +to create a ROM image. The <NUM_OF_WORKING_THREADS> must be an integer in the range 1-128.

If the -j option is not specified or an invalid value is specified, ROMBUILD +uses the following ways to determine the number of working threads:

    +
  • If the NUMBER_OF_PROCESSORS environment variable is set correctly, +ROMBUILD uses the number of processors as the number of working threads.

  • +
  • If the NUMBER_OF_PROCESSORS environment variable is not set or +is invalid, the default value 8 is used as the number +of working threads.

  • +
+
+ +

-gendep

+

Generates a dependencies file describing internal dependencies +among executables or dlls in a ROM image.

Note: You can +only generate dependence information in the paged section of a ROM +image.

+
+ +

-symbols

+

Generates symbols for each data or executable specified +in the OBY file.

Note: The symbols file is not generated +by default.

+
+ + +

<obeyfile> is a standard text file +containing statements that are used to control the operation of the +tool.

See the OBEY files reference for the full syntax.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-009D71C6-481F-5EF1-B230-EB64F67047C8.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-009D71C6-481F-5EF1-B230-EB64F67047C8.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,47 @@ + + + + + +CalibrationCalibration of the Digitizer Driver is required to convert between +digitiser ADC values and screen coordinates. +

Calibration is done through a user-side calibration application.

+

The platform specific layer performs the following calculation to convert +between ADC values and co-ordinates:

+ + + +

Where the R matrix determines the scaling and rotation, and the T vector +determines the translation.

+

This conversion is implemented by the platform specific layer's implementation +of DDigitiser::DigitiserToScreen() and DDigitiser::ScreenToDigitiser(). +Default implementations are provided by the template port. Note, however, +that in these implementations, the calculation is slightly more complex because +screen coordinate values are left shifted 16 bits. This allows the operations +to use integer divisions without loosing precision.

+

All that you need to do is to provide an initial set of values for R and T. +An example of how to set them up is included in the template port.

+

The principle is that the application draws cross hairs on the screen, +and then invites the user to touch these points. The digitiser ADC value is +used to calculate the digitiser to screen pixel value transformation.

+

Any calibration code will interface with the User-Side +Hardware Abstraction component using four UserHal functions.

+

On a cold restart, the calibration application goes through the following +steps:

+
    +
  • Gets the calibration +points by using UserHal::CalibrationPoints()

  • +
  • Sets calibration points +by using: UserHal::SetXYInputCalibration()

  • +
  • Saves calibration data +by using: UserHal::SaveXYInputCalibration()

  • +
+

On a warm restart, the calibration application just restores calibration +data using UserHal::RestoreXYInputCalibration().

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-01072199-382F-4691-AC0D-D1226EE5CF2F.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-01072199-382F-4691-AC0D-D1226EE5CF2F.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,78 @@ + + + + + +Time Client Interface Quick StartExplains how to use the interface between the Time platform +service and its clients. +
Introduction

The Time client interface is used when communicating with the +Real Time Clock (RTC). This client interface can be used to check +that the RTC is working correctly, maintain its request queue and +to set/reset the wake-up alarm.

+
Time +client interface limitations

None

+
Adaptation +dependencies

None

+
Time +client interface classes

The following classes provide the +RTC interface:

+ + + +

Name

+

Description

+
+ +

MRtcAdaptation

+

Provides the interface between the Real Time Clock (RTC) +and the upper layers of the OS.

+
+ +

ASIC

+

Provides an interface to the Application Specific Integrated +Circuit (ASIC) that is being used.

+
+ + +

The functionality provided by this class, can be split +into the following groups:

    +
  • Diagnostics

  • +
  • Management of the wake-up alarm

  • +
  • Request management

  • +
  • Set and read the RTC

  • +
+
Diagnostics

These methods are used to test that the RTC is working correctly. +The methods that are included in this group are:

    +
  • MRtcAdaptation::ValidateRtc()
  • +
  • ASIC::SetSystemTimeCalibration()
  • +
+
Management +of the wake-up alarm

This group of methods, relate to the +setting and releasing of the wake-up alarm. The methods that are included +in this group are:

    +
  • MRtcAdaptation::SetWakeUpAlarm()

  • +
  • MRtcAdaptation::UnsetWakeUpAlarm()

  • +

+
Request +management

Calls to the RTC are placed in a request queue, +waiting for the RTC to process them. Calls to the other two groups +of functionality add requests to the queue for the RTC, the methods +in this group remove them. The methods that are included in this +group are:

    +
  • MRtcAdaptation::Cancel()

  • +
  • MRtcAdaptation::Release()

  • +
+
Set +and read the RTC

These functions are used to set and read +the RTC. Both functions measure time as the number of seconds since +the start of the year 2000.

    +
  • ASIC::SystemTimeInSecondsFrom2000()
  • +
  • ASIC::SetSystemTimeInSecondsFrom2000()
  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-01F1F488-8E95-56B0-818E-6096CAE4C50C.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-01F1F488-8E95-56B0-818E-6096CAE4C50C.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,25 @@ + + + + + +ArchitectureThis topic describes the architecture of the Base Starter program, e32strt.exe. +

The Base Starter is started by the File Server, EFILE.EXE, +near the end of the boot process.

+

EFILE.EXE initialises generic file services. e32strt.exe performs +handset specific initialisation. The Base Starter completes the initialisation +of the file server, and then creates the system starter process. The system +starter process is the next process in the chain of processes responsible +for starting all the major Symbian platform services. The following +diagram shows the relative position of the Base Starter in the start-up sequence.

+ + Base Starter architecture + + +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-024EE22F-4B86-48EF-A55E-C9C1C7E9BADB.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-024EE22F-4B86-48EF-A55E-C9C1C7E9BADB.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,12 @@ + + + + + +SDIO Client InterfaceDescribes SDIO APIs and their use in a device driver. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-02B40662-B5F3-59BD-832B-9A28FE3B51C7.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-02B40662-B5F3-59BD-832B-9A28FE3B51C7.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,32 @@ + + + + + +DebugThis topic describes how to use debug messages in the USB +client controller. +

As the USB PDD runs in kernel mode, debug printf are implemented using the KTRACE macro. +This macro takes two arguments:

+
    +
  • The debug message +type

  • +
  • A kernel object +that takes a message string as a constructor.

  • +
+

Two debug message types are used:

+
    +
  • KPANIC for error messages

  • +
  • KUSBPSL for PSL information messages

  • +
+

The following code samples illustrate their use:

+_KTRACE_OPT(KPANIC, Kern::Printf("Error: USB Controller not present")); +_KTRACE_OPT(KUSBPSL, Kern::Printf("Received new Ep0 Setup packet")); +Do not use the KUSB flag. This flag is used +within the PDD PIL and the USB LDD only. +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-0346036B-A470-4C18-B276-3A3485F6A069.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-0346036B-A470-4C18-B276-3A3485F6A069.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,16 @@ + + + + + +Design +OptionsThese documents describe high-level implementation choices for +a device driver. +

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-04FF36CE-DEFA-45DC-BAAF-77F3BB649AFF-master.png Binary file Adaptation/GUID-04FF36CE-DEFA-45DC-BAAF-77F3BB649AFF-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-04FF36CE-DEFA-45DC-BAAF-77F3BB649AFF_d0e499_href.png Binary file Adaptation/GUID-04FF36CE-DEFA-45DC-BAAF-77F3BB649AFF_d0e499_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-052F58B7-117B-5EDD-A3D5-CB0DE6A4E239.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-052F58B7-117B-5EDD-A3D5-CB0DE6A4E239.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,80 @@ + + + + + +IIC SHAI Implementation Layer: Generic ConsiderationsThis document explains how to implement the SHAI implementation +layer for IIC. +
Purpose

This document covers information which is generic to master and +slave channel implementation

Intended Audience

Base porting engineers.

Introduction

IIC +buses (a term used in this document to represent serial inter-chip +buses that IIC can operate on) are a class of bus used to transmit +non time-critical data between components of a hardware system.

+
Generic +architecture

Different IIC buses have a large amount of +functionality in common, but some functionality is specific to individual +implementations. For this reason, the IIC software has an architecture +consisting of two layers, the Platform Independent Layer (PIL) and +the SHAI implementation layer. The Platform Independent Layer is a +set of classes which encapsulate generic functionality and have been +implemented for you. The SHAI implementation layer is an interface +which you must implement yourself to encapsulate the functionality +specific to the platform you are working on.

You implement +the SHAI implementation layer by subclassing the classes of the Platform +Independent Layer and writing functions that provide an abstraction +of your hardware. To access the hardware you are strongly recommended +to use existing Symbian APIs such as e.g. AsspRegister to access hardware registers, or GPIO to access +GPIO pins).

An IIC channel operates in one of two modes, master +and slave, and there are separate master and slave APIs to be implemented. +In master mode, a channel and a client communicating with that channel +execute in two separate threads. In slave mode there is only one thread +for both channel and client.

The SHAI implementation and platform +independent APIs assume an interrupt-driven approach to implementation. +An event on hardware triggers an interrupt, which then signals this +event to the channel thread (where client is master) or client thread +(where client is slave). This means that implementation involves writing +interrupt service routines (ISRs) and a DFC queue to hold the callbacks +which respond to them. For both master and slave operation, the callbacks +are queued for execution on the client thread - so the client thread +must not be blocked, otherwise the callbacks will never run.

Clients of a master channel request transactions for execution in +either a synchronous or asynchronous manner. This results in the transaction +being entered in the channel’s request queue.

If synchronous +execution is requested, the client thread is blocked until the transaction +completes (either an ISR or polling mechanism in the SHAI implementation +layer recognizes the transaction has completed, and it calls the PIL +method CompleteRequest(), which will unblock the +client thread.

If asynchronous execution is requested, the +client thread is not blocked, and may continue to perform other tasks. +In the meanwhile, the channel thread will retrieve the next transaction +from the request queue and pass it to the SHAI implementation layer +for processing. When the transaction completes, the SHAI implementation +layer calls the PIL method CompleteRequest() and +this adds the client’s callback to the client’s DFC queue.

A client of a slave channel provides receive and transmit buffers +to be used and specifies the types of event (trigger) that it wishes +to be notified of. When ANY event occurs, the SHAI implementation +layer should call the PIL method NotifyClient(); +this determines whether the reported triggers qualify for notifying +the client – if so, the client callback is added to the client’s DFC +queue for execution. Note that the same mechanism is used to notify +the client of completion of asynchronous capture of the channel, and +of bus errors.

You should refer to the template port at \os\kernelhwsrv\bsptemplate\asspandvariant\template_assp\iic for more information.

+
+IIC +SHAI Implementation Layer: Master Channel +IIC +SHAI Implementation Layer: Slave Channel +Client +of Master Channel Tutorial +Client +of Slave Channel Tutorial +IIC +Concepts +I2C +Technology Guide +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-0563266C-8B5A-5664-9AC6-A5504AB5056F.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-0563266C-8B5A-5664-9AC6-A5504AB5056F.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,15 @@ + + + + + +Porting TutorialDescribes the steps to implement a port of the Digitizer Driver. +Concepts + + \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-058BAEDF-5E04-5BB4-928F-0E0528FD9465.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-058BAEDF-5E04-5BB4-928F-0E0528FD9465.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,39 @@ + + + + + +MultiMediaCard +TechnologyMultiMediaCard (MMC) is a low cost data storage and communication +media, and is defined by the MultiMediaCard System Specification +

The MMC specification is published by the MultiMediaCard Association.

+

Communication is based on a 7-pin serial bus designed to operate in a low +voltage range (2.0 - 3.6V). The MultiMediaCard specification defines a communication +protocol referred to as MMC mode (0-20MHz). In addition, for compatibility +with existing controllers, MultiMediaCards may offer an alternative communication +protocol which is based on the SPI standard (0-5MHz).

+
Omissions

The +following features of the MultiMediaCard System Specification are not provided +in the Symbian platform MultiMediaCard controller:

    +
  • Stream read and write +operations are not supported.

  • +
  • SPI bus mode is not +supported.

  • +
  • The MultiMediaCard System +Specification includes a feature where a MultiMediaCard can be put into a +disconnected state. This can be performed on a card which is currently in +the programming state, i.e. writing data to the disk. To place that card into +the disconnected state involves placing another card into the transfer state, +which means giving the other card the current data transfer focus. A disconnected +card will not terminate the programming operation and, if re-selected, moves +back to the programming state. The Symbian platform MultiMediaCard controller +does not support this mode of operation even if the underlying hardware interface +does.

  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-058FAE44-DF72-53E2-BE62-EDC840A7C87F-master.png Binary file Adaptation/GUID-058FAE44-DF72-53E2-BE62-EDC840A7C87F-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-058FAE44-DF72-53E2-BE62-EDC840A7C87F_d0e25110_href.png Binary file Adaptation/GUID-058FAE44-DF72-53E2-BE62-EDC840A7C87F_d0e25110_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-05DAF5EF-6F2E-562D-9DB1-0985AD4A1E48.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-05DAF5EF-6F2E-562D-9DB1-0985AD4A1E48.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,17 @@ + + + + + +Port Implementation +TutorialDescribes the steps to implement a port of the User-Side Hardware +Abstraction component. +Concepts + + \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-07E0DEC0-A749-4B14-9E73-3AF8ACD28BC6.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-07E0DEC0-A749-4B14-9E73-3AF8ACD28BC6.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,13 @@ + + + + + +Register Access ImplementationProvides information about implementing the Register Access +platform service. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-0804E71D-8B20-49A2-9F7C-F2D6795681D0.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-0804E71D-8B20-49A2-9F7C-F2D6795681D0.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,56 @@ + + + + + +DMA Quick StartDMA is used to ease the burden on the main CPU, by performing +some of the data transfers. +

There are two types of user that are interested in DMA: those that +want to use it to transfer data, and those that need to implement +it for their hardware.

+
Users
    +
  • Device driver developers use DMA to reduce the burden on the +main CPU. They open a channel and then use that channel to queue one +or more DMA requests.

  • +
  • Hardware implementers, usually device creators, implement the +DMA Platform Specific Layer (PSL) so that it will work with the particular +DMA controller on a device.

  • +

Some devices will have more than one DMA controller, which +means the DMA channel manager may require the hardware implementer +to provide a means of identifying whether a particular DMA channel +is of the correct type and on the appropriate controller.

+
+DMA Class Diagram + +

The diagram represents different classes related to the DMA. +The classes in green provide the Client Interface which allows the +users to request data transfer, the classes in blue implement the +platform specific layer and the classes in white are the abstract +classes.

+
Device +driver developers

The device driver writers including the +developers of physical device drivers and kernel extension writers +use the client interface of the DMA platform service.

    +
  • DMA technology is described the DMA Technology Guide

  • +
  • The concepts of device driver are described in the DMA Device Driver +Guide

  • +
  • The Client Interface is explained in the DMA Client Interface +Guide

  • +
+
Hardware +implementers

If you are a device creator or are adapting +the DMA Framework for your DMA controller, you must implement the +Platform Specific Layer.

    +
  • The hardware interface is explained in the DMA Hardware Interface

  • +
  • The hardware specific functions are implemented in the platform +specific layer and the implementation is explained in the DMA Implementation +Guide

  • +
  • Testing the implementation is described in the DMA Testing Guide

  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-08867AEC-5866-5583-9AAB-068CB51F5C18.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-08867AEC-5866-5583-9AAB-068CB51F5C18.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,15 @@ + + + + + +Platform-Specific +Source CodeThe platform-specific layer of the bootstrap must implement +a set of standard functions and definitions that are used by the generic +layer. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-08E14B34-5144-5AA8-AA55-7AF03671676C.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-08E14B34-5144-5AA8-AA55-7AF03671676C.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,459 @@ + + + + + +The +Debug Monitor Command SyntaxThe debug monitor is entered when the kernel crashes, if a system +process panics, or an unhandled processor exception occurs. +

Under normal circumstances this ought not to happen, but when the kernel +faults, the device enters the kernel debug monitor.

+

There may be circumstances where you need to force a kernel crash, for +example, if the system is locking up. Running the test program crash.exe forces +a crash. This program takes a parameter that defines the number of seconds +that must elapse before the kernel crash is forced.

+

For example, when the system locks up under certain conditions, run "crash +60", and then recreate the conditions that lead to the lockup. After 60 seconds, +the kernel crash is forced and the debug monitor is entered.

+

Notes:

+
    +
  • the EKA2 debug monitor +is very similar to the EKA1 version, although the details displayed may be +different.

  • +
  • you will occasionally +find references to the crash debugger; this is the same as the debug +monitor.

  • +
+
Getting the +debug monitor going

When the kernel faults, the device enters the +debug monitor.

To make use of the debug monitor, do the following:

    +
  • Plug the mains adaptor +into the DC jack.

  • +
  • Connect the target device +COM port to your PC, and set the PC serial port to 115200 baud, 8 bits, no +parity, 1 stop bit, XON/XOFF flow control.

  • +
  • Press the ON key on +the target device.

  • +
  • Start a terminal program +on the PC (e.g. HyperTerminal.)

  • +
  • Press RETURN on +the PC. The target device should reply with the prompt:

    Password:
  • +
  • Enter the password "replacement" +(all lower case, but without the quotes) on the PC. The target device should +now reply:

    *** DEBUG MONITOR ***
  • +

You can now enter debug monitor commands.

+
Crash debugger +commands

Commands consist of a single letter describing the operation +to be performed, followed by any arguments. Not all commands take arguments. +Commands are case sensitive; the majority are lower case. Commands should +be entered at the command prompt, on the PC. The set of supported commands +is as follows:

    +
  • f - displays +kernel fault information

  • +
  • m - does +a memory dump

  • +
  • z - does +a memory dump, but skips over unmapped memory space

  • +
  • i - displays +information on the current thread and the current process

  • +
  • o - displays +brief DObject information

  • +
  • O - displays +full DObject information

  • +
  • p - display +short information about code segments

  • +
  • P - display +full information about code segments

  • +
  • c - displays +contents of object container; (nb lower case)

  • +
  • C - displays +contents of object container; (nb upper case)

  • +
  • r - dumps +register contents

  • +
  • S - dumps +thread stack contents

  • +
  • x - leaves +the debugger, does a cold restart of the same ROM image; (nb lower case)

  • +
  • X - leaves +the debugger, and returns to the bootloader to wait for a new ROM image to +be downloaded; (nb upper case)

  • +
  • h - help.

  • +
+
f - display +kernel fault information

This command displays information about +the the kernel fault that caused the debugger to be entered. The information +has the following format.

Fault Category: Exception Fault Reason: 10000000 +ExcId 00000001 CodeAddr ffe0016c DataAddr 80000001 Extra 00000013 +Exc 1 Cpsr=68000010 FAR=80000001 FSR=00000013 + R0=00000000 R1=00000000 R2=30000000 R3=80000001 + R4=00000001 R5=00403d68 R6=00002000 R7=00000000 + R8=00000000 R9=00000000 R10=00000000 R11=00403fa0 +R12=00403d34 R13=00403d48 R14=500d41e8 R15=ffe0016c +R13Svc=81716000 R14Svc=500480b8 SpsrSvc=20000010

Notes:

    +
  • R15 is the program counter

  • +
  • R14 is the link register,

  • +
  • R13 is the stack pointer

  • +
+
m - do a memory +dump

This command dumps memory in both hexadecimal and ASCII format. +Use one of the following command formats:

m start end m start+length

start specifies +the start address in hexadecimal, and end specifies the end +address in hexadecimal. If the second parameter starts with a + character, +then the following hexadecimal characters are interpreted as a length.

Address +parameters are always virtual addresses (the MMU is still on).

The +resulting format is similar to the EKA1 format.

For example:

.m +81c01c60+30

81C01C60: 00 00 00 00 15 00 00 10 E0 6A 13 50 01 00 00 80 .........j.P.... +81C01C70: 30 3B C0 81 34 D9 03 50 00 00 FF FF E8 1C C0 81 0;..4..P........ +81C01C80: 34 D9 03 50 30 3B C0 81 FC 4A 13 50 E8 1C C0 81 4..P0;...J.P..... +

If an illegal memory access occurs, the debugger traps the +exception and displays an error message.

+
z - do a memory +dump, skipping over unmapped memory

This command dumps memory in +both hexadecimal and ASCII format, but excludes any unmapped memory space. +If an illegal memory access occurs, it does not stop, but skips to the next +page instead. This is useful to inspect the content of discontiguous chunks.

The +syntax and the display format is the same as for the m command.

+
i - display +information for the current process and thread

This command displays +information for the current process and thread.

SCHEDULER @80000d98: CurrentThread 8070dd28 +RescheduleNeeded=00 DfcPending=00 KernCSLocked=00000001 +DFCS: next 80000ea8 prev 80000ea8 +ProcessHandler=5004b040, AddressSpace=8070d7c8 +SYSLOCK: HoldingThread 8070dd28 iWaiting 00000000 +Extras 0: 8070d7c8 1: 8070d7c8 2: 8070d7c8 3: 00000000 +Extras 4: 00000000 5: 00000000 6: 00000000 7: 00000000 +Extras 8: 00000000 9: 00000000 A: 00000000 B: 00000000 +Extras C: 00000000 D: 00000000 E: 00000000 F: 00000000 +

The format for the thread is:

TheCurrentThread=8070da6c +THREAD at 8070da6c VPTR=50052b50 AccessCount=3 Owner=8070d7c8 +Full name crash::Main +Thread MState READY +Default priority 28 WaitLink Priority 28 +ExitInfo 3,0, +Flags 80000004, Handles 8070a79c +Superviso81715000 size 1000 +User stack base 00402000 size 2000 +Id=19, Heap=00600000, Created heap=00600000, Frame=00000000 +Trap handler=00000000, ActiveScheduler=00000000, Exception +handler=00000000 +TempObj=00000000 TempAlloc=00000000 +NThread @ 8070dd28 Pri 28 NState READY +Next=8070dd28 Prev=8070dd28 Att=03 ExcInUserMode=10 +HeldFM=80000eb8 WaitFM=00000000 AddrSp=8070d7c8 +Time=0 Timeslice=20 ReqCount=0 +SuspendCount=0 CsCount=0 CsFunction=00000000 +SavedSP=81715d6c +CAR 00000001 +DACR 30315507 +R13_USR 00000000 R14_USR 81715dc4 SPSR_SVC 81715e10 + R4 30303031 R5 30303030 R6 81715dc4 R7 81715e14 + R8 81715dac R9 81715da0 R10 50055c88 R11 50055c3c + PC 81715dc0

The format for the process is:

TheCurrentProcess=8070d7c8 +PROCESS at 8070d7c8 VPTR=50052bc4 AccessCount=5 Owner=00000000 +Full name crash +ExitInfo 3,0, +Flags 00040000, Handles 80709c98, Attributes 60010000 +DataBssChunk 8070a514, CodeChunk 8070a9a8 +DllDataChunk 00000000, Process Lock 8070d90c +NumChunks=2 +0: Chunk 8070a514, run 00400000, access count 1 +1: Chunk 8070a704, run 00600000, access count 1 +Domain -1, DACR 55555507 +TheCurrentAddressSpace=8070d7c8 +TheCurrentVMProcess=8070d7c8 +PROCESS at 8070d7c8 VPTR=50052bc4 AccessCount=5 Owner=00000000 +Full name crash +ExitInfo 3,0, +Flags 00040000, Handles 80709c98, Attributes 60010000 +DataBssChunk 8070a514, CodeChunk 8070a9a8 +DllDataChunk 00000000, Process Lock 8070d90c +NumChunks=2 +0: Chunk 8070a514, run 00400000, access count 1 +1: Chunk 8070a704, run 00600000, access count 1 +Domain -1, DACR 55555507 +TheCurrentDataSectionProcess=8070d7c8 +TheCompleteDataSectionProcess=8070d7c8 +PROCESS at 8070d7c8 VPTR=50052bc4 AccessCount=5 Owner=00000000 +Full name crash +ExitInfo 3,0, +Flags 00040000, Handles 80709c98, Attributes 60010000 +DataBssChunk 8070a514, CodeChunk 8070a9a8 +DllDataChunk 00000000, Process Lock 8070d90c +NumChunks=2 +0: Chunk 8070a514, run 00400000, access count 1 +1: Chunk 8070a704, run 00600000, access count 1 +Domain -1, DACR 55555507 +
+
o - display +brief DObject information

This command in lower case displays +basic information about the DObject. The command has the +following syntax:

o address

where address specifies +the address of the DObject.

For example:

o +6403c170

THREAD at 6403c170 VPTR=f8046c18 AccessCount=3 Owner=6403bb4c +Full name crash::Main +
+
O - display +full DObject information

This command in upper case displays +full information about the DObject. The exact format displayed +depends on the exact type of the DObject being referenced, +for example, whether it is a thread, process, or a chunk. The command has +the following syntax:

O address

where address specifies +the address of the DObject.

+
p - display +short information about code segments

This command in lower +case displays basic information about one or more code segments, as encapsulated +by DCodeSeg objects. The command has the following syntax:

p address | all

where:

    +
  • address is +the address of a specific code segment

  • +
  • all refers +to all code segments.

  • +

For example:

p 64053b70

.p 64053b70 +CodeSeg at 64053b70: + FileName: Z:\sys\bin\crash.exe + RunAddress: f83e3498
+
P - display +full information about code segments

This command in upper case displays +the full information about one or more code segments, as encapsulated by DCodeSeg objects. +The command has the following syntax:

P address | all

where:

    +
  • address is +the address of a specific code segment

  • +
  • all refers +to all code segments.

  • +

For example:

P 64053b70

.p 64053b70 +CodeSeg at 64053b70: + FileName: Z:\sys\bin\crash.exe + RunAddress: f83e3498 + + iLink: Prev 64052f48 (64052f40) Next 640000e0 (640000d8) + iTempLink: Prev dfdfdfdf (dfdfdfcf) Next 00000000 (00000000) + iGbgLink: Prev 00000000 (00000000) Next 00000000 (00000000) + iAccessCount: 1 + iEntryPtVeneer: f83e3498 + iFileEntryPoint: f83e3498 + iExtOffset: 10 + iUids: 1000007a 00000000 00000000 + iDeps: 00000000 ( ) + iDepCount: 0 + iNextDep: 0 + iMark: 31 + iAttr: a + iExeCodeSeg: 64053b70 + iAttachProcess: 00000000 + iModuleVersion: a0000 + iS: + SecureId: 00000000, VendorId: 70000001 + Caps: 000fffff 00000000 + iSize: 370 + + iXIP: 1 + iInfo: f83e3420 (TRomImageHeader*) + iUid1: 1000007a, iUid2: 00000000, iUid3: 00000000 + iUidChecksum: 045ac39e + iEntryPoint: f83e3498 + iCodeAddress: f83e3498, iCodeSize: 00000370 + iDataAddress: 00000000, iDataSize: 00000000 + iTextSize: 00000370, iBssSize: 00000000 + iHeapSizeMin: 00001000, iHeapSizeMax: 00100000, iStackSize: 00002000 + iDllRefTable: 00000000 + iExportDirCount: 0, iExportDir: f83e33fc + iS: + SecureId: 00000000, VendorId: 70000001 + Caps: 000fffff 00000000 + iToolsVersion: Major 02 Minor 01 Build 0225 + iFlags: 0000002a + iPriority: 352 + iDataBssLinearBase: 00400000 + iNextExtension: 00000000 + iHardwareVariant: 01000000 + iTotalDataSize: 00000000 + iModuleVersion: 000a0000 + iExceptionDescriptor: f83e34f4 + + iCodeAllocBase: 80000000 + iDataAllocBase: 80000000 + iKernelData: 00000000
+
c - display +contents of object container

This command in lower case displays +the contents of one of the kernel's object containers, a DObjectCon type. +Note that information is dumped very quickly without page breaks, which is +useful in situations where the kernel is likely to become very unstable very +shortly after crashing. There is an upper case version of this command, C, +which generates output with a pause between pages.

The command has +the following syntax:

c type

where type is +a single hexadecimal digit between 0 and D inclusive that specifies which +kernel container is to be dumped. The mapping between the hexadecimal digit +and the kernel container is:

+ + + +

0

+

Threads

+
+ +

1

+

Processes

+
+ +

2

+

Chunks

+
+ +

3

+

Libraries

+
+ +

4

+

Semaphores

+
+ +

5

+

Mutexes

+
+ +

6

+

Timers

+
+ +

7

+

Servers

+
+ +

8

+

Sessions

+
+ +

9

+

LogicalDevices

+
+ +

A

+

PhysicalDevices

+
+ +

B

+

Channels

+
+ +

C

+

ChangeNotifiers

+
+ +

D

+

Undertakers

+
+ +

E

+

Message queues

+
+ +

F

+

Property references

+
+ + +

For example:

c A

Container 10 at 640275c4 contains 3 PHYSICAL DEVICES: +PHYSICAL DEVICE at 64032dac VPTR=f805d9fc AccessCount=2 Owner=00000000 +Full name Media.IRam +PHYSICAL DEVICE at 640339e8 VPTR=f8067e44 AccessCount=2 Owner=00000000 +Full name Media.Flash +PHYSICAL DEVICE at 64033a64 VPTR=f806b9f8 AccessCount=2 Owner=00000000 +Full name Media.Ata +

c 0

Container 0 at 807022b8 contains 12 THREADS: +THREAD at 807011c0 VPTR=50052b04 AccessCount=1 Owner=8070107c +Full name EKern::Null +Thread MState READY +Default priority 0 WaitLink Priority 0 +ExitInfo 3,0, +Flags 0000000c, Handles 80701520 +Supervisor stack base 80700000 size 1000 +User stack base 00000000 size 0 +Id=0, Heap=00000000, Created heap=00000000, Frame=00000000 +Trap handler=00000000, ActiveScheduler=00000000, Exception +handler=00000000 +TempObj=00000000 TempAlloc=00000000 +NThread @ 8070147c Pri 0 NState READY +Next=8070147c Prev=8070147c Att=00 ExcInUserMode=00 +HeldFM=00000000 WaitFM=00000000 AddrSp=8070107c +Time=-1 Timeslice=-1 ReqCount=0 +SuspendCount=0 CsCount=0 CsFunction=00000000 +SavedSP=80700f50 +CAR 00000001 +DACR 55555547 +R13_USR 00403ed4 R14_USR 500c88b4 SPSR_SVC 200000d3 + R4 00000009 R5 5004b7ec R6 50000000 R7 dc911000 + R8 00000000 R9 807103c0 R10 50002140 R11 80700fb4 + PC 500481b4 +

The information displayed for each object is the same as that +shown after using the q command. +After displaying the information for each object, the debugger pauses until +you press a key.

Notes

    +
  • the DObjectCon class +is internal to Symbian platform.

  • +
  • the type value passed +as an argument to the command is one of the enum values of the TObjectType enum; +this enum is internal to Symbian platform.

  • +
+
C - display +contents of object container

This command in upper case is +exactly the same as the lower case c command +except that the display of output pauses between pages. If you need to dump +output as fast as possible without pauses, use the lower case version.

+
r - dump register +contents

This command dumps the full ARM register set.

On +ARM this dumps the full set of user mode registers and all the alternate registers +for other modes.

For example:

r

MODE_USR: + R0=6571de54 R1=0000002a R2=00000002 R3=ffffffff + R4=0000002a R5=f8170414 R6=6571df14 R7=6403cba8 + R8=00000001 R9=6403c41c R10=640002f8 R11=6571de70 +R12=00000020 R13=00404e00 R14=f80818c0 R15=f800bfa8 +CPSR=60000013 +MODE_FIQ: + R8=00000000 R9=ffffffff R10=ffffffff R11=00000000 +R12=00000000 R13=64000d0c R14=c080079c SPSR=e00000dc +MODE_IRQ: +R13=6400110c R14=00000013 SPSR=20000013 +MODE_SVC: +R13=6571de54 R14=f80328bc SPSR=60000010 +MODE_ABT: +R13=6400090c R14=ffff0010 SPSR=400000d7 +MODE_UND: +R13=6400090c R14=95221110 SPSR=f000009d +
+
S - Dumps thread +stack contents

This command, in upper case, dumps both the user +and supervisor stacks used by each thread in the system. Some threads do not +have a user thread, in which case this is indicated. Each set of stacks is +displayed in turn, in the following format:

THREAD at c8052fa0 VPTR=80082304 AccessCount=6 Owner=c8044608 +Full name efile.exe::LoaderThread +User stack base at 00410000, size == 1000 +Stack pointer == 00413e30 +Stack mapped at 00410000 +00413e30: 10 01 70 01 99 93 1b 80 18 01 70 01 d0 56 1b 80 ..p.......p..V.. +00413e40: 00 00 00 00 00 00 00 00 84 00 70 01 84 00 70 01 ..........p...p. +00413e50: 04 00 00 00 23 91 1b 80 38 01 70 01 10 01 70 01 ....#...8.p...p. +00413e60: 80 3e 41 00 01 00 00 00 10 01 70 01 00 00 00 00 .>A.......p..... +00413e70: 84 00 70 01 cd 91 1b 80 30 02 70 01 00 00 00 00 ..p.....0.p..... + +Supervisor stack base at c9127000, size == 1000 +Stack pointer == c9127fbc +c9127fb0: b0 d1 0a c8 0c 00 00 00 13 00 00 00 00 07 00 00 ................ +c9127fc0: 00 00 f0 00 45 55 55 55 30 3e 41 00 89 ff 1b 80 ....EUUU0>A..... +c9127fd0: 10 00 00 20 10 01 70 01 80 3e 41 00 98 c7 23 80 ... ..p..>A...#. +c9127fe0: 58 3e 41 00 04 00 00 00 40 00 00 00 98 4b 04 c8 X>A.....@....K.. +c9127ff0: 60 04 00 c8 98 01 02 80 00 00 00 00 10 5a 1b 80 `............Z..

With +a multiple memory model, this command is the only way to reliably dump a stack.

+
x - leave debugger, +cold restart of ROM image

This command, in lower case, leaves the +debugger and does a cold restart of the current ROM image.

+
X - leave debugger, +return to bootloader

This command, in upper case, leaves the debugger, +and returns to the bootloader to wait for a new ROM image to be downloaded.

+
h - Help

Displays +a short summery of the crash debugger commands.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-092D336A-155A-4F18-AAF7-92E08473700E.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-092D336A-155A-4F18-AAF7-92E08473700E.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,30 @@ + + + + + +DMA OverviewDirect Memory Access (DMA) uses a controller to copy data +between memory locations, or between memory and peripherals with minimal +involvement from the CPU. +
Purpose

Direct Memory Access (DMA) channels allow you to copy data between +memory locations, or between memory and peripherals, while minimizing +the use of the CPU. The transfer operation is performed in hardware +by the DMA controller. The purpose of the DMA platform service is +to provide a common interface between hardware and device drivers +which use DMA.

The framework is divided into a platform-independent +layer and a platform-specific layer, with the DMA platform service +being the interface between the two. The framework presents an API +for use by device drivers and other client applications which transfer +data by DMA. The PSL must be implemented by hardware developers to +provide the same functionality on multiple platforms.

+
Architecture

+DMA Framework + +

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-092F414B-2279-4ADB-970F-75DAB8A80BD7.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-092F414B-2279-4ADB-970F-75DAB8A80BD7.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,68 @@ + + + + + +SDIO Testing GuideHow to run unit tests of the SDIO platform-specific layer. +

Before +running this test, you must do the following:

    +
  • Port the SDIO Controller for your platform (see SDIO Implementation +Guide)

  • +
  • Build the test ROM.

  • +
  • Boot the device with the test ROM.

  • +

+

After +you have ported the SDIO Controller on your platform, you can test +it using the provided unit test application, SDIOTest.

The +test application runs in a text shell and is made of two parts:

    +
  • The test program, sdiotest.exe tests the +Controller in isolation, at the interface level.

  • +
  • The test driver, d_sdioif.ldd uses the SDIO API, which is a kernel-side interface.

  • +

The source code of the test application is in /e32utils/sdio/source/.

You must build d_sdioif.ldd for the appropriate platform and sdiotest.exe for the appropriate CPU architecture.

To include the two test components in a ROM, specify the sdiotests.iby file in your command line when building +the image, such as in the following example:rom.bat -v h4hrp -i armv5 --symbol –t sdiotests.iby -m USE_SDIO_SD_MMC

The SDIOTest utility is not an automated test: it performs +various unitary operations which can be used to validate the behavior +of the SDIO Controller. First, you request an operation by pressing +the corresponding key on the command line. Then, you compare the resulting +display with the data expected from the card.

The following +steps provide an example of how to test your port.

+ +Run the +SDIOTest application. + +Power up +the stack by pressing the P key. +

The stack must report that no card is present.

+
+Insert a +card and power it up. +

The stack must report that a card is present.

+
+Read the +card information by pressing the I key. +

The data returned by the stack must match the data +sheet you have for the card.

+
+Read the +common control registers by pressing the R key. +

The values must match the expected card data.

+
+Read the +common configuration by pressing the C key. +

The values must match the expected card data.

+
+Read information +about the I/O function by pressing the F key. +

The data returned by the stack must match the I/O specifications +of the card.

+
+Quit the +test by pressing the Q key. + +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-09EE01E2-BF5E-5302-BA25-46C440ADECF5-master.png Binary file Adaptation/GUID-09EE01E2-BF5E-5302-BA25-46C440ADECF5-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-09EE01E2-BF5E-5302-BA25-46C440ADECF5_d0e11034_href.png Binary file Adaptation/GUID-09EE01E2-BF5E-5302-BA25-46C440ADECF5_d0e11034_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-0A6C8DB8-ED41-4243-BA96-CA691CF9CD19.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-0A6C8DB8-ED41-4243-BA96-CA691CF9CD19.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,34 @@ + + + + + +Data +BuffersThis document describes how device drivers allocate and access +memory buffers. +
+

Most device drivers need to use memory buffers for I/O operations. +Drivers typically own memory buffers, allocate them, and access them through +pointers. The thread should be in a critical section when it allocates or +de-allocates memory.

// Tx and Rx Buffers +TUInt8* iTxBuffer; +TUInt8* iRxBuffer; // Logical Channel second stage constructor +TInt DExDriverLogicalChannel::DoCreate(TInt /*aUnit*/, const TDesC8* +/*anInfo*/, const TVersion& aVer) + { + ... + // Initialize the Tx Buffer + iTxBuffer = (TUInt8*) Kern::Alloc(KTxBufferSize); + if (!iTxBuffer) + return KErrNoMemory; + ... + }

Memory buffers must be freed when they are not required. +If this is not done, a memory leak occurs.

// Free Tx Buffer +Kern::Free(iTxBuffer)
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-0A9C35DA-DF54-5885-AFE0-F4D5B3E49941.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-0A9C35DA-DF54-5885-AFE0-F4D5B3E49941.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,14 @@ + + + + + +Allocate Resources for EndpointsThis tutorial shows how to set up the required endpoint resources.

Note: This is an optional step when creating a class driver.

Introduction

Class drivers can allocate resources to endpoints. This allows the PDD PSL to manage DMA resources more efficiently and to enable and disable endpoint resources on particular interface settings.

Note: The functions AllocateEndpointResource(), QueryEndpointResourceUse() and DeAllocateEndpointResource() always refer to the endpoints of the currently active alternate interface setting. Since after interface creation, and before configuration through the host, alternate setting 0 (default) is active, resources for endpoints on other settings of that interface can only be accessed after a successful SetInterface() request from the host that selects the respective alternate setting. See Set the interface.

PDD Support for endpoint resource allocation

The USB Client PDD PSL must explicitly support the allocation of endpoint resources. The PDD will indicate if this is the case by setting the iFeatureWord1 member in the TUsbDeviceCapsV01 structure to the constant KUsbDevCapsFeatureWord1_EndpointResourceAllocV2.

TUsbDeviceCaps caps; +... +caps().iFeatureWord1 | KUsbDevCapsFeatureWord1_EndpointResourceAllocV2;

This structure is passed to the LDD as part of TUsbcInterfaceInfo at interface (and thus logical endpoint) creation time in the call to SetInterface(). See Define the interface data.

The successful outcome of the SetInterface() call does not depend on the availability of requested resources as the driver does not try to allocate requested endpoint resources at this point. The Physical Device Driver (PDD) PIL passes the resource request information to the PSL only at endpoint configuration time (after a SetInterface() request has been received from the host).

Check that the driver supports endpoint resource allocation for DMA and double buffering with by Getting the Device capabilities for iFeatureWord1.

Allocate endpoint resources

Allocate resources for endpoints with RDevUsbcScClient::AllocateEndpointResource(). Pass the function the endpoint number and a member of TUsbcEndpointResource to indicate the type of resource. The parameter that takes the resource type is not a bitmap and TEndpointResource values should not be combined in the same call to the function.

If more than one resource is to be specified then multiple calls to the function have to be made, each one selecting a single resource.

gPort.AllocateEndpointResource(aEndpoint, EUsbcEndpointResourceDoubleBuffering);

KErrNone is returned if the resource has been successfully allocated, in which case it will be used from when the current bus transfer has been completed. KErrNotSupported will be returned if the endpoint does not support the resource requested and KErrInUse will be returned if the resource is already consumed and cannot be allocated.

Query

There is no direct and immediate feedback as to whether the resources were successfully allocated. The user can find out about the outcome by calling RDevUsbcScClient::QueryEndpointResourceUse() after a configuration or interface alternate setting change notification.

QueryEndpointResourceUse() returns ETrue if the specified resource is in use at the endpoint and EFalse if not.

TBool res = gPort.QueryEndpointResourceUse(aEndpoint, EUsbcEndpointResourceDoubleBuffering);

A resource may be deallocated by the PDD if:

  • the host selects a different configuration (including zero) than the current one by sending a SET_CONFIGURATION request,

  • the host selects a different alternate interface setting than the current one by sending a SET_INTERFACE request,

  • the user calls RDevUsbcScClient::ReleaseInterface() or Unloads the USB Client LDD.

Deallocate

DeAllocateEndpointResource() de-allocates the use of aResource from some endpoint or ends a specified endpoint behaviour. aResource is typically some rationed hardware resource or possibly specifies a type of endpoint behaviour. aResource is not a bitmap and TEndpointResource values should not be combined. KErrNone is returned if the resource has been successfully de-allocated, in which case it will be removed from when the current bus transfer has been completed. KErrNotSupported will be returned if the endpoint does not support the resource requested.

After you have allocated resources for the endpoints you should force a Re-Enumeration.

\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-0AB3D313-79FF-4716-AFD4-FF3AA3C2E936.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-0AB3D313-79FF-4716-AFD4-FF3AA3C2E936.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,69 @@ + + + + + +Trace-Based +DebuggingThis document describes how to generate traces with the Kernel +Trace and BTrace APIs. +
Kernel +debug messages

KTRACE

During development, +drivers can display information for debugging purposes. The basic API to use +for this is Kern::Printf().

You can make the display +of debugging messages conditional on whether certain flags have been set in +the ROM. To do this, use the print command with the __KTRACE_OPT() macro. +For example:

_KTRACE_OPT(KDEVICE,Kern::Printf("++DExDriverLogicalChannel::DoCreate"));

This macro's first argument is a mask that must be enabled for the message +to be displayed. The kerneltrace keyword, defined in header.iby, +sets which masks are enabled for a debug ROM image.

The following +are some of the mask definitions that can be found in nk_trace.h:

    +
  • KHARDWARE

  • +
  • KEXTENSION

  • +
  • KDMA

  • +
  • KBOOT

  • +
  • KSCRATCH

  • +
  • KPANIC

  • +
  • KPBUS1

  • +
  • KPBUS2

  • +
+
BTrace service

BTrace +is a Kernel service that is designed to generate and capture trace information +with minimal impact on a running system. It is useful for generating trace +information in the Kernel and in drivers, for which fast tracing is required +and general serial debug is not possible.

BTrace defines API and macros +to use in programs to create trace information in e32btrace.h. +The generated trace messages can be retrieved from the driver or Kernel during +execution. To do this, BTrace must be built into the ROM image; it is included +by default in a text shell ROM. The BTrace command should +then be executed from the text shell with the appropriate options. For example, +the following commands sets various filter and buffer size options, runs a +program called t_expio that generates some trace data, +and finally writes the trace data into a file d:\expiolog.txt.

BTRACE -f1,2,3 -m3 -b1024 +t_expio.exe +BTRACE d:\expiolog.txt

The basic macros used for generating +traces are:

    +
  • BTrace0 (aCategory,aSubCategory)

  • +
  • BTrace4 (aCategory,aSubCategory,a1)

  • +
  • BTrace8 (aCategory,aSubCategory,a1,a2)

  • +
  • BTrace12(aCategory,aSubCategory,a1,a2,a3)

  • +

The macros set category and sub-category values with their first +two arguments. The category indicates the type of information being recorded, +which is specified using a value from the enumeration BTrace::TCategory. +The sub-category is an enumeration specific to each category. The other arguments, a1 -a3, +set the trace data, of lengths 0, 4, 8 or 12 bytes, to record.

For +longer traces that include a context ID, program counter values, and different +filters, more macros are provided. Performance logging macros are also available +which in turn use BTrace to log +performance related data. For example:

TKName nameBuf; +Name(nameBuf); + +// Output a fast-trace record of the specified category which also +// includes a Context ID +BTraceContextN(BTrace::EChunks,BTrace::EChunkCreated,this,iMaxSize, + nameBuf.Ptr(),nameBuf.Size());
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-0AFF5666-6BF9-5022-ADBC-5EFFA743B288.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-0AFF5666-6BF9-5022-ADBC-5EFFA743B288.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,48 @@ + + + + + +ROM +Paging GuideDescribes demand paging when applied to ROM demand paging. +
Introduction

Demand +paging using ROM demand paging is used when the files to be paged are in the +core ROM image and not using another file system such as ROFS.

+
Background information

The following are useful +background information for Demand Paging using ROM demand paging:

    +
  • Demand Paging

  • +
  • ROM paging

  • +
+
ROM Demand Paging features

Demand paging (using +ROM demand paging) provides the following features compared to code +paging and writable +data paging :

    +
  • Lower RAM overhead

  • +
  • Lower performance overhead.

  • +
+
ROM Demand Paging limitations

The following are +known limitations for Demand Paging (using ROM demand paging) compared to +the other types of code paging:

    +
  • If the executable has static dependencies, then it is best to place + these dependencies in ROFS. This is a limitation of ROFS and not ROM demand +paging.

  • +
  • This paging system can only be used with files that are stored using + the ROM filing system. This is because ROM images using the ROM filing system + are designed to be executed in place.

  • +
+
+ROFS File +System +ROM File +System +Composite +File System +Configuring +and building a ROM +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-0C3A4156-E5CF-55F9-91A0-A7961FDEE030.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-0C3A4156-E5CF-55F9-91A0-A7961FDEE030.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,35 @@ + + + + + +LCD Extension ArchitectureThis topic describes the architecture of the LCD Extension. +

The LCD Extension (or video driver) is implemented as a standard +kernel extension and is loaded by the kernel at boot time.

+

The public interface to the LCD Extension is accessed through the +User-Side Hardware Abstraction (HAL) interfaces HAL::Get() and HAL::Set(). The LCD Extension registers itself +with the kernel as the handler for the EHalGroupDisplay function group and implements the functions.

+

From Symbian^3 there is a new graphics architecture called ScreenPlay. When ScreenPlay is in use, the Display Channel Driver can provide a logical device driver proxy between the Composition +Implementation and the LCD Extension. However, the use of the Display +Channel Driver is optional and implementers may decide not to use +it.

+

When ScreenPlay is not in use, the Graphics Screen Driver component is a client of the LCD Extension. The Screen Driver is platform-specific +and must be ported by the device creator.

+

The Text Window Server also implements a version of the Screen +Driver for a simple console user interface.

+
+The +ScreenPlay Graphics Architecture +The +Non-ScreenPlay Graphics Architecture +Display +Channel Driver +Screen +Driver Component +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-0C435514-EEC6-5660-BB5F-535790349632.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-0C435514-EEC6-5660-BB5F-535790349632.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,127 @@ + + + + + +Power ManagementThe kernel provides a framework for managing power within +the system, and the management of the transition between power states. +

The kernel-side framework manages the transition between power +states on the device. A base port can implement a kernel extension +to interface to the power management hardware that is provided on +the phone. The framework also provides an interface for device drivers +to use the power

+

The user-side interface to the framework is provided by the Power +class in the User Library. This allows applications can be notified +about, and can react to, changes in power state, and indeed can initiate +changes to power state. The Domain Manager component provides a way to manage the power needs and dependencies +of applications.

+

In Symbian platform, an initial port of the system does not require +the existence of a power model. In this sense it is optional, and +its absence will result in default behaviour provided by Symbian platform. +However, this is not likely to result in optimal power usage, so the +development of a power model based on the framework provided by Symbian +platform will be required for commercial devices.

+

The interfaces for power management on the kernel-side are shown +in the following diagram:

+ + + +
    +
  • The power manager +manages the transition between power states.

  • +
  • The power controller +is a kernel extension that manages the device-specific power management +hardware such as an on-chip power management controller, oscillators +etc. The power controller kernel extension is provided in the base +port.

  • +
  • Power handlers +are device drivers that interface to the power manager.

  • +
+

The following sections describes these concepts in more detail.

+
Power +manager

The power manager manages the transition between +power states. It co-ordinates the change in the power state of peripherals +and the CPU (hardware), and provides the necessary interactions with +the device (peripheral) drivers and the power controller (software). +It also manages interactions with the user-side model.

The +power manager is an instance of the DPowerManager class, an object that is private to Symbian platform. This object +is created when the system is initialised, but is not installed as +the power manager until the power controller has been created and registered. Until the DPowerManager object is installed as the system's power +manager, Symbian platform manages power using built-in default behaviour.

The user-side uses the Power class, a set +of static functions, as an interface to the power manager. This allows +the user side to request a transition to the Standby or Off state, and to request notification of wake-up events, i.e. +events that will cause a transition back to the Active state.

The power manager object is the anchor point for the power controller +object and the power handler objects.

+
Power +controller

The power controller manages the device-specific +power management hardware such as an on-chip power management controller, +oscillators etc.

The power controller is an instance of a DPowerController class. This is an abstract class that +requires an implementation . A concrete implementation supports power +management hardware that is Variant specific. Typically, the Variant +creates a power controller object when the Variant is initialised, +and then registers it with the power manager through a call to DPowerController::Register(). Registration puts a pointer +to the DPowerController object into the Symbian platform +internal DPowerManager object.

The power +controller is responsible for tracking wake-up events, notifying the +power manager of such events through a call to DPowerController::WakeUpEvent().

+ +
+
Power +handlers

Device drivers interface to the power manager +through the DPowerHandler class. This is an abstract +class that requires a concrete implementation by device (peripheral) +drivers.

How a DPowerHandler object fits +into a driver's own object model is a matter of individual device +driver design. However, after construction of this object, the driver +is expected to register it with the power manager by calling DPowerHandler::Add(), after which it will receive notification +of changes to the power state.

The power manager calls DPowerHandler::PowerDown() when it requests a power state +transition to either the Off or the Standby state. The +power manager calls DPowerHandler::PowerUp() when +it requests a power state transition to the Active state. The +driver must respond to a power transition notification after it has +dealt with it by calling DPowerHandler::PowerUpDone() or DPowerHandler::PowerDownDone() as appropriate.

+ +
+
Shared +power sources

See the Power Resource Manager documentation for more information.

The set of power sources on a device, how they are connected to peripherals, +and their power states are totally dependent on the specific device. +This means that Symbian platform cannot provide a comprehensive API +for handling such sources.

However, Symbian platform does +provide an interface, MPowerInput, through which +drivers register their use of a power source and their release of +that power source. Symbian platform makes the following recommendations:

    +
  • Each (shared) +power source is represented by a separate object.

  • +
  • The class, or +class hierarchy, that represents the power source should implement +the MPowerInput interface so that device (peripheral) +drivers can register their use or their release of that power source.

  • +
  • Define a custom +interface with the power controller. It is likely that the Variant +will be responsible for providing the implementation for the power +inputs, and for providing this custom interface.

  • +

Drivers that need power from a specific power source call MPowerInput::Use() on the object that represents that power +source. To release dependence on that power source, the driver calls MPowerInput::Release().

To represent a shared power +source, a suggested implementation of MPowerInput might be to associate a counting value with the power source object. +A call to Use() would increment the counter, while +a call to Release() would decrement it. On construction +of the object, the initial value might be 0, indicating that no peripherals +require power from this source. A value of 1 or higher would indicate +that one or more peripherals require power from this source. The implementation +would, therefore, cause this power source to be kept on while at least +one peripheral needs it; the power source would only be switched off +when no peripherals need power from it.

+
+Domain +Manager +Power +Management Tutorials +Power +Resource Manager (PRM) +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-0C80F447-B82E-5586-9B02-4BC0D365FFD6.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-0C80F447-B82E-5586-9B02-4BC0D365FFD6.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,21 @@ + + + + + +Write Data to USB using Shared ChunksThis tutorial describes how to write shared chunk data to a USB connection.

Write data

To write data from the device to the host (In), read some data (e.g. from a media card on the device) to a shared chunk and make a write request to the driver. Use RDevUsbcScClient::WriteData() to send data placed inside a shared chunk to the USB hardware.

TUsbcScChunkHeader chunkHeader(gChunk); +TUsbcScHdrEndpointRecord* epInfo; +TRequestStatus status; + +TUsbcScBufferRecord* buff = chunkHeader.GetBuffer(0, 1, epInfo); +TInt inBuffNum = epInfo->iBufferNo; +TUint bufferOffset = buff->Offset(); +TUint length = buff->Size(); + +gPort.WriteData(inBuffNum, bufferOffset, length, 1, status);

The function WriteData() does not take an endpoint as a parameter. To send data to a particular endpoint the data must be put in the correct buffer. Find the buffer number in the chunk header with the endpoint number and the current alternate setting. See Setting the interface to see how alternate settings are created.

When sending buffers using this function, if a second buffer is ready to send before the first has finished transmitting then the second buffer can be sent to the LDD. The LDD will start sending the data in the second buffer when the first has finished. This reduces the delay between finishing one and transmitting the next. To do this the TRequestStatus objects must be kept track of as only one of these can be used with each request.

Note: an offset is provided that allows a buffer to be split into parts. This allows you to fill one half while sending the other.

When the request has completed, if there is no more data to be sent then close the channel and unload the driver.

When you have finished reading and writing Close and Unload the Driver.

\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-0C8318B1-71D7-5384-97EB-85CBBC3E6B84.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-0C8318B1-71D7-5384-97EB-85CBBC3E6B84.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,187 @@ + + + + + +IIC SHAI Implementation Layer: Master ChannelThis document explains how to implement the a master channel +in the SHAI implementation layer of IIC. +
Purpose

This document explains how to implement a master channel on the +SHAI implementation layer of IIC.

Intended Audience

Base porting engineers.

Introduction

IIC buses (a term used in this document to represent serial inter-chip +buses that IIC can operate on) are a class of bus used to transmit +non time-critical data between components of a hardware system.

+
Implementing +a master channel

You should read and understand the template +port at \os\kernelhwsrv\bsptemplate\asspandvariant\template_assp\iic\iic_master as this will provide most of the information you need to implement +the master channel.

To implement the SHAI implementation layer +of an IIC channel as master you must write a class extending DIicBusChannelMaster. You must implement certain pure virtual +functions of the parent class in the subclass. Those functions and +any other functions which you write in the subclass are called the +SHAI implementation layer. The functions inherited from the parent +class are called the Platform Independent Layer (PIL).

The +four functions you must implement are:

    +
  • DoCreate()

  • +
  • DoRequest()

  • +
  • HandleSlaveTimeout()

  • +
  • CheckHdr()

  • +

You must also provide the following functionality:

    +
  • validation of +input,

  • +
  • interrupt service +routines, and

  • +
  • reporting on +transmission status using the callback function CompleteRequest() with the relevant error code.

  • +

Your implementation of the SHAI implementation layer will +need to call functions of the PIL. You are restricted to using a certain +subset of these.

Implementing DoCreate()

DoCreate() is the second phase constructor of your class. +Implement it to perform functionality including:

    +
  • call the PIL +function Init(),

  • +
  • create the DFC +queue for the driver and assign it to the driver by calling SetDfcQueue(),

  • +
  • initialize the +hardware, setting up interrupts, and

  • +
  • initialize the +other data structures representing the channel.

  • +

Implementing DoRequest()

DoRequest() is the gateway function to the SHAI implementation layer. It configures +the interface using the supplied configuration and processes transactions. +It takes one argument aTransaction, a pointer to +a TIicBusTransaction object created by the client: +you use the protected data functions of the PIL (listed below) to +extract the data needed to perform the associated transfers. Implement DoRequest() with functionality including the following:

    +
  • Extract the +transaction parameters, that is the transaction header and transfers +(TIicBusTransfer),

  • +
  • configure the +interface with the configuration supplied in the transaction header,

  • +
  • set up the hardware +to start the first transfer, that is

      +
    • extract the +first transfer for one direction by calling GetTransHalfDuplexTransfer(),

    • +
    • and if the transfer +is full duplex extract the first transfer for the second direction +by calling GetTransFullDuplexTransferPtr(),

    • +

    in each case filling hardware FIFO buffers, enabling interrupts +and so on,

  • +
  • call the PIL +function StartSlaveTimeoutTimer(),

  • +
  • instruct the +hardware to start transmission, and

  • +
  • return either +an error code or KErrNone.

  • +

The effect of calling DoRequest() should +be to start the sequence of transfers comprising the transaction. +Typically, at the end of each transfer a hardware interrupt and associated +DFC callback occurs. If the PIL function StartSlaveTimeout() was called to monitor the duration of an individual transfer, the +PIL function CancelTimeout() should be called to +cancel the timer. If the transfer was successful and a call to get +the next transfers succeeds, the next transfer is set up. This continues +until either all the transfers have been processed, or there is an +error; after that, the PIL method DIicBusChannelMaster::CompleteRequest() is called to indicate the result.

Implementing HandleSlaveTimeout()

If the timer started by the PIL method StartSlaveTimeoutTimer() expires then the slave peripheral has not responded within the expected +time, and in such case some SHAI implementation layer-specific recovery +will be required; this is to be provided by the implementation of + HandleSlaveTimeout(). Implement it with functionality +including:

    +
  • stop the transmission,

  • +
  • disable the +hardware, and

  • +
  • call the PIL +function CompleteRequest() with the KErrTimedOut error code.

  • +

Implementing CheckHdr()

Implement CheckHdr(). This is the function which is called in the +context of the client thread when the client calls QueueTransaction(). Implement it with the following functionality:

    +
  • check if the +header of the transaction is valid.

  • +

Using the Platform Independent Layer

You can +only use certain functions of the PIL. Most are used to access private +data of the parent class. Others provide functionality which is generic +to IIC buses. These are:

    +
  • DIicBusChannelMaster(), the constructor of the superclass DIicBusChannelMaster with arguments representing the bus type and the duplex settings.

  • +
  • Init(). Initializes DIicBusChannelMaster.

  • +
  • SetDfcQ(). Sets the driver's DFC queue to +be used by DFCs in the PIL.

  • +
  • StartSlaveTimeOutTimer(). Starts a timer which causes the HandleSlaveTimeout() callback to run if the transaction (or transfer, SHAI implementation +layer decides) is not completed in the specified time.

  • +
  • CancelTimeOut();. Cancels the timeout timer which monitors the transaction time.

  • +
  • CompleteRequest(). Called to signal the PIL about completed transactions, transmission +errors and timeouts.

  • +

The functions accessing private members of TIicBusTransaction are:

+ + + +Function +Returns + + + + +

GetTransactionHeader()

+

A pointer to the configuration header.

+
+ +

GetTransHalfDuplexTfrPtr()

+

A pointer to the head of the list of half duplex transfers.

+
+ +

GetTransFullDuplexTfrPtr()

+

A pointer to the head of the list of full duplex transfers.

+
+ +

GetTransCallback()

+

A pointer to the callback function

+
+ +

GetTransFlags()

+

a pointer to the transaction flags

+
+ + +

The functions accessing private members of TIicBusTransfer are:

+ + + +Function +Returns + + + + +

GetTferType()

+

The transfer type, EMasterRead or EMasterWrite, defined in the enumeration TReqType.

+
+ +

GetTferBufGranularity()

+

The size of the buffer item in bits, typically 8 or 16.

+
+ +

GetTferBuffer()

+

A pointer to the buffer where the data is stored.

+
+ +

GetTferNextTfer()

+

A pointer to the next transfer in the transaction.

+
+ + +
In addition to the above functions, there are additional +functions for accessing transactions with preambles, extending transactions +(multitransactions) and extended transactions with preamble. Refer +to the header file for details on these functions.
+
+IIC +SHAI Implementation Layer: Generic Considerations +IIC +SHAI implementation Layer: Slave Channel +Client +of Master Channel Tutorial +Client +of Slave Channel Tutorial +IIC +Concepts +I2C +Technology Guide +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-0C84FD76-87B2-4AD1-B23A-2C5C8668BC4C.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-0C84FD76-87B2-4AD1-B23A-2C5C8668BC4C.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,14 @@ + + + + + +Base Porting GuideThe Base Porting Guide provides information that will help +you to port versions of the Symbian platform base to +new hardware. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-0C8C41EC-A8ED-5916-B944-DDDF20FADAF4.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-0C8C41EC-A8ED-5916-B944-DDDF20FADAF4.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,21 @@ + + + + + +Port +Implementation TutorialSteps required to implement a port of the Serial Port Driver. +

The actions needed in porting a Serial Port Driver are based on +the experience of porting the template reference board port. Note +however that the code shown here is idealized to show the basic principles; +it is not an exact copy of the template port code.

+

In the template reference board port, the .mmp for the physical device driver is ...\template_variant\datxtemplate.mmp. This is one of the PRJ_MMPFILES referenced +in the variant's bld.inf in the ...\template_variant\... directory, and means that the Serial Port Driver is built as part +of the variant. The source for the driver is contained entirely within ...\template_variant\specific\uart.cpp.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-0D2F811C-81C3-526F-8EA4-98E50261BF4B.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-0D2F811C-81C3-526F-8EA4-98E50261BF4B.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,282 @@ + + + + + +DMA +Framework TechnologyDescribes the classes that the DMA Framework provides to transfer +data using DMA. +

The following diagram shows the general relationship between the various +classes and structs that form the DMA Framework. The individual items are +described in more detail below.

+ + + +
The DMA Software +Controller

This is the TDmac object. It has +two purposes:

    +
  • It defines the main +interface between the platform independent and platform specific layers.

  • +
  • it is a container for +channels, descriptors and descriptor headers

  • +
+
The Channel +Manager

The channel manager is a DmaChannelMgr object.

DmaChannelMgr is +a static class defined by the platform independent layer but implemented in +the platform specific layer. The functionality is used by the platform independent +layer. It contains:

    +
  • a function to open a +DMA channel: DmaChannelMgr::Open()

  • +
  • a function that is called +when a channel is closed: DmaChannelMgr::Close()

  • +
  • a function that can +be used to extend the framework with platform specific functionality on a +channel independent basis: DmaChannelMgr::StaticExtension()

  • +
+
Descriptors

DMA +controllers operating in scatter/gather mode are configured via a linked list +of small data structures describing the data to be transferred. These data +structures are called descriptors. (Note that the use of the term descriptor +in the context of DMA should not be confused with the same term widely used +in Symbian platform to refer to the family of TDesC derived +classes).

The Symbian platform DMA Framework always uses descriptor +data structures to store transfer-configuration-information, even if the underlying +DMA controller does not support scatter/gather mode.

The following +example illustrates the idea: assume that a device driver needs to transfer +two disjoint blocks of memory, A and B, into another block C. Block A starts +at address 1000 and is 300 bytes long. Block B starts at address 2000 and +is 700 bytes long. The destination buffer C starts at address 5000 and is +1000 bytes long. Assume that the DMA descriptors are allocated in a pool starting +at address 600. The following diagram shows the scatter/gather list that the +device driver might create:

+ +

If the DMA controller supports the scatter/gather arrangement, then +the framework uses a structure that will be specific to the hardware. This +structure is defined in the platform specific layer.

If the DMA controller +does not support scatter/gather, then the framework uses the generic structure SDmaPseudoDes containing +the following information:

    +
  • a set of generic flags +that characterise the transfer. For example, is the source of the data memory +or a peripheral; is the destination memory or peripheral; what addressing +mode is to be used?

  • +
  • the source and destination +location. This is in the form of the base virtual address for a memory buffer, +and a 32-bit value (or cookie) for peripherals. The meaning of the 32-bit +value is interpreted by the platform specific layer.

  • +
  • The number of bytes +to be transferred.

  • +
  • A word that only has +meaning for the platform specific layer, and passed by the client at request +fragmentation time.

  • +
+
Descriptor +headers

These are objects of type SDmaDesHdr.

A +descriptor header allows additional information about a descriptor to be stored. +The header is a separate object from the descriptor because it is difficult +to embed additional data in a structure whose layout may be hardware-imposed.

Descriptors +and descriptor headers are stored in two parallel arrays allocated at boot-time, +and each descriptor is always associated with the header of same index, so +that there is always a one-to-one relationship between the header and the +descriptor.

+ +

In the current design, the only information in the descriptor header +is a pointer, SDmaDesHdr::iNext, that is used to chain headers +together on various lists. So, although the pool of headers is allocated as +an array, they are almost always accessed by following the chain of pointers +linking one header to the next.

Descriptors are always accessed +through their associated header.

The platform independent layer never +directly accesses hardware-specific descriptors. It just passes descriptor +headers to the platform specific layer. However, the platform independent +layer does directly manipulate the generic descriptors, SDmaPseudoDes.

+
Transfer Requests

A +transfer request is the way in which a device driver sets up and initiates +a DMA transfer, and is represented by a DDmaRequest object.

A +transfer request has a number of characteristics:

    +
  • it is always associated +with exactly one channel.

  • +
  • it stores a client-provided +callback function, which is invoked when the whole request completes, whether +successfully or not.

  • +
  • it can be in one of +four states:

      +
    • not configured

    • +
    • idle

    • +
    • being transferred

    • +
    • pending; this state +only occurs in streaming mode.

    • +
  • +

Internally, a transfer request is represented as a singly linked +list of descriptor headers. Each header in the list is associated with a descriptor +that specifies how to transfer one fragment of the whole request. Transfer +requests have pointers to the first and last headers in the list.

When +the request is idle, the header list ends with a NULL pointer. This is not +always true when the request is queued (i.e. when the request is being transferred +or is still pending). The following diagram shows an idle request with three +fragments.

+ +

Splitting a request into fragments is useful because:

    +
  • it insulates device +drivers from the maximum transfer size supported by the underlying DMA controller.

  • +
  • the source and destination +DMA buffers may not be physically contiguous and thus require fragmenting.

  • +

Both of these situations can be handled by using the generic fragmentation +algorithm DDmaRequest::Fragment().

Some device +drivers may have to create custom descriptors lists. For example, the USB +section of the PXA250 manual describes how to build custom lists where a descriptor +containing data transfer information is followed by another one poking an +I/O port to issue a command to the USB controller.

To cover that case, DDmaRequest provides +the DDmaRequest::ExpandDesList() member function to allocate +a list of headers associated with blank descriptors whose content is then +set by device drivers. Blank descriptors thus created can be accessed in the +following way (this example was taken and simplified from the PXA250 USB controller +driver):

TDmaChannel* channel; +TDmaChannel::SCreateInfo info; +info.x = y; +if (TDmaChannel::Open(info, channel) != KErrNone) + ... return; +DDmaRequest* req = new DDmaRequest(*channel); +if (!req) + ... return; +const TDmac* dmac = req->iChannel.Controller(); +if (req->ExpandDesList(2) != KErrNone) + ... return; +TDmaDesc* desc1 = static_cast<TDmaDesc*>(dmac->HdrToHwDes(*req->iFirstHdr)); +TDmaDesc* desc2 = static_cast<TDmaDesc*>(dmac->HdrToHwDes(*req->iFirstHdr->iNext)); +desc1->iSrcAddr = ...; +desc1->iDestAddr = ...; +desc1->iDescAddr = ...; +desc1->iCmd = ...; +desc2... +... +
+
Channels

A +channel is a TDmaChannel object, and there is one of these +for each hardware DMA channel.

A channel can be in one of 4 states:

    +
  • closed

  • +
  • open and idle

  • +
  • open and transferring +data

  • +
  • suspended following +an error.

  • +

On opening a channel, the client device driver specifies:

    +
  • A 32-bit value (cookie) +that is used by the platform specific layer to select which channel is to +be opened

  • +
  • The number of descriptors +that must be reserved for this channel.

  • +
  • A DFC to be used by +the framework to service DMA interrupts.

  • +

A channel maintains a queue of transfer requests. If the channel +is being used for one-shot transfers, the queue will always contain an idle +or a transferring request. In streaming mode, the queue may contain several +requests, the first one being transferred and the remaining ones pending. +When a request is completely transferred, it is removed from the queue. The +first request is always the one being transferred.

A transferring +channel has a pointer to the header associated with the descriptor being transferred. +The headers of all queued requests are linked together on one linked list.

The +following diagram shows a DMA channel with a three-fragment request being +transferred and a two-fragment one pending. The fragment currently being transferred +is the second one of the first request.

+ +

The TDmaChannel class contains the code and data +that is common to all of the channel types. The code and data for the specific +channel types: single buffer, double buffer, and scatter/gather channels, +are implemented in the derived classes: TDmaSbChannel, TDmaDbChannel, +and TDmaSgChannel respectively.

TDmaSbChannel +State Machine

For reference purposes, the following diagram shows +the state machine that TDmaSbChannel implements to deal +with a single buffer channel.

+ +

TDmaDbChannel +State Machine

For reference purposes, the following diagram shows +the state machine that TDmaDbChannel implements to deal +with a double buffer channel.

+ +

TDmaSgChannel +State Machine

For reference purposes, the following diagram shows +the state machine that TDmaSgChannel implements to deal +with a scatter/gather channel.

+ +
+
Streaming and +Scatter/Gather DMA Controllers

When a transfer request is queued +onto a channel that is already transferring data, the header descriptor for +the new list of descriptors is appended to the header of the previous request +on the queue. If the underlying DMA controller supports hardware descriptors, +they must also be linked together.

The following diagram shows how +headers and descriptors for a new request are appended to the existing ones +for a DMA controller. The dashed arrows represent the new links.

+ +

Note that hardware descriptors are linked together using physical +addresses, not virtual ones.

Linking hardware descriptors together +is implemented in the platform specific layer. There are two issues to consider:

    +
  • The channel may go idle +before the linking is complete, which means that the data for the new request +would not be transferred.

  • +
  • If the channel is transferring +the last descriptor in the list, then updating the “next” field in the descriptor +will have no effect because the content of the descriptor will already have +been loaded in the controller registers. Again the channel would go idle without +transferring the data associated with the new request.

  • +

The solutions available when porting the DMA Framework are:

    +
  • If the DMA controller +has hardware support for appending descriptors while transferring data, then +there is no problem.

  • +
  • If the peripheral attached +to the channel can withstand a short disruption in the transfer flow, then +the channel can be suspended while the appending takes place. This should +be done with interrupts disabled to minimise disruption.

  • +
  • The alternative technique +is to append the new list with interrupts disabled and set a flag. When the +next interrupt occurs, if the flag is set and the channel idle, then the interrupt +service routine must restart the transfer.

  • +

See Channels.

+
Interrupt Service +Routine (ISR) and DFC Issues

The platform specific layer must notify +the platform independent layer when the following events occur:

    +
  • when an error occurs.

  • +
  • when each fragment completes, +for single-buffer and double-buffer controllers.

  • +
  • when the last fragment +of a request completes, for scatter/gather controllers.

  • +

The ISR, as implemented in the platform specific layer, must:

    +
  • determine which channel +the interrupt is for. If the DMA controller uses dedicated interrupt lines +per channel, the ASSP/variant interrupt dispatcher will do this. See Interrupt Dispatcher Tutorial.

  • +
  • determine whether the +interrupt was asserted following a successful transfer completion or a failure. +If the DMA controller uses different interrupt lines for completion and failure, +the ASSP/variant interrupt dispatcher will do this.

  • +
  • Call TDmac::HandleIsr() in +the platform specific layer. This function queues the DFC associated with +the relevant channel. It takes care of the case where several interrupts occur +before the DFC gets a chance to run.

  • +

The DFC updates the state of the channel and, for single and double +buffer DMA controllers, configures the next fragment to transfer, if any. +When all fragments making up a request have been transferred, the DFC calls +the client-supplied callback associated with the completed request. The callback +is also called if an error occurs during transfer.

+
Locking Strategy

For +a given device driver, TDmaChannel and DDmaRequest instances +can be accessed concurrently from the device driver thread and from a DFC +queue thread. To avoid race conditions, each TDmaChannel instance +has a fast mutex, the protected data member TDmaChannel::iLock. +This lock is acquired when queuing a new request, cancelling requests and +executing the DFC.

TDmaChannel and DDmaRequest instances +are not protected against concurrent access from several client threads because +this is assumed to be an exceptional case. A device driver with such need +would have to implement its own locking scheme around calls to TDmaChannel and DDmaRequest member +functions.

Each TDmac instance includes a fast +mutex, the private member TDmac::iLock to protect descriptor +reservation and allocation, because several device drivers may try to reserve +or allocate descriptors concurrently.

The DmaChannelMgr static +class includes a fast mutex which is used to protect channel opening as several +device drivers may compete for the same channel. This lock is also used at +channel closing time.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-0DB79535-E4E6-50BD-852D-B2F177202C9C-master.png Binary file Adaptation/GUID-0DB79535-E4E6-50BD-852D-B2F177202C9C-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-0DB79535-E4E6-50BD-852D-B2F177202C9C_d0e13227_href.png Binary file Adaptation/GUID-0DB79535-E4E6-50BD-852D-B2F177202C9C_d0e13227_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-0DC908A1-6CF6-50B5-978F-AF6C8CE04F44.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-0DC908A1-6CF6-50B5-978F-AF6C8CE04F44.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,62 @@ + + + + + +Automatic +Translation of Header Files From C++Describes how C++ header files are translated into the assembler +language that the bootstrap requires. +

Some header files that the bootstrap uses are shared with the Kernel and +are written in C++. The header files are shared to avoid duplicate definitions +of, for example, super page layout in the kernel and in the bootstrap. Since +the bootstrap is written in assembler, the C++ header files must be translated +to assembler-syntax include files.

+

This is done automatically under the control of the generic makefile. The +translation tool can produce include files in ARMASM, GNU AS or Turbo Assembler +(for X86) syntax; the examples will all be in ARMASM syntax.

+

It should be noted that the translation tool does not process #include directives +or any other preprocessor directives. Only the types listed below and types +created from those (by typedef or class/struct declaration) will be recognised.

+

The following elements of C++ header files are translated:

+
Compile time constants, both at file and class scope

Constants +at file scope have the same name in the assembler include file and constants +at class scope have the name <class name>_<constant name> in +the assembler include file. Initialiser values may be expressions and may +involve previously-defined constants or enumerators as well as sizeof operations +applied to previously-defined types.

For example:

const TInt KBufferSize = 1024; +class X { const TInt KClassConstant = 100; }; +

translates to:

KBufferSize EQU 0x00000400 +X_KClassConstant EQU 0x00000064 +
+
Enumerators, both at file and class scope

For example:

enum T1 {E1=0, E2=8, E3}; +class X { enum {EE1=-1, EE2, EE3}; }; +

translates to:

E1 EQU 0x00000000 +E2 EQU 0x00000008 +E3 EQU 0x00000009 +X_EE1 EQU 0xFFFFFFFF +X_EE2 EQU 0x00000000 +X_EE3 EQU 0x00000001 +
+
Offset of a class member within the class

For example:

class X { TInt iX; TInt iY; TInt iZ[16]; };

translates +to:

X_iX EQU 0x00000000 +X_iY EQU 0x00000004 +X_iZ EQU 0x00000008 +X_iZ_spc EQU 0x00000004 +X_sz EQU 0x00000048

The offset of a class +member within the class is given the assembler name <class>_<member>. +For an array member, this offset is the offset of the first element of the +array within the class and <class>_<member>_spc is +the size of each array element. The overall size of the class is given the +assembler name <class>_sz.

When computing these +offsets and sizes the following basic types are known to the translation tool:

TInt8, TUint8 = 1 byteTInt16, TUint16 = 2 bytes aligned to 2 byte boundaryTInt32, TUint32, TInt, TUint, enum, TLinAddr, TPte, TPde = 4 bytes aligned to 4 byte boundaryTInt64, TUint64 = 8 bytes aligned to 8 byte boundary

The +tool will produce an error if an attempt is made to use a TInt64 or TUint64 which +is not aligned on an 8 byte boundary. This is done to avoid incompatibilities +between GCC and EABI compilers since the tool is not aware which is being +used to compile the kernel.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-0E93319A-439E-49D8-BF38-C809FEE4BB74.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-0E93319A-439E-49D8-BF38-C809FEE4BB74.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,47 @@ + + + + + +User-side +CreationThis document describes user-side creation of asynchronous requests. +

Asynchronous requests are commonly initiated by a call to RBusLogicalChannel::DoRequest(). +The user making an asynchronous request creates a TRequestStatus object +and passes it along with the request type to the DoRequest() call. +The request status is changed to KRequestPending by the +Kernel before sending the message to the driver. The user may then either +wait on the request using User::WaitForRequest(), or it +may queue one or more requests and then wait. It may have an active object +handler to receive the request complete notifications.

+// Request status object for transmit. This object will be used to +// read the status of asynchronous requests after the notification of +// request completion +// + TRequestStatus txStatus; + +// Call the LDD interface TransmitData() API with test data descriptor +// and TRequestStatus object as parameters. Here TransmitData() is a +// wrapper over a DoRequest() call. +// +r = ldd.TransmitData(txStatus, KTestSendData); +test(r==KErrNone); + +// Wait till the request is complete on txStatus. The user thread is +// blocked with this call, till it is notified about the request +// completion. +// +User::WaitForRequest(txStatus); + +// txStatus holds the request completion. TRequestStatus::Int() +// returns the completion code. It will be KErrNone in case of +// successful completion. +// +r = txStatus.Int(); +test(r==KErrNone); +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-0F17BCDF-CF50-40D1-9048-793DC4442B50.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-0F17BCDF-CF50-40D1-9048-793DC4442B50.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,15 @@ + + + + + +IntroductionThis set of documents describes the device driver development process +and provides links to example material. +

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-0FE0B646-A62F-55A8-A6E6-587D0909CE19-master.png Binary file Adaptation/GUID-0FE0B646-A62F-55A8-A6E6-587D0909CE19-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-0FE0B646-A62F-55A8-A6E6-587D0909CE19_d0e74784_href.png Binary file Adaptation/GUID-0FE0B646-A62F-55A8-A6E6-587D0909CE19_d0e74784_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-10C986FD-BD56-4F8E-87EC-7B890EFCDAC7.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-10C986FD-BD56-4F8E-87EC-7B890EFCDAC7.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,34 @@ + + + + + +DMA Chipset ConfigurationChipset configuration is performed entirely within the +platform service implementation. +

The DMA controller chipset has multiple DMA channels that can be +configured for different DMA transfers. Drivers generally initialize +and open the required DMA channel and use this channel to do the DMA +transfers.

+

For some peripherals, such as the Camera and the Display controller, +there can be dedicated DMA channels that cannot be configured for +DMA transfers by other peripherals.

+

To configure the channels and other features of the chipset, you +may need to write code. This code should be executed prior to the +DMA channels being used for the first time, or to configure dynamically-allocated +channels.

+

This requires chipset specific code which is beyond the scope of +this documentation. Please refer to your chipset's datasheet and any +accompanying documentation for details on how to perform any required +chipset configuration.

+

If you need to perform chipset configuration after the device +driver has loaded, there is an Extension() function. +This function passes chipset specific code or instructions from the +client to the platform service implementation. Implementation of the Extension() API is platform specific and is not covered +further in this documentation.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-10D79C75-6AB9-4717-87EF-057F19CB8283.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-10D79C75-6AB9-4717-87EF-057F19CB8283.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,40 @@ + + + + + +Time Implementation GuideHow to implement the Time platform service. +

The Time +platform service specifies functions to get and set the current time.

+

To implement +the Time platform service, you implement the functions RtcData() and SetRtcData() in hardware.

+ + +

The function SetRtcData() sets the state +of the real time clock to a passed in value. To implement it you write +that value to the RTC current time register. On Symbian platform, +the value should be the number of seconds that have elapsed since +the beginning of 2000.

+

The platform now has a function to set the current +time in seconds.

+
+ +

The function RtcData() returns the current +state of the real time clock. To implement it, you read the RTC current +time register and return that time as a TUint.

+

The current state of the real time clock is a TUint containing the number of seconds since the beginning +of 2000.

+
+
+

You have +now implemented the Time platform service in hardware.

+
+Time +Client Interface Tutorial — Using the Interface +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-10F3E16A-8CCE-420A-9D1C-F9891B3D75FE.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-10F3E16A-8CCE-420A-9D1C-F9891B3D75FE.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,13 @@ + + + + + +ConceptsDescribes the technology, architecture, and behaviour of +the power management framework. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-10FD1B94-EC0C-458F-839F-B60A8E47BAD6.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-10FD1B94-EC0C-458F-839F-B60A8E47BAD6.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,163 @@ + + + + + +Baseport Template Configuration GuideDescribes the configuration of the Baseport Template platform +service. +

The config.inc file provided at os/kernelhwsrv/bsptemplate/asspandvariant/template_variant/config.inc is used to set up the platform specific values in the Baseport. +The comments in the config.inc file explains +the various options that can be used to configure the baseport.

+
Template +configuration

A sample configuration file is available in +the template. The configuration file looks like the one below:

+; template\config.inc +; +;Include to enable tracing +; GBLL CFG_DebugBootRom + +; +; Include one of these to select the CPU +; GBLL CFG_CPU_GENERIC_ARM4 +; GBLL CFG_CPU_ARM710T +; GBLL CFG_CPU_ARM720T +; GBLL CFG_CPU_SA1 +; GBLL CFG_CPU_ARM925T +; GBLL CFG_CPU_ARM926J +; GBLL CFG_CPU_XSCALE +; GBLL CFG_CPU_ARM1136 +; GBLL CFG_CPU_ARM1176 +; GBLL CFG_CORTEX_A8 + +; Include the following line if this is a bootloader bootstrap +; GBLL CFG_BootLoader + +; TO DO: +; The following line needs to be removed for target hardware +GBLL CFG_Template + +; If you want to supply a custom set of initial vectors (including reset vector) include the following line +; GBLL CFG_CustomVectors +; +; and provide a custom_vectors.inc file + +; Variant Number, just an example: + INIT_NUMERIC_CONSTANT CFG_HWVD, 0x09080001 + +; On ARM architecture 6 processors, include the following line to override the threshold +; on total physical RAM size at which the multiple memory model switches into large address space mode +; i.e. size>threshold -> 2Gb per process, size<=threshold -> 1Gb per process +; Defaults to 32Mb. +; INIT_NUMERIC_CONSTANT CFG_ARMV6_LARGE_CONFIG_THRESHOLD, ;<value &rt; +; For the direct memory model only, include the following line if you wish the exception vectors at the +; start of the bootstrap to be used at all times. This is only relevant if an MMU is present - this option +; is mandatory if not. +; GBLL CFG_UseBootstrapVectors +; +; If the above option is in use (including if no MMU is present) the following symbol should be defined +; to specify the offset from the bootstrap to the kernel image. INIT_NUMERIC_CONSTANT KernelCodeOffset, 0x4000 +; Include the following line if you wish to include the ROM autodetection code based on data bus +; capacitance and image repeats. +; GBLL CFG_AutoDetectROM +; Include the following line to minimise the initial kernel heap size +; On the direct memory model the size of the kernel data area (super page to end of kernel heap) +; is rounded up to the next 1Mb if this is not included, 4K if it is. +; On the moving and multiple models, the size of the initial kernel heap area is rounded up to +; the next 64K if this is not included, 4K if it is. +; GBLL CFG_MinimiseKernelHeap +; Include the following line if default memory mapping should use shared memory. +; Should be defined on multicore (SMP) devices. +; GBLL CFG_USE_SHARED_MEMORY +; On the moving or multiple memory models, include either or both of the following lines to +; specify the size of the initial kernel heap +; INIT_NUMERIC_CONSTANT CFG_KernelHeapMultiplier, <multiplier> +; INIT_NUMERIC_CONSTANT CFG_KernelHeapBaseSize, <base> +; +; The initial kernel heap size is MAX( <base> + <multiplier> * N / 16, value specified in ROMBUILD ) +; where N is the total physical RAM size in pages. +; <base> defaults to 24K and <multiplier> defaults to 9*16 (ie 9 bytes per page). +; Uncomment if using ARM1136 processor and ARM1136 Erratum 353494 +; "Rare conditions can cause corruption of the Instruction Cache" +; is fixed on this hardware. +; NOTE: The boot table should use this macro to determine whether RONO or RORO permissions +; are used for the exception vectors. If the erratum is not fixed, RORO must be used. +; +; GBLL CFG_CPU_ARM1136_ERRATUM_353494_FIXED +; Uncomment if using ARM1136 processor and ARM1136 Erratum 364296 +; "Possible Cache Data Corruption with Hit-Under-Miss" +; is fixed on this hardware. +; +; GBLL CFG_CPU_ARM1136_ERRATUM_364296_FIXED +; Uncomment if using ARM1136 processor and ARM1136 Erratum 399234 +; "Write back data cache entry evicted by write through entry causes data corruption" +; is fixed on this hardware. +; +; Workaround +; The erratum may be avoided by marking all cacheable memory as one of write through or write back. +; This requires the memory attributes described in the translation tables to be modified by software +; appropriately, or the use of the remapping capability to remap write through regions to non cacheable. +; +; If this macro is enabled, it should be accompanied by: +; "macro __CPU_ARM1136_ERRATUM_399234_FIXED" in variant.mmh +; GBLL CFG_CPU_ARM1136_ERRATUM_399234_FIXED +; +; Uncomment if: +; 1) using ARM1136 processor and ARM1136 Erratum 411920: "Invalidate Entire Instruction Cache +; operation might fail to invalidate some lines if coincident with linefill" +; is fixed on this hardware, or +; 2) using ARM1176 processor and ARM1176 Erratum 415045: "Invalidate Entire Instruction Cache +; operation might fail to invalidate some lines if coincident with linefill +; is fixed on this hardware. +; Workaround: +; 1) Disables the use of of prefetch range cache operations by setting RV bit in Auxiliary Ctrl Reg. +; 2) Replaces Invalidate ICache operation with the sequence defined in the errata document. +; +; If this macro is enabled, it should be accompanied by: +; "macro __CPU_ARM1136_ERRATUM_411920_FIXED" in variant.mmh +; +; GBLL CFG_CPU_ARM1136_ERRATUM_411920_FIXED +; +; Uncomment if using ARM1136 processor and ARM1136 Erratum 415662: "Invalidate Instruction Cache by +; Index might corrupt cache when used with background prefetch range" is fixed on this hardware. +; Workaround: +; Disables the use of of prefetch range cache operations by setting RV bit in Auxiliary Ctrl Reg. +; +; GBLL CFG_CPU_ARM1136_ERRATUM_415662_FIXED +; +; These are deduced from the supplied configuration +; CFG_ARMV6 ; CFG_MMUPresent +; CFG_CachePresent ; CFG_WriteBufferPresent +; CFG_SplitCache +; CFG_SplitTLB +; CFG_AltDCachePresent +; CFG_WriteBackCache +; CFG_CacheWriteAllocate +; CFG_CachePhysicalTag +; CFG_CacheFlushByDataRead +; CFG_CacheFlushByWaySetIndex +; CFG_CacheFlushByLineAlloc +; CFG_CachePolicyInPTE +; CFG_TEX +; CFG_SingleEntryDCacheFlush +; CFG_SingleEntryICacheFlush +; CFG_SingleEntryITLBFlush +; CFG_SingleEntryTLBFlush +; CFG_CacheTypeReg +; CFG_BTBPresent +; CFG_CARPresent +; CFG_PrefetchBuffer +; CFG_FCSE_Present +; CFG_ASID_Present +; CFG_IncludeRAMAllocator + END + Ensure that you have made the line GBLL CFG_Template a comment and have selected the lines for the required configuration.
+
+Baseport +Template Build Guide +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-10FE825A-4383-4A10-A507-58577BB230FB-master.png Binary file Adaptation/GUID-10FE825A-4383-4A10-A507-58577BB230FB-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-10FE825A-4383-4A10-A507-58577BB230FB_d0e89974_href.png Binary file Adaptation/GUID-10FE825A-4383-4A10-A507-58577BB230FB_d0e89974_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-110DB7EF-5E85-5BC4-9BBB-9A37B2D0C3A6.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-110DB7EF-5E85-5BC4-9BBB-9A37B2D0C3A6.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,104 @@ + + + + + +Dynamic BehaviorThis topic describes in detail the dynamic relationships +between a keyboard driver, the Window Server, and related components. +
What +the keyboard driver does

The keyboard driver's job is to +interpret keyboard presses and to generate key-up and key-down events. +How the keyboard driver deals with the hardware depends to a great +extent on that hardware, and also on whether the hardware generates +interrupts as a result of key presses or whether the driver needs +to poll the hardware at regular intervals.

The template Base +port, which can be found at ...\cedar\template\..., gives two skeleton implementations, one for an interrupt driven +implementation and one for a poll driven implementation. See Keyboard Driver Implementation +Tutorial.

Whichever type is used, the end result is +the addition of a stream of events onto the kernel's event queue. +Events are represented by TRawEvent objects, and +each one represents either a key-up or a key-down event, together +with the scancode value for that key and the accompanying modifier +key values, for example, Shift and Ctrl. The driver adds these events onto the kernel's +event queue using Kern::AddEvent().

The +general pattern, taken from the template keyboard driver, is as follows:

TRawEvent e; +... +e.Set(TRawEvent::EKeyUp,stdKey,0); +... +Kern::AddEvent(e); TRawEvent e; +... +e.Set(TRawEvent::EKeyDown,stdKey,0); +... +Kern::AddEvent(e);

More generally, TRawEvent objects represent and encapsulate information about events such +as screen pointer events, mouse events, etc. as well as keyboard key +presses. Such events are mostly intended to result in a change to +the device display(s) or the finer details of the User Interface, +and for this reason, such events are captured by the Window Server.

The kernel event queue is a mechanism that allows this to happen. It is internal to Symbian platform, but to help you understand +what happens, it works like this:

    +
  • The kernel maintains +a circular buffer of TRawEvent objects anchored +in K::EventBufferStart, and this buffer is allocated +at system initialization.

  • +
  • As part of its +initialization, the Window Server calls the internal function UserSvr::CaptureEventHook(). This registers the +Window Server's interest in capturing these events, and subsequent +to this call, all such events are delivered to the Window Server. +However, do note that the kernel does not permit any process other +than the Window Server from registering to receive these events.

  • +
  • A call to Kern::AddEvent() causes a TRawEvent object +to be added to this queue; the kernel subsequently attempts to deliver +this to the Window Server.

  • +
  • The Window Server +uses an active object to wait for and subsequently dispatch the handling +of events (and most importantly, key press events). It makes a request +for further events by a call to the internal function UserSvr::RequestEvent().

  • +
+Dynamic Behavior + +
+
What +the Window Server does

There are two services that the +Window Server needs when dealing with key presses:

    +
  • it needs a translation +of a (hardware) scancode to a (Symbian platform or logical) keycode.

  • +
  • it needs to +know whether a key and combination of modifier key states is a "hot-key", +i.e. one that is intended to be sent to a specific window group, instead +of the window group that currently has focus. Note that, in this context, +a "hot-key" is more commonly referred to as a capture key.

  • +

To perform the translation, it creates an instance of a CKeyTranslator class.

To deal with capture keys, +it creates an instance of a CCaptureKeys class.

Both classes are implemented in ektran.dll, the key translation DLL, which is built and delivered as part of +the generic Symbian platform. The Window Server statically links to ektran.dll.

[Note that CKeyTranslator and CCaptureKeys +are internal to Symbian platform and are not part of the public interface. +This is an attempt to provide an outline understanding of the mechanisms +involved.]

The Window Server also decides on the name +of the key mapping tables DLL to be loaded. By default, the name of +this DLL is ekdata.dll. However, if the Hardware +Abstraction Layer (HAL) for the device records a language index, then +this index value is used to form the name of the DLL to be loaded. +For example, if the keyboard index value returned by a call to:

TInt keyboardIndex; +HAL::Get(HALData::EKeyboardIndex,keyboardIndex);

is +99, then the DLL loaded is ekdata99.dll.

The loading of this DLL is done by a member of CKeyTranslator, so although the Window Server decides which DLL is to be loaded, +the actual loading is done by ektran.dll. For +ease of explanation, we will continue to refer to this DLL as ekdata.dll.

On receipt of key-up and key-down +events, the Window Server calls CKeyTranslator::TranslateKey(). This function takes the (hardware) scancode and translates it into +the (logical) keycode. It also reports whether the key and combination +of modifier key states is a capture key, and if so, returns the handle +to the window group that is associated with it.

Before the +Window Server can be told that a capture key has been pressed, it +must previously have registered a pair of items:

    +
  • the capture +key itself, i.e. the (logical) keycode and combination of modifier +key states.

  • +
  • a handle to +a window group.

  • +

Registration is simply the act of adding this information +into the CCaptureKey object by a call to CCaptureKeys::AddCaptureKeyL(). The Window Server does this +as a result of a call to RWindowGroup::CaptureKey(), either by applications or the UI.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-1138D29D-2EC5-59DF-9AA7-2D863FBC024F.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-1138D29D-2EC5-59DF-9AA7-2D863FBC024F.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,133 @@ + + + + + +Factory +ImplementationDescribes how to implement a factory. +

The Sound Driver PDD must provide a factory class to create channels. All +PDD factory classes are derived from DPhysicalDevice. The +template PDD factory class TemplateSoundScPddFactory creates +the appropriate PDD object when a driver channel is opened on the device. +As well as the configurations supporting both record and playback, this class +implements control of those aspects of the audio hardware device that are +shared between the two channels.

+

DTemplateSoundScPddFactory is defined as:

+class DTemplateSoundScPddFactory : public DPhysicalDevice + { +public: + DTemplateSoundScPddFactory(); + ~DTemplateSoundScPddFactory(); + virtual TInt Install(); + virtual void GetCaps(TDes8& aDes) const; + virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* aInfo, const TVersion& aVer); + virtual TInt Validate(TInt aUnit, const TDesC8* aInfo, const TVersion& aVer); +private: + /** The DFC queue (used also by the LDD). */ + TDynamicDfcQue* iDfcQ; + friend class DTemplateSoundScTxPdd; + friend class DTemplateSoundScRxPdd; + }; +

The PDD factory class provided by the template Sound Driver creates a new +DFC queue and associated kernel thread, iDfcQ, for exclusive +use by this pair of Sound Driver channels. This is created within the second +stage constructor function Install(). +A pointer to the DFC queue is returned by the PDD function DfcQ(). +See the PDD +class constructor section.

+

The class DTemplateSoundScPddFactory contains four virtual +functions, including the constructor, that must be implemented by the PDD +for both driver channels. The template Sound Driver contains default implementations +together with a constructor and destructor and, typically, need little or +no modification:

+
    +
  • DTemplateSoundScPddFactory constructor

  • +
  • Install()

  • +
  • Validate()

  • +
  • Create()

  • +
+
DTemplateSoundScPddFactory +constructor

Ensure that the inherited data member iUnitsMask is +setup correctly according to the unit numbers to be supported. The default +version enables the PDD to open both the first playback driver channel number KSoundScTxUnit0 and +the first record driver channel number KSoundScRxUnit0:

// Support units KSoundScTxUnit0 & KSoundScRxUnit0 +iUnitsMask=(1<<KSoundScRxUnit0)|(1<<KSoundScTxUnit0);
+
Install()

This +is the second stage constructor for the PDD factory class. The template version +creates the DFC queue and sets the driver name.

_LIT(KSoundScPddName,"SoundSc.Template"); + +// Definitions for the kernel thread created for this sound driver. +_LIT(KSoundScDriverThreadName,"SoundDriverThread"); +const TInt KSoundScDriverThreadPriority=26; // One less than DFC thread 0 + +TInt DTemplateSoundScPddFactory::Install() +{ + TInt r=KErrNone; + if (iDfcQ==NULL) + { + // Create a new sound driver DFC queue (and associated kernel thread). + r=Kern::DynamicDfcQCreate(iDfcQ, KSoundScDriverThreadPriority, KSoundScDriverThreadName); + } + + if (r==KErrNone) + { + r=SetName(&KSoundScPddName); // Set the name of the driver object + } + return(r); + }

The physical device is identified by the driver name, +alter this to reflect your device. The driver name is the same as the LDD +name, but followed by a dot and a short string to represent the physical device. +For example, the name used for template is "SoundSc.Template ".

+
Validate()

This +function is called by the kernel device driver framework to see whether this +PDD is suitable for use with a particular driver channel. Ensure that the +unit number checking code is correct for the unit numbers that are to be supported. +The default version enables the PDD to open both the first playback driver +channel number KSoundScTxUnit0 and the first record driver +channel number KSoundScRxUnit0.

// Check the unit number is compatible +if (aUnit!=KSoundScTxUnit0 && aUnit!=KSoundScRxUnit0) + return(KErrNotSupported);
+
Create()

This +function is called by the kernel device driver framework to create a PDD object. +Ensure that the unit number checking code is correct for the unit numbers +that are to be supported. For configurations supporting both playback and +record, it must be capable of creating either a playback or record PDD object +according to the channel number specified. The template version is implemented +as follows:

TInt DTemplateSoundScPddFactory::Create(DBase*& aChannel, + TInt aUnit, + const TDesC8* /*anInfo*/, + const TVersion& /*aVer*/) + { + // Create the appropriate PDD channel object. + TInt r=KErrNoMemory; + if (aUnit==KSoundScRxUnit0) + { + // Create a record PDD channel object + DTemplateSoundScRxPdd* pD=new DTemplateSoundScRxPdd; + aChannel=pD; + if (pD) + { + pD->iPhysicalDevice=this; + r=pD->DoCreate(); + } + } + else + { + // Create a playback PDD channel object + DTemplateSoundScTxPdd* pD=new DTemplateSoundScTxPdd; + aChannel=pD; + if (pD) + { + pD->iPhysicalDevice=this; + r=pD->DoCreate(); + } + } + return(r); + }
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-113B3755-1797-5D1B-8E07-8A18F5FE1504.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-113B3755-1797-5D1B-8E07-8A18F5FE1504.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,43 @@ + + + + + +Power StatesDescribes three power states that are defined by the kernel. +
    +
  • Off - +a state where the device and all peripherals are powered off or inactive, +or are characterised by negligible power consumption due to current +leakage to the electric and electronic circuits that make up the system. +This state is achieved as a result of controlled system shutdown resulting +from a user action, an application request, UI inactivity, or as a +result of accidental loss of power. This may also be achieved as a +result of putting the system into a hibernation state. Note that a +reboot is necessary to return the system to the Active state; +this could be a cold reboot, or a warm reboot if the system was put +into a hibernation state.

  • +
  • Standby - a low power consuming state that results from turning off most +system resources (clocks, voltages), peripherals, memory banks (where +possible), cpu and internal logic, while still retaining the state +prior to the transition. Typically, the only systems that are active +are those that are required to detect the events that force the transition +back to the Active state (e.g. RTC, clocks and Peripherals involved +in detecting hardware events). Returning to the Active state will +normally take a far shorter period of time than that required to reboot +the system. This state is achieved as a result of user action or application +request.

  • +
  • Active - the fully active state.

  • +
+

The three power states are defined by the enum values of the TPowerState enum defined in e32power.h.

+
+Domain +Manager +Power +Management +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-124AC7EE-E227-5358-A755-628FFE257250.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-124AC7EE-E227-5358-A755-628FFE257250.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,162 @@ + + + + + +HAL Handler ImplementationDescribes how to implement or change a new HAL handler +when you create a base port. +

A HAL handler gets or sets hardware-specific settings, for example, +the display contrast.

+

A HAL handler is normally implemented in the kernel extension or +a driver that provides the hardware-specific functionality.

+

The easiest way to see the general pattern for implementing HAL +handlers is to look at a real example. We will use the screen (i.e. +video or LCD) driver for the template reference board, which is implemented +in ...\template_variant\specific\lcd.cpp.

+
HAL +handler function signature

The HAL handler function has +a signature that is defined by the THalFunc typedef +that is exported in epoc32\include\kernel\kernel.h.

For example:

TInt halFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2)
+
Registering +the HAL handler

Before the handler can do anything, the +extension or driver must register its handler for a specific HAL group. +It does so by calling:

Kern::AddHalEntry(group, handler_func, ptr);

where:

    +
  • group is the number of the HAL group attribute for which the HAL handler is being registered.

  • +
  • handler_func is a pointer to the HAL handler function.

  • +
  • ptr is a pointer that is passed to the HAL handler function when it +is called. This is usually a pointer to an object that can handle +the specified HAL attribute.

  • +

A group can only have one handler, any attempt to +register another handler returns an error. Typically, a driver will +register its handler during its initialisation phase.

Nearly all the functionality of the template screen driver is implemented +in a single class, the LCD power handler object; its DLcdPowerHandler::Create() function is called as part of startup processing. It is this function +that registers the HAL handler:

... +// install the HAL function +r=Kern::AddHalEntry(EHalGroupDisplay,halFunction,this); +if (r!=KErrNone) + return r; +... +

Note that the third parameter is, in general, an optional +pointer. It is a pointer to the current object, i.e. the DLcdPowerHandler object. It is this pointer that is passed on to the HAL handler +function as its first argument.

+
Common +implementation pattern

Using the template screen driver +as an example, the driver provides the HAL handler for dealing with +information related to the display HAL group, EHalGroupDisplay. The HAL handler is the function:

LOCAL_C TInt halFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2) + { + DLcdPowerHandler* pH=(DLcdPowerHandler*)aPtr; + return pH->HalFunction(aFunction,a1,a2); + } +

This is a stand-alone function. The first parameter aPtr is the pointer that was originally passed to the kernel +when the HAL handler was registered via the Kern::AddHalEntry() call, and in this case, points to the LCD's power handler object. +In this example, the main implementation of the HAL handler is the +member function HalFunction() of the DLcdPowerHandler instance.

Whether you use this kind of technique depends +on the way your drivers are implemented, but it is a pattern that +is also used by the digitiser and the keyboard driver, as well as +by the Symbian implemented HAL handlers.

The other parameters +passed to the HAL handler function, i.e. aFunction, a1, and a2 are the ones passed +into a call to UserSvr::HalFunction(), which itself +is called by the various accessory functions; see the Architecture of User-Side Hardware Abstraction (HAL) component.

It's useful to note that a single HAL handler may end up being +called as a result of calls to different accessory functions. For +example, ProcessDisplayCurrentModeInfo() and GetBacklightPresent() are accessory functions that result +in a call to the screen driver's HAL handler.

To further distinguish +between the different characteristics represented by a group, each +group has an associated set of function-ids. The function id is the +second parameter passed to the HAL handler function, and the most +common pattern for an implementation is to code a simple switch statement +based on this value. For example, the function-ids associated with +the EHalGroupDisplay are represented by the set +of enum values defined by the TDisplayHalFunction enum. This is a fragment taken from the template screen driver:

TInt DLcdPowerHandler::HalFunction(TInt aFunction, TAny* a1, TAny* a2) + { + TInt r=KErrNone; + switch(aFunction) + { + case EDisplayHalScreenInfo: + { + TPckgBuf<TScreenInfoV01> vPckg; + ScreenInfo(vPckg()); + Kern::InfoCopy(*(TDes8*)a1,vPckg); + break; + } + + case EDisplayHalWsRegisterSwitchOnScreenHandling: + iWsSwitchOnScreen=(TBool)a1; + break; + + case EDisplayHalWsSwitchOnScreen: + WsSwitchOnScreen(); + break; + + case EDisplayHalMaxDisplayContrast: + { + TInt mc=KMaxDisplayContrast; + kumemput32(a1,&mc,sizeof(mc)); + break; + } + ... + default: + r=KErrNotSupported; + break; + } + ... + }

If the HAL handler function does not deal with +a specific function-id, then it returns KErrNotSupported.

The meaning of the parameters a1 and a2 passed to the HAL handler depends on the group and function-id; +see the list: HAL Groups and Handlers and HAL Attributes and +Function IDs for the more detail.

Dealing with the +HAL::GetAll() function

Calls that come through the HAL::GetAll() function must be dealt with by the HAL handler +implementation in a particular way.

GetAll() calls the HAL handler and passes -1. The HAL handler must return +the HAL attribute value when it is passed a -1 as its parameter unless +the handler requires additional parameters. If the handler expects +more than one parameter then it must return the error code KErrArgument.

For example, using a HAL::Get() request with the attribute EDisplayBrightness returns the brightness for the specified device (screen).

HALArg = 0; +ret = HAL::Get(screen, HAL::EDisplayBrightness, HALArg);

The information cannot be retrieved by the GetAll() function.

When the HAL handler is expecting a value that +specifies a particular mode or setting but receives a -1 the HAL handler +must return the error code KErrArgument to indicate +that an additional parameter was expected.

See >THalImplementation and HAL::GetAll().

+
Context +of the call to the HAL handler

The HAL handler itself is +only called by the kernel, and is the end result of a sequence that +starts either with a call to the user interface functions provided +by the HAL class (HAL::Set(), HAL::Get() or HAL::GetAll()), or with a call to the kernel +side Kern::HalFunction().

The handler runs +on the kernel side in the context of the calling thread with no kernel +mutexes or fast mutexes held; the calling thread is not placed into +a critical section. It is the responsibility of the handler to do +any thread synchronisation required. The handler returns a TInt, which is passed back to the user side, or the caller +of Kern::HalFunction().

+
Platform +security

If you are providing or porting a HAL handler, +you need to be aware of platform security issues. In principle, for +each call into the HAL handler, you need to check the capabilities +of the caller's process.

Recall that function-ids are used to distinguish between the different +requests made on a given HAL handler. Different requests may require +different capabilities, although many requests require no special +capabilities. This means that each function-id is associated with +a capability, and means that code that is dealing with a request associated +with a specific function-id, must check the associated capability.

For example, the screen (i.e. video or LCD) driver must check +that the caller has the ECapabilityWriteDeviceData capability before proceeding with a request to set the device's +backlight on. This is a capability that grants write access to settings +that control the behaviour of the device.

TInt DLcdPowerHandler::HalFunction(TInt aFunction, TAny* a1, TAny* a2) + { + TInt r=KErrNone; + switch(aFunction) + { + ... + case EDisplayHalSetBacklightOn: + if(!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData,__PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetBacklightOn"))) + { + return KErrPermissionDenied; + ) + ... + break; + ... + }

To find the capabilities associated with function-ids, +see the HAL +Attributes and Related Function IDs Tables section. Capabilities +are documented as part of the API reference for each function-id.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-12A4418A-9BC6-4BEB-993D-B55E61240A15.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-12A4418A-9BC6-4BEB-993D-B55E61240A15.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,342 @@ + + + + + +SDIO +Client Interface GuideDescribes how to use the SDIO interface in a device driver. +

This is a generic description of how to use SDIO in a kernel-side device +driver. Specifics differ according to hardware and card function.

+
Socket, stack, +card and function

SDIO is an input/output protocol originally +introduced to enable a device to communicate with SDIO (Secure Digital) cards. +It can also be used as input/output for media such as Bluetooth adapters and +GPS receivers and for input/output within a device (for instance to talk to +an internal bus). These different uses of SDIO are called functions.

Symbian +platform implements SDIO as part of a larger framework involving SD cards, +which are a type of MMC (multimedia) card. For this reason, to use SDIO in +a device driver you will need to use classes representing SD and MMC cards +and the associated communications stack even if you only want the basic I/O +functionality. These classes are:

    +
  • DMMCSocket

  • +
  • DSDIOStack

  • +
  • TSDIOCard

  • +
  • TSDIOFunction

  • +

The work of data transfer is performed by reading to and writing from +registers in response to interrupts, and sometimes the read and write operations +are performed in sessions. The classes used are these:

    +
  • DSDIORegInterface

  • +
  • TSDIOInterrupt

  • +
  • DSDIOSession

  • +

This document illustrates the use of these classes to create a driver, +with example code fragments in which the driver being created is called DSDIODriver.

+
+
Creation and +initialization

The first step in writing a driver using SDIO is +thus to create socket, stack and card objects.

DMMCSocket* iSocket = static_cast<DMMCSocket>DPBusSocket::SocketFromId(KSocketNumber)); + if (NULL == iSocket) + return KErrNoMemory; + + DMMCStack* iStack = static_cast<DSDIOStack*>(iSocket->Stack(KStackNumber)); + if (NULL == iStack) + return KErrNoMemory; + + TSDIOCard* iCard = static_cast<TSDIOCard*>(iStack->CardP(KCardNumber)); + if (NULL == iCard) + return KErrNoMemory; + +
+
Function types

The +functions supported by SDIO are represented by the enumeration TSdioFunctionType which +is declared in the TSdioFunctionCaps class.

enum TSdioFunctionType + { + /** Not an SDIO standard interface */ + ESdioFunctionTypeUnknown = 0, + /** SDIO UART standard interface */ + ESdioFunctionTypeUART = 1, + /** SDIO 'thin' Bluetooth standard interface */ + ESdioFunctionTypeThinBT = 2, + /** SDIO 'complete' Bluetooth standard interface */ + ESdioFunctionTypeFullBT = 3, + /** SDIO GPS standard interface */ + ESdioFunctionTypeGPS = 4, + /** SDIO Camera standard interface */ + ESdioFunctionTypeCamera = 5, + /** SDIO PHS Radio standard interface */ + ESdioFunctionTypePHS = 6, + /** SDIO WLAN standard interface (Introduced in SDIO Rev. 1.10f) */ + ESdioFunctionTypeWLAN = 7, + /** Extended SDIO standard interface (Introduced in SDIO Rev. 1.10f) */ + ESdioFunctionTypeExtended = 15, + }; +
+
Kernel polling

Kernel +polling means the use of the Kern::PollingWait() function +of the kernel to call a function repeatedly if it is likely to fail on a first +try. You specify the number of attempts and the delay between them as parameters. +It is a recommended technique in writing kernel drivers and is used more than +once in the example code in this document.

+
Initialization

To +initialize the card you must power it up and test whether it is ready for +use. The following code uses kernel polling to perform the test 10 times at +100 millisecond intervals.

… + iSocket->PowerUp(); + Kern::PollingWait(CardReady, iCard, 100, 10); + + if (!iCard->IsReady()) + return(KErrNotReady); + … + + +TBool DSDIODriver::CardReady(TAny* aSelfP) + { + TSDIOCard& card = *(TSDIOCard*)aSelfP; + return card.IsReady(); + } +

You may also want to test that the card is an SDIO card.

if (!pCard->IsIOCard()) + return KErrNotReady; +

Next you locate and enable the function of the card (Bluetooth, +UART etc.) which you want to use. A function has a location which differs +from card to card and which is stored in a data structure called the CIS (Card +Information Structure. To use a card's CIS you load it using the CheckCis() function +of the TSDIOCard class.

TInt err = iCard->CheckCIS(); + if (KErrNone != err) + return err; +

The following code is a simple test to determine whether the +passed in function type is present on the card.

TSDIOFunction* DSdioDriver::FindFunction(TSdioFunctionType aFunctionType) + { + // We are going to try to match the function type + TUint32 capsMatchMask = TSDIOFunctionCaps::EFunctionType; + + // Create the caps specification for a BT function + TSDIOFunctionCaps functionCaps; + functionCaps.iType = aFunctionType; + + // Request to find the function on the card + TSDIOFunction* pFunction = iCard->FindFunction(functionCaps, capsMatchMask); + + // If the function cannot be found, pFunction will be NULL + + return pFunction; + } +

Once you have the location of a function, you register the +client driver with the stack and enable the function on the card.

TInt err = iFunction->RegisterClient(this); + if (err != KErrNone) + { + return err; + } + + // Enable the function + err = iFunction->Enable(ETrue); + + if (KErrNone == err) + { + Kern::PollingWait(FunctionReady, this, 100, 10); + } + + TBool isReady = EFalse; + iFunction->IsReady(isReady); + If (!isReady) + return KErrNotReady; + … + + +TBool DSdioDriver::FunctionReady(TAny* aSelfP) + { + TSDIOFunction* pFunction = (TSDIOFunction*)aSelfP; + TBool isReady = EFalse; + pFunction->IsReady(isReady); + return isReady; + } +
+
Transferring +data: registers and shared chunks

SDIO cards place data to be read +or written in a register whose address depends on the function and is defined +in the relevant specification available at www.sdcard.org. Registers are also used to send commands +to the card and to enable or disable interrupts. You access the register for +a function using the DSDIORegisterInterface class which +is obtained from the function pointer like this.

// Get the register interface + DSDIORegisterInterface* pRegIfc = iFunction->RegisterInterface(this); +

Data can be transferred.

    +
  • as individual bytes,

  • +
  • as the contents of byte buffers (both directly and using shared chunks), +and

  • +
  • by setting bits in the register.

  • +

The following code uses the Read8() and Write8() functions +of the DSDIORegisterInterface class to read and write a +single byte from and to the card function. You typically set registers on +the card and enable interrupts by this method.

TUint8 readVal = 0; + TInt ret = pRegIfc->Read8(KReadRegister, &readVal); + if (KErrNone != ret) + return ret; + + TUint8 writeVal = readVal + 1; + ret = pRegIfc->Write8(KWriteRegister, writeVal); + if (KErrNone != ret) + return ret; +

This code demonstrates the use of the ReadMultiple8() and WriteMultiple8() functions +to read to and write from byte buffers.

TUint8 client[6]; + memcpy(client, “client”, 6); + TInt ret = pRegIfc->WriteMultiple8(KWriteRegister, client, 6); + if (KErrNone != ret) + return ret; + + TUint8 server[6]; + ret = pRegIfc->ReadMultiple8(KReadRegister, server, 6); + if (KErrNone != ret) + return ret; + + if (memcmp(server, “server”) != 0) + return KErrNotFound; +

When large amounts of data are being transferred it is good +practice to use a shared chunk. You call the same functions as before with +the chunk as additional argument. The following example writes 1024 bytes +with an offset of zero and reads 1024 bytes with an offset of 1024.

TInt ret = pRegIfc->WriteMultiple8(KWriteRegister, chunk, 0, 1024); + if (KErrNone != ret) + return ret; + + ret = pRegIfc->ReadMultiple8(KReadRegister, chunk, 1024, 1024); + if (KErrNone != ret) + return ret; +

The advantages of shared chunks are that they can be used from +user space and reduce copying overhead.

The following code example shows +how to set and clear bits in a register using the Modify8() function +of the DSDIORegisterInterface class

TUint8 setBits = 0x80; + TUint8 clearBis = 0x02; + + ret = pRegIfc->Modify8(KModifyRegister, setBits, clearBits); + if (KErrNone != ret) + return ret; +

Another advantage of shared chunks is that they make it possible +to send commands to the card while a multibyte data transfer is taking place. +Not all cards support this functionality: you can check whether a particular +card does so by reading the SDC bit in the Card Capability register. To do +this, you need to create a second register interface to write the commands +in the form of one byte transfers. This second interface (or 'second session') +must run in a different thread from the interface performing the multibyte +transfer and it is created in a different way, as in this code:

// Create a second session + DSDIORegisterInterface* interfaceP = new DSDIORegisterInterface(cardP, functionP->FunctionNumber()); + + // Using the second interface run a direct command + TUint8 readVal = 0; + ret = interfaceP->Read8(KReadRegister, &readVal); + + … +
+
Controlling +data transfer: interrupts

Cards generate interrupts which control +the process of data transfer: for instance the arrival of data on the function +of a card generates an interrupt which serves as a signal that a read operation +should take place. The are two levels of interrupts. A card level interrupt +indicates which function has triggered it and a separate function level interrupt +gives information specific to that function which is covered in the documentation +for a particular card.

You must provide ISRs (interrupt service routines) +to handle interrupts. ISRs typically queue DFCs to perform the required actions +such as read and write operations on the card since ISRs must complete very +quickly to maintain real-time guarantees whereas data transfer can wait for +the current time slice to complete. The exact functionality of the DFCs will +vary depending on the nature of the function and the hardware. Two things +you must do in any driver implementation are enabling and disabling interrupts +and binding the ISRs to the stack. Also, when an interrupt is triggered you +must read the interrupt register to make sure that the interrupt is applicable +and then clear the function level interrupt and re-enable interrupts.

You +enable card level interrupts as in this example code:

// Enable SDIO card interrupt + iFunction->Interrupt().Enable(); + + // Disable SDIO card interrupt + iFunction->Interrupt().Disable(); +

How you enable function level interrupts is described in the +documentation for a particular card.

You bind ISRs to the stack as in +the following code fragment.

… + // Bind to interrupt + err = iFunction->Interrupt().Bind(DSDIODriver::Isr, this); + if (KErrNone != err) + return err; + + … + +void DSDIODriver::Isr(TAny* aParam) + { + DSDIODriver* pDriver = (DSDIODriver*)aParam; + … + } +
+
Notifications +and powering down: callbacks

Register callbacks to be notified of +events. This mechanism is standard for handling the removal of a card and +powering down.

The SDIO stack can notify clients of events they must +react to such as power down or the removal of the card. Events of this kind +are listed in the enumeration TSDIOFunctionCallbackReason.

enum TSDIOFunctionCallbackReason + { + /** Card has powered up */ + ESdioNotifyPowerUp = 0, + /** Card requests to power down */ + ESdioNotifyPowerDownPending = 1, + /** Card has powered down */ + ESdioNotifyPowerDown = 2, + /** Request to enter sleep mode */ + ESdioNotifyPowerSleep = 3, + /** Emergency power down */ + ESdioNotifyEmergencyPowerDown = 4, + /** PSU fault */ + ESdioNotifyPsuFault = 5, + /** Card has been removed */ + ESdioNotifyCardRemoved = 6, + /** Card has been inserted */ + ESdioNotifyCardInserted = 7, + }; +

You respond to notifications with callback functions which +you write to provide appropriate functionality. Use the callback to initialize +a TSDIOFunctionCallback object and then register that object +with the socket. The following code uses an example callback FnCallback() and +object functionCallback.

TSDIOFunctionCallback functionCallback(DSDIODriver::FnCallback, this); + + // Register the callback + functionCallback.Register(iSocket); + … + +TInt DSDIODriver::FnCallback(TAny* aParam, TSDIOFunctionCallbackReason aReason) + { + DSDIODriver* pDriver = (DSDIODriver*)aParam; + + switch(aReason) + { + case ESdioNotifyCardRemoved: + … + break; + } + … + } +

You typically use notifications and callbacks to perform cleanup +before a pending power down event. The socket class has functions to postpone +power down at the start of cleanup and to resume power down when cleanup is +finished. They are used like this.

iSocket->RequestAsyncPowerDown(); + +/* cleanup code here */ + iSocket->PowerDownComplete();
+
TutorialsThe +classes and commands used to create a device driver are discussed further +in the tutorials.
    +
  • DSDIOREGInterface +Class Tutorial

  • +
  • DSDIOSession +Class Tutorial

  • +
  • DSDIOStack Class +Tutorial

  • +
  • TSDIOCard Class +Tutorial

  • +
  • TSDIOFunction +Class Tutorial

  • +
  • TSDIOInterrupt +Class Tutorial

  • +
  • SDIO Commands +Tutorial

  • +

A reference implementation using Bluetooth is described in SDIO +BT Example.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-12CD8E91-4102-5253-A7DE-E5436028764F-master.png Binary file Adaptation/GUID-12CD8E91-4102-5253-A7DE-E5436028764F-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-12CD8E91-4102-5253-A7DE-E5436028764F_d0e18431_href.png Binary file Adaptation/GUID-12CD8E91-4102-5253-A7DE-E5436028764F_d0e18431_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-12EFB295-C527-5F96-81F1-6021D335D865.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-12EFB295-C527-5F96-81F1-6021D335D865.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,57 @@ + + + + + +Thread +TerminationThis topic describes how and in what conditions to kill a kernel +side thread. +

The only way to kill a kernel side thread is for code running in that thread +to call Kern::Exit().

+

A kernel side thread can kill itself, but cannot kill any other kernel +side thread. This avoids the overhead of critical sections. Remember that +a kernel side thread can kill a user side thread.

+

In practice, device drivers will create threads that can run queued DFCs +(Deferred Function Calls) only if they choose not to use the two supplied +DFC threads, known as DFC thread 0 and DFC thread 1.

+
How to kill a thread running queued DFCs

In principle +the only way to kill a thread that runs queued DFCs is to schedule a DFC that +simply calls Kern::Exit(). The DFC should have priority +0 (the lowest). We refer to this as a 'kill' DFC.

In practice you +create a 'kill' DFC by creating a TDfc object, and then +make the DFC's callback function include a call to Kern::Exit(). +You then queue the DFC onto the DFC queue, a TDfcQue object, +from the destructor of the logical device driver's factory class, i.e. the +destructor of the class derived from DLogicalDevice.

+
Issues to be aware of
    +
  1. You need to make sure +that no other DFCs are on that DFC queue at the time that the 'kill' DFC runs +as there is no automatic cleanup.

    Perform cleanup by calling Cancel() (i.e. TDfc::Cancel()) +on all queued DFCs.

  2. +
  3. You need to make sure +that the DFC queue object, i.e. the TDfcQue object, and +the 'kill' DFC object, i.e. the TDfc object, are not destroyed +before the 'kill' DFC has a chance to run.

    You can do this by making +both the DFC queue object and the 'kill' DFC object static objects within +the driver. The device driver will only be unloaded from RAM by the null thread. +By queuing the 'kill' DFC on the DFC thread, you mark it ready-to-run, which +means that your 'kill' DFC will run before the driver is unloaded and before +the DFC queue object and the 'kill' DFC object vanish.

  4. +
  5. You need to make sure +that any code queued to run on your DFC thread never hangs.

    The important +point is that Kern::Exit() can only be used by the thread +itself, but if the thread hangs, then it can execute nothing. This means that +kernel side threads must be written very carefully so they cannot hang. Any +defect in kernel side code is likely to be fatal.

    It may be that you +have to consider writing defensive style code; for example, if your thread +is waiting for an event, you could consider using a timer to wake it up in +case the expected event never happens. Alternatively, you could consider moving +some processing to the user side.

  6. +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-132349A6-9A5F-4866-A54D-F01B6F58ABDD.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-132349A6-9A5F-4866-A54D-F01B6F58ABDD.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,41 @@ + + + + + +Shared +ChunksThis document describes the use of shared chunks to share data. +
Shared +chunks

Device drivers often need to share data between user +space and kernel space threads. Though there are APIs for doing this, such +as Kern::ThreadRawRead() and Kern::ThreadRawWrite(), +these involve an overhead of a memory copy, which can be a problem when there +is a large amount of data.

To avoid unnecessary data transfer, Symbian +platform provides shared chunks, which are similar to shared memory in other +operating systems. Shared chunks can be created and used by both a driver +and user-side code directly. An example application for shared chunks is for +a camera driver. Without shared chunks, the image data would have to be copied +from the camera driver to the user process, which would then copy it to the +display driver. This would have a high memory copy overhead. Using shared +chunks instead would improve the performance of the camera view finder.

A +shared chunk is created and controlled by the kernel side code, for example, +the device driver, rather than the user code. This memory is safe to be used +by ISRs and DMA. A shared chunk can be mapped into multiple user processes +in sequence or at the same time. The memory object can be transferred between +another process and another device driver. Multiple drivers and multiple user +processes can have access to the same shared chunk.

+
Comparison +between shared memory and shared I/O buffers

The EKA1 versions of +Symbian platform had a mechanism called shared I/O buffers. These are now +deprecated, and shared chunks should be used instead. The disadvantage of +a shared I/O buffer is that only one user process can access the chunk at +a time, and that it does not have a user handle: the user process is only +supplied with the address and size of the buffer. Shared chunks solve these +issues, and give more flexibility for users to do safe operations.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-13664BB9-7D05-594E-95D4-49C0D31D3734-master.png Binary file Adaptation/GUID-13664BB9-7D05-594E-95D4-49C0D31D3734-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-13664BB9-7D05-594E-95D4-49C0D31D3734_d0e18989_href.png Binary file Adaptation/GUID-13664BB9-7D05-594E-95D4-49C0D31D3734_d0e18989_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-1391CDCC-9A09-54FB-BA7D-BC7A91DB2351.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-1391CDCC-9A09-54FB-BA7D-BC7A91DB2351.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,40 @@ + + + + + +Writable Data Paging (WDP) Tutorial OverviewCollection of the tutorials related to writable data paging. + + The following group of tutorials go through the stages required +to produce a ROM image that can implement writable data paging and +are in the order of the top tutorial downwards: +Configuration +Tutorial +MMP +Tutorial +OBY +Tutorial +Building +ROM Tutorial + + +The next group of tutorials relate to producing device drivers +that are compatible with writable data paging: +Device +Driver Writing and Migration Technology Tutorial +Media +Driver Migration Guide + + + The final group of tutorials relates to other issues that should +be considered when working with writable data paging: +Preventing +And Recovering From Thrashing Tutorial + + \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-142C21E1-2629-5215-9FBD-B507436E17DB.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-142C21E1-2629-5215-9FBD-B507436E17DB.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,20 @@ + + + + + +Port +Implementation TutorialThis section describes the steps to implement a port of +the USB client controller. +

This guide uses the port for the template board as +an example. Other porting example code is also available.

+
+Concepts + +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-1499E635-B6E3-51A0-AE38-ADF99FF86CD6.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-1499E635-B6E3-51A0-AE38-ADF99FF86CD6.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,59 @@ + + + + + +Sound +Driver LDD OverviewDescribes the sound driver LDD part of the sound driver framework. +
Purpose

The sound driver provides the conduit by +which Symbian platform can access the audio hardware and hence create sounds: +for example multi-media applications and ring tones.

+
Required background

Since audio hardware is rather +complex, the reader of this document needs to know what is meant by:

    +
  • Audio channels

  • +
  • Codec

  • +
+
Key concepts and terms
+ +
Codec
+

Stands for COmpressor-DECompressor and refers to the algorithm used +to compress and decompress the audio data stream.

+
+
+
Architecture

The LDD for the sound driver sits +below the RBusLogicalChannel and the RSoundSc classes.

The +communication between the driver and the application on the user-side is handled +by class RSoundSc.

+
APIs + + + +API +Description + + + + +

DSoundScLdd

+

Defines each logical channel. One instance of this class is created +for each driver channel opened.

+
+ + +
+
Typical uses

The sound driver is used whenever +audio operations are required: for example MP3 player, having a phone call +and ring tones.

    +
  • MP3 player

  • +
  • Multi-media

  • +
+
+Sound Driver +Technology +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-14B65BE7-A166-48B6-B43D-DFF267F87F9E-master.png Binary file Adaptation/GUID-14B65BE7-A166-48B6-B43D-DFF267F87F9E-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-14B65BE7-A166-48B6-B43D-DFF267F87F9E_d0e433_href.png Binary file Adaptation/GUID-14B65BE7-A166-48B6-B43D-DFF267F87F9E_d0e433_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-159BDA2E-123C-52DF-9F8B-E058379EBFB8.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-159BDA2E-123C-52DF-9F8B-E058379EBFB8.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,23 @@ + + + + + +Interrupt::SetPriority()The interrupt architecture supports the concept of adjustable +interrupt priorities. +

The Interrupt::SetPriority() function can be +used to implement adjustable interrupt priorities.

+

The function takes the Interrupt ID to identify the interrupt source, and a TInt value specifying the priority value. The meaning of +the priority value is hardware and implementation dependent and is +defined by the port.

+

At its simplest, the function could be used to decide whether interrupts +generate an IRQ or FIQ at the ARM. For hardware that supports interrupt +priority in hardware, priorities can be modified through this function. +If priority adjustment is not supported, or will not be implemented, Interrupt::SetPriority() should just return KErrNotSupported.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-15FDDEED-89F1-5BE5-97AD-8DFD3640369A.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-15FDDEED-89F1-5BE5-97AD-8DFD3640369A.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,101 @@ + + + + + +Playback +operationDescribes the operation of the Sound Driver for sound playback. +
Normal operation

The client calls RSoundSc::PlayData() to +issue an audio request.

The LDD breaks the audio request into manageable +fragments and transfers them to the PDD by calling DSoundScPdd::TransferData().

When +the PDD has transmitted the fragment it calls DSoundScLdd::PlayCallback() to +signal to the LDD that it has finished transfer of a fragment. When the client +request has been completed, the LDD calls DSoundScPdd::StopTransfer() to +stop the PDD transmitting data and to release any transfer specific resources.

To +ensure uninterrupted playback, a client must have multiple play requests pending +on the driver. As soon as one request completes, the client issues a further +request until the end of the track. Typically, a client issues a series of +calls to RSoundSc::PlayData() to play an audio track.

Each RSoundSc::PlayData() request +is handled in the context of the driver's Deferred Function Call (DFC) thread. +Assuming that the driver is not already in the process of playing data when +the first request is received, the LDD checks whether the client has specified +or supplied a shared +chunk to the Driver +channel and also whether the audio configuration and volume have both +been set. If the chunk configuration has not been specified, then the driver +cannot proceed and returns KErrNotReady. However, if the +audio configuration or volume has not been specified, then the LDD simply +applies default settings to the audio hardware device. These values are returned +by the PDD functions DSoundScPdd::SetConfig() and DSoundScPdd::SetVolume() when +called by the LDD.

The LDD may need to break the play request down +into fragments to support the maximum amount of data that the PDD can handle +in a single transfer. The function DSoundScPdd::MaxTransferLen() returns +this maximum value. The LDD queues as many transfer fragments on the PDD as +it can accept with a call to DSoundScPdd::TransferData() for +each fragment.

To support uninterrupted transfer of audio data, the +PDD must be able to accept at least two transfer fragments simultaneously: +the first being actively transferred by the audio hardware device, the other +being queued for transfer on the same device. Therefore, as long as the LDD +has transfer fragments still to queue, it continues to call DSoundScPdd::TransferData() on +the PDD until this signals that it has temporarily reached its capacity, by +returning KErrNotReady.

If the PDD accepts all the +fragments for this initial play request then the LDD moves on to process the +subsequent requests from the client. These are also fragmented until either +the PDD reaches its capacity or all pending play requests are queued.

Each +time the PDD completes the transfer of a fragment from a play buffer, it must +signal this event back to the LDD by calling the function DSoundScLdd::PlayCallback(). +This must always be called in the context of the driver DFC thread so there +are no synchronisation problems. For example, where transfer completion interrupts +the processing of new play requests from the client.

In executing DSoundScLdd::PlayCallback(), +the LDD checks whether the entire transfer for the current request is now +complete. If so, it signals completion back to the client. Also within the DSoundScLdd::PlayCallback() function, +the LDD will attempt to queue further fragments on the PDD, by calling DSoundScPdd::TransferData(), +as the PDD should now have the capability to accept more transfers. The PDD +must be written to handle calls to DSoundScPdd::TransferData() within +its callback to DSoundScLdd::PlayCallBack().

If, +on completing a request from the client, the LDD discovers that there are +no further play requests pending from the client, then this is treated as +an underflow situation and KErrUnderflow is returned to the +client. If however, the client specified KSndFlagLastSample as +the aFlag argument of the RSoundSc::PlayData() function +then an underflow is expected after this request completes.

When the +audio request has been completed the LDD calls DSoundScPdd::StopTransfer() on +the PDD. This allows the PDD to release any resources necessary for transfer.

+
Pausing and resuming audio playback

The client +may temporarily halt the progress of audio playback at any time by issuing DSoundScLdd::Pause(). +In order to configure the audio hardware device to halt playback, the LDD +calls DSoundScPdd::PauseTransfer() on the PDD. Ideally, +playback should be suspended in such a way that it can be resumed later, starting +from next sample following the one last played.

The client +requests resumption of playback by calling DSoundScLdd::Resume() on +the LDD. The LDD, in turn tells the PDD to re-commence playback by calling DSoundScPdd::ResumeTransfer()

Since +access to the hardware is required in both cases, pause and resume are handled +in the context of the driver DFC thread.

+
Error handling during playback

If the PDD reports +an error when setting up the audio device for playback then the LDD immediately +completes the first play request back to the client returning the error value +as the result. For example, if the PDD returns a value other than KErrNone from +a call to the function DSoundScPdd::StartTransfer(). The +LDD attempts to re-start playback data transfer when it processes any further +play requests from the client.

If the PDD reports an error when commencing +transfer or as the result of the transfer of a playback fragment, then the +LDD ceases transfer of the associated request and instead immediately completes +the request back to the client returning the error value as the result.

Unexpected +errors from the PDD are returned to the LDD via the functions DSoundScPdd::TransferData() and DSoundScLdd::PlayCallback(). The DSoundScPdd::TransferData() function signals that +an error has occurred when setting up the transfer of a playback fragment +by returning an error value other than KErrNone or KErrNotReady. +The DSoundScLdd::PlayCallback() function called by the +PDD at the end of a transfer, signals an error to the LDD if the value passed +is not equal to KErrNone.

The LDD does not cancel +the transfer of other fragments for the same request which are already queued +on the PDD, but it ignores their outcome. However, the LDD does try to carry +on with the transfer of subsequent play requests queued by the client.

In +any of the above situations, the client may choose to terminate playback operation +by cancelling all outstanding play requests when it detects a playback error.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-16423056-C435-5C4D-BE3D-4A15F95F7F68.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-16423056-C435-5C4D-BE3D-4A15F95F7F68.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,113 @@ + + + + + +Configuration +Tutorial Describes the steps required in producing a ROM that will work +with Writable Data Paging (WDP). +

Writable Data Paging +(WDP) allows allocated memory that is to be written e.g. stacks and heaps +to be paged in and out of the RAM pool.

+ + +It is recommended to enable WDP kerneltrace warnings if the build is +being migrated to a data paged system. +This is done by setting trace bit number 60 of the kernel trace flags. +The UDEB version of the build has to be used in order for tracing messages +to be available. +Once the demand paging build is stable, then the REL version of the +build can be used. + + +Set the paging policy for pages of the core ROM image. This is done +by using the datapagingpolicy and pagingpolicy keywords in the 'ROM_IMAGE[0] +{}' block. + + +Next, the data paging for ROFS images is enabled by using datapagingoverride +and pagingoverride keywords for each ROFS partition that contains executables +that should use data paging. This is done by adding the keywords into each +relevant 'ROM_IMAGE[<partion>] {}' block. + + +In order for a ROM to support data paging, it has to have a media driver +that supports data paging. + + +

The output of this +tutorial will be a configuration that allows the ROM build to use demand paging.

This +tutorial only describes how to configure the general paging behaviour.

+Example OBY +configuration file

Below is a typical OBY file that uses data paging, +XIP ROM and code paging:

// MyDPConfig.oby +// +// The section below is used to specify if XIP ROM paging is to be implemented. +#if !defined PAGED_ROM +#define PAGED_ROM +#endif + +// The section below is used when code paging is to be implemented. +#if !defined USE_CODE_PAGING +// Comment out the next line if code paging is wanted +#define USE_CODE_PAGING +#endif + +#if !defined CODE_PAGING_FROM_ROFS +// Comment out the next line if code paging from primary rofs is wanted +#define CODE_PAGING_FROM_ROFS +#endif + +// The section below is used to configure the RAM pages for writable data paging. +ROM_IMAGE[0] { +pagedrom +compress +// Min Max Young/Old +// Live Live Page +// Pages Pages Ratio +demandpagingconfig 256 512 3 +pagingoverride defaultpaged + +// The section below specifies if the default paging policy is to used. +#if defined USE_CODE_PAGING && !defined USE_DATA_PAGING +codepagingpolicy defaultpaged +#endif + +#if defined USE_DATA_PAGING +#if defined USE_CODE_PAGING +codepagingpolicy defaultpaged +#endif + +datapagingpolicy defaultpaged +#endif +} + +#if defined CODE_PAGING_FROM_ROFS || defined USE_DATA_PAGING +ROM_IMAGE[1] { +pagingoverride defaultpaged +} +#endif +

The OBY file that determined the start of the primary ROFS +partition, for example base.iby, would then be adjusted thus:

+#if defined(_NAND) || defined(_NAND2) +#if !defined PAGED_ROM || defined CODE_PAGING_FROM_ROFS || defined USE_DATA_PAGING +REM Start of ROFS image +ROM_IMAGE[1] { +#endif +#endif

Make sure to include media drivers that can +support writable data paging.

+

This tutorial only +covers the configuration of the general demand paging parameters. To see how +to make individual executables pageable see (the +mmp configuration tutorial).

The next step is to build +the writable data paging ROM

+
+Building +ROM tutorial +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-178E140F-BB15-5A82-99A6-D1BC0E11E018.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-178E140F-BB15-5A82-99A6-D1BC0E11E018.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,111 @@ + + + + + +Kernel-side +MessagesKernel-side messages are a means of communication between Symbian +platform threads executing kernel-side code. +

Typically, they are used by device drivers to communicate between a client +thread, usually a user thread, and a kernel thread running the actual device +driver code.

+

The mechanism consists of a message, containing data, and a queue that +is associated with a DFC. The DFC runs in order to deal with each message.

+

A kernel-side message is represented by a TMessageBase object, +that allows a single 32-bit argument to be passed, and a single 32-bit return +value. In general, more arguments can be passed by deriving classes from TMessageBase. +In practice, each Symbian platform thread has a TThreadMessage object +embedded within it. TThreadMessage is derived from TMessageBase, +and contains space for 10 extra 32-bit arguments. These objects are used for +communication with device driver threads.

+

Both TMessageBase and TThreadMessage are +defined in ...\kernel\kernel.h, which is exported to epoc32\include\kernel.

+ +Message threads and queues + + +

SDblQueLink is simply an object that allows a message +to be linked to another in the form of a doubly-linked list.

+

The message queue is represented by a TMessageQue object, +which consists of a DFC plus a doubly-linked list of received messages. The +DFC is attached to the receiving thread’s DFC queue and it runs whenever a +message becomes available for processing.

+

TMessageQue is defined in ...include\kernel\kernel.h, +which is exported to epoc32\include\kernel; SDblQueLink is +defined in ...\nkern\nklib.h, which is exported to epoc32\include\nkern.

+

The following shows, in simple terms, the relationship between messages +and the message queues:

+ +Relationship between messages and message queues + + +

When a message is sent to the queue, either:

+
    +
  • the message is accepted +immediately, and the receiving thread’s DFC runs. This will happen if the +message queue is ready to receive, which will be the case if the message queue +is empty and the receiving thread has requested the next message.

  • +
+

or

+
    +
  • the message is placed +on the delivered message queue, and the DFC does not run. This will happen +if there are other messages queued ahead of this one or if the receiving thread +has not (yet) requested another message.

  • +
+

A kernel-side message may be in one of three states at any time:

+
    +
  • FREE - represented by +the TMessageBase::EFree enum value. This indicates that +the message is not currently in use.

  • +
  • DELIVERED - represented +by the TMessageBase::EDelivered enum value. This indicates +that the message is attached to a message queue but is not currently in use +by the receiving thread. It may be removed from the queue and discarded with +no ill effects on the receiving thread. The client thread pointer may not +be used while the message is in this state.

  • +
  • ACCEPTED - represented +by the TMessageBase::EAccepted enum value. This indicates +that the message is not attached to a message queue but is currently in use +by the receiving thread. The message may not be discarded.

  • +
+

Transitions between these states, including adding the message to, and +removing the message from a message queue, occur under the protection of the +global TMessageQue::MsgLock fast mutex. The use of a mutex +is necessary to avoid queue corruption, for example, when multiple threads +are sending messages to the same message queue at the same time. The use of +a fast mutex means that message passing operations may only be invoked from +a thread context.

+

Kernel-side messages may be sent either synchronously or asynchronously. +Each TMessageBase object contains an NFastSemaphore on +which the sending thread will wait after sending a synchronous message. The +semaphore is signalled by the receiving thread after the message has been +processed and the completion code has been written in. The sending thread +is then released and picks up the return code. The NFastSemaphore also +contains a pointer to the sending NThread; this serves +to identify the sending thread and is therefore set up for both synchronous +and asynchronous message send. Note that this pointer is reference counted +- the access count of the originating DThread is incremented +when the message is sent. This prevents the sending DThread object +disappearing if the thread terminates unexpectedly. When the message is completed +the extra access is removed asynchronously - the thread completing the message +will not need to delete the DThread itself. This is done +to avoid unpredictable execution times for message completion. Also note that +even messages sent asynchronously must be completed; this is required to set +the message state back to FREE and to remove the access count from the sending +thread.

+

The TThreadMessage objects embedded in Symbian platform +thread control blocks, DThread objects, are always sent +synchronously - this ensures that one message per thread will always suffice. +In addition, these messages are cancelled if the corresponding thread terminates. +Cancelling an ACCEPTED message has no effect, but cancelling a DELIVERED message +will remove the message from the queue and also remove the access count held +by the message on the sending thread. Hence the sending thread pointer should +only be used by the receiving thread if the message is in the ACCEPTED state.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-180973A1-5C0A-5A85-82CC-E6B739A7F207.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-180973A1-5C0A-5A85-82CC-E6B739A7F207.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,177 @@ + + + + + +Platform +Specific Layer ValidationDescribes the test code to validate a port of the MMC Controller. +

There are three stages involved in testing a port of the MultiMediaCard +controller. The first stage tests the controller in isolation; subsequent +stages test an additional area of functionality.

+

All three stages involve text shell based test programs and test drivers, +and therefore these tests can be run by just building a text shell ROM. You +can also run tests on the Emulator.

+
Testing the +controller in isolation

MMCTEST.EXE tests +the MultiMediaCard controller in isolation, at the controller’s client interface +level. Since the controller’s client API is a kernel side interface, this +requires a test driver, D_MMCIF.LDD, as well as the test +program itself.

This is not a 'go/no-go' type test, but is a test +utility that can perform a small variety of operations. These are selected +a simple interactive way by pressing appropriate keys.

+ + + +

Building MMCTEST.EXE and D_MMCIF.LDD

+

The source and header files needed to build MMCTEST.EXE can +be found in ...\e32utils\pccd; the mmp file is ...\e32utils\group\mmctest.mmp.

The +source and header files needed to build the test driver D_MMCIF.LDD can +be found in ...\e32utils\pccd; the mmp file is ...\e32utils\group\d_mmcif.mmp.

You +need to build MMCTEST.EXE for the appropriate CPU target +architecture (e.g. ARMI,THUMB etc.); you need to build D_MMCIF.LDD for +the appropriate platform (e.g. MINT).

Include both of these components +in a ROM

+
+ +

Running the tests

+

Run MMCTEST and perform the following suggested sequence:

    +
  • Without a card inserted, +power up the stack by pressing P, and check that it +reports that no card is present.

  • +
  • Insert a card, power +it up, and check that it reports that a card is present.

  • +
  • Now that the card is +powered up, read the card info by pressing C, and check +the data returned about the card against the expected card data, by referring +to the datasheet for the card.

  • +
  • Read the first sector +of the card by pressing M.

  • +
  • Now read a few more +sectors by pressing the space bar.

  • +
  • Test writing to a sector: +while still viewing a sector, edit a part of this, by using the direction +keys and typing in a hex number. Now save the change by pressing ESC, +followed by Y. Now navigate to the same sector again +and check that it displays the new contents of the sector.

  • +
  • Quit the test by pressing Q.

  • +
+
+ + +
+
Testing the +controller with the media driver and the local media sub-system
    +
  1. DRVTEST.EXE tests +the MultiMediaCard controller in conjunction with the media driver and the +local media sub-system, in effect accessing the card as a local drive. This +requires a kernel side test driver D_DRVIF.LDD as well +as the test program itself.

    This is not a 'go/no-go' type test, but +is a test utility that can perform a small variety of operations. These are +selected a simple interactive way by pressing appropriate keys. It is used +to test that card initialization and single block read and write requests +are performed successfully.

  2. +
  3. T_ATADRV.EXE tests +that card initialization and simple read and write requests succeed. It also +tests multi-block read/write operations, format requests, accessing the device +following a media change event, and a machine power down event.

    This +is a 'go/no-go' type test. If this test succeeds, you can have fairly high +confidence that the F32 test suite will run successfully.

  4. +
+ + + +

Building DRVTEST.EXE, D_DRVIF.LDD, +and T_ATADRV.EXE

+

The source and header files needed to build DRVTEST.EXE can +be found in ...\e32utils\pccd; the mmp file is ...\e32utils\group\drvtest.mmp.

The +source and header files needed to build the test driver D_DRVIF.LDD can +be found in ...\e32utils\pccd; the mmp file is ...\e32utils\group\d_drvif.mmp.

The +source and header files needed to build T_ATADRV.EXE can +be found in ...\e32test\pccd; the mmp file is ...\e32test\group\t_atadrv.mmp.

You +need to build DRVTEST.EXE for the appropriate CPU target +architecture (e.g. ARMI,THUMB etc.)

You need to build D_DRVIF.LDD for +the appropriate platform (e.g. MINT)

You need to build T_ATADRV for +the appropriate CPU target architecture (e.g. ARMI,THUMB).

Include +these components in a ROM.

+
+ +

Running the DRVTEST test

+

Run DRVTEST and perform the following suggested sequence:

    +
  • Without a card inserted, +power up the stack by pressing P, and check that it +reports that no card is present.

  • +
  • Insert a card, power +it up, and check that it reports that a card is present.

  • +
  • Now that the card is +powered up, read the card info by pressing C, and check +the data returned about the card against the expected card data, by referring +to the datasheet for the card.

  • +
  • Read the first sector +of the card by pressing M.

  • +
  • Now read a few more +sectors by pressing the space bar.

  • +
  • Test writing to a sector: +while still viewing a sector, edit a part of this, by using the direction +keys and typing in a hex number. Now save the change by pressing ESC, +followed by Y. Now navigate to the same sector again +and check that it displays the new contents of the sector.

  • +
  • Quit the test by pressing Q.

  • +
+
+ +

Running the T_ATADRV test

+

Run T_ATADRV and follow the on-screen instructions. Check that the +test runs to the end with no errors.

+
+ + +
+
Testing using +the F32 test suite

The final test stage is to run the entire file +server test suite on a card drive.

To perform these tests:

    +
  • build a text shell ROM +that contains the F32 test suite, i.e. build the ROM with the option:

    -t=f32tests
  • +
  • boot the test machine +into the text shell.

  • +
  • launch the F32 automatic +tests and check that all of the tests run without error. Use the command option +"-d" to set the default drive, for example:

    RUNTESTS F32TEST.AUTO.ARMI.BAT -d d
  • +
+
Emulator-based +tests

It is possible to emulate a user opening and closing the +MMC drive door, replacing and removing the MMC card, and assigning a password +to an emulated MMC card. This is important so that you can test:

    +
  • how an application behaves +when the MMC card, from which the application is running, is removed and/or +swapped

  • +
  • how an application behaves +when it is reading and writing data to and from an MMC card

  • +
  • that data stored on +an MMC card is not lost or corrupted during MMC drive events

  • +
  • that MMC card locking +and password notification works correctly.

  • +

The platform independent layer of the MuiltiMediaCard controller, +as its name implies, is common to all platforms, including the emulator. However, +the emulator provides its own implementation of the platform specific layer.

The +emulator does not provide access to any kind of MultiMediaCard hardware. Instead, +the memory area of each emulated card is represented by a file, a .bin type +file in the Windows system temp directory, on the host +machine. The MultiMediaCard emulator emulates a single stack containing two +separate cards, the first in slot 0, and the second in slot 1. Each emulated +card has an associated .bin file on the host machine. +As the emulator only supports the swapping of cards in slot 0, there are two .bin files, +one for each of the two emulated MMC cards in slot 0. There is no support +for card swapping on slot 1, and therefore this has only one .bin file.

This +means that all the test programs described can be run on the emulator, and +they will exercise the platform independent layer code in the same way as +on real target hardware. It also means that call entries to, and exits from +platform specific layer code can be traced, and may be useful for debugging +problems on real hardware, and to help understand how the controller operates.

The +code for the emulator specific layer code can be found in ...\wins\specific\mmc.cpp.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-18DD4FE5-6641-5A0E-A00E-DC0C00639CE4.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-18DD4FE5-6641-5A0E-A00E-DC0C00639CE4.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,45 @@ + + + + + +Set +the Configuration DescriptorsA short document that describes how to set the configuration descriptors. + +
Introduction

The +configuration descriptor contains values required by the class drivers. The +settings are:

    +
  • number of interfaces +in the configuration,

  • +
  • maximum power taken +by the device,

  • +
  • is remote wakeup enabled.

  • +

Note: that the number of interfaces in the configuration +must be set, all the other settings are optional.

The size of the +data to be copied may be obtained by using GetConfigurationDescriptorSize().TInt desc_size = 0; +gPort.GetConfigurationDescriptorSize(desc_size);

The size +should normally be KUsbDescSize_Config as defined in <usb.h>

+
Setting configuration descriptors

Set the configuration +descriptor using RDevUsbcScClient::SetConfigurationDescriptor().

TBuf8<desc_size> descriptor; + +// Invert Remote-Wakup support +descriptor[KConfDesc_AttribOffset] = (descriptor[KConfDesc_AttribOffset] ^ KUsbDevAttr_RemoteWakeup); + +// Change the reported max power to 200mA (2 * 0x64) +descriptor[KConfDesc_MaxPowerOffset] = 0x64; +r = gPort.SetConfigurationDescriptor(descriptor);

Additional +values may be set using the RDevUsbcScClient class. These +values can be set, retrieved and removed:

    +
  • Manufacturer,

  • +
  • Product,

  • +
  • Serial numbers.

  • +
+ +

After you have set the configuration descriptors you should Set the Interface Descriptors.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-197A1071-CDAA-5A87-9981-A52FB32C084E.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-197A1071-CDAA-5A87-9981-A52FB32C084E.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,72 @@ + + + + + +ReferenceA summary of documentation related to the Keyboard Driver. +

This topic provides a summary of related documentation for the +Keyboard Driver to which you can refer.

+
API +Reference

Kernel Architecture 2

+ + + +

Item

+

Header

+
+ +

SConvSubTable

+

k32keys.h

+
+ +

SConvTable

+

k32keys.h

+
+ +

SConvTableNode

+

k32keys.h

+
+ +

SFunc

+

k32keys.h

+
+ +

SFuncAndState

+

k32keys.h

+
+ +

SFuncTable

+

k32keys.h

+
+ +

SFuncTableEntry

+

k32keys.h

+
+ +

SFuncTables

+

k32keys.h

+
+ +

SKeyCodeList

+

k32keys.h

+
+ +

SScanCodeBlock

+

k32keys.h

+
+ +

SScanCodeBlockList

+

k32keys.h

+
+ + +
+
Engineering +Specifications

No specifications are published.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-1A72F75A-1930-5C32-93B7-20F4934BCFAA.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-1A72F75A-1930-5C32-93B7-20F4934BCFAA.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,41 @@ + + + + + +ROM +Paging OverviewMemory may be conserved by only loading the parts of an execute +in place (XIP) image that are required at any given time. +
Description

If +an XIP ROM image is stored on an XIP media such as NOR flash, it does not +have to be copied into main memory before it can be executed. If it is stored +on non-XIP media, such as NAND flash, then it must be copied into main memory +before it can be executed. The entire XIP image can run to many megabytes, +and therefore use a lot of main memory. If ROM Paging is used, then only those +sections of the XIP image which are required are loaded into memory. Additional +sections are loaded as and when they are needed, and sections which have not +been used in some time can be discarded. The overall effect is to leave more +memory available for applications.

<add links to memory mapping, +NOR NAND>

If the ROM image is in a non-XIP ROM it has to be loaded +into RAM before it can be executed. The ROM image is split into two parts:

    +
  • Paged

  • +
  • Unpaged

  • +

The unpaged part of the ROM image is loaded by the bootloader and +it always present in RAM. The paged part of the ROM image is paged in on demand.

+
Using ROM Paging

The type of paging used and the +area of memory to use first is specified in the oby and mmp files and then +built by using specific parameters in the buildrom utility.

+
+ROM Paging +Guide +ROM file +system +ROFS file +system +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-1A92047A-3C1D-5B4C-949B-98D770F5F530-master.png Binary file Adaptation/GUID-1A92047A-3C1D-5B4C-949B-98D770F5F530-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-1A92047A-3C1D-5B4C-949B-98D770F5F530_d0e32642_href.png Binary file Adaptation/GUID-1A92047A-3C1D-5B4C-949B-98D770F5F530_d0e32642_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-1AFAD1C4-340B-4119-94A8-F50E9D8DA8E6.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-1AFAD1C4-340B-4119-94A8-F50E9D8DA8E6.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,18 @@ + + + + + +TimersThis document introduces the use of timers by device drivers. +
+

Device drivers use timers for tasks such as providing timeouts for +device operations, and to wait for programming device timing.

The +Kernel provides timer APIs that device drivers can use, for example, NTimer. +The following sections discuss these.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-1BB379B6-C0B5-5099-90A0-1BA39DC2C7DD-master.png Binary file Adaptation/GUID-1BB379B6-C0B5-5099-90A0-1BA39DC2C7DD-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-1BB379B6-C0B5-5099-90A0-1BA39DC2C7DD_d0e25918_href.png Binary file Adaptation/GUID-1BB379B6-C0B5-5099-90A0-1BA39DC2C7DD_d0e25918_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-1D3E61BD-C09D-51FD-A10B-22392FDAEFEC.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-1D3E61BD-C09D-51FD-A10B-22392FDAEFEC.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,130 @@ + + + + + +Inactivity +Monitoring and Peripheral Low Power StatesPeripheral inactivity can be defined as the state when that peripheral’s +driver has no pending request and is not performing background tasks. +

It is recommended that peripheral drivers monitor peripheral inactivity +because they are in the best position to understand the current hardware requirement.

+

The preferred approach is to implement inactivity monitoring in the platform +specific portion of peripheral drivers. However it is not always possible +to safely do it that way. In this case, an interface between the platform +specific and generic portions of the driver might need to be devised leading +to, in the future, inactivity monitoring functionality or assistance being +included in generic components.

+

In some cases the developer of the driver might decide to implement inactivity +monitoring with a grace delay, using timers. For example, consider a peripheral +used as a data input device. If the only way that the platform specific layer +of the peripheral driver has any knowledge that an input request is pending, +and that data is arriving, is when an incoming unit of data causes an interrupt, +then the resulting ISR (or deferred DFC) could re-start a timer with a suitable +period. Inactivity could be monitored in the timer callback. This guarantees +that if another unit of data arrives before the timer expiration, the peripheral +is still in its operational power state.

+
    +
  • Peripheral Power States

  • +
  • Peripheral standby

  • +
  • Moving peripherals to a low power state

  • +
  • High latency low power states and non-transparent transitions

  • +
  • Peripheral power state diagram and transitions

  • +
+
Peripheral +Power States

It is possible that a particular ASSP allows peripheral +hardware blocks to be independently transitioned to a low power state. From +the point of view of power consumption, the base port might consider that +those peripherals have three logical power states:

    +
  • Operational Power – +the peripheral is either processing some request, or performing a background +task with data transactions to or from it, or the peripheral is being kept +in this state in anticipation that data will be input to it, and is drawing +an amount of power corresponding to one of its possible modes of operation.

  • +
  • Low Power – +the peripheral is “idling” after a period of inactivity has been detected, +drawing a minimal amount of power required to preserve its internal state. +The peripheral should be able to keep its internal state and transition from +this to the Operational Power state with a negligible delay and with no impact +on the performance of either the peripheral driver or the upper layer components +that use it.

  • +
  • Off – the peripheral +power has been cut off, and only leakage accounts for power consumption. No +state is preserved and the delay to a return to full power is not negligible.

  • +

Note that peripheral power states are a notion that only applies +to the peripheral hardware block, and not to the driver. The peripheral driver +is the component that requests the peripheral to transition between these +states.

Note also that both Operational and Low Power states are subsets +of the Peripheral "Active" state. In some cases the differences in power consumption +between the Operational and Low Power modes might not be significant as, with +some hardware, only part of the peripheral needs to be operational to service +a particular type of request.

+
Peripheral +standby

Some ASSPs make provision for a peripheral standby mode, +where individual peripherals can be transitioned to a low power consumption +mode of operation under software control, usually by writing to an ASIC internal +register.

If the peripheral is capable of keeping its internal state, +and the transition out of this mode is either done automatically on hardware, +or controlled by software, but has no impact on the performance of the peripheral +driver or on the users of this peripheral, and can be done with negligible +delay, then the peripheral standby mode could be considered a low power state +as above.

+
Moving peripherals +to a low power state

It is assumed that peripherals can be transitioned +between power states under the peripheral driver's software control. However, +transitioning peripherals to a low power state should only be performed if +it can be done transparently to the users and consumers of the services provided +by that peripheral. Negligible interactive delays may be acceptable, data +loss is not acceptable.

The transition of a peripheral to a low power +state can be requested by the platform-dependent layers of that peripheral +driver after inactivity, as defined above, has been detected. That request +usually assumes the form of a request to turn a controllable power resource +off. The request should be handled by the ASSP/Variant component that manages +platform power resources (the resource manager).

It can also assume +the form of an operation required to put the peripheral in standby mode. In +this case the peripheral driver is totally responsible for handling the transition +to the low power state.

+
High latency +low power states and non-transparent transitions

This guide is +only concerned with peripheral low power states that can be reached and left +with no impact on system performance. However, it is possible that transitions +to and from a peripheral low power state are long enough to have an impact +on system performance, or cause loss of data, or the peripheral is not capable +of detecting the hardware events required to guarantee correct operation while +in a low power state. If this is the case, then the decision to transition +to a low power state cannot be taken solely by the peripheral driver, and +will have to be taken in agreement with the users and consumers of the services +provided by this peripheral.

+
Peripheral +power state diagram and transitions +Peripheral power state diagram + +

It can be assumed that when the peripheral driver is loaded, the +peripheral is put into the Low Power state. If a new request is asserted +on that peripheral driver from a user of that peripheral (which can include +another dependent peripheral driver or user side Engine/server/application), +the peripheral should move to its Operational Power state. The driver +can then start monitoring for peripheral inactivity, and when that is detected, +and no other dependent peripheral is using this peripheral, it can move the +peripheral back to the Low Power state.

If, however, the power +manager requests the driver to power down the peripheral and no other dependent +peripheral is using it, it then moves into its Off state from which +it can only return to the Operational Power state when the power manager +issues a power up request. Moving from the Off state to the Operational +Power state is a relatively lengthy operation and requires resetting the +internal state of the peripheral.

If another dependent peripheral +is using this peripheral, and the power manager issues a power down request, +then the driver keeps the peripheral in its operational power state until +the dependent peripheral relinquishes its request on it.

From the Low +Power state, a peripheral can also be turned Off (unconditionally) if +the power manager so requests. It can be moved back to the Operational +Power state on an internal event (Interrupt, Timer).

+Peripheral power states + +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-1E43E258-A926-5D24-B0A5-8756491C687F.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-1E43E258-A926-5D24-B0A5-8756491C687F.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,384 @@ + + + + + +Call +Stack Information Commands +

Describes how to use the debug monitor commands to get information about +the call stack.

+
    +
  • General points

  • +
  • Finding the stack

  • +
  • Tracing through the call stack heuristically

  • +
  • Walking through the call stack

  • +
+
General points

Tracing +the call stack is an advanced use of the m command that allows you to examine +memory.

Every time a function is called, the return address +is automatically saved into register R14 (Link Register). +In addition to this the return address is generally pushed onto the call stack; +it is always pushed in debug builds but the push operation is sometimes optimized +out in release builds. This allows you to trace back through the value of R14 and +these saved addresses to see the sequence of function calls. Unfortunately +this is quite tedious to do because the stack is also used for automatic variables +and other data. You need to work out which values on the stack refer to return +addresses.

When you are debugging only ROM-based code, it is relatively +easy to identify the pushed return addresses because all code addresses will +be in the ROM range: 0xF800000 to 0xFFEFFFFF for +the moving +model. However, there is also data in the ROM, which means that an +address on the stack which is in the ROM range could point to data instead +of code. If you want to trace applications loaded into RAM, i.e. anything +not run from drive Z:, then stack tracing is more difficult because the code +can move about and RAM-loaded code is given an address assigned at load time.

Note +that using the MAKSYM +tool is essential for tracing back through the stack.

+
Finding the +stack

To trace back through a thread’s kernel or user stack, you +first need to find the stack pointer value. On the ARM, R13 always +points to the stack, but there are different R13 registers +for each processor mode:

    +
  • In thread context:

      +
    • R13usr points +to the thread’s user stack,

    • +
    • R13svc points +to the thread’s kernel stack.

    • +
  • +
  • When handling interrupts, +dedicated stacks are used:

      +
    • R13Fiq points +to the stack used when processing fast interrupts (FIQ).

    • +
    • R13Irq points +to the stack used when processing general purpose interrupts (IRQ).

    • +
  • +

To find out which stack to inspect, you need to know what mode the +CPU was in when the fault occurred. The processor +mode is identified by the five least-significant bits of the CPSR register. +To get the value of the CPSR register:

    +
  • use the f command when the debug monitor is triggered by a hardware exception.

  • +
  • use the r command when the debug monitor is triggered by a panic.

  • +

The following examples show how to find the stack(s):

    +
  • Kernel & user stacks of the current thread after a hardware exception

  • +
  • Kernel & user stacks of the current thread after a panic

  • +
  • Interrupt stacks

  • +
  • Kernel & user stacks of a non-current thread

  • +

Kernel & user stacks +of the current thread after a hardware exception

Use the f command.

Fault Category: Exception Fault Reason: 10000000 +ExcId 00000001 CodeAddr f816c908 DataAddr 80000001 Extra c0007003 +Exc 1 Cpsr=60000010 FAR=80000001 FSR=c0007003 + R0=00000000 R1=00000000 R2=30000000 R3=80000001 + R4=00000001 R5=00403d88 R6=00002000 R7=f816c768 + R8=00000012 R9=00000040 R10=00000000 R11=00403fa4 +R12=00403d5c R13=00403d70 R14=f80906f8 R15=f816c908 +R13Svc=6571e000 R14Svc=f80074bc SpsrSvc=80000010 +

In this example:

    +
  • the kernel stack is +the value of R13Svc, i.e. 0x6571e00.

  • +
  • the user stack is the +value of R13, i.e. 0x00403d70.

  • +

Kernel & user stacks +of the current thread after a panic

Use the r command.

MODE_USR: + R0=6571de54 R1=0000002a R2=00000002 R3=ffffffff + R4=0000002a R5=f8170414 R6=6571df14 R7=6403cc50 + R8=00000001 R9=6403c44c R10=640002f8 R11=6571de70 +R12=00000020 R13=00404e00 R14=f80818c0 R15=f800bfa8 +CPSR=60000013 +MODE_FIQ: + R8=00000000 R9=ffffffff R10=ffffffff R11=00000000 +R12=00000000 R13=64000d0c R14=c080079c SPSR=e00000dc +MODE_IRQ: +R13=6400110c R14=00000013 SPSR=20000013 +MODE_SVC: +R13=6571de54 R14=f80328bc SPSR=60000010 +MODE_ABT: +R13=6400090c R14=ccbfd0e0 SPSR=b00000d9 +MODE_UND: +R13=6400090c R14=b5a39950 SPSR=f000009d +

In this example:

    +
  • the kernel stack is +the value of R13 under MODE_SVC:, i.e. 0x6571de54.

  • +
  • the user stack is the +value of R13 under MODE_USR:, i.e. 0x00404e00.

  • +

Interrupt stacks

Use +the r command.

MODE_USR: + R0=6571de54 R1=0000002a R2=00000002 R3=ffffffff + R4=0000002a R5=f8170414 R6=6571df14 R7=6403cc50 + R8=00000001 R9=6403c44c R10=640002f8 R11=6571de70 +R12=00000020 R13=00404e00 R14=f80818c0 R15=f800bfa8 +CPSR=60000013 +MODE_FIQ: + R8=00000000 R9=ffffffff R10=ffffffff R11=00000000 +R12=00000000 R13=64000d0c R14=c080079c SPSR=e00000dc +MODE_IRQ: +R13=6400110c R14=00000013 SPSR=20000013 +MODE_SVC: +R13=6571de54 R14=f80328bc SPSR=60000010 +MODE_ABT: +R13=6400090c R14=ccbfd0e0 SPSR=b00000d9 +MODE_UND: +R13=6400090c R14=b5a39950 SPSR=f000009d +

In this example:

    +
  • the IRQ stack is the +value of R13 under MODE_IRQ:, i.e. 0x6400110c.

  • +
  • the FRQ stack is the +value of R13 under MODE_FIQ:, i.e. 0x64000d0c.

  • +

Kernel & user stacks +of a non-current thread

Use the output of the i, q and c0 commands.

THREAD at 6403c194 VPTR=f8046c18 AccessCount=5 Owner=6403bb4c +Full name t_dmasim::Main +Thread MState READY +Default priority 12 WaitLink Priority 12 +ExitInfo 3,0, +Flags 00000002, Handles 6403b418 +Supervisor stack base 6571d000 size 1000 +User stack base 00403000 size 2000 +Id=25, Alctr=00700000, Created alctr=00700000, Frame=00000000 +Trap handler=00000000, ActiveScheduler=007000c8, Exception handler=00000000 +TempObj=00000000 TempAlloc=00000000 +NThread @ 6403c44c Pri 12 NState READY +Next=6403c44c Prev=6403c44c Att=03 iUserContextType=02 +HeldFM=00000000 WaitFM=00000000 AddrSp=6403bb4c +Time=0 Timeslice=20 ReqCount=0 +SuspendCount=0 CsCount=1 CsFunction=00000000 +SavedSP=6571df98 +DACR f800bd2c +R13_USR 0d404c38 R14_USR 00000001 SPSR_SVC 00000000 + R4 f8022d84 R5 6571dfd4 R6 6571dfbc R7 f8022db8 + R8 f800bddc R9 f800a454 R10 00000000 R11 f801daac + PC 60000010 +

In this example:

    +
  • the kernel stack is +the value of SavedSP, i.e. 0x6571df98.

  • +
  • the user stack is the +value of R13_USR, i.e. 0x0d404c38.

  • +
+
Tracing through +the stack heuristically

One way of tracing through the call stack +is to assume that every word on the stack which looks like a ROM code address +is a saved return address. We say that this heuristic because:

    +
  • some data words may +look like code addresses in ROM.

  • +
  • there may be saved return +addresses left over from previous function calls. For example, suppose that F() calls A() and +then B() in sequence. A() itself calls X(), +which calls Y(). If a crash occurs in B(), +the saved return addresses from the calls to X() and Y() are +still present on the stack and may be mistaken for function calls occuring +while B() is active.

    This scenario happens frequently +when B() allocates a buffer (e.g. TBuf) +on the stack which overlaps old stack frames.

    + +
  • +

If you want to trace applications loaded into RAM, then stack tracing +is more difficult because RAM-loaded DLLs are given addresses assigned at +load time.

On ARM, the stack pointer starts at the higher address +end and moves 'down' towards the lower address end. This means that values +at the top of the memory dump are more recent. You need to look back through +this for code addresses. For ROM code this will be words with most significant +byte in the range 0xF8 to 0xFF, remembering +that they are little-endian. This can either be done manually, or automatically +using the printsym.pl perl script, which can be found +in ...\epoc32\tools.

Let's follow this in an example +session:

    +
  • Decide whether the crash +has been caused by a panic or an exception using the f command:

    .f +Fault Category: EXAMPLE Fault Reason: 0000002a +ExcId 00000000 CodeAddr 00000000 DataAddr 00000000 Extra 00000000 +
  • +
  • This shows that the +crash was caused by a panic, so now use the r command to find the CPU mode and the stack pointer:

    .r +MODE_USR: + R0=6571de54 R1=0000002a R2=00000002 R3=ffffffff + R4=0000002a R5=f8170414 R6=6571df14 R7=6403cba8 + R8=00000001 R9=6403c41c R10=640002f8 R11=6571de70 +R12=00000020 R13=00404e00 R14=f80818c0 R15=f800bfa8 +CPSR=60000013 +MODE_FIQ: + R8=00000000 R9=ffffffff R10=ffffffff R11=00000000 +R12=00000000 R13=64000d0c R14=c080079c SPSR=e00000dc +MODE_IRQ: +R13=6400110c R14=00000013 SPSR=20000013 +MODE_SVC: +R13=6571de54 R14=f80328bc SPSR=60000010 +MODE_ABT: +R13=6400090c R14=ffff0010 SPSR=400000d7 +MODE_UND: +R13=6400090c R14=95221110 SPSR=f000009d +

    The panic happened in supervisor mode, because CPSR +& 0x1F == 0x13, so R13Svc, i.e. +the value of R13 shown under MODE_SVC: in +the above display, is the stack pointer to look at; this has the value 0x6571DE54.

  • +
  • Using the m command to look at memory starting at location 0x6571DE54 gives:

    .m6571de54+200 +6571de54: 07 00 00 10 14 04 17 f8 00 00 00 00 d4 4e 40 00 .............N@. +6571de64: e8 de 71 65 74 de 71 65 74 fb 16 f8 88 28 03 f8 ..qet.qet....(.. +6571de74: 0c d4 03 f8 64 35 03 f8 00 00 00 00 00 00 00 00 ....d5.......... +6571de84: d0 00 00 00 14 df 71 65 a8 cb 03 64 a8 cb 03 64 ......qe...d...d +6571de94: d0 00 00 00 14 df 71 65 1c df 71 65 ec 4e 40 00 ......qe..qe.N@. +6571dea4: 1c c4 03 64 b4 2a 03 f8 00 00 00 00 14 df 71 65 ...d.*........qe +6571deb4: d0 de 71 65 c4 de 71 65 b0 ab 03 f8 00 00 00 00 ..qe..qe........ +6571dec4: e0 ba 03 64 14 df 71 65 1c df 71 65 01 00 00 00 ...d..qe..qe.... +6571ded4: 1c c4 03 64 f8 02 00 64 10 df 71 65 ec de 71 65 ...d...d..qe..qe +6571dee4: 84 da 01 f8 5c fb 16 f8 00 4e 40 00 00 00 00 00 ....\....N@..... +6571def4: 00 4e 40 00 00 00 00 00 d3 00 00 00 ec 4e 40 00 .N@..........N@. +6571df04: d4 df 71 65 14 df 71 65 e0 db 01 f8 c0 d9 01 f8 ..qe..qe........ +6571df14: a8 cb 03 64 e0 ba 03 64 01 00 01 00 00 00 00 00 ...d...d........ +6571df24: 00 00 00 00 d4 4e 40 00 00 00 00 30 40 00 00 00 .....N@....0@... +6571df34: 13 00 00 60 98 df 71 65 48 df 71 65 f4 81 00 f8 ...`..qeH.qe.... +6571df44: 8c 7a 00 f8 68 df 71 65 58 df 71 65 6c df 71 65 .z..h.qeX.qel.qe +6571df54: 60 df 71 65 0c 2b 00 f8 bc 2a 00 f8 84 df 71 65 `.qe.+...*....qe +6571df64: 70 df 71 65 e4 7d 04 f8 08 2b 00 f8 0d 00 00 00 p.qe.}...+...... +6571df74: 0a 00 00 30 40 00 00 00 54 65 73 74 44 6d 61 53 ...0@...TestDmaS +6571df84: 69 6d 04 f8 a9 4b 40 00 b8 df 71 65 9c df 71 65 im...K@...qe..qe +6571df94: 2c be 00 f8 2c bd 00 f8 38 4c 40 0d 01 00 00 00 ,...,...8L@..... +6571dfa4: 00 00 00 00 84 2d 02 f8 d4 df 71 65 bc df 71 65 .....-....qe..qe +6571dfb4: b8 2d 02 f8 dc bd 00 f8 54 a4 00 f8 00 00 00 00 .-......T....... +6571dfc4: ac da 01 f8 10 00 00 60 d8 df 71 65 70 74 00 f8 .......`..qept.. +6571dfd4: b8 da 01 f8 d4 4e 40 00 20 f7 16 f8 d0 4e 40 00 .....N@. ....N@. +6571dfe4: 00 00 00 00 00 00 00 00 ec 4e 40 00 40 00 00 00 .........N@.@... +

    We can look for potential ROM addresses by scanning the log +and look up the corresponding function name in the symbol file generated using the MAKSYM tool . +The first one is 0xF8170414 at offset 4 in +the memory dump.

  • +
  • Alternatively, we can +use the printsym.pl perl script, passing it the dump +output. The following is part of the output:

    R:\base\e32\rombuild>perl -S printsym.pl ASSABETARM4D.symbol +ROM Symbols from ASSABETARM4D.symbol +Please enter data to be decoded +6571de54: 07 00 00 10 14 04 17 f8 00 00 00 00 d4 4e 40 00 .............N@. += 10000007 .... += f8170414 .... etext=. + 0x0 += 00000000 .... += 00404ed4 .N@. +6571de64: e8 de 71 65 74 de 71 65 74 fb 16 f8 88 28 03 f8 ..qet.qet....(.. += 6571dee8 ..qe += 6571de74 t.qe += f816fb74 t... DDmaTestChannel::DoCreate(int, TDesC8 const *, TVersion const & +) + 0x24 += f8032888 .(.. Kern::Fault(char const *, int) + 0xc +6571de74: 0c d4 03 f8 64 35 03 f8 00 00 00 00 00 00 00 00 ....d5.......... += f803d40c .... RHeap::Alloc(int) + 0xf4 += f8033564 d5.. Kern::MutexSignal(DMutex &) + 0xc += 00000000 .... += 00000000 .... + +[............ truncated ...............] + += f801da84 .... DLogicalDevice::ChannelCreate(DLogicalChannelBase *&, TChannelC +reateInfo &) + 0xd0 += f816fb5c \... DDmaTestChannel::DoCreate(int, TDesC8 const *, TVersion const & +) + 0xc += 00404e00 .N@. += 00000000 .... +6571def4: 00 4e 40 00 00 00 00 00 d3 00 00 00 ec 4e 40 00 .N@..........N@. += 00404e00 .N@. += 00000000 .... += 000000d3 .... += 00404eec .N@. +6571df04: d4 df 71 65 14 df 71 65 e0 db 01 f8 c0 d9 01 f8 ..qe..qe........ += 6571dfd4 ..qe += 6571df14 ..qe += f801dbe0 .... ExecHandler::ChannelCreate(TDesC8 const &, TChannelCreateInfo & +, int) + 0x134 += f801d9c0 .... DLogicalDevice::ChannelCreate(DLogicalChannelBase *&, TChannelC +reateInfo &) + 0xc + +[.......................... truncated .........................] + += f8022db8 .-.. ExecHandler::DebugPrint(void *, int) + 0x34 += f800bddc .... A::UserDebugPrint(unsigned char const *, int, int) + 0xc += f800a454 T... EpocSlowExecTable + 0xc += 00000000 .... +6571dfc4: ac da 01 f8 10 00 00 60 d8 df 71 65 70 74 00 f8 .......`..qept.. += f801daac .... ExecHandler::ChannelCreate(TDesC8 const &, TChannelCreateInfo & +, int) + 0x0 += 60000010 ...` += 6571dfd8 ..qe += f8007470 pt.. __ArmVectorSwi + 0xd8 +6571dfd4: b8 da 01 f8 d4 4e 40 00 20 f7 16 f8 d0 4e 40 00 .....N@. ....N@. += f801dab8 .... ExecHandler::ChannelCreate(TDesC8 const &, TChannelCreateInfo & +, int) + 0xc += 00404ed4 .N@. += f816f720 ... etext=. + 0x560 += 00404ed0 .N@. +6571dfe4: 00 00 00 00 00 00 00 00 ec 4e 40 00 40 00 00 00 .........N@.@... += 00000000 .... += 00000000 .... += 00404eec .N@. += 00000040 @... +^C +R:\base\e32\rombuild> +

    There are several false positives in this output (and even +more in the truncated parts). So some study of the source code is needed to +discard the noise and find the actual call stack. Here it is (innermost frame +first):

      +
    • Kern::Fault

    • +
    • DDmaTestChannel::DoCreate

    • +
    • ExecHandler::ChannelCreate

    • +
    • __ArmVectorSwi

    • +

    Note that for the sake of the example, a call to Kern::Fault() was +deliberately inserted into DDmaTestChannel::DoCreate().

    All +other function names are false positives and should be ignored.

  • +
+
Walking through +the call stack

The heuristic method is quick but produces lots +of false positives. Another option is to manually reconstitute the call stack +from the memory dump. This is relatively easy for debug builds because GCC +uses R11 as a frame pointer (FP) and generates the same prologue/epilogue +for every function.

For release builds, there is no generic solution. +It is necessary to check the generated assembler code as there is no standard +prologue/epilogue and R11 is not used as frame pointer.

A typical +prologue for a debug ARM function looks like this:

mov ip, sp +stmfd sp!, {fp, ip, lr, pc} +sub fp, ip, #4 /* FP now points to base of stack frame */ +sub sp, sp, #16 /* space for local variables */ +

noting that: SP = R13, FP = R11, IP += R12, LR = R14, and PC = R15.

This +code creates the following stack frame:

+ +

Looking at the example session listed in when tracing through the stack heuristically. in which the crash is due +to a panic, the FP value is the R11 value; this is 0x6571de70. +This gives us the innermost stack frame:

6571de64: e8 de 71 65 <------------- pointer to previous stack frame + 74 de 71 65 + 74 fb 16 f8 <------------- Saved return address + 88 28 03 f8 <------------- FP points to this word +

Looking up the saved return address, 0xf816fb74, +in the symbol file shows that the current function was called from DDmaChannel::DoCreate().

f816fb50 0198 DDmaTestChannel::DoCreate(int, TDesC8 const *, TVersion const &) +f816fce8 007c DDmaTestChannel::~DDmaTestChannel(void) +f816fd64 0294 DDmaTestChannel::Request(int, void *, void *) +

Using the pointer to the previous stack frame saved into the +current frame, we can decode the next frame:

6571ded4: 1c c4 03 64 + f8 02 00 64 + 10 df 71 65 <------------- pointer to previous stack frame + ec de 71 65 + +6571dee4: 84 da 01 f8 <------------- saved return address + 5c fb 16 f8 <------------- start of second stack frame + 00 4e 40 00 + 00 00 00 00 +

Looking up the saved return address, 0xf801da84, +in the symbol file shows that DDmaTestChannel::DoCreate() was +called from DLogicalDevice::ChannelCreate().

f801d9b4 00f8 DLogicalDevice::ChannelCreate(DLogicalChannelBase *&, TChannelCreateInfo &) +f801daac 01b8 ExecHandler::ChannelCreate(TDesC8 const &, TChannelCreateInfo &, int) +f801dc64 00e4 ExecHandler::ChannelRequest(DLogicalChannelBase *, int, void *, void *) +

And here is the third stack frame:

6571df04: d4 df 71 65 <------------- pointer to previous stack frame + 14 df 71 65 + e0 db 01 f8 <------------- saved return address + c0 d9 01 f8 <------------- start of third stack frame +

So DLogicalDevice::ChannelCreate() was called +from ExecHandler::ChannelCreate().

Note that this +mechanical way of walking the stack is valid only for debug functions. For +release functions, it is necessary to study the code generated by the compiler.

For +completness, this is a typical prologue for a debug THUMB function:

push { r7, lr } +sub sp, #28 +add r7, sp, #12 /* R7 is THUMB frame pointer */ +

and this creates the following stack frame:

+ +

A call stack can mix ARM and THUMB frames. Odd return addresses +are used for THUMB code and even ones for ARM code.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-1E822A8F-3144-509D-A949-BDAF4BB9634A.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-1E822A8F-3144-509D-A949-BDAF4BB9634A.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,468 @@ + + + + + +Kernel +State Information CommandsDescribes how to use the i command to get detailed +information on the current process, thread, user process, user thread, and +the state of the kernel. +

The output shown below is a typical result of using the i command, and we use this to illustrate how information can be extracted +about the:

+
    +
  • Scheduler state

  • +
  • Current thread state

  • +
  • Current process state

  • +
  • Current data section process

  • +
+SCHEDULER @64000348: CurrentThread 640396b0 +RescheduleNeeded=00 DfcPending=00 KernCSLocked=00000001 +DFCS: next 64000458 prev 64000458 +ProcessHandler=f8014904, AddressSpace=64038d5c +SYSLOCK: HoldingThread 00000000 iWaiting 00000000 +Extras 0: 64038d5c 1: 64038d5c 2: 64038d5c 3: 00000000 +Extras 4: 00000000 5: 00000000 6: 00000000 7: 00000000 +Extras 8: 00000000 9: 00000000 A: 00000000 B: 00000000 +Extras C: 00000000 D: 00000000 E: 00000000 F: 00000000 + +TheCurrentThread=64039408 +THREAD at 64039408 VPTR=f803423c AccessCount=3 Owner=64038d5c +Full name test2.exe::Main +Thread MState READY +Default priority 16 WaitLink Priority 16 +ExitInfo 2,100,USER +Flags 00000004, Handles 640330bc +Supervisor stack base 6571f000 size 1000 +User stack base 00402000 size 2000 +Id=26, Alctr=00600000, Created alctr=00600000, Frame=00000000 +Trap handler=00000000, ActiveScheduler=00000000, Exception handler=00000000 +TempObj=00000000 TempAlloc=00000000 IpcCount=00000000 +NThread @ 640396b0 Pri 16 NState READY +Next=640396b0 Prev=640396b0 Att=03 iUserContextType=0b +HeldFM=00000000 WaitFM=00000000 AddrSp=64038d5c +Time=17 Timeslice=20 ReqCount=0 +SuspendCount=0 CsCount=1 CsFunction=fffffffe +SavedSP=6571ff34 ExtraContext=00000000 ExtraContextSize=0000 +DACR 63990000 +R13_USR 6571ff88 R14_USR f8025bc0 SPSR_SVC 10000004 + R4 f8033794 R5 64039408 R6 640396b0 R7 f8028518 + R8 640396b0 R9 640396b0 R10 00000000 R11 f80284d8 + PC 00000000 + +TheCurrentProcess=64038d5c +PROCESS at 64038d5c VPTR=f80342a4 AccessCount=6 Owner=00000000 +Full name test2.exe +ExitInfo 3,0, +Flags a0000000, Handles 6403860c, Attributes 60010000 +DataBssChunk 64039234, CodeSeg 6403919c +DllLock 64039044, Process Lock 64038eec SID 00000000 +TempCodeSeg 00000000 CodeSeg 6403919c Capability 00000000 0003ffff +CodeSegs: Count=0 +NumChunks=2 +0: Chunk 64039234, run 00400000, access count 1 +1: Chunk 6403613c, run 00600000, access count 1 +Process shared IO buffers cookie 0000031d +Process has no shared IO buffers +Domain -1, DACR 55555507 +TheCurrentAddressSpace=64038d5c +TheCurrentVMProcess=64038d5c +PROCESS at 64038d5c VPTR=f80342a4 AccessCount=6 Owner=00000000 +Full name test2.exe +ExitInfo 3,0, +Flags a0000000, Handles 6403860c, Attributes 60010000 +DataBssChunk 64039234, CodeSeg 6403919c +DllLock 64039044, Process Lock 64038eec SID 00000000 +TempCodeSeg 00000000 CodeSeg 6403919c Capability 00000000 0003ffff +CodeSegs: Count=0 +NumChunks=2 +0: Chunk 64039234, run 00400000, access count 1 +1: Chunk 6403613c, run 00600000, access count 1 +Process shared IO buffers cookie 0000031d +Process has no shared IO buffers +Domain -1, DACR 55555507 +TheCurrentDataSectionProcess=64038d5c +TheCompleteDataSectionProcess=64038d5c +PROCESS at 64038d5c VPTR=f80342a4 AccessCount=6 Owner=00000000 +Full name test2.exe +ExitInfo 3,0, +Flags a0000000, Handles 6403860c, Attributes 60010000 +DataBssChunk 64039234, CodeSeg 6403919c +DllLock 64039044, Process Lock 64038eec SID 00000000 +TempCodeSeg 00000000 CodeSeg 6403919c Capability 00000000 0003ffff +CodeSegs: Count=0 +NumChunks=2 +0: Chunk 64039234, run 00400000, access count 1 +1: Chunk 6403613c, run 00600000, access count 1 +Process shared IO buffers cookie 0000031d +Process has no shared IO buffers +Domain -1, DACR 55555507 + +
Scheduler state

The +first three lines and the fifth line of the output show the state of the kernel +scheduler. This information is mainly of interest to kernel engineers, although +the state of the kernel and the system locks can be useful when debugging +device driver crashes.

SCHEDULER @64000348: CurrentThread 640396b0 +RescheduleNeeded=00 DfcPending=00 KernCSLocked=00000001 +DFCS: next 64000458 prev 64000458 +... +SYSLOCK: HoldingThread 00000000 iWaiting 00000000 +

The values are interpreted as follows:

+ + + +

SCHEDULER @

+

This is the address of the kernel’s scheduler instance; this is +not very useful.

+
+ +

CurrentThread

+

The address of the kernel object for the current kernel thread.

+
+ +

RescheduleNeeded

+

This is set to non-zero by the kernel to force a reschedule, for +example if a thread has been signalled

+
+ +

DfcPending

+

This is non-zero when there are DFCs queued.

+
+ +

KernCSLocked

+

This is incremented each time the kernel is locked by a call to NKern::Lock(), +and decremented by calls to NKern::Unlock(). A value of +zero means that the kernel is not locked.

+
+ +

DFCS:

+

The addresses of the next and the previous items on the DFC queue

+
+ +

HoldingThread

+

The address of the thread holding the system lock mutex. The system +lock is set by call to NKern::LockSystem() and unset by +call to NKern::UnlockSystem()

+
+ +

iWaiting

+

Non-zero, if any thread is waiting for the system lock mutex.

+
+ + +
+
Current thread +state

The current thread is the thread that was executing when +the fault occurred. The 23 lines starting at line 10 of the output gives information +relating to the current thread:

TheCurrentThread=64039408 +THREAD at 64039408 VPTR=f803423c AccessCount=3 Owner=64038d5c +Full name test2.exe::Main +Thread MState READY +Default priority 16 WaitLink Priority 16 +ExitInfo 2,100,USER +Flags 00000004, Handles 640330bc +Supervisor stack base 6571f000 size 1000 +User stack base 00402000 size 2000 +Id=26, Alctr=00600000, Created alctr=00600000, Frame=00000000 +Trap handler=00000000, ActiveScheduler=00000000, Exception handler=00000000 +TempObj=00000000 TempAlloc=00000000 IpcCount=00000000 +NThread @ 640396b0 Pri 16 NState READY +Next=640396b0 Prev=640396b0 Att=03 iUserContextType=0b +HeldFM=00000000 WaitFM=00000000 AddrSp=64038d5c +Time=17 Timeslice=20 ReqCount=0 +SuspendCount=0 CsCount=1 CsFunction=fffffffe +SavedSP=6571ff34 ExtraContext=00000000 ExtraContextSize=0000 +DACR 63990000 +R13_USR 6571ff88 R14_USR f8025bc0 SPSR_SVC 10000004 + R4 f8033794 R5 64039408 R6 640396b0 R7 f8028518 + R8 640396b0 R9 640396b0 R10 00000000 R11 f80284d8 + PC 00000000
    +
  • Thread object and access count

  • +
  • The thread name

  • +
  • The thread state, exit information, priority

  • +
  • Thread flags

  • +
  • Handles

  • +
  • Kernel & user stack addresses

  • +
  • Thread id, RAllocator instances, trap frame

  • +
  • Trap handler, active scheduler and user-side exception handler

  • +
  • Temporary object, temporary allocation, IPC count

  • +
  • Underlying nanokernel thread

  • +
  • Fast mutexes

  • +
  • Timing, request semaphore count

  • +

Thread object and access +count

THREAD at 64039408 VPTR=f803423c AccessCount=3 Owner=64038d5c

The THread at field contains a pointer to the DThread object +representing the thread.

The AccessCount field contains +the reference count on the thread object.

The owner field +contains a pointer to the object that owns this DThread object.

The thread name

Full name test2.exe::Main

The +thread name is the part after the colons. The part before the colons is the +process name. This means that the thread is called Main inside the +process test2.exe.

The thread state, exit information, +priority

Thread MState READY +Default priority 16 WaitLink Priority 16 +ExitInfo 2,100,USER

The information that characterises the +thread exit is described by ExitInfo; this is shown as exit +type, exit reason and exit category. In this example:

    +
  • the thread has panicked, +as indicated by: exit type 2; See also TExitType.

  • +
  • the panic category was: USER

  • +
  • the panic number was:100

  • +
  • the thread was running +or it was in a ready-to-run state: MState READY

  • +

The priority shown is for the underlying thread, see also Process and thread priorities.

Thread flags

Flags 00000004, Handles 640330bc

The Flags field +contains information about the state of the thread. The possible values in +this field are defined by the KThread... constants in u32std.h. +While the symbols are internal to Symbian platform, the following table summarises +the values and their meaning.

+ + + +

Symbol

+

Value

+

Meaning

+
+ +

KThreadFlagProcessCritical

+

0x00000001

+

A thread panic causes the process to panic.

+
+ +

KThreadFlagProcessPermanent

+

0x00000002

+

If the thread exits for any reason, then this causes the process +to exit.

+
+ +

KThreadFlagSystemCritical

+

0x00000004

+

If the thread panics, then this causes the entire system to reboot.

+
+ +

KThreadFlagSystemPermanent

+

0x00000008

+

If the thread exits for any reason, then this causes the entire +system to reboot.

+
+ +

KThreadFlagOriginal

+

0x00000010

+

Reserved for future use.

+
+ +

KThreadFlagLastChance

+

0x00000020

+

Set if the thread is currently handling an exception.

+
+ + +

Handles

Flags 00000004, Handles 640330bc

The Handles field +contains the address of a DObjectIx object that contains +the handles owned by the thread.

Kernel & user stack +addresses

Supervisor stack base 6571f000 size 1000 +User stack base 00402000 size 2000 +

These fields give the base address and size, in bytes, of +the kernel and user stacks respectively.

Thread id, RAllocator instances, +trap frame

Id=26, Alctr=00600000, Created alctr=00600000, Frame=00000000

The Id field contains the thread id.

The Alctr field +contains a pointer to the current RAllocator instance used +for heap allocation.

The Created alctr field contains +a pointer to the original RAllocator instance used for +heap allocation. This may be different from the current instance if User::SwitchAllocator() has +been called.

The Frame field contains a pointer to +the current trap frame, an instance of the TTrap class, on +the cleanup stack.

Trap handler, active scheduler, +user-side exception handler

Trap handler=00000000, ActiveScheduler=00000000, Exception handler=00000000

The Trap handler field contains a pointer to the current +trap handler, an instance of TTrapHandler, for the cleanup +stack.

The ActiveScheduler field contains a pointer +to the current active scheduler.

The Exception handler field +contains a pointer to the current user-side exception handler.

Temporary object, temporary +allocation, IPC count

TempObj=00000000 TempAlloc=00000000 IpcCount=00000000

The Tempobj field contains a pointer to an instance +of a DObject derived class that must be closed when the +thread terminates.

The TempAlloc field contains a +pointer to a kernel heap cell that must be freed when the thread terminates. +Both this and Tempobj are used to avoid leaks if the thread +terminates unexpectedly.

The IpcCount field contains +the number of messages currently queued to this thread.

Underlying nanokernel thread

NThread @ 640396b0 Pri 16 NState READY +Next=640396b0 Prev=640396b0 Att=03 iUserContextType=0b

The NThread field +contains a pointer to the underlying nanokernel thread object, an instance +of the NThread class.

The Pri field +contains the current priority of the underlying nanokernel thread.

The NState field +shows the current state of the underlying nanokernel thread. Note that this +state is often referred to as the N-state, as compared to the to M-state, +the state of a Symbian platform thread. See the Thread +state summary.

The Next field points to the +next nanokernel thread object.

The Prev field points +to the previous nanokernel thread object.

The Att field +contains the nanokernel thread attributes, which is an 8-bit mask that controls +how the thread is scheduled in certain cases. Two attributes are defined:

+ + + +

KThreadAttImplicitSystemLock

+

This attribute signifies that the thread may not be scheduled if +another thread currently holds the system lock, unless the the former thread +holds another fast mutex. This attribute is used in implementing address space +switching in the moving memory model and also in implementing change of user +context in order to allow exceptions to be raised on other threads.

+
+ +

KThreadAttAddressSpace

+

This attribute signifies that the thread may require a change of +address space to schedule it. This attribute is used in conjunction with the +thread’s iAddressSpace field; if this does not match the +scheduler’s iAddressSpace field at the point where the thread +is scheduled an address space switch will occur. Note that this is not required +if the address space change is limited to the ARM domain permissions since +these are saved and restored as part of the thread context.

+
+ + +

Fast mutexes

HeldFM=00000000 WaitFM=00000000 AddrSp=64038d5c

The HeldFM field +contains a pointer to the fast mutex held by this thread; this is NULL if +no fast mutext was held.

The WaitFM field contains +a pointer to the fast mutex that this thread was waiting on; this is NULL +if this thread was not waiting on a fast mutex.

The AddrSp field +is the address space identifier used by the scheduler to determine whether +an address space change is required when scheduling in a new thread.

Timing, request semaphore +count

Time=17 Timeslice=20 ReqCount=0

The Time field +contains the number of nanokernel ticks, usually in milliseconds, to go before +the thread is preempted.

The Timeslice field contains +the maximum number of ticks for which the thread can run before being preempted.

The ReqCount contains +the request semaphore counter. If the value is negative, then the thread is +blocked waiting for a request to complete; if it is positive, then one or +more requests have completed.

Suspend count, critical +section counter, register values

SuspendCount=0 CsCount=1 CsFunction=fffffffe +SavedSP=6571ff34 ExtraContext=00000000 ExtraContextSize=0000 +DACR 63990000 +R13_USR 6571ff88 R14_USR f8025bc0 SPSR_SVC 10000004 + R4 f8033794 R5 64039408 R6 640396b0 R7 f8028518 + R8 640396b0 R9 640396b0 R10 00000000 R11 f80284d8 + PC 00000000 +

The SuspendCount field contains the number +of times that the thread has been suspended.

The CsCount field +critical section counter. When this value is greater than zero, then the thread +is in a critical section and cannot be suspended or killed.

The remaining +content is a list of register values. Note that they are not the register +values when the thread panicked. They are the values in the registers +the last time that this thread was pre-empted.

+
Current process +state

The current process is the process in whose address space +the current thread was executing when the fault occurred. The 15 lines starting +at line 33 of the output gives information relating to the current process. +This has some similarities with the current thread information:

TheCurrentProcess=64038d5c +PROCESS at 64038d5c VPTR=f80342a4 AccessCount=6 Owner=00000000 +Full name test2.exe +ExitInfo 3,0, +Flags a0000000, Handles 6403860c, Attributes 60010000 +DataBssChunk 64039234, CodeSeg 6403919c +DllLock 64039044, Process Lock 64038eec SID 00000000 +TempCodeSeg 00000000 CodeSeg 6403919c Capability 00000000 0003ffff +CodeSegs: Count=0 +NumChunks=2 +0: Chunk 64039234, run 00400000, access count 1 +1: Chunk 6403613c, run 00600000, access count 1 +Process shared IO buffers cookie 0000031d +Process has no shared IO buffers +Domain -1, DACR 55555507
    +
  • Process object and access count

  • +
  • The process name

  • +
  • Exit information

  • +
  • Process flags

  • +
  • Handles

  • +
  • Attributes

  • +
  • Information about memory

  • +
  • Secure id

  • +
  • Capability

  • +
  • Code segments

  • +
  • Chunks owned by the process

  • +
  • Shared IO buffer information

  • +
  • Domain information

  • +

Process object and access +count

PROCESS at 64038d5c VPTR=f80342a4 AccessCount=6 Owner=00000000

The Process at field contains a pointer to the DProcess object +representing the process.

The AccessCount field contains +the reference count on the process object.

The owner field +contains a pointer to the object that owns this DProcess object.

The process name

Full name test2.exe

The Full +name field gives the name of the process. In this example, the name +of the process is test2.exe.

See the +thread name.

Exit information

ExitInfo 3,0,

The ExitInfo field +contains the information that characterises the process exit. In this example, +the value is 3, meaning that this process has not exited. See also TExitType.

Process flags

Flags a0000000, Handles 6403860c, Attributes 60010000

The Flags field +contains information about the state of the process. The possible values in +this field are defined by the KProcess... constants in u32std.h. +While the symbols are internal to Symbian platform, the following +table summarises the values and their meaning.

+ + + +

Symbol

+

Value

+

Meaning

+
+ +

KProcessFlagSystemCritical

+

0x00000004

+

A process panic causes the entire system to reboot.

+
+ +

KProcessFlagSystemPermanent

+

0x00000008

+

If the process exits for any reason, then this causes the entire +system to reboot.

+
+ +

KProcessFlagPriorityControl

+

0x40000000

+

If set, then other threads are allowed to change this thread’s priority.

+
+ +

KProcessFlagJustInTime

+

0x80000000

+

If set, then just-in-time debug is enabled for this thread.

+
+ + +

Handles

Flags a0000000, Handles 6403860c, Attributes 60010000

The Handles field +contains the address of a DObjectIx object that contains +the handles owned by the process.

Attributes

Flags a0000000, Handles 6403860c, Attributes 60010000

The Attributes field contains the attributes of the process. Some are generic, as defined +by DProcess::TProcessAttributes, but others depend on the +memory model.

Information about memory

DataBssChunk 64039234, CodeSeg 6403919c

The DataBssChunk field +contains a pointer to the DChunk object representing the +chunk that contains the process data and .bss memory. Be +aware that this is not the same as the heap - heaps are allocated to threads, +and chunk information is found in the DThread object.

The CodeSeg field +contains a pointer to the DCodeSeg object that represents +the code segment.

Secure id

DllLock 64039044, Process Lock 64038eec SID 00000000

The SID field +contains the secure id of the process.

Capability

TempCodeSeg 00000000 CodeSeg 6403919c Capability 00000000 0003ffff

The +second four bytes of the Capability field contains the set of bits that define +the capability for this process. This defines what the process can and cannot +do.

Code segments

CodeSegs: Count=0

The CodeSegs: +Count field contains the number of code segments that have been dynamically +loaded into the process. This will be zero if the process is XIP.

Chunks owned by the process

NumChunks=2 +0: Chunk 64039234, run 00400000, access count 1 +1: Chunk 6403613c, run 00600000, access count 1 +

The NumChunks field contains the number of chunks owned by +the process.

Successive lines contain information about each chunk:

    +
  • the Chunk field +contains the address of a kernel DChunk object.

  • +
  • the run field +contains the virtual address at which the chunk resides when this is the current +process.

  • +
  • the access count field +contains the reference count of the object.

  • +

Shared IO buffer information

Process shared IO buffers cookie 0000031d +Process has no shared IO buffers +

This is information about shared IO buffers. The cookie is +only really of interest to base engineers.

Domain information

Domain -1, DACR 55555507

This +is ARM MMU-specific protection information. Processes have domain -1 and DACR +0xFFFFFFFF.

+
Current data +section process

In the moving memory model the current process +could be a fixed process, in which case there is also a current moving process. +The current data section process is the current moving process.

TheCurrentDataSectionProcess=64038d5c

This +field contains a pointer to the DProcess object for the current +moving process. This line is followed by detailed information about the process +itself; the format is the same as that described for the Current process state.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-209514AE-9457-4ED2-AFE0-FDC059CE2B30.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-209514AE-9457-4ED2-AFE0-FDC059CE2B30.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,16 @@ + + + + + +Time Client InterfaceThe basic steps to use the client interface of the Time +platform service. +

The Time client interface provides the Real Time Clock (RTC) functionality +to the OS.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-20F8DA2A-9157-54C5-97D0-4CCA50AB0631.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-20F8DA2A-9157-54C5-97D0-4CCA50AB0631.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,14 @@ + + + + + +ReferenceThis section describes the macros that can be used in the Bootstrap. +

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-2281F91F-67BD-5B85-A47F-30A5E683BBF6.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-2281F91F-67BD-5B85-A47F-30A5E683BBF6.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,30 @@ + + + + + +Double +BuffersTo improve throughput, Symbian platform provides the double buffer +mechanism. This is a feature that allows a block of data to be prepared by +the media driver while the hardware transfers a block of data. DMA transfers +data without interrupting the CPU. +

The MultiMediaCard subsystem performs multiple data transfers in a single +bus transaction.

+

If your implementation uses double buffers, you must set the ESupportsDoubleBuffering flag +into the TMMCMachineInfoV4::iFlags data member in your +implementation of DMMCStack::MachineInfo(). This flag causes +the platform independent layer to provide the support you need.

+

If your MultiMediaCard controller uses DMA and your platform specific layer +supports physical addresses, you must use double buffers.

+

See also:

+
    +
  • MachineInfo()

  • +
  • Implement double buffers

  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-22CCA5B5-D4AB-4ABC-94C6-CD85EC470238.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-22CCA5B5-D4AB-4ABC-94C6-CD85EC470238.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,86 @@ + + + + + +System +InformationThis topic describes various system information related to the +device drivers. +
Presence +of PDD

Some drivers may only require an LDD, and not provide +a PDD. However, if the driver has a PDD, then the driver must inform the framework +of this. The LDD should set the DLogicalDevice::iParseMask bitmask +with the KDeviceAllowPhysicalDevice flag. If this flag +is not set, then the Kernel assumes that the driver does not have a PDD.

// Logical Channel Second stage constructor +DExDriverLogicalDevice:: DExDriverLogicalDevice () + { + iParseMask = KDeviceAllowPhysicalDevice | KDeviceAllowUnit; + ... + }
+
+
Capabilities

The +device driver framework provides a method to set and provide general information +to the user on the capabilities of the device driver. Typically, implementations +simply return the version number of the LDD. The device driver framework allows +both the LDD and PDD to set the device capabilities.

The user typically +calls the RDevice::GetCaps() function to retrieve the device +capabilities.

RDevice device; +r = device.Open(KDriverName); +if (r==KErrNone) + { + TPckgBuf<RExDriver::TUartCaps> caps; + device.GetCaps(caps); + ... + device.Close(); + }

Note: The device capabilities in this context +refer to the services that the driver can offer. Do not confuse this with +the idea of platform security capabilities, which are completely different.

+
HAL handlers

Symbian +platform provides a Hardware Abstraction Layer (HAL) interface that can be +used by device drivers and kernel extensions to provide information on device +specific attributes to user code. It comprises set and get interfaces used +by the Kernel and by user code. The attributes are divided into groups of +similar functionality, each of which is managed by a function called a HAL +handler.

Drivers must register any HAL handlers they provide, and +de-register them when unloading. Kernel extensions do not remove their HAL +handlers.

// Adds a HAL entry handling function for the specified group of +// HAL entries. +Kern::AddHalEntry(EHalGroupDisplay, &handler, this, 1); + +// Removes the HAL handler +TInt Kern::RemoveHalEntry(EHalGroupDisplay);

The arguments +to AddHalEntry() are the ID of a HAL group, a pointer to +the handler function and a pointer to a data structure that will be passed +to the handler function. The HAL handler function prototype is defined by THalFunc.

// Implementation of the kernel extension's exported function +EXPORT_C void TExClientInterface::MyExAPI() + { + … + ExController->MyExAPI(); + … + } + +LOCAL_C TInt halFunction(TAny* aPtr, TInt aFunction, TAny* a1, + TAny* a2) + { + DLcdPowerHandler* pH=(DLcdPowerHandler*)aPtr; + return pH->HalFunction(aFunction,a1,a2); + } + +TInt DLcdPowerHandler::HalFunction(TInt aFunction, TAny* a1, +TAny* a2) + { + ... + switch(aFunction) + { + ... + } + }

When the user calls HAL::Set() or HAL::Get(), +it invokes the corresponding halFunction() of the HAL function +group.

+ \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-2344B900-5EC5-4467-BEAD-AB55C88CE63E.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-2344B900-5EC5-4467-BEAD-AB55C88CE63E.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,134 @@ + + + + + +Stack +Implementation GuideHow to implement the platform-specific class for an SDIO stack +of an SDIO-based hardware component. +

The stack is provided by the DSDIOStack class. The developers +porting the SDIO Controller must derive the DSDIOStack class +and implement three platform-specific functions: IssueMMCCommandSM(), EnableSDIOInterrupt() and MaxBlockSize().

+

The following sections describe how to implement these functions in the DMySdioStack class +derived from DSIOStack.

+
Hardware registers

The DMySdioStack class +needs to have access to the values and offsets of the SDIO configuration registers. +Refer to the platform documentation and declare appropriate constants in the +header file of the stack class.

+
IssueMMCCommandSM()

If +you have not declared it already, declare the following function in the definition +of DMySdioStack:TMMCErr IssueMMCCommandSM();

DSDIOStack::IssueMMCCommandSM() handles the commands to the bus and must be extended to support the SDIO +protocol. See also DSDStack::IssueMMCCommandsSM().

Rely on the platform documentation to perform the operations and +update appropriate hardware registers when you intercept the following commands:

    +
  • IO_OP_COND (CMD5)

  • +
  • IO_RW_DIRECT (CMD52)

  • +
  • IO_RW_EXTENDED (CMD53)

  • +

You should also handle the additional IO_SEND_OP_COND (R4) +and IO_RW_DIRECT (R5) responses.

In the following example, +the hypothetical hardware platform has two requirements, which are implemented +by the IssueMMCCommandSM() function. The function disables +the CRC7 check when receiving an R4 response to an CMD5 command, and disables +the SDIO interrupt before issuing a CMD52 command.void DMySdioStack::IssueMMCCommandSM() + { + TMMCCommandDesc& cmd = Command(); + ... + // CMD5 + // Disable the CRC7 check for R4 responses + if (cmd.iCommand == ECmd5) + { + // Clear the MMC_CRC7_R4_ENABLE bit + // MMC_SDIO_REG_SLOT0 is a 32-bit hardware register for SDIO in slot 0 + AsspRegister::Modify32(MMC_SDIO_REG_SLOT0, MMC_CRC7_R4_ENABLE, 0); + } + else + { + // Set the MMC_CRC7_R4_ENABLE bit + AsspRegister::Modify32(MMC_SDIO_REG_SLOT0, 0, MMC_CRC7_R4_ENABLE); + } + + // CMD52 + // Disable SDIO interrupts for CMD 52 + if (cmd.iCommand == ECmd52) + { + EnableSDIOInterrupt(EFalse); + } + ... + } +

As the SDIO Controller is instantiated at run-time, the +memory used to support the SDIO transfer mechanisms must be allocated dynamically. +Therefore, you can use two different types of memory and of data transfer:

    +
  • Programmatic input/output using virtual memory

  • +
  • DMA using physically-allocated DChunk objects.

  • +

The KMMCCmdFlagDMARamValid flag of the TMMCCommandDesc object +indicates which kind of memory transfer to use.

If you use the Programmatic I/O method, you need to queue pending data transfers +while you handle hardware interrupts. Your platform's documentation specifies +which interrupts may be received during transfers.

+
EnableSDIOInterrupt()

Declare +the following function in the definition of DMySdioStack:virtual void EnableSDIOInterrupt(TBool aEnable);

DSDIOStack::EnableSDIOInterrupt() enables or disables +the SDIO interrupt.

The following example is a typical implementation +of EnableSDIOInterrupt():void DMySdioStack::EnableSDIOInterrupt(TBool aEnable) + { + if (aEnable) + { + // Set the Interrupt Enable Master Bit + // MMC_SDIO_REG_SLOT0 is a 32-bit hardware register for SDIO in slot 0 + AsspRegister:: Modify32(MMC_SDIO_REG_SLOT0, SDIO_IENM, 0); + } + else + { + // Set the Interrupt Enable Master Bit + AsspRegister:: Modify32(MMC_SDIO_REG_SLOT0, 0, SDIO_IENM); + } + } +

You must also ensure that your interrupt handler checks +the SDIO interrupt register and the card slot before forwarding the interrupt +to the stack. If checking the card slot is likely to take too long, +use a DFC (Delayed Function Call) for the interrupt handler to preserve real-time +performance.

The following example illustrates how to implement +this aspect of the interrupt handler:void DMySdioInterrupt::Service(TAny* aSelf) + { + ... + // Get access to the stack + DPlatMMCStack* stack = (reinterpret_cast<DMySdioInterrupt*>(aSelf))->Stack(); + + // MMC_SDIO_REG_SLOT0 is a 32-bit hardware register for SDIO in slot 0 + TInt32 sdioReg = AsspRegister::Read32(MMC_SDIO_REG_SLOT0); + // Test for the SDIO interrupt + if (sdioReg & KMMC_SDIO_IntPending) + { + // Trigger the PIL’s interrupt handler for slot 0 + stack->HandleSDIOInterrupt(0); + return; + } + + // MMC_SDIO_REG_SLOT1 is a 32-bit hardware register for SDIO in slot 1 + sdioReg = AsspRegister::Read32(MMC_SDIO_REG_SLOT1); + // Test for the SDIO interrupt + if (sdioReg & KMMC_SDIO_IntPending) + { + // Trigger the PIL’s interrupt handler for slot 1 + stack->HandleSDIOInterrupt(1); + return; + } + + ... + } +
+
MaxBlockSize()

Declare +the following function in the definition of DMySdioStack:virtual TUint32 MaxBlockSize() const;

DSDIOStack::MaxBlockSize() returns the maximum block size in bytes +that can be transferred on the SDIO bus. Extended read/write commands require +this information.

In the SD protocol, the block size must be a power +of two. SDIO does not have the same constraint and the block size can be anything +between 1 and 2048.

The following example is a typical implementation +of MaxBlockSize():TUint32 DMySdioStack::MaxBlockSize() const + { + return(512); + } +

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-2380FDDE-5489-5B1C-87BB-1FD882E385D2.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-2380FDDE-5489-5B1C-87BB-1FD882E385D2.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,238 @@ + + + + + +Migration +Tutorial: Direct Memory AddressingTo handle direct memory addressing, you must to make the following +changes to your code. +

If a media driver uses a data transfer mechanism like DMA, +data transfer can be faster if the media driver knows that an address passed +in an I/O request is a physical address. This is known as direct memory addressing.

+
    +
  • Changes to registration

  • +
  • Changes to request handling

  • +
  • Issues about physical addresses

  • +
+
Changes to +registration

If the media driver code can handle physical addresses, +it must tell the local media subsystem. This process is called registration. +The media driver calls LocDrv::RegisterDmaDevice() to register +as part of the media +driver initialisation process. The media driver calls RegisterDmaDevice() after +the media driver has registered +with the local media subsystem.

After the call to LocDrv::RegisterDmaDevice(), +the local media subsystem will test if the address in an I/O request is a +physical address or a virtual address. The local media subsystem extracts +the information that the media driver requires. The media driver gets this +information through calls to the functions:

    +
  • TLocDrvRequest::IsPhysicalAddress().

  • +
  • TLocDrvRequest::GetNextPhysicalAddress().

  • +

A TLocDrvRequest object represents an I/O request +and is passed to the media driver.

There are three pieces of information +that the local media subsystem needs from the media driver when the media +driver registers:

    +
  • The minimum number +of bytes that the media device can transfer. For example, the architecture +of some memory card types requires data transfer in blocks of 512 bytes. The +local media subsystem can not support I/O requests for physical addresses +where the length of the data is smaller than this minimum number. This limit +prevents accidental access of the data outside the limits of the request.

  • +
  • The maximum number +of bytes that the media driver can transfer in one burst. This value depends +on the hardware. For eaxample,DMA +Framework has limits that depend on the DMA controller.

  • +
  • The alignment of +memory that the DMA controller requires. For example: a DMA controller +might require 2 byte (word or 16 bit) alignment or 4 byte (double word or +32 bit) alignment. For 2 byte alignment, specify 2; for 4 byte alignment specify +4 etc. The local media subsystem can not support I/O requests for physical +addresses that are not aligned according to this value.

  • +

You get all of this information from the documentation for the platform.

This +example code extends the code shown in the section Media +driver initialisation before the system is initialised. It adds a call +to LocDrv::RegisterDmaDevice(). This call follows registration +of the media driver with the local media subsystem.

DECLARE_STANDARD_EXTENSION() + { + TInt r=KErrNoMemory; + DPrimaryMediaBase* pM=new DPrimaryMediaBase; + if (pM) + {//…Required here for Asynchronous creation (if supported) + pM->iDfcQ = &MyDfcQ; + + // Perform registration here + r = LocDrv::RegisterMediaDevice(MEDIA_DEVICE_TYPE, + MEDIA_DRIVECOUNT, + &IMediaDriveNumbers[0], + pM,MEDIA_NUMMEDIA,KMediaDriveName + ); + if ® != KErrNone) + { + return r; + } + + // Register support for physical addressing. + // + // Note : in practice the values passed to RegisterDmaDevice() would be + // either symbolic constants or functions that return values. If the + // media driver is split into platform independent and platform dependent + // layers, and this code is in the independent layer, then you will need + // functions in the dependent layer to provide these values. + r = LocDrv::RegisterDmaDevice(pM, + 512, // Block Addressing 512 Bytes + 1024, // 1024 Byte address range + 2 ); // 2 Byte alignment + if ® != KErrNone) + { + return r; + } + ... + } + return®); + } +
+
Changes to +request handling

To use physical addreses, you need to make changes +to the code that deals with ERead and EWrite requests +in your implementation of the DMediaDriver::Request() function. This section discusses the issues with ERead requests, +but the principles apply to EWrite requests.

There +are a number of points to consider:

Check if the address is physical

Call TLocDrvRequest::IsPhysicalAddress() to +test if the address passed is a physical address. For example, for a ERead request:

... + // iReadReq points to a TLocDrvRequest object + ... + iMediaStartPos = iReadReq->Pos(); + iTotalLength = I64LOW(iReadReq->Length()); + iDoPhysicalAddress = iReadReq->IsPhysicalAddress(); + if(iDoPhysicalAddress) + { + ..< Physical address memory code >.. + } + else + { + ...< Virtual address memory code >...

Physical address code

If you want to use the physical address, +you need to get the physical address and the length of contiguous memory at +this location. Call TLocDrvRequest::GetNextPhysicalAddress() to +get the physical address and the length of physically contiguous memory. The +length of physically contiguous memory can be smaller than the length supplied +in the read request, because physical memory can be fragmented into a number +of small blocks. If the length is smaller than the length supplied in the +read or write request, you call TLocDrvRequest::GetNextPhysicalAddress() again +to get the address of the next physically contiguous block of memory. You +repeat this operation until the read request is complete. For example, for +a ERead request:

... + // iReadReq points to a TLocDrvRequest object + ... + TPhysAddr physAddr; + TInt physLength; + TInt err = KErrNone; + err = iReadReq->GetNextPhysicalAddress(physAddr, physLength); + if(err == KErrNone) + { + if (physLength < iTotalLength) + { + // Memory is fragmented, note remainder. You will need + // to use this code again using the remainder value. + iRemaining = iTotalLength – physLength; + iTotalLength -= physLength; + } + + // Start data transfer into the current physically + // contiguous block of physical memory. + DoDataTransfer(iMediaStartPos, physLength, physAddr); + ... + } +

If you do not want to deal with fragmented physical memory, +you can use your original code.

Virtual to physical address translation

Your code must not +perform a virtual to physical address translation when it deals with physical +memory. For example:

void DMMCRxDmaHelp::ChannelTransfer(const SDmaPseudoDes& aDes) + { + … + TPhysAddr dest; + + if (iCurrentReq->IsPhysicalAddress()) + dest = (TPhysAddr) aDes.iDest; + else + dest = Epoc::LinearToPhysical(aDes.iDest); + TPlatDma::SetDMARegister(KHoDMA_CDSA(iChno), dest); + … + }

Eliminate inter-process copy

You must change your code to +remove calls to TLocDrvRequest::WriteRemote(). For ERead requests, +data for transfer is already at the physical address. For example:

if (!iCurrentReq->IsPhysicalAddress()) + { + if( (id == DMediaPagingDevice::ERomPageInRequest)|| + (id == DMediaPagingDevice::ECodePageInRequest) ) + { + r = iCurrentReq->WriteToPageHandler((TUint8 *)(& iBufPtr [0]), len, usrOfst); + } + else if(id==DLocalDrive::ERead) + { + r = iCurrentReq->WriteRemote(&iBufPtr,usrOfst); + } + }

The same logic applies to EWrite requests. +You need to remove calls to TLocDrvRequest::ReadRemote().

Test your changes

You are recommended to run regression tests +on your changed code to makes sure that the media driver operates correctly.

+
Issues about +physical addresses

If the media driver can use physical addresses, +you need to be aware of a number of issues.

The address scheme used by the hardware

All media devices +have a minimum number of bytes that they can transfer. For example, the architecture +of some memory card types requires data transfer in blocks of 512 bytes. To +read one byte from this type of media device, the media driver must read a +block of 512 bytes and extract the byte from the block. To write one byte +to a media device, the media driver must read a block of 512 bytes, change +the content of the byte, and write the block to the media device.

Data transfer smaller than the minimum size

If the local +media subsystem receives a request to transfer data with a length smaller +than the minimum transfer size, the local media subsystem does not make a +physical address available to the media driver. A call to TLocDrvRequest::IsPhysicalAddress() returns +false. It is considered unsafe to give access to the physical data surrounding +the requested memory location.

Data transfer not aligned to the media device block boundary

If +the local media subsystem receives a request to transfer data, and the address +on the media device is not aligned to the media device block boundary, +you need to adopt the technique suggested below. The local media subsystem +will make the physical address available to the media driver. A call to TLocDrvRequest::IsPhysicalAddress() returns +true.

Consider the following case. A request has been made to read +1024 bytes from a media device that has a block size of 512 bytes. The 1024 +bytes start at offset +256 on the media device.

+ +

To get the first 256 bytes, you must read the first block of 512 +bytes from the media device. This can corrupt the physical memory passed in +the I/O request. The solution is to read the first block from the media device +into an intermediate buffer. Copy the 256 bytes from that buffer into the +physical memory passed in the I/O request.

To get the last 256 bytes, +you must read the third block of 512 bytes from the media device into the +intermediate buffer. Copy the 256 bytes from that buffer into the correct +position in the physical memory passed in the I/O request.

The middle +512 bytes are aligned on the media device block boundary. The media driver +can read this data into the correct position in the physical memory passed +in the I/O request.

Scatter/Gather DMA controllers

DMA controllers can support +the Scatter/Gather mode of operation. Each request in this mode of operation +consists of a set of smaller requests chained together. This chain of requests +is called the Scatter/Gather list. Each item in the list consists of a physical +address and a length.

Use TLocDrvRequest::GetNextPhysicalAddress() to +help you populate the Scatter/Gather list.

The following code fragment +shows how you do this. The example assumes that the DMA controller supports +a Scatter/Gather list with an unlimited number of entries. In practice, the +number of entries in the list is finite.

TPhysAddr physAddr; + TInt physLength; + TInt err = KErrNone; + + while (iRemaining > 0) + { + err = iCurrentReq->GetNextPhysicalAddress(physAddr, physLength); + if(err != KErrNone) + return err; + + iRemaining -= physLength; + PopulateScatterGatherList(physAddr, physLength); + } + + return DoDataTransfer(pos, length);
+
+MMC Porting +Implementation Tutorial +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-240EE926-BAFC-4A53-A8F8-D559BA7BB672.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-240EE926-BAFC-4A53-A8F8-D559BA7BB672.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,29 @@ + + + + + +DMA Client Interface Quick StartBasic steps to use the Client interface of the DMA framework. +

The DMA framework provides an interface for clients, such as device +drivers, to perform data transfers.

+
Basic steps

The following are the basic steps to +use the DMA framework:

    +
  1. The DMA Technology Guide describes the basic concepts of the DMA framework.

  2. +
  3. The DMA Device Driver +Guide explains the concepts of device driver guide.

  4. +
  5. The DMA Client Interface +Guide explains the interface and how to use it.

  6. +
  7. The DMA Testing Guide provides the location of the test application.

  8. +
+
+DMA +Tutorials Overview +DMA +Hardware Interface +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-2490DA46-A57B-4DFD-AA9C-2004D58486E3.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-2490DA46-A57B-4DFD-AA9C-2004D58486E3.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,16 @@ + + + + + +Interrupt Testing GuideDescribes the test suites required to test the platform +service implementation. +

There is no specific test suite available for the Interrupt platform +service at the moment.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-2559E3F7-314B-5DCC-A7FE-A08162A89721.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-2559E3F7-314B-5DCC-A7FE-A08162A89721.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,56 @@ + + + + + +Local +Media Subsystem OverviewProvides the logical device driver for the internal and removable +storage media on a phone. +
Purpose

The local media sub-system allows the Symbian +platform file system and other programs to communicate with local media devices.

+
Required background

The local media sub-system +requires an understanding of the Symbian platform file system and local media +devices.

+
Key concepts and terms
+ +
local drive
+

A media drive mounted within the phone.

+
+
+
Architecture

The TBusLocalDrive class +provides an interface to the local media sub-system. Each instance of this +class represents a channel of communication with a local drive. To establish +a channel a client connects an instance of the class to a specified drive. +The file server contains 16 instances of TBusLocalDrive, +one for each local drive. Programs other than the file server may also create +instances to access a local drive. Drives are abstracted by the TDrive class.

+
Local Media Sub-system Summary

The local media +subsystem provides the following:

    +
  • Local media LDD

    elocd.ldd

    The +kernel-side logical device driver which implements communication between physical +devices and applications which use them.

  • +
+
Typical uses

The TBusLocalDrive class +is used to connect to and disconnect from local drives, to read to and write +from them, to provide information about the capabilities of the drives, to +format them, and to mount and remount drives on specified media drivers.

Local +media subsystem:

    +
  • Manages device connections

  • +
  • Manages data transfer

  • +
  • Handles notifications +and device configuration.

  • +
+
+ +File Server + +File Systems + +Media Drivers +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-25941CD2-D124-55DD-8716-ACC93E3F1D6C.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-25941CD2-D124-55DD-8716-ACC93E3F1D6C.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,285 @@ + + + + + +Bootstrap Source MacrosDescribes the macros used in source files. +

This set of macros is available for use in source files, but not in platform +specific configuration header files. Their definitions are obtained by including os/kernelhwsrv/kernel/eka/include/kernel/arm/bootcpu.inc.

+
General macros

GETCPSR

GETCPSR reg

Reads +the CPSR into the specified ARM general register reg.

This +macro should be used in preference to MRS instructions to avoid problems related +to syntax incompatibility between different assembler versions.

CGETCPSR

CGETCPSR reg, cc

Reads +the CPSR into the specified ARM general register reg. This +is conditionally executed using cc as the execution condition.

This +macro should be used in preference to MRS instructions to avoid problems related +to syntax incompatibility between different assembler versions.

GETSPSR

GETSPSR reg

Reads +the SPSR into the specified ARM general register reg.

This +macro should be used in preference to MRS instructions to avoid problems related +to syntax incompatibility between different assembler versions.

CGETSPSR

CGETSPSR reg, cc

Reads +the SPSR into the specified ARM general register reg. This +is conditionally executed using cc as the execution condition.

This +macro should be used in preference to MRS instructions to avoid problems related +to syntax incompatibility between different assembler versions.

SETCPSR

SETCPSR reg

Writes +the entire (all 32 bits) CPSR from the specified ARM general register reg.

This +macro should be used in preference to MRS instructions to avoid problems related +to syntax incompatibility between different assembler versions.

CSETCPSR

CSETCPSR reg, cc

Writes +the entire (all 32 bits) CPSR from the specified ARM general register reg. +This is conditionally executed using cc as the execution +condition.

This macro should be used in preference to MRS instructions +to avoid problems related to syntax incompatibility between different assembler +versions.

SETSPSR

SETSPSR reg

Writes +the entire (all 32 bits) SPSR from the specified ARM general register reg.

This +macro should be used in preference to MRS instructions to avoid problems related +to syntax incompatibility between different assembler versions.

CSETSPSR

CSETSPSR reg, cc

Writes +the entire (all 32 bits) SPSR from the specified ARM general register reg. +This is conditionally executed using cc as the execution +condition.

This macro should be used in preference to MRS instructions +to avoid problems related to syntax incompatibility between different assembler +versions.

BOOTCALL

BOOTCALL call_numbe

Calls +the specified function via the boot table. call_number should +be one of the BTF_* values in the TBootTableEntry enumeration, +defined in os/kernelhwsrv/kernel/eka/include/kernel/arm/bootdefs.h.

The +macro is transparent; the function is entered with all registers and flags +having the same values as immediately before the macro.

GETPARAM

GETPARAM pnum, default

Retrieves +the parameter with number pnum from the boot parameter table, +and returns its value in R0. If the parameter is not present +in the table, then R0 is loaded with value default.

See +the description of BTF_Params for +more information on the boot parameter table.

GETMPARAM

GETMPARAM pnum

Retrieves +the parameter with number pnum from the boot parameter table, +and returns its value in R0. If the parameter is not present +in the table, then the macro faults the system.

See the description +of BTF_Params for +more information on the boot parameter table.

FAULT

FAULT cc

Faults +the system if condition cc is true. The condition is a standard +ARM condition code.

BTP_ENTRY

Declares +MMU permissions and cache attributes. The macro takes a variable number of +arguments depending on the processor in use.

For ARM architecture 6 +CPUs:

BTP_ENTRY $domain, $perm, $cache, $execute, $global, $P, $S

For +XScale CPUs:

BTP_ENTRY $domain, $perm, $cache, $P

For +other CPUs:

BTP_ENTRY $domain, $perm, $cache + + + +

$domain

+

ARM domain number 0-15. In general only one memory-model-dependent +value is used here and the symbol CLIENT_DOMAIN specifies +this.

+
+ +

$perm

+

Permissions for mapping.

For architecture 6 CPUs, use one +of PERM_NONO, PERM_RWNO, PERM_RWRO, PERM_RWRW, PERM_RONO, PERM_RORO.

For other CPUs, use one of PERM_RORO, PERM_RWNO, PERM_RWRO, PERM_RWRW.

In each of these names the first pair of letters +refers to supervisor, and the second pair to user access, so PERM_RWNO means +supervisor read/write, user no access.

+
+ +

$cache

+

Cache attributes for mapping. These are processor dependent - see +the CACHE_* macros in os/kernelhwsrv/kernel/eka/include/kernel/arm/bootcpu.inc.

+
+ +

$execute

+

ARM architecture 6 only. Determines whether code can be executed +from the mapped region; either BTPERM_EXECUTE or BTPERM_NO_EXECUTE.

+
+ +

$global

+

ARM architecture 6 only. Determines whether the mapped region is +ASID specific (local) or non-ASID specific (global); either BTPERM_LOCAL or BTPERM_GLOBAL.

+
+ +

$P

+

ARM architecture 6 and XScale only. Determines whether or not ECC +should be used on the mapped region (assuming hardware supports ECC); either BTPERM_ECC or BTPERM_NON_ECC.

+
+ +

$S

+

ARM architecture 6 only. Determines whether the mapped region is +shared between multiple CPUs or not; either BTPERM_SHARED or BTPERM_NON_SHARED.

+
+ + +

ROM_BANK

ROM_BANK PHYS, SIZE, LIN, WIDTH, TYPE, RAND, SEQ

Declares +an XIP ROM bank entry.

+ + + +

PHYS

+

The physical base address of the ROM bank.

+
+ +

SIZE

+

The size of the ROM bank.

+
+ +

LIN

+

Linear address override (usually 0).

+
+ +

WIDTH

+

Bus width. One of: ROM_WIDTH_8, ROM_WIDTH_16 or ROM_WIDTH_32

+
+ +

TYPE

+

The ROM type; see the TRomType enumeration.

+
+ +

RAND

+

Random access speed.

+
+ +

SEQ

+

Sequential access speed.

+
+ + +

See also BTF_RomBanks in Boot Table Functions.

+
Macros for +declaring I/O mappings

HW_MAPPING

HW_MAPPING PHYS,SIZE,MULT

Defines +an I/O mapping using the standard permissions and cache attributes for I/O +mappings, i.e. those defined for the BTP_Hw boot table entry. +See Boot Table MMU +Permission and Cache Attribute Definitions.

+ + + +

PHYS

+

Physical base address.

+
+ +

SIZE

+

Size of the mapping.

+
+ +

MULT

+

Granularity +of the I/O mapping (below).

+
+ + +

See also:

    +
  • Determining the linear address (below).

  • +
  • BTF_HwBanks in Boot +Table Functions.

  • +

HW_MAPPING_EXT

HW_MAPPING_EXT PHYS,SIZE,MULT

Defines +an I/O mapping using the permissions and cache attributes defined by a BTP_ENTRY macro +that immediately follows this macro. See Boot +Table MMU Permission and Cache Attribute Definitions.

+ + + +

PHYS

+

Physical base address.

+
+ +

SIZE

+

Size of the mapping.

+
+ +

MULT

+

Granularity +of the I/O mapping (below).

+
+ + +

See also:

    +
  • Determining the linear address (below).

  • +
  • BTF_HwBanks in Boot +Table Functions.

  • +

HW_MAPPING_EXT2

HW_MAPPING_EXT2 PHYS,SIZE,MULT,LIN

Defines +an I/O mapping using the standard permissions and cache attributes for I/O +mappings, i.e. those defined for the BTP_Hw boot table entry. +See Boot Table MMU +Permission and Cache Attribute Definitions.

+ + + +

PHYS

+

Physical base address.

+
+ +

SIZE

+

Size of the mapping.

+
+ +

MULT

+

Granularity +of the I/O mapping (below).

+
+ +

LIN

+

Linear address.

+
+ + +

See also BTF_HwBanks in Boot Table Functions.

HW_MAPPING_EXT3

HW_MAPPING_EXT3 PHYS,SIZE,MULT,LIN

Defines +an I/O mapping using the permissions and cache attributes defined by a BTP_ENTRY macro +that immediately follows this macro. See Boot +Table MMU Permission and Cache Attribute Definitions.

+ + + +

PHYS

+

Physical base address.

+
+ +

SIZE

+

Size of the mapping.

+
+ +

MULT

+

Granularity +of the I/O mapping (below).

+
+ +

LIN

+

Linear address.

+
+ + +

See also BTF_HwBanks in Boot Table Functions..

Granularity of the I/O mapping

The +granularity of the I/O mapping is defined by the MULT parameter +of the I/O mapping macros: HW_MAPPING, HW_MAPPING_EXT, HW_MAPPING_EXT2 and HW_MAPPING_EXT3.

The MULT parameter specifies the granularity of the mapping. It takes one of the +following values:

    +
  • HW_MULT_4K use +4K pages. The PHYS and LIN parameters must +be multiples of 4K.

  • +
  • HW_MULT_64K use +64K pages. The PHYS and LIN parameters must +be multiples of 64K.

  • +
  • HW_MULT_1M use +1M sections. The PHYS and LIN parameters +must be multiples of 1M.

  • +

In each case the unit in which the SIZE parameter +is specified is MULT, that is to say the actual mapping size +in bytes is SIZE*MULT. For example:

HW_MAPPING 0x80000000, 1, HW_MULT_4K +HW_MAPPING 0x80010000, 3, HW_MULT_64K

declares a mapping +of size 4K starting at physical address 0x80000000 followed +by a mapping of 192K in 64K pages starting at physical address 0x80010000.

Determining the linear address

For +those macros that don't specify a linear address: HW_MAPPING and HW_MAPPING_EXT, +it is determined as follows:

    +
  • On the direct memory +model, it is equal to the physical address.

  • +
  • On the moving memory +model and the multiple memory model, the first such mapping is placed at KPrimaryIOBase (0x63000000 on +the moving model, 0xC3000000 on the multiple model). Each +mapping first rounds the linear address counter up to the next multiple of MULT before +making the mapping, then increments it by SIZE*MULT after +making it.

  • +

For example, on the moving memory model, the following mappings would +have linear addresses 0x63000000, 0x63002000, 0x63010000, 0x63020000 and 0x63100000 respectively:

HW_MAPPING 0x80000000, 2, HW_MULT_4K +HW_MAPPING 0x80010000, 1, HW_MULT_4K +HW_MAPPING 0x80100000, 1, HW_MULT_64K +HW_MAPPING 0x80200000, 1, HW_MULT_4K +HW_MAPPING 0x90000000, 1, HW_MULT_1M

For the direct memory +model, all I/O mappings required by the system must be listed here since it +is not possible to make further mappings once the kernel is running.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-2607CCFA-3D24-4716-A447-74304F861C44.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-2607CCFA-3D24-4716-A447-74304F861C44.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,490 @@ + + + + + +DSDIORegisterInterface +Class TutorialDescribes the DSDIORegisterInterface API class. +
Description

This +class provides the main client API between the SDIO implementation and the +rest of the system.

For portability reasons, it is recommended that +this class is allocated on behalf of the client by the appropriate function +class after the client has been registered with the SDIO function.

Unless +stated otherwise, all the register offsets are defined to be relative to offsets +within the SDIO function.

+ + + +

Header file

+

regifc.h

+
+ +

Source code file

+

regifc.cpp

+
+ +

Required libraries

+

EPBUSSDIO

+
+ +

Class declaration

+

class DSDIORegisterInterface: public DSDIOSession

+
+ + +
+
Read8()

The +function declaration for the Read8() method is:

IMPORT_C TInt Read8(TUint32 aReg, TUint8* aReadDataP);

Description

This method reads a single 8 bit value from the +specified register.

Parameters

+ + + +

TUint32 aReq

+

The Source register address.

+
+ +

TUint8* aReadDataP

+

The location of the byte to read into.

+
+ + +

Return value

+ + + +

TInt

+

The result of the operation. KErrNone if the operation was successful, +otherwise a system wide error code.

+
+ + +
+
Write8()

The +function declaration for the Write8() method is:

IMPORT_C TInt Write8(TUint32 aReg, TUint8 aWriteVal);

Description

This method writes a single 8 bit value to the +register specified.

Parameters

+ + + +

TUint32 aReg

+

The destination register address.

+
+ +

TUint8 aWriteVal

+

The 8 bit value to be written.

+
+ + +

Return value

+ + + +

TInt

+

The result of the operation. KErrNone if the operation +was successful, otherwise a system wide error code.

+
+ + +
+
Modify8()

The +function declaration for the Modify8() method is:

IMPORT_C TInt Modify8(TUint32 aReg, TUint8 aSet, TUint8 aClr); +

Description

This method performs a bitwise read-modify-write +operation on the specified register.

Parameters

+ + + +

TUint32 aReg

+

The destination register address.

+
+ +

TUint8 aSet

+

A bitmask of the values to be set.

+
+ +

TUint8 aClr

+

A bitmask of the values to be cleared.

+
+ + +

Return value

+ + + +

TInt

+

The result of the operation. KErrNone if the operation +was successful, otherwise a system wide error code.

+
+ + +
+
Modify8() with +read-after-write

The function declaration for the Modify8() with +read-after-write method is:

IMPORT_C TInt Modify8(TUint32 aReg, TUint8 aSet, TUint8 aClr, TUint8* aReadDataP);

Description

This method performs a bitwise read-modify-write operation on the +specified register.

Parameters

+ + + +

TUint32 aReg

+

The destination register address.

+
+ +

TUint8 aSet

+

A bitmask of the values to be set.

+
+ +

TUint8 aClr

+

A bitmask of the values to be cleared.

+
+ +

TUint8* aReadDataP

+

The address of the byte to read into. The result of the operation +is stored in this buffer.

+
+ + +

Return value

+ + + +

TInt

+

The result of the operation. KErrNone if the operation +was successful, otherwise a system wide error code.

+
+ + +
+
ReadMultiple8()

The +function declaration for the ReadMultiple8() method is:

IMPORT_C TInt ReadMultiple8(TUint32 aReg, TUint8* aDataP, TUint32 aLen); +

Description

This method reads the specified number +of bytes starting at the specified register offset.

Parameters

+ + + +

TUint32 aReg

+

The source register address.

+
+ +

TUint8* aDataP

+

The start address of the destination buffer.

+
+ +

TUint32 aLen

+

The number of bytes to be read.

+
+ + +

Return value

+ + + +

TInt

+

The result of the operation. KErrNone if the operation +was successful, otherwise a system wide error code.

+
+ + +
+
ReadMultiple8() +with auto-increment

The function declaration for the ReadMultiple8() +method with auto-increment is:

IMPORT_C TInt ReadMultiple8(TUint32 aReg, TUint8* aDataP, TUint32 aLen, TBool aAutoInc); +

Description

This method reads the specified number +of bytes starting at the specified register offset.

Parameters

+ + + +

TUint32 aReg

+

The source register address.

+
+ +

TUint8* aDataP

+

The start address of the destination buffer.

+
+ +

TUint32 aLen

+

The number of bytes that are to be read.

+
+ +

TBool aAutoInc

+

Enable or disable the auto-increment functionality.

+
+ + +

Return value

+ + + +

TInt

+

The result of the operation. KErrNone if the operation +was successful, otherwise a system wide error code.

+
+ + +
+
ReadMultiple8() +using shared chunks

The function declaration for the ReadMultiple8()method +using shared chunks is:

IMPORT_C TInt ReadMultiple8(TUint32 aReg, DChunk* aChunk, TUint32 aOffset, TUint32 aLen); +

Description

This method reads the specified number +of bytes starting at the specified register offset.

Parameters

+ + + +

TUint32 aReg

+

The source register address.

+
+ +

DChunk* aChunk

+

The chunk that hosts the destination buffer.

+
+ +

TUint32 aOffset

+

The offset from the start of the chunk to the start of the destination +buffer.

+
+ +

TUint32 aLen

+

The number of bytes to be read.

+
+ + +

Return value

+ + + +

TInt

+

The result of the operation. KErrNone if the operation +was successful, otherwise a system wide error code.

+
+ + +
+
ReadMultiple8() +with auto-increment using shared chunks

The function declaration +for the ReadMultiple8() method with auto-increment using +shared chunks is:

IMPORT_C TInt ReadMultiple8(TUint32 aReg, DChunk* aChunk, TUint32 aOffset, TUint32 aLen, TBool aAutoInc);

Description

This method reads the specified number of bytes +starting at the specified register offset.

Parameters

+ + + +

TUint32 aReg

+

The source register address.

+
+ +

DChunk* aChunk

+

The chunk that hosts the destination buffer.

+
+ +

TUint32 aOffset

+

The offset from the start of the chunk to the start of the destination +buffer.

+
+ +

TUint32 aLen

+

The number of bytes to be read.

+
+ +

TBool aAutoInc

+

Enable or disable the auto-increment functionality.

+
+ + +

Return value

+ + + +

TInt

+

The result of the operation. KErrNone if the operation +was successful, otherwise a system wide error code.

+
+ + +
+
WriteMultiple8()

The +function declaration for the WriteMultiple8() method is:

IMPORT_C TInt WriteMultiple8(TUint32 aReg, TUint8* aDataP, TUint32 aLen); +

Description

This method writes the specified length +of bytes starting at the specified register.

Parameters

+ + + +

TUint32 aReg

+

The destination register address.

+
+ +

TUint8* aDataP

+

The start address of the source buffer.

+
+ +

TUint32 aLen

+

The number of bytes to be written.

+
+ + +

Return value

+ + + +

TInt

+

The result of the operation. KErrNone if the operation +was successful, otherwise a system wide error code.

+
+ + +
+
WriteMultiple8() +with auto-increment

The function declaration for the WriteMultiple8() method +with auto-increment is:

IMPORT_C TInt WriteMultiple8(TUint32 aReg, TUint8* aDataP, TUint32 aLen, TBool aAutoInc); +

Description

This method writes the specified length +of bytes starting at the specified register.

Parameters

+ + + +

TUint32 aReg

+

The destination register address.

+
+ +

TUint8* aDataP

+

The start address of the source buffer.

+
+ +

TUint32 aLen

+

The number of bytes to be written.

+
+ +

TBool aAutoInc

+

Enable or disable the auto-increment functionality.

+
+ + +

Return value

+ + + +

TInt

+

The result of the operation. KErrNone if the operation +was successful, otherwise a system wide error code.

+
+ + +
+
WriteMultiple8() +using shared chunks

The function declaration for the WriteMultiple8() method +using shared chunks is:

IMPORT_C TInt WriteMultiple8(TUint32 aReg, DChunk* aChunk, TUint32 aOffset, TUint32 aLen); +

Description

This method writes the specified length +of bytes starting at the specified register.

Parameters

+ + + +

TUint32 aReg

+

The destination register address.

+
+ +

DChunk* aChunk

+

The chunk that hosts the source buffer.

+
+ +

TUint32 aOffset

+

The offset from the start of the chunk and the start address of +the source buffer.

+
+ +

TUint32 aLen

+

The number of bytes to be written.

+
+ + +

Return value

+ + + +

TInt

+

The result of the operation. KErrNone if the operation +was successful, otherwise a system wide error code.

+
+ + +
+
WriteMultiple8( +) with auto-increment using shared chunks

The function declaration +for the WriteMultiple8() method with autoincrement using +shared chunks is:

IMPORT_C TInt WriteMultiple8(TUint32 aReg, DChunk* aChunk, TUint32 aOffset, TUint32 aLen, TBool aAutoInc);

Description

This method writes the specified length of bytes +starting at the specified register.

Parameters

+ + + +

TUint32 aReg

+

The destination register address.

+
+ +

DChunk* aChunk

+

The chunk that hosts the source buffer.

+
+ +

TUint32 aOffset

+

The offset from the start of the chunk and the start address of +the source buffer.

+
+ +

TUint32 aLen

+

The number of bytes to be written.

+
+ +

TBool aAutoInc

+

Enable or disable the auto-increment functionality.

+
+ + +

Return value

+ + + +

TInt

+

The result of the operation. KErrNone if the operation +was successful, otherwise a system wide error code.

+
+ + +
+
SetAsync()

The +function declaration for the SetAsync() method is:

IMPORT_C TBool SetAsync(TMMCCallBack& aCallback); +

Description

This function allows the user to disable +the synchronous nature of the DSDIORegInterface class, by using the specified +callback function to indicate the completion of an operation.

Parameters

+ + + +

TMMCCallback& aCallback

+

Reference to the callback function.

+
+ + +

Return value

+ + + +

TBool

+

The result of the operation. KErrNone if the operation +was successful, otherwise a system wide error code.

+
+ + +
+
SetSync()

The +function declaration for the SetSync() method is:

IMPORT_C TBool SetSync();

Description

Allows the synchronous nature of the DSDIORegInterface class to be enabled.

When +the synchronous nature of the DSDIORegInterface class is enabled, then completion +of an operation is specified by waiting on a semaphore.

Parameters

None

Return +value

+ + + +

TBool

+

The result of the operation. KErrNone if the operation +was successful, otherwise a system wide error code.

+
+ + +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-2622DE31-AA12-5FAD-86FB-B13259EFC6D9-master.png Binary file Adaptation/GUID-2622DE31-AA12-5FAD-86FB-B13259EFC6D9-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-2622DE31-AA12-5FAD-86FB-B13259EFC6D9_d0e9239_href.png Binary file Adaptation/GUID-2622DE31-AA12-5FAD-86FB-B13259EFC6D9_d0e9239_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-2648B61C-6EBD-4668-AACD-EA4B2C435BB2.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-2648B61C-6EBD-4668-AACD-EA4B2C435BB2.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,90 @@ + + + + + +Message +HandlingThis document describes message queues and message handling. +
Message queues

The +request handling kernel side DFC is managed by a message queue object of the TMessageQueue type. +The message queue consists of a DFC and a doubly linked list of received messages. +The messages are represented by TThreadMessage objects +and are owned by each user thread. Requests are queued as message objects +on the message queue.

The driver framework requires that the driver +sets a DFC queue to use with the message queue. This is done by calling DLogicalChannel::SetDfcQ(). +The message queue must also be enabled to receive incoming messages by calling TMessageQue::Receive().

// Logical Channel Second stage constructor +TInt DExDriverLogicalChannel::DoCreate(TInt /*aUnit*/, const TDesC8* + /*anInfo*/, const TVersion& aVer) + { + ... + // Set up the DFC queue for this driver. Here, the DFC + // queue is created by the PDD dedicated for this driver. + SetDfcQ(Pdd()->DfcQ()); + + // Start receiving the incoming requests on the message queue + iMsgQ.Receive(); + ... + }

The Kernel provides a standard DFC queue, which runs +on a dedicated kernel thread called DFCThread0, for general +use by drivers. However, it is recommended that the driver creates its own +DFC thread to process its requests. The following example shows how a PDD +can implement the DfcQ() function to return a newly created +DFC thread:

// DfcQ - Creates a DFC queue dedicated for the tutorial driver +TDynamicDfcQue* DExUartPhysicalChannelH4::DfcQ() + { + // Create a DFC queue dedicated to the driver with a specified + // priority + TInt r = Kern::DynamicDfcQCreate(pDfcQ,KExUartDfcPriority, + KExUartDfcName); + if (r!=KErrNone) + { + // DfcQ failed, return NULL + return NULL; + } + return iDfcQueue; + }

The DFC thread that is created for the driver must be +destroyed after use. To do this, the driver can create an Exit or Kill DFC +request and queue it to the thread to be destroyed in the logical channel +destructor. This exit DFC function cancels any other requests pending using TDfc::Cancel() and +calls Kern::Exit() to terminate the thread.

The TDynamicDfcQue has +a destroy method that can be run on the channel destructor. The destroy method +destroys the DFC queue, kills the DFC thread and deletes the TDynamicDfcQue object +itself. This avoids the possibilities of memory leaks in the DFC.

+
Message handling

All +synchronous and asynchronous requests are passed to the HandleMsg() function +by the framework, with the message as an argument. A driver should implement +the function to identify the message type and handle the messages accordingly.

The +client thread is blocked until the message is completed, as the request uses +the thread's message object. If the client thread was left free, it would +corrupt the message if another request was issued.

When the driver +has completed handling the message, it notifies the framework by calling TThreadMessage::Complete(). +The client thread is then unblocked, and can either block on the thread semaphore +or issue further requests before blocking.

For synchronous requests, +the message is not completed until the request itself is complete, and the +driver calls the TThreadMessage::Complete() function after +the actual completion of the request. However, for asynchronous requests, +the message is completed after the driver has accepted the request, but not +necessarily after the actual completion of the request, which can happen later. +This means that the driver calls TThreadMessage::Complete() as +soon as it has received the message and initiated the required processing +to complete the request.

void DExDriverLogicalChannel::HandleMsg(TMessageBase* aMsg) + { + TThreadMessage& m = *(TThreadMessage*)aMsg; + // obtain the function id value to determine the request nature + TInt id = m.iValue; + ... + if (id>=0) // Synchronous messages + { + // call synchronous message handler function, DoControl() + TInt r = DoControl(id,m.Ptr0(),m.Ptr1()); + m.Complete(r,ETrue); + return; + } + }
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-26621CA5-B686-53FB-AF3E-96CDD38C8520.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-26621CA5-B686-53FB-AF3E-96CDD38C8520.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,148 @@ + + + + + + Physical +RAM DefragmentationDescribes Symbian platform RAM defragmentation. +

Symbian platform physical RAM defragmentation is the process of moving +physical pages, used to back virtual allocations, in order to create empty +physical ranges. This enables the powering off of individual RAM banks or, +if required, the allocation of a large contiguous buffer, for example, for +a CCD image. This functionality allows a more efficient use of RAM in terms +of both memory and power consumption.

+

Symbian platform RAM defragmentation is used to create large areas +of contiguous RAM and/or allow the powering down of surplus RAM ICs: it does +not locate and consolidate fragmented files and folders. This functionality +enables more efficient use of physical RAM and may enable a lower Bill Of +Materials (BOM), or increase battery life.

+

There are two interrelated use cases for defragmenting physical RAM:

+
    +
  • many device drivers +require physical RAM for use for buffers. For example, a camera driver may +require a physically contiguous buffer for holding the output of the CCD. +In releases 9.3 and before such memory was typically allocated at boot time. +This practice increases initial RAM consumption after boot. Total RAM consumption +can be reduced if memory for such buffers is only allocated as required, rather +than at boot time. It is not possible to provide an absolute guarantee that +the RAM will be available when needed, but it should succeed in all but exceptional +cases.

  • +
  • typically, memory consumption +of a phone while idle is less than the total memory available. Idle and active +power consumption can be decreased by powering down unused RAM chips or unused +RAM banks within a RAM chip. This may also involve cooperation with a higher +level component in the UI which can shut down unused applications to reclaim +more memory.

  • +
+
Defragmention +of RAM

TRamDefragRequest is the class used +by device drivers to perform all defragmentation operations. The three defragmentation +operations provided are:

    +
  • TRamDefragRequest::DefragRam() – +Performs a general defragmentation.

  • +
  • TRamDefragRequest::ClaimRamZone() – +Attempts to claim a whole RAM zone.

  • +
  • TRamDefragRequest::EmptyRamZone() – +Removes allocated pages from a RAM zone.

  • +

There are three overloads for each of these TRamDefragRequest defragmentation +methods which behave differently:

    +
  • The first overload is +synchronous and blocks the calling thread until the defragmentation is complete +(or is cancelled using TRamDefragRequest::Cancel). In this +case, the return value is the result of the defragmentation – an appropriate +system-wide error code.

  • +
  • The second overload +is asynchronous and takes a pointer to an NFastSemaphore. +The semaphore is signalled when the defragmentation is complete. The return +value is KErrNone unless there was a problem initializing +the request, in which case an appropriate system-wide error code is returned. +The result of the defragmentation can be obtained by calling TRamDefragRequest::Result() after +the semaphore has been signalled.

  • +
  • The third overload is +asynchronous and takes a DFC. The DFC is queued when the defragmentation is +complete. The return value is KErrNone unless there was +a problem initializing the request, in which case an appropriate system-wide +error code is returned. The result of the defragmentation can be obtained +by calling TRamDefragRequest::Result().

  • +

All TRamDefragRequest defragmentation operations +are placed onto a FIFO queue. Any currently running defragmentation operation +must complete or be cancelled before a new defragmentation operation can begin.

All +the TRamDefragRequest defragmentation methods have the +following parameter in common:

aPriority

aPriority specifies the priority +of the thread that performs the defragmentation. If aPriority = KInheritPriority, +the default, then the defragmentation thread will execute with the same priority +as thread that invokes the defragmentation operation.

Determining the result of +a defragmentation operation

For synchronous overloads of the defragmentation +methods the error code returned by the defragmentation method can be used +to determine the result of the defragmentation operation. KErrNone signifies +that the defragmentation operation was successful.

For asynchronous +overloads of the defragmentation methods the result of the defragmentation +operation is determined by invoking TRamDefragRequest::Result() after +it has signalled that it has completed. Again, KErrNone signifies +that the defragmentation operation was successful.

Cancelling a defragmentation +operation

A defragmentation operation can be cancelled by invoking +the TRamDefragRequest::Cancel() method. This method cancels +the defragmentation, if it is in progress or is in the queue, and causes it +to complete with KErrCancel. If the defragmentation operation +has already completed, this method has no effect and the result remains as +it was.

+
General defragmentation

TRamDefragRequest::DefragRam() initiates a general defragmentation. A general defragmentation attempts +to arrange the currently allocated pages so that only the minimum number and +the most preferable RAM zones required are powered and refreshed. Each time +the general defragmentation successfully empties a RAM zone the base port +invokes the RAM zone call back function with aOp = ERamZoneOp_PowerDown see RAM +zone call back function. This informs the base port that it can decide +to, not refresh or power down the empty RAM zone when it deems it to be appropriate.

Depending +on the current state of the system and the value of aMaxPages, +a general defragmentation may require a significant amount of time to complete. +Therefore, if a general defragmentation is performed too frequently the power +saving benefits achieved by powering down or not refreshing RAM zones, may +prove to be less than the power consumed while performing the general defragmentation. +It is recommended that a general defragmentation is only performed once the +device has been idle for a significant period of time.

aMaxPages

TRamDefragRequest::DefragRam() is +similar to the other defragmentation methods, except that it has an additional +parameter aMaxPages. aMaxPages specifies +a limit on the number of pages that can be moved during a general defragmentation +when set to zero there is no limit. This can be useful in limiting the amount +of processing a general defragmentation performs and therefore the power consumed +by the general defragmentation. However, setting aMaxPages too +low may prevent the general defragmentation from being able to empty a single +RAM zone despite there being enough free pages in the most preferable RAM +zones.

+
RAM defragmentation +of Physically contiguous allocations

Some devices may define RAM Zones for use +by particular applications or hardware peripherals requiring a block of physically +contiguous RAM. TRamDefragRequest::ClaimRamZone() is used +by the device driver when it requires use of the pre-determined RAM zone to +be used for the block of physically contiguous RAM.

TRamDefragRequest::ClaimRamZone() is +similar to the other defragmentation methods, except that it has two extra +parameters:

    +
  • aId – +the ID of the RAM zone to be claimed.

  • +
  • aPhysAddr – +on successful completion of the claim operation this is loaded with the physical +base address of the claimed RAM zone.

  • +

Once a RAM zone has been successfully claimed its memory can be used +by the device driver after being mapped into a shared +chunk. When the claimed RAM zone is no longer required, the device +driver must use Epoc::FreePhysicalRam to release it for +use by the rest of the system.

+
Zone specific +allocations

A device driver may attempt to allocate memory from +a specific RAM zone using Epoc::ZoneAllocPhysicalRam(). +If the allocation fails then use TRamDefragRequest::EmptyRamZone() to +remove as many pages as is reasonable from the RAM zone.

TRamDefragRequest::EmptyRamZone() is +similar to the other defragmentation methods, as described in Defragmention of RAM, except that it has an extra parameter:

    +
  • aId – the ID of the +RAM zone to be emptied.

  • +

Once the empty defragmentation operation has completed the RAM zone +specific allocation can be attempted again. However, the RAM zone specific +allocation may still fail in high RAM usage situations or if the RAM zone +has too many fixed pages allocated.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-26714A57-B6B4-5E81-B512-FB520718482B.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-26714A57-B6B4-5E81-B512-FB520718482B.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,28 @@ + + + + + +Debug Monitor +ToolDescribes how to get basic information about the system state when +problems occur on hardware to help you debug your software. +

Device drivers are typically run and debugged on target hardware rather +than on the Emulator. The tool that provides this information is called the debug +monitor or the crash debugger.

+

The debug monitor is used when the Kernel faults. This can happen because +there is a fault in a kernel-side component, such as a device driver, or because +a thread or process marked as system-critical crashes.

+

Note that the debug monitor is one of the basic ways of debugging software +problems on target hardware. Full interactive debugging on reference hardware +and some real phones is available through commercial IDEs.

+
+ +H4 in the Debug Monitor (or Why is the board flashing?) + +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-2700AAC8-A034-5E7D-B0E0-26B49E68BB18.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-2700AAC8-A034-5E7D-B0E0-26B49E68BB18.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,73 @@ + + + + + +Personality Layer for Real Time ApplicationsA base port can add a software layer called a personality +layer to the Kernel to provide an emulation of a real time operating +system (RTOS) +

. You can provide a personality layer so that a phone can run existing +protocol stacks, for example, mobile telephony signalling stacks, +or Bluetooth stacks, on the same CPU that runs the Symbian platform +applications.

+

Such protocol stacks, often referred to as Real Time Applications +(RTA), almost always run on an RTOS, and the aim of the personality +layer is to provide the same API as the RTOS, or at least as much +of it as is required by the RTA. The RTA can then run, using the Kernel +Architecture 2 Nanokernel layer as the underlying real time kernel.

+

The following diagram illustrates the point simply.

+ + + +

There is sample code at ...\e32\personality\... that you should refer to while reading this.

+
RTOS +environment features

As a basis for emulating an RTOS, +the RTOS is assumed to provide the following features:

    +
  • Threads

  • +
  • Thread synchronisation/communication

  • +
  • Thread scheduling +following a hardware interrupt

  • +
  • Timer management +functionality

  • +
  • Memory management.

  • +

Threads

Threads are independent units of execution, +usually scheduled on a strict highest-priority-first basis. There +are generally a fixed number of priorities. Round robin scheduling +of equal priority threads may be available but is usually not used +in real time applications. Dynamic creation and destruction of threads +may or may not be possible.

Thread synchronisation/communication

Typical examples +of such thread synchronisation and communication mechanisms are semaphores, +message queues and event flags.

There is wide variation between +systems as to which primitives are provided and what features they +support. Again, dynamic creation and destruction of such synchronisation +and communication objects may or may not be supported. Mutual exclusion +protection is often achieved by simply disabling interrupts, or occasionally +by disabling rescheduling.

Thread scheduling following a hardware interrupt

This +is usually achieved by allowing interrupt service routines (ISRs) +to make system calls which perform operations such as signalling a +semaphore, posting a message to a queue or setting event flags, which +would cause a thread waiting on the semaphore, message queue or event +flag to run.

Some systems don't allow ISRs to perform these +operations directly but require them to queue some kind of deferred +function call. This is a function which runs at a lower priority than +hardware interrupts (i.e. with interrupts enabled) but at a higher +priority than any thread - for example a Nucleus Plus HISR. The deferred +function call then performs the operation which causes thread rescheduling.

Timer management functionality

A timer management +function is usually also provided, allowing several software timers +to be driven from a single hardware timer. On expiry, a software timer +may call a supplied timer handler, post a message to a queue or set +an event flag.

Memory management

An RTOS often provides memory management, +usually in the form of fixed size block management as that allows +real time allocation and deallocation. Some RTOSs may also support +full variable size block management. However most RTOSs do not support +use of a hardware MMU and, even if the RTOS supports it (for example +OSE does), the real time applications under consideration do not make +use of such support since they are generally written to run on hardware +without an MMU.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-28844FE0-AE0F-531C-826E-CDA8400A0581.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-28844FE0-AE0F-531C-826E-CDA8400A0581.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,104 @@ + + + + + +Sessions +and Request ManagementDescribes how the MultiMediaCard Controller manages the sessions +and sets the order of requests. +

When a number of drivers have a session with the MultiMediaCard Controller, +the MultiMediaCard Controller can have many requests to service.

+
Session queues

To +handle sessions, the MultiMediaCard controller implements a scheduler. The +MultiMediaCard stack has three internal queues:

    +
  • an entry queue - this +is the queue onto which a session is initially added when a client submits +the session object by calling DMMCSession::Engage() on +it. This is anchored in the DMMCStack::iEntryQueue private +member.

  • +
  • a ready queue - this +is the queue into which a session is moved when it is ready to be handled; +the scheduler moves all the sessions from the entry queue into the ready queue +when it can. This is anchored in the DMMCStack::iReadyQueue private +member.

  • +
  • a working set queue +- this is the queue of sessions to be processed as chosen by the scheduler. +This queue is limited to eight sessions. The scheduler moves a session from +the ready queue to the working set queue if all current sessions in the working +set queue are blocked and there are less than eight sessions in it. This is +anchored in the DMMCStack::iWorkSet private member.

  • +

All three queues are circular queues as implemented using the internal +Symbian platform class TMMCSessionRing.

+ +
+
The scheduler

Every +time one of the following events occurs, the MultiMediaCard stack invokes +its scheduler to deal with that event:

    +
  • a client submitting +a session to the MultiMediaCard controller

  • +
  • a client aborting a +session

  • +
  • a card interrupt occurring.

  • +

The stack invokes the scheduler by calling the internal function DMMCStack::Scheduler().

+
Blocking a +session

Sometimes, the MultiMediaCard controller has to perform +its processing in a DFC context. In those cases the Controller postpones operation +by queuing a DFC; the DFC call-back function then resumes the operation by +invoking the scheduler again. This means that the scheduler may be running +as part of a kernel executive call, a DFC or an interrupt service routine.

In +general, the MultiMediaCard controller processes a session in stages, issuing +commands, checking responses, reading or writing data etc. Each stage is usually +done asynchronously, first setting up the activity and then setting up a means +of being notified when that activity is complete, for whatever reason (e.g. +issuing a command and setting up an interrupt when a response has been received).

If +a session is waiting on an asynchronous operation, it is blocked. When one +session is blocked, the stack tries to process another session which isn’t +blocked.

The blocking of sessions is set up and implemented internally +to Symbian platform. However, the platform specific layer can block a session +by calling the DMMCStack::BlockCurrentSession() function +with the KMMCBlockOnASSPFunction bit set in the parameter +passed to that function.

Internally, the DMMCSession::iBlockOn private +data member is set when a session is blocked. This is a bit-mask variable +containing the reason that the session is blocked.

+
Scheduler algorithm

The +following flow-diagram shows the algorithm used by the scheduler.

+ +

The DMMCStack private members referenced in this +diagram have the following meaning:

+ + + +

DMMCStack::iAbortReq

+

Set to ETrue when there are sessions on the stack +that have been marked for abort by the client. This is set as a result of +a call to DMMCSession::Abort().

+
+ +

DMMCStack::iAttention

+

Set to ETrue when there are sessions ready to +run. This is set when a session is submitted to the stack as a result of a +call to DMMCSession::Engage(), or when a session becomes +unblocked.

+
+ +

DMMCStack::iCompReq

+

Set to ETrue when there are sessions on the stack +ready to complete. This is set internally by the controller through calls +to the private functions DMMCStack::MarkComplete() or DMMCStack::CompleteAll().

+
+ +

DMMCStack::iInitialise

+

Set to ETrue when stack initialization (CIM_INIT_STACK) +has been forced. This is set when the controller needs to re-power the stack, +and to power up a card on client requests.

+
+ + +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-28F3F720-A2E0-59C9-8BB4-B6124CFC6C89-master.png Binary file Adaptation/GUID-28F3F720-A2E0-59C9-8BB4-B6124CFC6C89-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-28F3F720-A2E0-59C9-8BB4-B6124CFC6C89_d0e11050_href.png Binary file Adaptation/GUID-28F3F720-A2E0-59C9-8BB4-B6124CFC6C89_d0e11050_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-29B84A67-9DB7-5F4C-A4D1-A3BDC69015A8.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-29B84A67-9DB7-5F4C-A4D1-A3BDC69015A8.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,113 @@ + + + + + +Additional +System Wide Power StatesA base port can add new power states to improve power management +for phone hardware. +

The Kernel defines three system wide power states. A base port can add +new power states to improve power management for phone hardware.

+

The generic system wide power states that are defined are Active, Standby and Off. +Any additional sub-states of the Active power state must be wholly +managed by the base port. These states may not need to be declared explicitly +and may result from peripherals, or groups of peripherals, having moved to +their low power state (see also moving +to their low power state). The device will then “trickle“ into one +of these sub-states instead of transitioning into them as a result of a user +action or system policy decision.

+

Usually, the transition of the system into one of the additional low power +states happens when the CPU enters the idle mode. The transition may be automatic +and wholly managed by the ASSP hardware or may result from an action taken +by the software routine that prepares the CPU to go to idle mode.

+
Sleeping in idle mode

An example of this is when +the base port uses the idle mode to put the CPU and the device into hardware +“Sleep” mode similar to that which can be achieved with a transition to Standby mode +as described in the implementation issues for implementing +DPowerController::PowerDown()

When called, the power controller’s DPowerController::CpuIdle() implementation +could take the necessary steps to prepare the CPU and the platform to go to +“Sleep”.

There is a balance between the power savings obtained from +moving the CPU and platform into “Sleep” mode in Idle and the performance +hit resulting from spending time restoring the status after coming out of +“Sleep” mode. Usually the CpuIdle() routine investigates +the timer queue (using NTimerQ::IdleTime()) for the next +timer expiration and decides to move or not to move the CPU and platform into +“Sleep” mode based on how much time there is before the next timer expiration. +The threshold above which it is considered productive to move into “Sleep” +is dependent on the base port.

The decision to move into “Sleep” mode +may also be based on the current level of activity, or collected metrics on +the length of time spent in Idle, or other historical information. This can +be implemented entirely by the base port, or it may require the services of +an external component (such as, for example, Speed Management).

The +transition to a hardware “Sleep” mode may also depend on shared peripherals +being in a particular state, for example, no pending requests from other peripherals. +This means that the power controller may need to check with the peripheral +driver before initiating the change. The power controller could use the ASSP/Variant +method to access the resource manager and check the usage of a shared peripheral +using its GetCount() API.

The decision to move into +“Sleep” mode could be dependent on a number of peripherals (shared and not +shared) being in Standby and a number of controllable power resources being +turned off. Therefore the power controller may also need to check with the +resource manager (through the Variant or ASSP) for the state of a specific +set of controllable power resources (using the ResourceManager::GetResourceState() API).

On +going to “Sleep”, an action or set of actions might need to be taken that +would affect the whole platform. An example of this is when DRAM is put into +self-refresh mode on entering the CPU Idle mode after all peripherals that +might access it (including the LCD controller and DSP) are in low power state. +Unused DRAM banks may also be powered down.

The following diagram +exemplifies how the evolution of system power would look like on a system +when the most power saving “Sleep” mode can only be reached – from Idle - +when Peripherals A, B and C are already in their low power mode. On going +to the most power saving “Sleep” mode, additional actions can be taken to +lower the system power level:

+System power use over time + +
    +
  • The system is active +when a request for service is made on peripheral A; the peripheral driver +for peripheral A requests its transition to operational state increasing the +system power requirement (a).

  • +
  • After a period of activity +related to servicing the request, the system enters the idle thread; in CpuIdle() the +time for the next timer expiration is investigated and is found to be long +enough to send the system to sleep, powering down peripherals A, B and C to +their low power state and other system resources (b).

  • +
  • The timer expires and +the system wakes up to the same power level as before (c).

  • +
  • The inactivity timer +implemented in the peripheral driver for peripheral A expires: the peripheral +is transitioned to the low power state (d).

  • +
  • At (e) the system enters +the idle thread again: the timer queue is investigated and then enters sleep +mode, waking up again when an interrupt occurs (f).

  • +
  • The inactivity timer +associated with the peripheral drive for peripheral B expires and the peripheral +is transitioned to its low power state (g).

  • +
  • On the next call to CpuIdle() the +time for the next timer expiration is not long enough to power off peripherals +and other system resources: only limited power savings can be made (h) until +the system wakes up again (i).

  • +
  • Finally, the inactivity +timer for peripheral C expires and the peripheral is transitioned to low power +state (j). On reaching another period of system idle all conditions are met +to send the system to the deepest sleep mode available accompanied by the +switching off other power resources (k).

  • +
  • On waking up (l) the +system resources are restored to the same power level as before.

  • +

Any transition to and from these low power states must be transparent +to the rest of the system. A transparent transition is one that can be instantly +reversed, perhaps automatically in hardware, and has no noticeable impact +on system performance. In other words, it should be possible to wake the processor +up and move the entire device to Active Mode as if coming from a “normal” +Idle Mode.

To perform a system wide power change which is not transparent, +peripherals that may be affected by the transition would need to be examined, +and interfaces would have to be provided so that the users of these peripherals +could query the peripheral and allow or disallow the system transition into +that state.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-2ADB873A-1580-476A-9642-AB47D13D4A98.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-2ADB873A-1580-476A-9642-AB47D13D4A98.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,102 @@ + + + + + +Driver +Source FilesThis document details the directory structure and file types of +logical device drivers and physical device drivers. +
Directory +structure

Device driver DLLs come in two types - the logical +device driver (LDD), and the physical device driver (PDD). Typically, a single +LDD supports functionality common to a class of hardware devices, whereas +a PDD supports a specific member of that class.

In Symbian platform +source code, PDDs are part of variant baseports, while LDDs are stored in +a shared location that is not specific to a particular variant:

    +
  • PDD source files (.cpp, .h and .mmp) for peripherals for the H4 variant are in source directories named base\omap_hrp\h4\ <driver_pdd >.

  • +
  • PDD source files (.cpp, .h and .mmp) for peripherals for the Emulator variant are in source directories named base\wins\ <driver_pdd >.

  • +
  • LDD source files are +in source directories named base\e32\ <driver _ldd >, +which are shared for all variants.

  • +
  • Common test application +source files are in source directories named base\e32test\ <driver_test >.

  • +

For both types of driver, the source files are generally organised +in the following sub-directories:

    +
  • <driver >\group.mmp files

  • +
  • <driver >\inc.h files

  • +
  • <driver >\src.cpp files

  • +
+
File extensions

The +project files of a device driver that is part of the Kernel code are similar +to those for other components in Symbian platform. The following tables summarise +the source and binary file types you will see:

+ + + +

Source File Type

+

Description

+
+ +

.h

+

Include files

+
+ +

.cpp

+

Source files

+
+ +

.inl

+

Inline files

+
+ +

.mmp

+

Project file, similar to a makefile in other operating systems

+
+ +

.inf

+

Build file grouping multiple mmp files. Command line builds are +done from this file's directory.

+
+ +

.iby

+

ROM include file. This file specifies the built files that need +to be included in a ROM image. This is not used in builds for the Emulator.

+
+ + +

+ + + +

Binary File Type

+

Description

+
+ +

.ldd

+

Logical Device Driver target. A LDD contains code that is common +to a class of hardware devices.

+
+ +

.pdd

+

Physical Device Driver target. A PDD contains code that is specific +to one particular type of device.

+
+ +

.exe

+

Application executable target.

+
+ +

.ext

+

Kernel extension target, a driver that is started when the kernel +boots.

+
+ + +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-2AE438CC-F2E4-5FCB-971F-CFFAE5EF81E4-master.png Binary file Adaptation/GUID-2AE438CC-F2E4-5FCB-971F-CFFAE5EF81E4-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-2AE438CC-F2E4-5FCB-971F-CFFAE5EF81E4_d0e93636_href.png Binary file Adaptation/GUID-2AE438CC-F2E4-5FCB-971F-CFFAE5EF81E4_d0e93636_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-2B7D04D9-98DE-5284-836D-01DB4FA8949D.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-2B7D04D9-98DE-5284-836D-01DB4FA8949D.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,15 @@ + + + + + +Writable Data +Paging +

Describes writable data paging and how to use it.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-2BDDB4F8-3175-411B-A206-FAE27DEBF678.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-2BDDB4F8-3175-411B-A206-FAE27DEBF678.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,19 @@ + + + + + +DMA Tools GuideTools used to debug the DMA implementation. +

You implement DMA with the standard base porting tools (a compiler +and hardware-specific debugger). There are no tools specifically required +for DMA implementation.

+
+DMA +Implementation Overview +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-2C1B74C4-C80D-5EF9-B822-2DA2FCF9B006.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-2C1B74C4-C80D-5EF9-B822-2DA2FCF9B006.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,26 @@ + + + + + +General +MacrosDescribes macros that can be used in the platform-specific configuration +header and in bootstrap code. +
INIT_LOGICAL_SYMBOLINIT_LOGICAL_SYMBOL SYM, COUNT

Checks if the symbol SYM is defined. If so, it sets it to +a value which is logically TRUE and increments symbol COUNT by +one; COUNT may be omitted if not required.

If the +symbol SYM is not defined, then the macro defines it, and +sets it to a logically FALSE value.

+
INIT_NUMERIC_SYMBOLINIT_NUMERIC_SYMBOL SYM, DEFAULT

Checks if the symbol SYM is defined. If so, its value +is left unchanged.

If SYM is not defined, then the +macro defines it as a numeric variable and sets its value to DEFAULT.

+
INIT_NUMERIC_CONSTANTINIT_NUMERIC_CONSTANT SYM, DEFAULT

Checks if the symbol SYM is defined. If so, its value +is left unchanged.

If SYM is not defined, then the +macro defines it as a numeric constant and sets its value to DEFAULT.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-2C312536-2410-42D7-B976-F7CF99492DEA-master.png Binary file Adaptation/GUID-2C312536-2410-42D7-B976-F7CF99492DEA-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-2C312536-2410-42D7-B976-F7CF99492DEA_d0e344_href.png Binary file Adaptation/GUID-2C312536-2410-42D7-B976-F7CF99492DEA_d0e344_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-2C6B7D51-C201-453D-ABBA-C9EC6B3DBDB2.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-2C6B7D51-C201-453D-ABBA-C9EC6B3DBDB2.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,15 @@ + + + + + +Client InterfaceThe boundary between the generic implementation and any +part of the OS that uses the client interface. +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-2C915A03-AD8C-5924-87BB-953AE323E0FA.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-2C915A03-AD8C-5924-87BB-953AE323E0FA.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,23 @@ + + + + + +Set +UpDescribes how to use the template port to start your port. +

The template port digitizer code can be found in ...\template\template_variant\specific\xyin.cpp.

+

The template .mmp file can be found in ...\template\template_variant\exxytemplate.mmp.

+

Following the general pattern, your implementation will be contained in +the directory: <path to your variant>\specific. Create +a copy of the template port implementation file xyin.cpp and +copy it into your variant specific directory.

+

Rename the class DTemplateDigitiser to reflect the name +of your device. You should also be prepared to add your own private data and +functions into it.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-2D8B8FF1-7A35-5E98-BDDB-2B0BD8DE6215.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-2D8B8FF1-7A35-5E98-BDDB-2B0BD8DE6215.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,16 @@ + + + + + +Writable Data +Paging Tutorial +

Contains the guides that describe various aspects of writable data paging +in more detail.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-2D977A02-5928-5441-8AE7-42A722F2A4B8.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-2D977A02-5928-5441-8AE7-42A722F2A4B8.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,26 @@ + + + + + +User-Side Hardware AbstractionThe User-Side Hardware Abstraction (HAL) component provides a simple +interface for programs to read and set hardware-specific settings, for example, +the display contrast. +

A base port must define the attributes that clients can use on a phone, +and implement any functions that are required to get and set the attributes.

+

To define attributes, you +must change the source of the hal.dll library and rebuild +it. Functions that get and set attributes are implemented as HAL handler functions +in kernel-side programs, for example, device drivers.

+
+LCD Extension + +Power HAL + Handler +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-2D98DB88-BA48-5EF8-A5F9-0CB8688B0B63-master.png Binary file Adaptation/GUID-2D98DB88-BA48-5EF8-A5F9-0CB8688B0B63-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-2D98DB88-BA48-5EF8-A5F9-0CB8688B0B63_d0e32099_href.png Binary file Adaptation/GUID-2D98DB88-BA48-5EF8-A5F9-0CB8688B0B63_d0e32099_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-2E402D4E-53A9-5BA6-9FBD-B2713DBC7858.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-2E402D4E-53A9-5BA6-9FBD-B2713DBC7858.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,101 @@ + + + + + +Peripheral +Power DomainsA peripheral power domain can be defined as being a peripheral, +or group of peripherals, whose power supply can be controlled independently +from the rest of the device, but not independently from other peripherals +within the same power domain. +

Power domains depend on the physical wiring of a device, and this must +be taken into account by the base port. They are usually manipulated when +peripherals or groups of peripherals transition between the Operational +Power and Off states.

+

The following diagram is an example of such an arrangement.

+ +Example of peripheral power domains + + +

To reduce power leakage, it may be useful to cut the power supply to an +area or a group of peripherals in the ASIC or the hardware platform, when +all peripherals on that peripheral power domain have moved to the Off state.

+

In the arrangement shown here, when all peripherals on a power domain have +been powered down, the power supply to that domain can be cut off, using the +RESn signal.

+

A suggested implementation would have peripheral power domains modelled +by a MPowerInput reference counted object, and controlled +using the MPowerInput::Use() and MPowerInput::Release() interfaces +that would enable the domain on request. The peripheral driver’s request on +that power resource would only be changed when entering the Operational +Power state from the Off state, or when entering or exiting the Off states. +In other words, a peripheral power domain should only be turned off when all +peripherals in that domain have transitioned to their Off state.

+

This is a suggested definition for a peripheral power domain class.

+class PeripheralPowerDomain : public MPowerInput + { +public: + void InitPowerDomain(); // (optional) handles any initialisation + void Use(); // implementation of pure virtual + void Release() // implementation of pure virtual + TUint GetCount(); +private: + TInt TurnSupplyOn(); // re-establishes power supply to this domain (asynch) + TInt TurnSupplyOff(); // cuts power supply to this domain + }; + +

The Use() and Release() functions implement +a usage count. Peripheral drivers for peripherals on that domain will call +these functions whenever their power handler’s PowerUp() and PowerDown() member +functions are called, respectively. If the usage count is 0 and Use() is +called, it should call TurnSupplyOn(). If Release() is +called and the usage count is decremented to 0, TurnSupplyOff() is +called.

+

Often, re-establishing the power supply to a power domain is a lengthy +operation and should be modelled by an asynchronous operation. In that case TurnSupplyOn() should +be able to sleep the thread in which this function is called until the power +supply is stable.

+

We recommend that peripheral power domains are defined as part of, and +accessed through, a resource manager object as suggested in the discussion +of Controllable Power +Resources. Extending the original A +suggested implementation of a resource manager would give us:

+class ResourceManager + { +public: + void InitResources(); // called by your Asic::Init3()/Asic::Init1() + void Modify(TUint aSetMask, TUint aClrMask); // only 32 simple Resources can be managed + TBool GetResourceState(TUint aResBitMask); // only 1 bit set on this mask, returns On/Off +public: + (MPowerInput-derived) iSharedResource1; // 1 per shared resource + (MPowerInput-derived) iSharedResource2; + ... + PeripheralPowerDomain iPeripheralPowerDomain1; + PeripheralPowerDomain iPeripheralPowerDomain2; + PeripheralPowerDomain iPeripheralPowerDomain3; + ... + }; + +

where InitResources() could call each PeripheralPowerDomain::InitPowerDomain().

+

Peripheral power domains may also be a useful concept when transitioning +peripherals to low power mode after peripheral inactivity detection. It is +only after all peripherals on a peripheral power domain have requested moving +the resource to the level corresponding to low power that the resource level +can be changed. This is exemplified again in the block diagram above: when +all peripherals in a domain have requested transitioning to low power (using +a ReleaseToLevel() -type call) the power supply level to +that power domain can be set to VLowPwr.

+

The following base port software architecture diagram could be used to +address control of the peripheral power domains shown in the hardware block +diagram above:

+ +Base port software architecture diagram + + +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-2E42E7EA-FED8-522C-8A5F-F65D799476C9.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-2E42E7EA-FED8-522C-8A5F-F65D799476C9.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,131 @@ + + + + + +Keyboard Driver Implementation TutorialThis topic describes how to implement an interrupt driven +keyboard driver. +

The steps are:

+
    +
  • Implement the +driver entry point function and initialisation code. This function +is called when the extension is loaded.

    The initialisation +code binds the hardware interrupt to the Interrupt Service Routine +(ISR) and enables the interrupt.

  • +
  • Implement an +ISR to handle key events. The ISR queues a keyboard DFC.

  • +
  • Implement a +keyboard DFC. This function interrogates the keyboard, converts the +scancode to a keypress event, and places it onto the kernel's event +queue.

  • +
+
Set +Up

In the template reference board port, the .mmp file for the keyboard driver is ...\template_variant\exkey_inttemplate.mmp. This is one of the PRJ_MMPFILES referenced in the template variant's bld.inf file in the ...\template_variant\... directory, and means that the keyboard driver is built as part of +the Variant.

The source for the driver is contained entirely +within ...\template_variant\specific\keyboard_interrupt.cpp.

The driver is defined as a kernel extension and is loaded +early in the boot sequence.

+
Entry +point implementation

The driver functionality is encapsulated +by the DKeyboardTemplate class, and an instance of +this is created when the extension is loaded.

As the driver +is a kernel extension, it must have a DECLARE_STANDARD_EXTENSION() statement. In the template port, this is implemented:

DECLARE_STANDARD_EXTENSION() + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("Starting keyboard driver")); + + // create keyboard driver + TInt r=KErrNoMemory; + DKeyboardTemplate* pK=new DKeyboardTemplate; + if (pK) + r=pK->Create(); + + __KTRACE_OPT(KEXTENSION,Kern::Printf("Returns %d",r)); + return r; + } + +

It simply creates an instance of the DKeyboardTemplate class and then performs a second-phase initialisation, which is +a common pattern in Symbian platform and third party applications.

Initialisation on construction

The constructor +of the DKeyboardTemplate class has the following +signature:

DKeyboardTemplate::DKeyboardTemplate() + : DPowerHandler(KLitKeyboard), + iMsgQ(rxMsg,this,NULL,1), + iPowerUpDfc(PowerUpDfcFn,this,6), + iPowerDownDfc(PowerDownDfcFn,this,7), + iEventDfc(EventDfcFn,this,1) + { + } + +

See also Interrupt Dispatcher +Tutorial.

+
Interrupt +Service Routine (ISR) implementation

The ISR (Interrupt +Service Routine) just schedules the DFC that handles the keypress. +It can also optionally contribute the timing of key interrupts as +a source of random data for the Random Number Generator (see CSPRNG Implementation +in Kernel). On the template reference board, this is implemented +as:

void DKeyboardTemplate::Isr(TAny* aPtr) + { + Interrupt::Disable(KIntIdKeyboard); + + // Add the timing of key interrupts as entropy data for the RNG + Interrupt::AddTimingEntropy(); + + k.iEventDfc.Add(); + } +

The ISR disables the keyboard interrupt, as repeated +ISRs are not allowed to queue further DFC routines.

+
DFC +function implementation

The DFC is the function DKeyboardTemplate::EventDfcFn which is implemented as a +call to DKeyboardTemplate::EventDfc().

void DKeyboardTemplate::EventDfcFn(TAny* aPtr) + { + ((DKeyboardTemplate*)aPtr)->EventDfc(); + } + +void DKeyboardTemplate::EventDfc() + { + __KTRACE_OPT(KHARDWARE,Kern::Printf("DKeyboardTemplate::EventDfc")); + + TInt irq=NKern::DisableAllInterrupts(); + while (IsKeyReady()) // while there are keys in the controller's output buffer + { + NKern::RestoreInterrupts(irq); + TRawEvent e; + TUint keyCode=GetKeyCode(); // Read keycodes from controller + __KTRACE_OPT(KHARDWARE,Kern::Printf("#%02x",keyCode)); + + // + // TO DO: (mandatory) + // + // Convert from hardware scancode to EPOC scancode and send the scancode as an event (key pressed or released) + // as per below EXAMPLE ONLY: + // + TUint bareCode=keyCode&~KFlagKeyPressed; + TUint8 stdKey=convertCode[bareCode]; + if (keyCode&KFlagKeyPressed) + e.Set(TRawEvent::EKeyUp,stdKey,0); + else + e.Set(TRawEvent::EKeyDown,stdKey,0); + Kern::AddEvent(e); + NKern::Sleep(1); // pause before reading more keycodes + irq=NKern::DisableAllInterrupts(); + } + Interrupt::Enable(KIntIdKeyboard); + NKern::RestoreInterrupts(irq); + }

This:

    +
  • reads the scan +code data by calling DKeyboardTemplate::GetKeyCode()

  • +
  • re-enables the +keyboard interrupt, now that the DFC has freed up the input data register

  • +
  • translates the +keypress event into a Symbian scancode

  • +
  • puts the translated +event on to the event queue.

  • +
+
See +also

Concepts

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-2E4F8732-F253-5E0D-9A37-9476541E6004.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-2E4F8732-F253-5E0D-9A37-9476541E6004.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,83 @@ + + + + + +Platform-Specific +Configuration HeaderDescribes how to write the file providing build-time configuration +options. +

The platform-specific configuration header is a file that provides the +configuration options that must be known at build time.

+

The configuration header is an include file written in assembler, and is +named config.inc.

+

Use the configuration header file in the Template port in os/kernelhwsrv/bsptemplate/asspandvariant/template_variant/config.inc as the basis of your own configuration header file.

+

The file consists of a number of global logical symbol definitions (GBLL statements), +including the following:

+
    +
  • symbols that define +the CPU, listed below

  • +
  • a number of less commonly +used macros and symbols, which are documented in the template configuration +header file

  • +
  • a set of general bootstrap +macros described in the Reference section, +including the macros that define the presence of Level 2 cache (L210 cache +and L220 cache).

  • +
+
CPU +symbols

The CPU that the bootstrap runs on is indicated by defining one of +the following symbols:

    +
  • CFG_CPU_ARM710T

  • +
  • CFG_CPU_ARM720T

  • +
  • CFG_CPU_SA1

  • +
  • CFG_CPU_ARM920T

  • +
  • CFG_CPU_ARM925T

  • +
  • CFG_CPU_ARM926J

  • +
  • CFG_CPU_XSCALE

  • +
  • CFG_CPU_ARM1136

  • +
  • CFG_CPU_GENERIC_ARM4

  • +

Note that CFG_CPU_GENERIC_ARM4 refers to an ARM +architecture 4, or later device, with no MMU.

The template file contains +all these symbol definitions; just move the comment symbol (;) +as appropriate for your platform.

+
Other symbols + + + +

CFG_DebugBootRom

+

Define this symbol to enable debug tracing in the bootstrap.

+
+ +

CFG_BootLoader

+

Define this symbol if the bootstrap is a bootloader.

+
+ + +
+
Derived +symbols

A number of commonly used symbols are derived from the +supplied configuration options, and may be used in your code.

Precisely one of +the following three logical symbols is true, indicating the memory model in +use:

    +
  • CFG_MMDirect

  • +
  • CFG_MMMoving

  • +
  • CFG_MMMultiple

  • +

The following logical symbols are true or false depending on whether +the CPU in use has the corresponding property. The property represented by +the symbol is given by the symbol name.

    +
  • CFG_ARMV6

  • +
  • CFG_MMUPresent

  • +
  • CFG_CachePresent

  • +
  • CFG_WriteBufferPresent

  • +
  • CFG_SplitCache

  • +
  • CFG_SplitTLB

  • +
  • CFG_AltDCachePresent

  • +
  • CFG_WriteBackCache

  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-2E54DA7D-1094-41C6-AFB0-9999471991F8.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-2E54DA7D-1094-41C6-AFB0-9999471991F8.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,430 @@ + + + + + +Interrupt Implementation GuideDescribes how to implement the Interrupt class. +
Introduction

Interrupt handling is implemented by writing platform +specific versions of the structures and functions of the Interrupt +class. The details of the implementation depend on hardware and the +architecture of the device. This document describes a simple implementation +of the structures and functions and then discusses more elaborate +strategies required with the use of device specific interrupts , chained +interrupts and multiple interrupt sources. It also covers implementation +on unicore platforms only. The SMP version of the kernel now implements +support for the ARM Generic Interrupt Controller and relies on its +use.

    +
  • Chained interrupts are interrupts which are output by one controller +and input to another. They need to be distinguished in the ISR table +and require extensions to the handler functions.

  • +
  • Multiple interrupt sources to the same ISR require the use +of pseudo-interrupts.

  • +
  • When a Symbian port is split into an ASSP and variant (common +and device specific) layer, the variant may include additional interrupt +sources. Their API is defined by the port. Device specific interrupts +are sometimes used to handle interrupts from peripherals: another +technique is to route peripheral interrupts to a GPIO pin. Peripheral +interrupts cannot be specified as part of the ASSP layer.

  • +

The Template Baseport provides a skeleton implementation for +developers to modify at kernelhwsrv/bsptemplate/asspandvariant/template_assp/interrupts.cpp.

+
The +ISR table

The ISR table is a data structure which pairs +each ISR with the interrupt source to which it will be bound. It must +have enough space for each interrupt source on the device. It is implemented +as an array of Interrupt::SInterruptHander of size KINterruptSourceCount in which the interrupt Id is used +as an index to the table. This example code assumes a size of 32.

... +const TInt KInterruptSourceCount = 32; +SInterruptHandler IsrHandlers[KInterruptSourceCount]; +...
+
DisableAndClearAll()

Interrupts must be disabled and cleared with a call to Interrupt::DisableAndClearAll() before the call to Interrupt::Init1() at the start of initialization. Implementation +of this function is entirely hardware dependent.

+
Init1()

The kernel is initialized in phases, interrupts being involved +in the first phase and sometimes the third. The Init1() function should +be implemented to

    +
  • Initialize the ISR table, binding all ISRs to the spurious +interrupts handler.

  • +
  • Register the dispatcher functions.

  • +
  • Bind ISRs which handle chained or pseudo interrupts.

  • +

Interrupts must be disabled during first phase initialization.

This example code illustrates initialization of the ISR table.

... +const TInt KInterruptSourceCount = 32; +SInterruptHandler IsrHandlers[KInterruptSourceCount]; +... + +for( TInt i = 0; i < KInterruptSourceCount; ++i ) + { + IsrHandlers[i].iIsr = SpuriousHandler; + IsrHandlers[i].iPtr = (TAny*)i; + }

This example code illustrates an implementation +of Interrupt::Init1() after the point at which +the ISR table has been initialized.

void TemplateInterrupt::Init1() + { + // + // need to hook the ARM IRQ and FIQ handlers as early as possible + // and disable and clear all interrupt sources + // + ... + DisableAndClearAll(); + Arm::SetIrqHandler((TLinAddr)TemplateInterrupt::IrqDispatch); + Arm::SetFiqHandler((TLinAddr)TemplateInterrupt::FiqDispatch); + } +
+
Init3()

Third phase initialization involves initializing various interrupt +handlers and sources which can only be initialized when the kernel +is fully functional. This is done with a call to Interrupt::Init3().

It is important to remember that interrupts are enabled during +third phase initialization.

+
Spurious()

Interrupts not bound to a real ISR must be bound to a 'spurious' +handler function Interrupt::Spurious() which returns +an error with the number of the interrupt.

+
Bind()

The Interrupt::Bind() function binds ISRs to +interrupt sources.

The argument aId is the +Id of an interrupt source and is used to index an entry in the ISR +table. Set the iPtr and iIsr members +of that entry (ISR parameter and ISR pointer) to the passed in values aPtr and aIsr.

The implementation +should perform some preliminary checks.

    +
  • The interrupt Id must be checked for validity

  • +
  • The ISR must not already be bound to a real interrupt. It should +have been bound to the spurious interrupt handler at initialization.

  • +

All interrupts must be disabled during binding.

This +example code provides a basic implementation.

EXPORT_C TInt Interrupt::Bind(TInt aId, TIsr aIsr, TAny* aPtr) + { + TInt r = KErrNone; + If(TUint(aId)>=TUint(KInterruptSourceCount)) + { + r = KErrArgument; // Illegal interrupt number + } + else + { + SInterruptHandler& h = IsrHandlers[aId]; + TInt irq = NKern::DisableAllInterrupts(); + if (h.iIsr != &SpuriousHandler) + { + r = KErrInUse; // Already bound to an ISR + } + else + { + h.iPtr = aPtr; // The ISR parameter + h.iIsr = aIsr; // Pointer to the ISR + } + NKern::RestoreInterrupts(irq); + } + return r; + } +

The implementation of Interrupt::Bind() can be more complicated in the case of chained interrupts, multiple +interrupt sources, pseudo interrupt sources and device interrupts: +see the discussion of those topics.

+
Unbind()

The Interrupt::Unbind() function unbinds ISRs +from interrupt sources.

The argument aId is +the Id of an interrupt source and is used to index an entry in the +ISR table. Reset the entry in the ISR table to reference the spurious +handler function.

The implementation should perform some preliminary +checks.

    +
  • The interrupt Id must be checked for validity

  • +
  • The ISR must not already be unbound (that is, bound to the +spurious interrupt handler).

  • +

All interrupts must be disabled during unbinding.

This +example code provides a basic implementation.

EXPORT_C TInt Interrupt::Unbind(TInt aId) + { + TInt r = KErrNone; + if (TUint(aId) >= TUint(KInterruptSourceCount)) + { + r = KErrArgument; // Illegal interrupt number + } + else + { + SInterruptHandler& h = IsrHandlers[aId]; + TInt irq = NKern::DisableAllInterrupts(); + if (h.iIsr == &SpuriousHandler) + { + r = KErrGeneral; // Already unbound + } + else + { + h.iPtr =(TAny*)aId; + h.iIsr = SpuriousHandler; // Replace with spurious handler + // NOTE: at this point it may be wise to + // force the hardware interrupt source to disabled. + } + NKern::RestoreInterrupts(irq); + } + return r; + } +

The implementation of Interrupt::Unbind() can be more complicated in the case of chained interrupts, multiple +interrupt sources, pseudo interrupt sources and device interrupts: +see the discussion of those topics below.

+
Enable()

Device drivers call the Interrupt::Enable() function to enable the interrupt source identified by the argument anId in the interrupt controller hardware.

The implementation +is entirely hardware dependent.

This example involves a check +for chained interrupts, which are discussed in their own section below.

EXPORT_C TInt Interrupt::Enable(TInt anId) + { + TInt r=KErrNone; + // if ID indicates a chained interrupt, call variant... + if (anId<0 && ((((TUint)anId)>>16)&0x7fff)<(TUint)KNumTemplateInts) + r=TemplateAssp::Variant->InterruptEnable(anId); + else if ((TUint)anId>=(TUint)KNumTemplateInts) + r=KErrArgument; + else if (TemplateInterrupt::Handlers[anId].iIsr==TemplateInterrupt::Spurious) + r=KErrNotReady; + else + { + // + // TO DO: (mandatory) + // + // Enable the corresponding Hardware Interrupt source + // + } + return r; + } +
+
Disable()

Device drivers call the Interrupt::Disable() function to disable the interrupt source identified by the argument anId in the interrupt controller hardware. The implementation +is entirely hardware dependent.

+
Clear()

Device drivers call the Interrupt::Clear() function +to acknowledge that they have serviced the interrupt and cleared the +pending flag in the interrupt controller hardware. The implementation +is entirely hardware dependent.

Clear() is +a useful function in cases where an interrupt must be cleared explicitly +rather than as a side effect of I/O register access: for instance +in PC card and MMC controller code.

+
SetPriority()

The Interrupt::SetPriority() function associates +a priority value (passed as a TInt) with an interrupt +Id. The meaning of the priority value is entirely hardware dependent.

Priority is a property of interrupts on some hardware, an example +being OMAP. Where the hardware is of this type, Interrupt::SetPriority() can be used to modify priorities in hardware. A simple use is to +determine whether an interrupt generates an IRQ or an FIQ. If priority +adjustment is not supported or not specified, the function should +simply return KErrNotSupported.

The implementation +is entirely hardware dependent.

+
IrqDispatch() +and FiqDispatch()

The functions Interrupt::IrqDispatch() and Interrupt::FiqDispatch() dispatch an interrupt +by calling the associated ISR. Interrupts are either IRQ or FIQ interrupts +and separate dispatch functions must be provided for each type. What +follows refers to IRQs but applies equally to FIQs as the distinction only operates at the level of hardware and the two +dispatch functions look the same.

In the simplest implementation, +the interrupt Id is used as an index into the ISR table. The iIsr member of the entry is called as a function with the iPtr member as its argument. The interrupt Id is taken from +a list of pending IRQs as in this example code.

void IrqDispatch() + { + TUint32 pendingIrqs = TheAssp::IrqPendingRegister(); + // for the purposes of this example we assume that reading + // this register also clears the pending flags + + TInt index = 0; + while( pendingIrqs ) + { + // while there is at least one pending IRQ + if( pendingIrqs & 1 ) + { + // the next interrupt is pending - dispatch it + (IsrHandlers[index].iIsr)(IsrHandlers[index].iPtr); + } + ++index; + pendingIrqs >>= 1; + } + } +

This code is a simplified example which assumes that

    +
  • The interrupt controller provides 32 interrupt sources and +has a 32 bit pending interrupt register where a 1 indicates a pending +interrupt and all ones are cleared when the register is read.

  • +
  • The interrupt source represented by the low order bit in the +pending interrupt register is represented by interrupt Id 0 and so +on.

  • +

Implementation will be more complex where chained interrupts +and multiple interrupt sources are involved, as discussed below.

Dispatch functions are time critical. You will probably write +an initial implementation in C++ to get them working and then rewrite +in assembler for maximum efficiency.

+
Chained +interrupts

A platform often has multiple interrupt controllers +of higher and lower priority (higher and lower level controllers), +organized so that the output of a lower level controller is one of +the inputs to a higher level controller. Interrupt sources organized +in this way are called chained interrupts.

In a system with +chained interrupts, the ISR table must be structured so that interrupts +from higher and lower level controllers can be distinguished by their +Ids.

The Interrupt::Bind() and Interrupt::Unbind() functions are the same whether interrupts are chained or not.

In a system with chained interrupts it can be desirable to write +the Interrupt::Enable() and Interrupt::Disable() functions so as to disable not the interrupt itself but a the higher +level interrupt on the controller to which it is the input.

The Interrupt::IrqDispatch() and Interrupt::FiqDispatch() functions need to be extended in a system with chained interrupts. +There are two techniques for doing this, both of which involve a separate +second level dispatch function, but which differ in the way it is +called.

    +
  • In one technique, the main interrupt dispatcher calls the second +level dispatcher if the relevant condition is satisfied.

  • +
  • In the other technique, the second level dispatcher is bound +directly to an interrupt source as its ISR.

  • +

The first technique works well in cases where there is only +a main and a secondary interrupt controller. It does not scale well +in cases which make use of multiple controllers chained to substantial +depth.

You need to allocate locations in your ISR table for +the secondary controllers so that the interrupt Id identifies which +hardware controller the input is on. For example, if each interrupt +controller handles 32 interrupt sources, you could allocate the first +32 Ids to the highest level controller, the next 32 to a second level +controller and so on.

This example code illustrates a main dispatcher +which calls a second level dispatcher.

void IrqDispatch() + { + TUint32 pendingIrqs = TheAssp::IrqPendingRegister(); + + TInt index = 0; + while( pendingIrqs ) + { + if( pendingIrqs & 1 ) + { + if( index == EMainIntChainIrq ) + { + // second-level controller is signalling + SecondLevelIrqDispatch(); + } + else + { + // call ISR + (IsrHandlers[index].iIsr)(IsrHandlers[index].iPtr); + } + } + ++index; + pendingIrqs >>= 1; + } + } +

This example code illustrates a second level dispatcher +bound directly to an interrupt source.

void IrqDispatch() + // MAIN IRQ DISPATCHER, FIRST-LEVEL INTERRUPT + { + TUint32 pendingIrqs = TheAssp::IrqPendingRegister(); + + TInt index = 0; + while( pendingIrqs ) + { + if( pendingIrqs & 1 ) + { + (IsrHandlers[index].iIsr)(IsrHandlers[index].iPtr); + } + ++index; + pendingIrqs >>= 1; + } + } +void SecondLevelIrqDispatch( TAny* /* aParam */ ) + { + TUint32 pendingIrqs = TheAssp::SecondLevelIrqPendingRegister(); + + TInt index = EStartOfSecondLevelIntId; + while( pendingIrqs ) + { + if( pendingIrqs & 1 ) + { + (IsrHandlers[index].iIsr)(IsrHandlers[index].iPtr); + } + ++index; + pendingIrqs >>= 1; + } + } +void InitialiseSecondLevelDispatch() + // Bind and enable the second-level dispatcher + { + Interrupt::Bind(EMainIntChainIrq,SecondLevelIrqDispatch,NULL); + Interrupt::Enable( EMainIntChainIrq ); + } +

This example assumes an ISR table in which the second +level interrupt ISRs begin at location 32 (EStartOfSecondLevelIntId). EMainIntChainIrq is the interrupt Id of the chained +interrupt source to the main interrupt controller. The second level +dispatcher is itself an ISR with an argument TAny* which is not needed in this example (possible uses are to distinguish +between core and device specific ISR tables or to point to I/O addresses).

+
Multiple +interrupt sources

In cases where multiple peripherals are +connected to the same interrupt source, multiple sources may generate +the same interrupt which will then require a different ISR depending +on the specific source. However, EKA2 does not allow binding of multiple +ISRs to the same interrupt. There are two strategies for solving this +problem, both of which involve assigning the multiple ISRs not to +the real interrupt but to pseudo-interrupt Ids. In one strategy the +dispatcher examines the hardware to determine where the interrupt +originated and calls the appropriate ISR. In the other strategy, the +ISRs are written so that they examine their peripheral hardware and +only run if it is actually signalling an interrupt: in this strategy +the dispatcher calls all the ISRs bound to the real interrupt but +only one of them runs.

There is no requirement to extend the +implementation of Interrupt::Bind() and Interrupt::Unbind() where multiple interrupt sources are +involved.

Multiple interrupt sources require you to extend the +implementation of Interrupt::Enable() and Interrupt::Disable() to enable and disable the true interrupt +source.

The dispatch functions should be extended in the same +way as with chained interrupts, using one of the two techniques described +for that case.

The ISR table should be structured so that the +interrupt Id identifies the hardware controller the interrupt is on. +For instance the first 32 Ids might refer to the highest level controller, +the next 32 to a second level controller and so on.

+
Device +specific interrupts

Interrupts generated by peripherals +are sometimes routed to a GPIO pin and sometimes included in a variant +layer. Where they are part of the variant layer, they must be listed +in a separate ISR table which is part of the device implementation. +However, we want device drivers to be able to use the Interrupt class +functions on interrupts of either type. The solution is to write separate +device specific functions derived from those of the core class. Core +class functions are then written in such a way as to identify device +specific interrupts and pass them on to the derived functions.

A recommended way of labelling interrupts as being device specific +is to assign negative numbers as their Ids. The core functions can +then identify negative Ids as belonging to device specific interrupts +and pass them to the device specific derived functions. The device +specific functions can convert them to positive numbers which serve +as indexes to the device specific ISR table.

This example code +illustrates device specific interrupt handling.

EXPORT_C TInt Interrupt::Bind(TInt aId, TIsr aIsr, TAny* aPtr) + { + TInt r = KErrNone; + if(aId < 0 ) + { + return MyAsic->VariantBind( aId, aIsr, aPtr ); // Device specific ID, call variant + } + else if (aId >= KInterruptSourceCount) + { + r = KErrArgument; // Illegal interrupt number + } + else + { + SInterruptHandler& h = IsrHandlers[aId]; + TInt irq = NKern::DisableAllInterrupts(); + if (h.iIsr != SpuriousHandler) + { + r = KErrInUse; // Already bound to an ISR + } + else + { + h.iPtr = aPtr; + h.iIsr = anIsr; + } + NKern::RestoreInterrupts(irq); + } + return r; + } + +SInterruptHandler VariantHandlers[KNumVariantInts]; +EXPORT_C TInt TMyVariant::VariantBind(TInt aId, TIsr aIsr, TAny* aPtr) + { + TInt r = KErrNone; + aId = (-aId)-1; // convert to positive number >=0 + If (aId >= KInterruptSourceCount || aId < 0) + { + r = KErrArgument; // Illegal interrupt number + } + else + { + SInterruptHandler& h = VariantHandlers[aId]; + TInt irq = NKern::DisableAllInterrupts(); + if (h.iIsr != VariantSpuriousHandler) + { + r = KErrInUse; // Already bound to an ISR + } + else + { + h.iPtr = aPtr; + h.iIsr = anIsr; + } + NKern::RestoreInterrupts(irq); + } + return r; + }

The example provides a version of Interrupt::Bind() which calls a variant layer function VariantBind() to process device specific interrupts (here assigned negative Ids) +to ISRs held in the variant specific table VariantHandlers.

+
+Interrupt +Technology Guide +Interrupt +Client Interface Guide +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-2EC16C9C-7241-46B2-B569-B89751933C57.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-2EC16C9C-7241-46B2-B569-B89751933C57.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,13 @@ + + + + + +DMA Configuration OverviewHow to configure a DMA controller in the Platform Specific +Layer. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-2ECF13A1-9D56-5740-A09F-8267E6A45DD9.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-2ECF13A1-9D56-5740-A09F-8267E6A45DD9.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,106 @@ + + + + + +Porting the Power Resource ManagerThis tutorial describes how to port the Platform Specific +Layer (PSL) of the Power Resource Manager (PRM) +and how to modify clients, such as device drivers, to use the PRM +framework. +
Purpose

The PRM is a framework for managing system power resources. This +framework improves portability across different platforms and reduces +device driver complexity.

The PRM framework is split into +two layers:

    +
  • Platform Independent +Layer - the PIL is a generic software layer that is implemented by +Symbian. This is the base virtual class for the Power Resource Controller +(DPowerResourceController),

  • +
  • Platform Specific +Layer - the PSL is developed specifically to interface with the target +hardware by licensees. This is the class derived from DPowerResourceController.

  • +

Other acronyms used in this document set:

    +
  • LDD - Logical +Device Driver. The higher layer of abstraction within the Symbian +platform device driver framework which implements common functionality +among differing pieces of hardware of one type,

  • +
  • PDD - Physical +Device Driver. The lower layer of abstraction within the Symbian platform +device driver framework which implements functionality that is specific +to a particular piece of hardware.

  • +

Intended audience

This document is intended +to be used by Symbian platform device creators.

Required +background

The reader of this document is assumed to have +knowledge of the Symbian platform device driver model and base port layering and components.

    +
  • Device Driver Concepts,

  • +

Introduction

The PRM provides a unique place +where all the current power states for resources can be obtained at +any time. The sum of all internal and external power states defines +the current system-wide power state.

Setup and configuration +requirements

The PRM component is implemented as a kernel +extension with an exported public interface that is accessible to +kernel side components through statically linking against its export +library. The export library is built from the resource manager and +the resource manager libraries.

There are two versions available:

    +
  • basic resource +manager - provides essential or required functionality for static +resources.

    The basic version of the PIL layer is compiled +into resmanpsl.lib. This kernel library must +be included by the PSL to produce the kernel extension.

  • +
  • extended resource +manager - provides additional support for dynamic resources and resource +dependencies.

    The extended version of the PIL layer is complied +into resmanextenedpsl.lib. This kernel library +must be included by the PSL to produce the kernel extension.

  • +

Device drivers that require the use of the PRM should link +against the appropriate library. resman.lib to +use the basic version and resmanextended.lib to +use the extended version of the PRM.

Building the PRM for +the target platform

The PRM is an early extension, so +the targettype in the mmp file +must be set to kext. If the PRM is implemented as +a PDD the targettype in the mmp file should be should +be pdd.

Boot sequence

The +PRM cannot be used to operate on power resources until later in the +boot sequence when the kernel allows the scheduling of other threads. +During this time it is not possible to read or change the state of +resources, but DPowerResourceController::PostBootLevel() can be used to specify the state of specific resources and the PRM +can change the state of resources to appropriate levels before the +PRM is fully initialised.

PostBootLevel() is used within the extension entry point, during this time PRM is +not fully initialised. Note: This function can only be used +for static resources and static resources with dependencies.

static TInt PostBootLevel(TUint aResId, TInt aLevel);

PostBootLevel() takes the resource ID and the +post boot level that the level a resource needs to be after it is +initialised. Typically the post boot level is only known to the PSL. +However kernel extensions (and the variant) may request a post boot +level.

If a kernel extension needs to know if certain resources +have reached the post boot state in order to complete its own initialisation +then the kernel extension should queue resource state change notifications +for the resource when first registering as clients with the PRM. Note: notification requests are accepted before the PRM is fully +initialised.

Variants or kernel extensions can register static +resources before the PRM is fully initialised with DPowerResourceController::RegisterStaticResource(). This API can only be used by static resources and not by static +resource that support dependency. See DoRegisterStaticResources().

+
Using +the Power Resource Manager

Porting the PRM consists of +implementing the PSL layer for a given hardware platform and modifying +clients, such as device drivers, to use the PRM framework.

The following tasks are covered in this tutorial:

    +
  • Implement the controllable +power resources,

  • +
  • Implement the PSL +for the target,

  • +
  • Port the client +drivers to use the PRM (to control the implemented resources),

  • +
  • Debugging the PRM,

  • +
  • Testing the PRM +PSL.

  • +
+
+Power +Resource Manager (PRM) +Power +Management Tutorials +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-3046453A-AB3A-5491-87A0-00F3514D4768.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-3046453A-AB3A-5491-87A0-00F3514D4768.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,109 @@ + + + + + +Vector +Floating Point Implementation TutorialThis topic describes how to configure a base port to use the floating +point coprocessor. +

ARM provide a hardware floating point coprocessor that provides floating +point computation that is fully compliant with IEEE Std 754-1985.

+

To support a coprocessor, you need to:

+
    +
  • Configure the Kernel +to use VFP through a macro setting in the Variant.

  • +
  • Configure the ROM to +include a Kernel extension to support IEEE-without-exceptions mode.

  • +
  • Configure the ROM to +include VFP support libraries.

  • +
  • Port the User Library +to implement its Math class functions to use VFP-enabled +functions. This is described in the Math +Class Port Tutorial.

  • +
+
Variant configuration

Define the macro __CPU_HAS_VFP in +the base port’s variant.mmh. This macro forces the inclusion +of VFP support when the kernel is re-compiled. As an example, see the Integrator +CM1136 base port, and specifically: ...\integrator\core\cm1136\variant.mmh. +When the kernel is re-compiled, VFP support is included.

+
HAL configuration

Add the HAL attribute for VFP +to your base port's config.hcf file, by adding the following +line to this file:

EHardwareFloatingPoint = GetHardwareFloatingPoint

As an example, see the Integrator CM1136 base port, and specifically: ...\integrator\core\cm920\hal\config.hcf

See +also Creating the Config +& Values files in the HAL Port +Implementation Tutorial for more information.

+
IEEE-without-exceptions +mode

Symbian platform supports two execution modes :

+ + + +

RunFast

+

In this mode, denormalised numbers, i.e. those outside the range +of normal floating point values, are treated as zero, and a default NaN (Not +a Number) value is used for all NaN situations regardless +of the inputs.

+
+ +

IEEE-without-exceptions

+

In this mode, denormalised numbers are treated as their actual values, +and the IEEE754-mandated values for NaN s are used.

The +floating point model mandated by the Java specification is identical to this +mode, and means that this mode is sufficient to implement a VFP-accelerated +JVM.

+
+ + +

NOTE: There may be some applications that depend on the correct +handling of calculations involving, or resulting in, very small numbers; for +such applications, RunFast mode may not be appropriate.

RunFast mode

For RunFast execution +mode, nothing else needs to be implemented, and no extra components need to +be added to the ROM.

IEEE-without-exceptions +mode

For IEEE-without-exceptions mode, you need +to include the kernel extension evfp.dll in the ROM image +by adding the following line into the .iby or .oby file +for your port:

extension[VARID]=KERNEL_DIR\DEBUG_DIR\evfp.dll \sys\bin\evfp.dll

As an example, see the Integrator CM1136 base port, and specifically: ...\integrator\core\cm1136\rom\base_integrator1136.iby

Note:

    +
  • This is the default +execution mode.

  • +
  • It is possible to switch +between this execution mode and the RunFast execution mode.

  • +
  • evfp.dll is +built using ARM's VFP support code and can only be built using the RVCT tool +chain.

  • +
+
VFP-enabled +floating port support libraries

Symbian platform provides both +the VFP version and the non-VFP version of the floating point support functions. +You choose the VFP version when you build your ROM image by specifying the VFPHELPERS macro +to BUILDROM. +This causes the ROM building tool chain to replace the following three DLLs:

    +
  • drtaeabi.dll

  • +
  • dfpaeabi.dll

  • +
  • dfprvct2_2.dll

  • +

There are two ways to specify the VFPHELPERS macro:

    +
  1. by adding the following +line into the header.iby file for your port:

    #define VFPHELPERS

    You +use this technique to permanently include the VFP versions in your ROM image.

  2. +
  3. by passing VFPHELPERS as +a pre-processor argument using the -D option when invoking BUILDROM, i.e. :

    BUILDROM +-DVFPHELPERS ...

    You use this technique if you only want +to include the VFP versions for a specific ROM image, for example, when testing.

  4. +

If you use the first technique, you can still provide non-VFP versions +for a specific ROM image by passing NOVFPHELPERS as a pre-rpocessor +argument using the -D option when invoking BUILDROM, +i.e. :

BUILDROM -DNOVFPHELPERS ... +

In effect, you are overriding the definition in the header.iby file.

For +example, see the Integrator CM1136 base port, and specifically: ...\integrator\core\cm1136\rom\header.iby

+
+Math Class +Port Tutorial + +User-Side Hardware Abstraction +Vector Floating +Point (VFP) +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-306A0B41-94CD-534A-B3BA-FAECB858E9A9.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-306A0B41-94CD-534A-B3BA-FAECB858E9A9.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,29 @@ + + + + + +Platform-Specific +FunctionsExplains how bootstrap functions are organised. +

Platform-specific source code needs to implement a set of standard functions +that are called by the generic source code. It also needs to provide a set +of standard MMU permission and cache attribute definitions.

+

Standard functions are organised in the following way:

+
    +
  • a set of public functions +that the Symbian platform generic source links to directly

  • +
  • a set of functions that +are contained in a table, known as the boot table.

  • +
  • a set of entries that +define MMU and cache attributes to be used for standard memory and I/O areas; +this set of entries is also contained in the boot table.

  • +
+

Refer to the Template bootstrap source code: os/kernelhwsrv/bsptemplate/asspandvariant/template_variant/bootstrap/template.s

+All bootstrap source code should be position independent. +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-30978E00-D244-44CD-8F4E-9676DF172A52.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-30978E00-D244-44CD-8F4E-9676DF172A52.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,39 @@ + + + + + +Driver-side +HandlingThis document describes how device drivers handle asynchronous +requests. +

Drivers generally implement the DoRequest() function +in the LDD to handle the received asynchronous messages.

+

The implementation reads the request type and other passed arguments, and +initiates handling of the request appropriately.

+

The return value of this function only indicates the status of the message +reception to the driver. It does not actually indicate the request completion +result.

+TInt DExDriverLogicalChannel::DoRequest(TInt aReqNo, TRequestStatus* aStatus, + TAny* a1, TAny* a2) + { + switch (aReqNo) + { + case RExDriverChannel::ERequestTransmitData: + // Call TransmitData function + r = TransmitData ((const TDesC8*)a1); + // The status object is stored + // to be used when notifying the completion of the + // request at a later point. + // + iTxDataStatus = aStatus; + break; + } + return r; + } +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-3102F778-DD2F-4C87-A0DF-7FA44C9709D8.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-3102F778-DD2F-4C87-A0DF-7FA44C9709D8.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,38 @@ + + + + + +Multiple +Client SupportThis document describes how multiple clients can access a driver +over a single logical channel. +

A single channel has a single handle which is shared by driver users. A +driver can allow or prevent the sharing of a handle to a logical channel between +multiple users. This policy is implemented by the DLogicalChannel::RequestUserHandle() function. +The default implementation does not restrict sharing of the channel, but a +driver can override the function to change this.

+

In the following example, the driver ensures that only the intended clients +can get the handle and access the driver. Any other client that tries to share +the handle gets a KErrAccessDenied error.

+TInt DExDriverLogicalChannel::RequestUserHandle(DThread* aThread, + TOwnerType aType) + { + // Handle should be provided only to the intended client. Any + // other clients that try to get a handle to the driver should get an access + // denied error. + if ( aType!=EOwnerThread || aThread!=iClient) + return KErrAccessDenied; + return KErrNone; + } +

DLogicalChannel::RequestUserHandle() only restricts +the user from sharing or duplicating an existing channel. It does not restrict +another process from opening its own separate channel on the same device.

+

More than one user can access the driver at the same time. It is +up to the driver to manage and provide correct and secure access to the driver.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-315DD62B-8669-471F-BDDC-BC4D700AEA60.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-315DD62B-8669-471F-BDDC-BC4D700AEA60.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,29 @@ + + + + + +Interrupt Client Interface Quick StartBasic steps to use the client interface of the Interrupt +platform service. +

The Interrupt platform service provides an interface that allows +clients to have access to interrupts.

+
Basic +steps

The following are the basic steps to use the Interrupt +platform service:

    +
  1. The Interrupt Technology +Guide describes the basic concepts of the Interrupt platform +service.

  2. +
  3. The Interrupt Client +Interface Guide explains the client interface and how to use +it.

  4. +
  5. The Interrupt Build Guide explains how to include the Interrupt platform service in a build.

  6. +
  7. The Interrupt Testing +Guide explains how to test the Interrupt platform service.

  8. +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-31CE66F2-B36C-56ED-A399-BA9EFA179DED-master.png Binary file Adaptation/GUID-31CE66F2-B36C-56ED-A399-BA9EFA179DED-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-31CE66F2-B36C-56ED-A399-BA9EFA179DED_d0e75538_href.png Binary file Adaptation/GUID-31CE66F2-B36C-56ED-A399-BA9EFA179DED_d0e75538_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-31FFA810-129A-4E35-A47F-C6D3C1C71D5E.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-31FFA810-129A-4E35-A47F-C6D3C1C71D5E.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,15 @@ + + + + + +Register Access Tools GuideTools required for the Register Access platform service. +

There are no specific tools required to use or implement the Register +Access platform service.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-32B82E5C-FD53-48E6-9ABC-88F82ACF71BC.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-32B82E5C-FD53-48E6-9ABC-88F82ACF71BC.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,56 @@ + + + + + +The +LDD Entry Point and FactoryThis document describes how LDDs are created. +

An LDD +must define an entry point function using the macro DECLARE_STANDARD_LDD, +or DECLARE_EXTENSION_LDD in the case of kernel extensions. +This must create an LDD factory object derived from DLogicalDevice:

DECLARE_STANDARD_LDD() + { + return new DerivedLogicalDevice; + }

This factory object is created on the kernel heap. Its +purpose is to create the logical channel, the object through which all client +interaction with the driver will occur.

DLogicalDevice is +derived from DObject, and is, therefore a reference-counting +object. It also means that DLogicalDevice objects are given +a name, as these objects are always subsequently found by name. The user-side +specifies the name of the logical device through the first parameter in the +user-side call to RBusLogicalChannel::DoCreate().

The +file extension of a LDD DLL can be any permitted Symbian Platform name but, +by convention, the LDD DLL has the extension .LDD. Device +driver DLLs are polymorphic interface DLLs. When building LDDs, specify a +target type of ldd in the .mmp file.

An +LDD is loaded by calling User::LoadLogicalDevice(). This +static function:

    +
  • loads the DLL into RAM, +if necessary

  • +
  • calls the exported function +at ordinal 1 to create the factory object, the DLogicalDevice derived +object

  • +
  • places the factory object +into the appropriate object container.

  • +
This only needs to be done once, not every time the driver is +used.

If an LDD needs to perform initialisation at boot time (before +the driver is loaded by User::LoadLogicalDevice()) then +specify the entry point macros DECLARE_STANDARD_EXTENSION and DECLARE_EXTENSION_LDD.

DECLARE_STANDARD_EXTENSION() + { + // initialise code here + } + +DECLARE_EXTENSION_LDD() + { + return new DMyLogicalFactory; + }

In order for the kernel to initialise the LDD extension +at boot time then the .oby file must specify the extension keyword. +Also note that initialisation of the extension will not load +the LDD: this still has to be done through a call to User::LoadLogicalDevice().

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-3335663A-BC11-556E-B5A6-F83622AE34C3.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-3335663A-BC11-556E-B5A6-F83622AE34C3.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,21 @@ + + + + + +Audio Driver Porting +Implementation TutorialDescribes the steps to implement a physical device driver (PDD) +for the Sound Driver. +

The audio device driver +implementation may provide for playback, recording, or both at the same time, +but there are design considerations for each option.

+
+ +Concepts +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-33A7D8D4-84D6-56EA-8EAB-2A3A3ACABF77.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-33A7D8D4-84D6-56EA-8EAB-2A3A3ACABF77.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,299 @@ + + + + + +ReferenceProvides a summary of related documentation for the MMC Controller +to which you can refer. +

API Reference

+
Peripheral bus layer + + + +

Item

+

Header

+
+ +

DMediaChangeBase

+

pbus.h

+
+ +

DPBusPowerHandler

+

pbus.h

+
+ +

DPBusPrimaryMedia

+

pbusmedia.h

+
+ +

DPBusPsuBase

+

pbus.h

+
+ +

DPBusSocket

+

pbus.h

+
+ +

TMediaState

+

pbus.h

+
+ +

TPBusCallBack

+

pbus.h

+
+ +

TPBusCallBackFn

+

pbus.h

+
+ +

TPBusIsr

+

pbus.h

+
+ +

TPBusPsuInfo

+

pbus.h

+
+ +

TPBusPsuState

+

pbus.h

+
+ +

TPBusPsuStatus

+

pbus.h

+
+ +

TPBusState

+

pbus.h

+
+ +

TPBusType

+

pbus.h

+
+ +

TPsuVoltChkMethod

+

pbus.h

+
+ + +
+
MultiMediaCard layer + + + +

Item

+

Header

+
+ +

DMMCMediaChange

+

mmc.h

+
+ +

DMMCPsu

+

mmc.h

+
+ +

DMMCSession

+

mmc.h

+
+ +

DMMCSocket

+

mmc.h

+
+ +

DMMCStack

+

mmc.h

+
+ +

SMF_BEGIN

+

mmc.h

+
+ +

SMF_BPOINT

+

mmc.h

+
+ +

SMF_CALL

+

mmc.h

+
+ +

SMF_CALLMEWR

+

mmc.h

+
+ +

SMF_CALLMYS

+

mmc.h

+
+ +

SMF_CALLWAIT

+

mmc.h

+
+ +

SMF_END

+

mmc.h

+
+ +

SMF_EXIT

+

mmc.h

+
+ +

SMF_EXITWAIT

+

mmc.h

+
+ +

SMF_GOTONEXTS

+

mmc.h

+
+ +

SMF_GOTOS

+

mmc.h

+
+ +

SMF_INVOKES

+

mmc.h

+
+ +

SMF_INVOKEWAITS

+

mmc.h

+
+ +

SMF_JUMP

+

mmc.h

+
+ +

SMF_JUMPWAIT

+

mmc.h

+
+ +

SMF_NEXTS

+

mmc.h

+
+ +

SMF_RETURN

+

mmc.h

+
+ +

SMF_STATE

+

mmc.h

+
+ +

SMF_WAIT

+

mmc.h

+
+ +

SMF_WAITS

+

mmc.h

+
+ +

TBusWidth

+

mmc.h

+
+ +

TCID

+

mmc.h

+
+ +

TCSD

+

mmc.h

+
+ +

TExtendedCSD

+

mmc.h

+
+ +

TMMCardControllerInterface

+

mmccd_ifc.h

+
+ +

TMMCArgument

+

mmc.h

+
+ +

TMMCBusConfig

+

mmc.h

+
+ +

TMMCCallBack

+

mmc.h

+
+ +

TMMC

+

mmc.h

+
+ +

TMMCCmdDirEnum

+

mmc.h

+
+ +

TMMCCommandDesc

+

mmc.h

+
+ +

TMMCCommandEnum

+

mmc.h

+
+ +

TMMCCommandSpec

+

mmc.h

+
+ +

TMMCErrTypedef.xml

+

mmc.h

+
+ +

TMMCMachineInfo

+

mmc.h

+
+ +

TMMCMediaTypeEnum

+

mmc.h

+
+ +

TMMCStackConfig

+

mmc.h

+
+ +

TMMCStateMachine

+

mmc.h

+
+ +

TMMCStatus

+

mmc.h

+
+ + +
+
State machine function list

This is a list of state +machine functions defined for the MultiMediaCard controller.

+
Top level state machine functions
    +
  • DMMCStack::CIMUpdateAcqSM()

  • +
  • DMMCStack::CIMInitStackSM()

  • +
  • DMMCStack::CIMCheckStackSM()

  • +
  • DMMCStack::CIMCheckStackSM()

  • +
  • DMMCStack::NakedSessionSM()

  • +
  • DMMCStack::CIMSetupCardSM()

  • +
  • DMMCStack::CIMReadWriteBlocksSM()

  • +
  • DMMCStack::CIMEraseSM()

  • +
  • DMMCStack::CIMReadWriteIOSM()

  • +
  • DMMCStack::NoSessionSM()

  • +
+
Child state machine functions
    +
  • DMMCStack::AcquireStackSM()

  • +
  • DMMCStack::AttachCardSM()

  • +
  • DMMCStack::ExecCommandSM()

  • +
  • DMMCStack::IssueCommandCheckResponseSM()

  • +
  • DMMCStack::PollGapTimerSM()

  • +
  • DMMCStack::RetryGapTimerSM()

  • +
  • DMMCStack::DoPowerUpSM()

  • +
  • DMMCStack::InitClockOnSM()

  • +
  • DMMCStack::ProgramTimerSM()

  • +
  • DMMCStack::IssueMMCCommandSM()

  • +
+
Engineering +Specifications

No specifications are published.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-34D1D0BF-20DE-5677-A067-8FF9DD72E703.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-34D1D0BF-20DE-5677-A067-8FF9DD72E703.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,331 @@ + + + + + +Power Controller DPowerController Implementation TutorialThis topic describes how to implement the DPowerController class to provide the main power controller functionality in a base +port. +

DPowerController is defined as:

+class DPowerController : public DBase + { +public: + IMPORT_C DPowerController(); + IMPORT_C void Register(); + IMPORT_C void WakeupEvent(); + +#ifndef __X86__ + IMPORT_C TInt RegisterResourceController(DBase* aController, TInt aClientId); +private: + struct SResourceControllerData + { + DBase* iResourceController; + TInt iClientId; + } iResourceControllerData; +#endif + +public: + volatile TPowerState iTargetState; +public: + virtual void CpuIdle() = 0; + virtual void EnableWakeupEvents() = 0; + virtual void DisableWakeupEvents() = 0; + virtual void AbsoluteTimerExpired() = 0; + virtual void PowerDown(TTimeK aWakeupTime) = 0; + }; + +

The first three functions are exported from the kernel, EKERN.EXE, while the other five pure virtual functions +are implemented by your base port. You do not need to export any other +functions.

+
    +
  • Initialising the power controller,

  • +
  • DPowerController::RegisterResourceController(),

  • +
  • DPowerController::EnableWakeupEvents(),

  • +
  • DPowerController::AbsoluteTimerExpired(),

  • +
  • DPowerController::PowerDown(),

  • +
  • CpuIdle().

  • +
+
Initialising +the power controller

Typically, you implement your derived +class in a power management kernel extension, which has the opportunity +to perform initialisation before the system itself is fully initialised. +This is done via the extension's DLL entry point. You use the DECLARE_STANDARD_EXTENSION() macro as a wrapper around +your initialisation code. There are at least three things to do here:

    +
  • create an instance +of your power controller object

  • +
  • register your +power controller object with the Symbian platform power manager, by +calling DPowerController::Register(). Your power +controller cannot be used by the Symbian platform power manager until +it has been registered.

  • +
  • if you intend +to use a battery monitor, then you would create it and register it +as the HAL handler to deal with THalFunctionGroup::EHALGroupPower calls. See Battery Monitor Implementation Tutorialc and Power HAL Handler +Tutorial for more detail.

  • +

For example:

DECLARE_STANDARD_EXTENSION() + { + TInt r=KErrNoMemory; + + // Create the power controller object, and register it. + DPowerController* pC = new DYourPowerController; + if !(pC) + { + return (r); + } + pC->Register(); + + // Create the battery monitor. + DBatteryMonitor* pM = new DYourBatteryMonitor; + if !(pM) + { + return(r); + } + + r = KErrNone; + return(r); + }
+
DPowerController::RegisterResourceController()

The function DPowerController::RegisterResourceController() allows the Resource Controller to register itself with the Power +Controller. See registering with the resource controller in the PSL implementation +document.

To support idle power management the Power Controller's +PSL must override RegisterResourceController() to +include the registration of a list of resources whose states are of +interest to idle power management.

Idle power management

The Power Controller can assemble +a list of resources whose state it is interested in from a NULL thread +in an array of SIdleResourceInfo structures. Each +entry in the list contains the resource ID that the power controller +must enter before registering with the PRM. The resource list should +be created in the kernel heap or data section.

The example +below creates a buffer to capture the state of all static resources. +The PRM captures the information using DPowerResourceController::RegisterResourcesForIdle().

... +//Allocate buffer for Idle resource management + NKern::ThreadEnterCS(); + pBuf = HBuf::New(numResources * sizeof(SIdleResourceInfo)); + NKern::ThreadLeaveCS(); + if(!pBuf) + { + return KErrNoMemory; + } + SIdleResourceInfo* pI = (SIdleResourceInfo*)pBuf->Ptr(); + +//Update resource ID + for(TUint c = 0; c < numResources; c++) + { + pI[c].iResourceId = c+1; + } + r = (iResourceControllerData.iResourceController)->RegisterResourcesForIdle(iResourceControllerData.iClientId, numResources, (TPtr*)pI); + ...

The first parameter passed to RegisterResourcesForIdle() is the client Id generated for the power controller this is the +client ID passed by the PRM when calling RegisterResourceController.

Note: RegisterResourcesForIdle() is not exported and is only available for use by the Power Controller +to register resources for idle power management. Note: RegisterResourcesForIdle() can only be called by the Power +Controller once.

+
DPowerController::EnableWakeupEvents() virtual void EnableWakeupEvents() = 0;

The Symbian Power Model defines 3 generic system-wide power states: Active, Standby and Off, as defined in the Symbian platform +power model.

Each of the system-wide low power states: Standby and Off, has a defined set of wake-up events. +If a wake-up event occurs while the system is preparing to transition +into one of these low power states, or when the system is in the Standby state, then this can result in the system moving back +to the Active power state. Wake-up events may be different +for different target power states. Wake-up events are platform-specific +hardware events, and it is your base port that decides which events +count as wake-up events.

When is it called?

DPowerController::EnableWakeupEvents() is called called by the power manager as a result of a user side call to Power::EnableWakeupEvents(). The class Power is the user side interface to the power manager, and is used by +the user side entity that is responsible for moving the device into +a low power state.

Context

When the user side entity decides to move +the device to a low power state, it sends a notification to all of +the user side power domains registered with it, giving their applications +a chance to save their data and state. However, before doing this, +it calls Power::EnableWakeupEvents(). It also calls Power::RequestWakeupEventNotification() so that it can +be informed of a wake-up event. If it is notified of a wake-up event, +it can halt, and reverse the user side response to the power transition.

+ +

Before calling DPowerController::EnableWakeupEvents(), the power manager sets the iTargetState member +of DPowerController to the applicable TPowerState. This means that you can enable the appropriate set of wake-up events.

Once the user side transition is complete, it calls Power::PowerDown() in the user side interface to the power manager, which results in a call to DPowerController::PowerDown() in the power controller. This starts the transition of all power handlers to a low power state, a potentially long process. +This means that the power controller needs the ability to detect wake-up +events so that it can halt, and reverse the power transition.

Implementation issues

There are three possibilities +in dealing with wake-up events:

    +
  • if wake-up events +are not handled by specific peripheral drivers, you could set up the +hardware so that wake-up events are recorded in a location accessible +by the software. Prior to completing the system power transition, +the Power controller would check the relevant hardware to see whether +a wakeup event had occurred. On detecting a wake-up event it would +tell the power manager by calling DPowerController::WakeupEvent().

  • +
  • if wake-up events +are not handled by specific peripheral drivers, you could arrange +for wake-up events to interrupt the CPU. The code that services those +interrupts would tell the power manager by calling DPowerController::WakepEvent().

  • +
  • if wakeup events +are intercepted, serviced and cleared by peripheral drivers, then +the following outline solution could be adopted:

      +
    • The power controller +would need to publish a list of wake-up events, preferably as a bit +mask, and export an API which peripheral drivers could use to notify +the power controller that a wake-up event has occurred. The following +interface class could be used for this purpose:

      class TPowerController + { +public: + inline static void SetPowerControllerPointer(DPowerController* apPowerController) + { iPowerControllerPointer = apPowerController; } + IMPORT_C static void WakeupEventOccurred(TUint aWakeupEvent); + … // other methods if required +private: + DPowerController* iPowerControllerPointer; + }; +

      The class would be implemented +as part of the power management kernel extension and SetPowerControllerPointer() would be called when initialising the power controller, but after creation of the +power controller object.

      Those peripheral drivers that intercept +wake-up events would need to link to the power controller DLL (i.e. +the power management kernel extension).

      On the occurrence +of a wake-up event, the peripheral driver software servicing that +event would notify the power controller by calling WakeupEventOccurred(), specifying the appropriate wake-up event bit(s).

      You might +implement WakeupEventOccurred() as follows:

      EXPORT_C void TPowerController::WakeupEventOccurred(TUint aWakeupEvent) + { + if(iPowerControllerPointer->iWakeupEvents & aWakeupEvent) + { + iPowerControllerPointer->WakeupEvent(); + } + }

      where iWakeupEvents is a data +member defined in your DPowerController -derived +class that contains the bitmask representing the wake-up events. The +bitmask groups wakeup events according to the target power state.

    • +
  • +

When the peripheral driver powers down, it should leave the +hardware that generates the wake-up event powered and enabled for +detection. Thus, if a wake-up event of the type handled by this peripheral +driver occurs, it will not be serviced in the normal way, but will +be left pending until the power controller services it.

When +the power controller’s DPowerController::PowerDown() function is called, the power controller must check the peripheral +hardware directly to see whether the wakeup event has happened, or +is happening right now, prior to transitioning the device to the target +system-wide low power state. If the wake-up event is found to have +happened then DPowerController::PowerDown() would +return immediately, instead of initiating the power handlers power down of the peripheral drivers.

+
DPowerController::AbsoluteTimerExpired() virtual void AbsoluteTimerExpired() = 0;

When is it called?

DPowerController::AbsoluteTimerExpired() is called by the power manager whenever an absolute timer expires. An absolute +timer is one that is set to complete at a specific time, as queued +by a call to RTimer::At().

Implementation issues

If absolute timer expiration +is one of your wake-up events, then your implementation of DPowerController::AbsoluteTimerExpired() should call DPowerController::WakeupEvent() to notify the power manager +that a wake-up event has happened.

It is recommended that +you track absolute timers.

+
DPowerController::PowerDown() virtual void PowerDown(TTimeK aWakeupTime) = 0;

When is it called?

DPowerController::PowerDown() is called by the power manager to move the device into one of the system-wide +low power states: Standby or Off.

Typically, +this is a result of the user side entity that is responsible for moving +the device into a low power state calling Power::PowerDown() in the user side interface to the power manager.

If physical RAM defragmentation is implemented you may wish to include calls to TRamDefragRequest::DefragRam() within this function to enable defragmentation of RAM zones that +can then be powered down.

Context

The target state is defined by the value of +the iTargetState member of DPowerController, as set by the power manager.

Implementation issues

Implementation depends on the +target state:

    +
  • if the target +state is Standby, as implied by a value of TPowerState::EPwStandby in DPowerController::iTargetState, then the power +controller should put the hardware into a state corresponding to the Standby state.

    If at least one wake-up event has been +detected and recorded since the last call to DPowerController::EnableWakeupEvents(), then PowerDown() should return immediately; otherwise, +it should continue with the process of putting the device into Standby; execution of the function will halt, and can only continue, +and return, when a wake-up event occurs.

  • +
  • if the target +state is Off, as implied by a value of TPowerState::EPwOff in DPowerController::iTargetState, then PowerDown() must never return. Typically, the power +controller turns the device off, but can choose to perform other device-specific +action such as a system reboot.

  • +

The TTimeK parameter passed to the function +is a system time value. If non-zero, it specifies the time when the +system should wakeup. The kernel calculates it as the time that the +next absolute timer expires. Typically, your implementation will use +the Real Time Clock module to generate an event at the specified time, +and this will cause a return to the Active state. This implies +that the base port should enable Real Time Clock event detection during Standby.

The Symbian definition of the Standby state usually translates into the hardware manufacturer’s CPU “Standby” +or “Sleep” modes of operation. Typically, the internal clocks associated +with the core and some of the core peripherals, or their power supply, +are suppressed, and their internal state is not preserved. In this +case, the state of the core and core peripherals should be saved before +going into Standby so that they can be restored when the system +wakes-up. Note the following:

    +
  • for the core +state, save the current mode, the banked registers for each mode, +and the stack pointer for both the current mode and user mode

  • +
  • for the core +peripherals, save the state of the interrupt controller, the pin function +controller, the bus state controller, and the clock controller

  • +
  • for the MMU +state, save the control register, the translation table base address, +and the domain access control, if this is supported

  • +
  • flush the data +cache and drain the write buffer.

  • +

If all of this data is saved to a DRAM device, then this +should be put into self refresh mode.

Peripherals modules +involved in the detection of wake-up events should be left powered.

Tick timer events should be disabled, and the current count of +this and any other system timers should be saved; relevant wake-up +events should be left unmasked, and any others should be disabled.

+
DPowerController::CpuIdle() virtual void CpuIdle()=0;

When is it called?

DPowerController::CpuIdle() is called whenever the Null thread is scheduled to run. This can +happen as soon as the power model has been installed. It is the mechanism +through which your base port can increase power savings when the system +becomes inactive by moving the CPU or the system into a low power +mode.

If physical RAM defragmentation is implemented you may wish to +include calls to TRamDefragRequest::DefragRam() within this function to enable defragmentation while the device +is idle.

Implementation issues

The implementation can call +the Variant or ASSP implementation of Asic::Idle().

The idle state is usually implemented via a Wait-For-Interrupt +type instruction that will usually suspend execution of the CPU, possibly +triggering other ASIC power saving actions, and will resume execution +when any unmasked interrupt occurs.

Suppressing the system tick interrupt

To further increase +power savings during CPU Idle, a base port can choose to suppress +the system tick interrupt until the next nanokernel Timer (as implemented +by NTimer) is due to expire. Nanokernel timers +are the basic timing service and all Symbian platform tick-based timers +and time-of-day functions are derived from nanokernel timers.

In EKA2, timing services rely on a hardware timer, which is programmed +by the base port Variant code, to generate the system tick. We refer +to this as the system timer.

Typically, the platform-specific +ASSP or Variant object has a pointer to the nanokernel timer queue, +an NTimerQ object. The number of ticks before the +next NTimer is due to expire can be found by calling NTimerQ::IdleTime().

Before going into Idle mode, CpuIdle() disables the hardware timer used to generate the +system tick (i.e. the system timer) for the number of ticks to be +suppressed; i.e. the system timer is reset to go off and generate +an interrupt only when the NTimer expires. Note +that the clock supply to the hardware timer must be left enabled.

On returning from Idle mode, the software must examine the system +timer and decide whether the NTimer expiration +was responsible for waking up the processor, or whether it was due +to some other interrupt.

If waking up was due to the NTimer, the system timer must be reset to generate the +system tick at the frequency desired, and the tick count, NTimerQ::iMsCount, must be adjusted with the NTimer expiration time. As the expiration time is always an integer multiple +of the number of ticks, then the NTimerQ::Advance() function can be used for this purpose.

If waking up was +due to another interrupt, then the software must read the system timer +and calculate the time elapsed since going into Idle mode, and adjust +the system tick count with the elapsed time (which could be a fractional +number of ticks) and reprogram the system timer to continue generating +the tick after the correct interval, as above.

If the hardware +timer that is used to generate the system ticks does not use a Compare-Match +function, then some care has to be taken not to introduce skewing +when manipulating the timer value directly. If the timer needs to +be reloaded with the new value to give the next tick, then the software +usually “spins”, waiting for the hardware timer to change, and then +reloads it. This way the timer will always be reloaded on an edge +of its internal clock.

Waking up from “Sleep” modes with long wakeup latencies

Often, to further enhance power savings, the CPU and some peripherals +are moved into a hardware “sleep” mode when CpuIdle() is called. This could be of long latency, and waking up could take +longer than the system Tick period. There are two situations:

    +
  • if the wakeup +time can be determined precisely, then CpuIdle() programs +the system timer to bring the CPU back from the “Sleep“ mode at a +time corresponding to the next NTimer expiration +(as a number of Ticks to suppress) minus the number of ticks +it takes to wake up from that mode. On waking up on the timer, the +System tick count should be adjusted with the total number of ticks +suppressed, i.e. the count corresponding to the time of the NTimer expiration.

  • +
  • If the wakeup +time cannot be known deterministically, then the above scheme must +be combined with another system to allow adjusting the system timer +from the hardware Real Time Clock (RTC).

    Typically, the hardware +RTC is clocked with a 1Hz clock, and can be programmed to interrupt +the CPU on multiples of one second intervals. The clock supply to +the RTC must be left enabled on going into "sleep" mode.

  • +

To guarantee that timed events occur when they are due, the +CPU should only be allowed to go to into the long latency hardware +“sleep” mode if the RTC can be guaranteed to complete a second tick +before the CPU is due to wakeup.

Note that if waking up from +hardware “Sleep” mode takes a non-negligible amount of time, extreme +care should be taken when deciding to move the platform into that +mode. For example, if a receive request is pending on a data input +device and the CPU reaches the Idle mode and the platform +is transitioned into a “sleep” state and data arrives while +it is still in that state, then there is a possibility that +the system will not wake up on time to service the incoming data.

+
Validation

The e32test programs t_power, and t_timer will put the system into standby +and resume off a timer.

+
+Power +Management +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-3574BE12-9DA9-573D-8545-3B073005A139.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-3574BE12-9DA9-573D-8545-3B073005A139.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,67 @@ + + + + + +Configuration: +Timer ConstantsDescribes how to set the values of timer constants that change +the behaviour of the Digitizer Driver. +

The timing constants are defined near the beginning of the template port +implementation of the platform specific layer in ...\template\template_variant\specific\xyin.cpp.

+

The values and their meaning are as follows:

+
KInterSampleTime

This +constant determines the rate at which individual samples within a group are +collected.

A group of samples is collected when the pen is down, and, +in the template port, this is handled by DTemplateDigitiser::TakeSample().

Once +all the samples in a group have been collected, the function calls Digitiser::RawSampleValid() in +the platform independent layer, whose main purpose is to ensure the validity +of the samples by checking the spread. If the samples appear valid, it averages +the samples to obtain the current position.

The setting of the timer +constant depends on the sample resolution of the digitizer:

    +
  • A high resolution can +lead to more jitter between samples, and therefore more smoothing is required +to obtain nice steady values. This argues for higher sampling rates, and a +smaller value of KInterSampleTime.

  • +
  • A low resolution means +that there is very little variation between consecutive samples, and therefore +fewer are required. This argues for lower sampling rates, and a larger value +of KInterSampleTime.

  • +

Another consideration when setting this constant is the speed of +the communications between the MPU and the digitizer.

In the Symbian +reference ports, this value varies between 1 and 3.

+
KPenDownDelayTime

This +value is used in the implementation of the pen +interrupt interrupt service routine (ISR). It represents a delay, measured +in nano-kernel ticks, between a pen down event and the start of the collection +of digitizer samples.

The value is optional. Choose a value of 0 if +no delay is required. Typically, a value of 2 is chosen.

+
KInterGroupTime

This +value is used in DTemplateDigitiser::WaitForPenUp() and DTemplateDigitiser::WaitForPenUpDebounce(). +After a group of samples has been collected, there is a delay, dictated by +the value of this constant, before the collection for the next group begins.

The +inverse of the sum of KInterSampleTime, +and KInterGroupTime will therefore determine the frequency +at which groups of samples are taken. This, in turn, dictates how often pen +movement events are issued, and, if no interrupt is used on pen up, how quickly +this situation is ascertained. The constant is optional. Typically it is set +at 1ms

The delay is optional, a value of zero meaning that there is +no delay. Typically, a value of 1 is chosen.

+
KPenUpDebounceTime

This +value is used in DTemplateDigitiser::TakeSample(). If, during +sample collection, the pen goes up, then the digitizer will wait for this +period of time before deciding whether the removal of the pen is momentary, +or whether it is an intentional removal - this is also referred to as debounce.

If, +after the delay, the pen is still up, then a pen-up event is issued; otherwise +the state of the digitizer reverts to collecting mode, resetting the sample +buffer

Typically, this value is set to around 30.

+
KPenUpPollTime

This +value is used in DTemplateDigitiser::TakeSample().

If +the pen is down when the system powers on, then the digitizer is sampled using +this delay until the pen is up.

Typically, this value is set at 30.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-360DEB3A-3E38-413A-9941-6C758BA01ADE.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-360DEB3A-3E38-413A-9941-6C758BA01ADE.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,169 @@ + + + + + +DSDIOSession +Class TutorialDescribes the DSDIOSession API class. +
Description

This +class is used for setting up a session to form specific SDIO specific command +sequences.

The stages involved in initializing a session are as follows:

    +
  1. The session is first +created with the required parameter values

  2. +
  3. The session is placed +on the stack.

  4. +
  5. On completion of initialization, +a callback is called.

  6. +

It is intended that the DSDIORegInterface class +should be used for the majority of SDIO operations. This class should only +be used in more complex scenarios, for example where the asynchronous nature +of the stack could be an advantage. The same thing can also be achieved with +the DSDIORegInterface documented here .

Some +functions have an auto-increment parameter. If the hardware function requires +you to use the register as a pointer to an address, auto-increment automatically +increments the register to point to the next address after each call. If the +hardware function requires you to use the register as a FIFO, auto-increment +should be disabled.

+ + + +

Header file

+

sdio.h

+
+ +

Source code file

+

sdiosession.cpp

+
+ +

Required libraries

+

EPBUSSDIO

+
+ +

Class declaration

+

class DSDIOSession : public DSessionBase

+
+ + +
+
SetupCIMIoWrite()

The +function declaration for the SetupCIMIoWrite() method is:

IMPORT_C void SetupCIMIoWrite(TUint32 aAddr, TUint8 aWriteVal, TUint8* aReadDataP);

Description

Set the session to transfer a single byte of +data to the card, and optionally read the register after the write operation.

Parameters

+ + + +

TUint32 aAddr

+

Address of the destination register.

+
+ +

TUint8 aWriteVal

+

The byte to be written

+
+ +

TUint8* aReadDataP

+

Pointer to the start of the byte which is to be read into.

If +this parameter is NULL, then a read-after-write operation is not performed.

+
+ + +

Return value

None

+
SetupCIMIoRead()

The +function declaration for the SetupCIMIoRead() method is:

IMPORT_C void SetupCIMIoRead(TUint32 aAddr, TUint8* aReadDataP);

Description

Set the session to perform a read of a single +byte of data from the card.

Parameters

+ + + +

TUint32 aAddr

+

Address of the source register.

+
+ +

TUint8* aReadDataP

+

Pointer to the byte which is to be read into.

+
+ + +

Return value

None

+
SetupCIMIoWriteMultiple()

The +function declaration for the SetupCIMIoWriteMultiple() method +is:

IMPORT_C void SetupCIMIoWriteMultiple(TUint32 aAddr, TUint32 aLen, TUint8* aDataP, TBool aInc);

Description

Sets the session to perform a multi-byte (or multi-block) transfer +of data to the card.

Parameters

+ + + +

TUint32 aAddr

+

Address of the destination register.

+
+ +

TUint32 aLen

+

The number of bytes to be transferred.

+
+ +

TUint8* aDataP

+

Pointer to the start of the source buffer.

+
+ +

TBool aInc

+

Specifies whether the auto-increment feature is enabled or not.

+
+ + +

Return value

None

+
SetupCIMIoReadMultiple()

The +function declaration for the SetupCIMIoReadMultiple() method +is:

IMPORT_C void SetupCIMIoReadMultiple(TUint32 aAddr, TUint32 aLen, TUint8* aDataP, TBool aInc);

Description

Sets the session to perform a multi-byte (or multi-block) transfer of +data from the card.

Parameters

+ + + +

TUint32 aAddr

+

Address of the source register.

+
+ +

TUint32 aLen

+

The number of bytes to be transferred.

+
+ +

TUint8* aDataP

+

Pointer to the start of the destination buffer.

+
+ +

TBool aInc

+

Specifies whether the auto-increment feature is enabled or not.

+
+ + +

Return value

None

+
SetupCIMIoModify()

The +function declaration for the SetupCIMIoModify() method +is:

IMPORT_C void SetupCIMIoModify(TUint32 aAddr, TUint8 aSet, TUint8 aClr, TUint8* aReadDataP);

Description

Sets the session to perform a safe read-modify-write operation on a single +byte of data on the card.

Parameters

+ + + +

TUint32 aAddr

+

Address of the destination register.

+
+ +

TUint8 aSet

+

A bitmask of the values to be set: pass 1 where the bit is to be +set, otherwise pass 0.

+
+ +

TUint8 aClr

+

A bitmask of the values to be cleared: pass 1 where the bit is to +be cleared, otherwise pass 0.

+
+ +

TUint8* aReadDataP

+

If this value is not NULL, then the result of the modification is +returned in this parameter.

+
+ + +

Return value

None

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-365283F1-54B4-519A-81EC-9B5018896DDE-master.png Binary file Adaptation/GUID-365283F1-54B4-519A-81EC-9B5018896DDE-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-365283F1-54B4-519A-81EC-9B5018896DDE_d0e35432_href.png Binary file Adaptation/GUID-365283F1-54B4-519A-81EC-9B5018896DDE_d0e35432_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-36CD752C-45FE-5BFE-A695-11DF085F301F.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-36CD752C-45FE-5BFE-A695-11DF085F301F.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,30 @@ + + + + + +Debug +MacrosDescribes the macros that can be used to debug the bootstrap. +

The macro have no effect in non-debug builds of the bootstrap, when CFG_DebugBootRom is +FALSE. These macros do not modify any registers, but they may modify flags. +See Platform-Specific +Configuration Header.

+
PRINTPRINT text

Sends +the quoted text string text to the debug port.

+
PRTLNPRTLN text

Appends +a new-line character to the quoted text string text, and +sends the resulting text to the debug port.

+
DWORDDWORD reg, text

Sends +the quoted text string text to the debug port followed by +the value of ARM general register reg as an 8 digit hexadecimal +number followed by a new-line character.

+
MEMDUMPMEMDUMP base, len

Dumps +an area of memory of length len starting at base, +specified in hexadecimal, and sends it to the debug port.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-3722B946-07CF-4AEA-B228-E50642D6B5BE.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-3722B946-07CF-4AEA-B228-E50642D6B5BE.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,85 @@ + + + + + +Register Access Implementation GuideDescribes the implementation of the Register Access platform +service. +

A ASSP hardware register is a physical interface to an item of +hardware which contains values, such as bit fields, for controlling +ASSP features.

+
ASSP

An ASSP (Application Specific Standard Product) is a class of +integrated circuit. Different ASSPs have different architectures and +instructions sets. The AsspRegister class provides device driver writers with a simple interface to +access ASSP registers. Hardware implementers must provide the specified +functionality on a given platform and ASSP by writing the appropriate +machine instructions.

+
Pre-requisites

Before the implementing a register access implementation, the +following must be decided:

    +
  • The area in memory to which the registers are mapped. The start +of this memory region is known as the base address.

  • +
  • The location of each register in terms of an offset from the +base address.

  • +

The above information will be present in a specific header +file which is used by any device driver that uses this API. This header +file also contains other information required to access the registers, +such as:

    +
  • constants for bit field offsets

  • +
  • bit field values

  • +
+
Implementation

To provide register access, hardware implementers need to implement +the AsspRegister class.

Generic access to a register is provided in the form of three +operations on a hardware register: read, write and modify. All these +functions can be called in any context.

Symbian platform provides +the class header and inline implementations of the 8, 16 and 32-bit +wide functions. You must implement all the register modify functions +and all functions to access 64-bit wide registers. You may also need +to replace the inline 8, 16 and 32-bit wide register read and write +functions if the ASSP contains write-only registers.

You must +implement these functions atomically so that there is no possibility +of another thread or interrupt service routine accessing the contents +of the register before the function returns. Where you cannot implement +the function with a single machine instruction you must disable interrupts +during the register operation (if you are working with a single core +architecture) or wrap a spinlock around the register operation (if +you are working with a multicore architecture).

There are +three cases in which you must enforce atomicity with interrupt disabled +or use of spinlocks.

    +
  • The modify operations +involve reading the register, taking a local copy, changing the local +copy and writing it back to the register and cannot be performed with +a single machine instruction.

  • +
  • Operations on +write-only registers involve maintaining a copy of the current contents +of the register within the AsspRegister class. All write and modify operations therefore cannot be performed +with a single machine instruction.

  • +
  • Some architectures +contain 64-bit registers. In this case, 64-bit operations involve +at least two machine instructions.

  • +

Baseport implementations of the Register Access platform service +come in the form of a ASSP library (or DLL). To avoid the need for +each device driver which uses the ASSP register class having to specify +a baseport specific library file corresponding to the ASSP library, +the name of the baseport specific library file should instead be included +in a file used to define other variant specific settings such as the +CPU core type, the memory model and the name of the variant. Each +baseport will have a file called variant.mmh, +where variant is the name of the baseport to be used. +An example of this being used in a variant.mmh file is:

#if defined(__USING_BASPORT__) +library VariantTarget(basport_name,assp_library) +#endif +baseport_name is the name of the variant and assp_library +is the name of the ASSP specific library file.

In order to +specify which baseport assp register set up is to be used in the client +projects for this baseport, the following line is included in the +MMP file of those projects

#define __USING_BASEPORT___
+
+ +SMP - Locking +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-372D2B88-2035-44A5-82CF-57FF131DDEBE.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-372D2B88-2035-44A5-82CF-57FF131DDEBE.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,15 @@ + + + + + +Platform ServiceA service that is intended to be used by any part of the +OS. +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-3773A78D-F491-52EB-AA1D-201636497F28.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-3773A78D-F491-52EB-AA1D-201636497F28.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,23 @@ + + + + + +Power Management +TutorialsThis topic describes how to implement a power controller in a base +port. +

A power controller is a kernel extension that manages the power management +hardware of a phone, for example on-chip power management controllers and +oscillators.

+
+Power Management + +Power States + +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-37B8243E-027A-49D0-A896-27946DAC9052.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-37B8243E-027A-49D0-A896-27946DAC9052.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,114 @@ + + + + + +Baseport Template Tools GuideDescribes the tools required needed to implement and test +the Baseport Template platform service. +
Build +tools

The following build tools are available:

+ + + +Name +Description + + + + +BUILDROM +BUILDROM is a unified ROM building front end. +It invokes ROMBUILD to build the ROM image and ROFSBUILD to build the ROFS image. + + +ROMBUILD +ROMBUILD is the Symbian platform binary XIP +(execute-in-place) ROM builder. It is normally invoked through BUILDROM. + + +ROFSBUILD +ROFSBUILD is the Symbian platform non-XIP +ROFS builder. It is normally invoked through BUILDROM. + + +iMaker +iMaker is a ROM-image creation tool that creates +a flash image from a set of Symbian binary and data files. iMaker mainly functions on top of BUILDROM. + + +SPITOOL +SPITOOL is a utility tool to create static +plug-in information (SPI) files. + + +InterpretSIS +InterpretSIS is a command-line tool used to +install SIS files. It can be invoked either through BUILDROM or directly. + + +READIMAGE +READIMAGE is a command-line tool that provides +readable data from a ROM, ROFS, or E32 image. + + +MAKSYM/MAKSYMROFS +MAKSYM/MAKSYMROFS is a tool to create a readable +symbol file listing the virtual addresses of the exported functions. + + +Obey +Files +OBEY files are standard text files containing +statements that are used to control the operation of the ROM building +tools. + + +Symbian Build System v2 +SBSv2 is a tool for building Symbian platform +and applications developed for Symbian platform. It helps you build +a set of components, or the complete Symbian platform, on Windows +and Linux platforms for the ARMv5, TOOLS2 and WINSCW target platforms. +They also provide a reference to the file formats used as input to +the build tools. For more information about SBSv2, see the Symbian +Build System v2 documentation that is provided with the Platform +Developer Toolkit. + + + +
+
Emulators

The following emulators are available:

+ + + +Name +Description + + + + +QEMU +QEMU is an open source emulator which can +be used to run and debug a Symbian ROM image on a PC. + + +Syborg + Syborg is a Symbian baseport for use with +QEMU. + + + +
+
+Base +Porting Guide +Baseport +Template Implementation Guide +Baseport +Template Testing Guide +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-388004AF-6F99-4BBB-A8E0-D75DC5B6790C.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-388004AF-6F99-4BBB-A8E0-D75DC5B6790C.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,134 @@ + + + + + +Test +ApplicationThis document describes a simple application which is used to load +a device driver and test its functionality. +
Testing +device drivers

Drivers, apart from kernel extensions, are +not automatically started by the Kernel, so they must be explicitly loaded +by application.

When testing an LDD-PDD model driver, it is a general +practice to write a simple test application that loads the LDD and PDD by +name, opens a logical channel, and calls the driver API to test the driver's +functionality.

The following shows a command line test application +that does this:

/** E32Main - Application, exe main entry point. */ +GLDEF_C TInt E32Main() + { + ... + // Load the PDD. This user API will load the PDD DLL by name + // and also enable the loader to search for the PDD object + // by name. + r = User::LoadPhysicalDevice(KExDriverPdd); + + // PDD loading is considered successful, if either it is + // loaded now or it is already loaded. + test((r==KErrNone)||(r==KErrAlreadyExists)); + + // Load the LDD. This user API loads the LDD DLL by name + // and also enable the loader to search for the LDD object + // by name. + r = User::LoadLogicalDevice(KExDriverLdd); + + // LDD loading is considered successful, if either it is + // loaded now or it is already loaded. + test((r==KErrNone)||(r==KErrAlreadyExists)); + ... + + // Get device capabilities + ... + + // Open the device with reference to the driver name. + r = device.Open(KDriverName); + if (r==KErrNone) + { + ... // do required operations + // Close the device. This handle is required only to + // get any device related information from the LDD factory + // object. + device.Close(); + } + + // RExDriverChannel is an RBusLogicalChannel derived class, which provides a user side + // handle to a logical channel. It defines the driver interface. + RExDriverChannel ldd; + + // Open the logical channel to the driver for unit 1. This is a + // user-side wrapper function for the + // RBusLogicalChannel::DoCreate() API. DoCreate() is + // called in Open() for unit 1. + // + r = ldd.Open(KUnit1); + test(r==KErrNone); + + // Call the driver API using the RExDriverChannel interface and + // test for the functionality + ... + + // Close the logical channel + ldd.Close(); + + // Free the logical device / LDD + r=User::FreeLogicalDevice (KDriverName); + test(r==KErrNone); + + // Instead of directly using the PDD name, get the PDD + // factory object name and append the extension name, to + // unload the PDD. + TName pddName(KDriverName); + _LIT(KVariantExtension, ".pdd"); + pddName.Append(KVariantExtension); + + // Free the PDD, resulting in freeing the PDD factory object + r=User::FreePhysicalDevice (pddName); + test(r==KErrNone); + + ... + }

If the driver is a kernel extension, then the Kernel +loads the driver when it boots, so an application does not need to load the +driver explicitly. Applications simply open a channel to the driver and call +the driver API as required.

The RTest class provides +macros and functions that can be used in test applications. It provides macros +to validate a return value against an expected value, and to leave giving +the line number where the error occurred. It also provides macros to print +debug messages, to group the test sets, and so on.

// Create RTest object (test framework) +LOCAL_D RTest test(_L("Tutorial Driver")); + +GLDEF_C TInt E32Main() + { + // Initialize the test object with a title + test.Title(); + + // RTest::Starts() starts a set of tests + test.Start(_L("Load Physical Device")); + ... + // RTest::Next() starts a new set of tests + test.Next(_L("Open Channel")); + ... + // Test if a condition is true. If not, the application leaves + // displaying the line number and error type + test(r==KErrNone) + ... + // Prints a string to the screen + test.Printf(_L(“<display string %d>”),r); + ... + // End the tests + test.End(); + }

The drivers developed and built can be tested on the +target hardware. The debug or release versions of the driver are built into +the ROM and downloaded to the target. This is done either by using a MMC card, +USB, Serial or JTAG interface, as supported by the particular hardware board. +Once the board is powered on or reset, Symbian platform boots and the text +shell is displayed (assuming a text shell ROM image). To test an LDD-PDD driver, +run the test application from the command line.

If debug messages +are enabled in the driver, by using KTRACE or BTRACE, +the messages can be viewed on the LCD screen, or through a connected COM port, +using the HyperTerminal application on a PC.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-38FD682F-656B-48F7-A553-50BC4F1FB4BB.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-38FD682F-656B-48F7-A553-50BC4F1FB4BB.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,17 @@ + + + + + +Base PortThe base code of the Symbian platform is structured so +that generic code is separated from hardware-specific code. This means +that porting Symbian to new hardware requires modification or creation +of hardware-specific code only. This is what is known as a base port. +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-3A1BCF46-FFBB-4E4F-A73A-6E68254B23FF.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-3A1BCF46-FFBB-4E4F-A73A-6E68254B23FF.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,30 @@ + + + + + +SDIO +Implementation Quick StartProvides a collection of documents that describe SDIO (Secure Digital +Input Output) implementation. +

The implementation guide describes how SDIO is included in a build of the +Symbian platform.

+

SDIO Implementation +Guide

+

The testing guide describes techniques that can be used for testing the +SDIO functionality.

+

SDIO Implementation +Testing Guide

+

The tools guide describes the tools that can be used to test an implementation +of SDIO.

+

SDIO Implementation +Tools Guide

+

The build guide describes how to include the SDIO adaptation in a ROM image.

+

SDIO Implementation +Build Guide

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-3A30DA16-ECA8-5639-A9DC-6BE2AD55420B.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-3A30DA16-ECA8-5639-A9DC-6BE2AD55420B.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,69 @@ + + + + + +I2C Technology GuideThis topic describes the Inter Integrated Circuit (I2C) +bus technology. +
Introduction

The I2C is a serial bus technology invented by Philips. The I2C +is a multi master serial interface used by the low power peripherals +to exchange data. The I2C supports different modes of data transfer +and three commonly used modes are:

    +
  • Standard mode supports 100Kbps data transfer

  • +
  • Fast mode supports 400Kbps data transfer

  • +
  • High speed mode supports 3.4Mbps data transfer

  • +
+
Architecture

The I2C bus contains 2 bi-directional lines, a serial clock (SCL) +and serial data (SDA) lines. In the I2C bus, more than one device +could act as Master device. There can be only one master device active +at a given time. The master device initiates the communication and +slave responds to the master. The master and slave devices can be +interchanged after a data STOP signal is sent from +the master. The master device can address more than one slave at a +time.

+ I2C Bus + +

The master device can read and write data to the slave device. +The I2C bus uses 7 or 10 bit address.

+
Features

The features of the I2C bus are:

    +
  • the master device +can send and receive data from the slave device

  • +
  • the I2C bus +uses 7 or 10 bit address

  • +
  • only uses 2 +bi-directional lines for communication

  • +
  • multiple master +device can be connected to the same bus

  • +
+
Communication

The first byte from the master is used to address the slave device. +In the first byte the master sends the address and read/write signal +to the slave. There are three types of messages:

    +
  1. master just +reads data from the slave

  2. +
  3. master just +writes data to the slave

  4. +
  5. master reads +and writes data

  6. +

The communication is initiated with a start signal and completed +with a stop bit. In the third type of message the master starts the +communication with a start signal with a read or write bit to the +slave. The process continues until the master has completed the read +and write tasks. The communication is terminated with a stop signal.

+
Typical +Uses

The typical uses of I2C bus are:

    +
  • to read data +from various flash devices like EEPROM and SDRAM

  • +
  • to control LCD

  • +
  • to read real +time clock data

  • +
+
+ +I2C bus specification v2-1 Jun 2000 +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-3A625B23-354E-5CB4-98CF-FF53AD724FA0.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-3A625B23-354E-5CB4-98CF-FF53AD724FA0.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,66 @@ + + + + + +Dealing with Demand PagingWhen demand paging is used, the contents of memory are +available to a program when they are required (“on demand”). When +the contents are no longer required, the RAM can be used for other +content. +

Demand paging is a change to how the kernel can use RAM from Symbian +platform v9.3. This topic describes the possible results for base +port.

+

When demand paging is used, the contents of memory are available +to a program when they are required - that is, 'on demand'. When the +contents are no longer required, the RAM can be used for other content. +In this way, the total RAM required to store content is less than +if it were all permanently available.

+

The Device Driver Guide provides Suggested techniques for mitigating the effects of demand paging for writers of device drivers. These recommendations can result +in a more ‘multithreaded’ base-port. This may have the following impact +that needs to be considered:

+
    +
  • A base-port +component may provide services to device drivers, exposing to them +a shared resource; either hardware or software:

      +
    • hardware - may +be a hardware controller whose non-instantaneous operation, once initiated, +cannot be disturbed until it completes

    • +
    • software - may +be a list of requests for services.

    • +
  • +
  • A hardware component +has a control interface that can be used by a number of drivers. Operations +on the control interface although near instantaneous, are not atomic +and cannot be interrupted.

  • +
+

In the case of the base-port component, when the state of a resource +needs to be protected from the effects of pre-emption for a non-negligible +period of time, the recommended approach is to use mutual exclusion, +protecting the resource with a mutex: unless there is any chance that +the same driver may trigger the same operation before the previous +one completed. For example, when operations are non-blocking and happen +in a context different from the initiator’s, a NFastMutex should suffice.

+

An example of the hardware component situation is a set-clear control +interface, where a pair of registers (one containing the bits to be +set, the other the bits to be cleared) have to be written to produce +the desired change. If the operation is pre-empted after bits are +set but before they are cleared for a desired final output, and a +new set-clear operation is initiated, the final state of the interface +may be undetermined. Pre-emption protection in this case is achieved +by simply locking the Kernel using NKern::Lock() before the operation starts and unlocking it with NKern::Unlock() after it completes. If the interface is to be used from an interrupt +context disabling all interrupts is sufficient to protect against +thread concurrency.

+
+Migration + Tutorial: Demand Paging and Internal MMC Cards + +Migration +Tutorial: Demand Paging and Media Drivers + +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-3A785F02-F4AA-432C-9331-8827029BB384.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-3A785F02-F4AA-432C-9331-8827029BB384.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,25 @@ + + + + + +Status +QueryThis document describes how the status of an asynchronous request +is maintained and monitored. +

A TRequestStatus object is used to monitor the status +and result of the asynchronous request. This object maintains the status of +the request at various stages and finally contains the request result. The +driver uses the status object when performing operations on the request such +as cancelling, completing, or managing multiple similar requests.

+

Initially, when the request is made, the Kernel changes the status to KRequestPending. +After completion of the request, the status is changed to KRequestComplete to +indicate request completion. It also contains the result of the request, which +can indicate an error or failure of the request. TRequestStatus::Int() returns +the request result.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-3AFE0D8B-FB9B-5355-A63B-FB71DD13E7D0-master.png Binary file Adaptation/GUID-3AFE0D8B-FB9B-5355-A63B-FB71DD13E7D0-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-3AFE0D8B-FB9B-5355-A63B-FB71DD13E7D0_d0e73917_href.png Binary file Adaptation/GUID-3AFE0D8B-FB9B-5355-A63B-FB71DD13E7D0_d0e73917_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-3B6544CD-FA6E-5AB2-AA63-61186F52167D.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-3B6544CD-FA6E-5AB2-AA63-61186F52167D.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,231 @@ + + + + + +Controllable +Power ResourcesThis topic explains how power resources were controlled in older +releases of Symbian platform. For later releases see the Power Resource Manager +documentation. +

This documentation is retained for reference for those working with hardware +or software that is based on older versions of Symbian platform version (in +particular old release 9.5). For later releases see the Porting +the Power Resource Manager documentation.

+

Controllable power resources are defined as being any device resource, +such as voltages on power-lines or clocks, which can be independently enabled, +disabled or modified under software control.

+

The following hardware block diagram is an example of the way power resources +might be arranged:

+ +Example power resource arrangement + + +

There is no default support or default implementation for controllable +power resources in the generic layers of Symbian platform. They must be managed +by the base port.

+

We suggest that the management of controllable power resources (the resource +manager) be implemented in the Variant DLL or the ASSP DLL. This allows the +resource manager to be up and running by the time peripheral drivers, which +might also be kernel extensions, are loaded. See the ASSP/Variant Architecture and the ASSP/Variant +Tutorials.

+

A suggested implementation has the instance of the Asic derived +class owning a pointer to the resource manager object. The interface class +for the ASSP or Variant could then have an exported or an inline member function +to return a pointer to this resource manager object. Peripheral drivers are +expected to link against either the ASSP DLL, or the Variant DLL, or both.

+

For example, for a device that has a Variant and an ASSP:

+class MyVariant : public MyASSP + { +public: + Init1(); + Init3(); + // Other mandatory Asic-derived member functions + ... +public: + ResourceManager* myResMgrPtr; + ... + }; + +

where class MyASSP is derived from class Asic.

+GLREF_D MyVariant TheVariant; +class TMyVariant + { +public: + inline static ResourceManager* ResourceManager() + {return(TheVariant.myResMgrPtr);} + // other exported methods + ... + }; + +

where TMyvariant is the Variant interface class, and ResourceManager is +the resource manager class.

+

The resource manager can be declared as a global object at the Variant +(or ASSP) scope and can therefore be created when this component is first +loaded. In this case, the Asic::Init3() function would +initialise the ResourceManager object, and set up myResMgrPtr. +Alternatively, if the Variant (or ASSP) were to need the resource manager +up and running, then you would initialise ResourceManager in Asic::Init1().

+

In this implementation, the Variant would export a header file(s) publishing +a list of controllable power resources.

+
Shared controllable +power resources

Some controllable power resources can be shared +between groups of peripherals and therefore may require usage tracking.

We +recommend that shared power resources be represented by a class derived from MPowerInput. +This class offers the Use() and Release() interface +that encapsulates resource counting behaviour. This mechanism should turn +the resource on when the count becomes non-zero, and turn the resource off +when the count becomes zero.

We suggest that your MPowerInput derived +class defines and implements a GetCount() function that returns +the usage count on the shared resource.

+
A suggested +implementation of a resource manager

While we have implied that +a resource manager is a single class, which we have called ResourceManager, +the resource manager is a notional concept for controlling power resources. Symbian +neither mandates a format for a ResourceManager class, nor even its existence. +In practice, it may be more useful to embed resource manager functions and +data in the Variant interface class (or the ASSP interface class, if appropriate).

However, +for the purpose of explaining what a resource manager can do, it is easier +to assume that this behaviour is handled by a resource manager class. This +is the outline definition of such a class.

class ResourceManager + { +public: + void InitResources(); // called by your Asic::Init3()/Asic::Init1() + void Modify(TUint aSetMask, TUint aClrMask); // only 32 simple Resources can be managed + TBool GetResourceState(TUint aResBitMask); // only 1 bit set on this mask, returns On/Off +public: + (MPowerInput-derived) iSharedResource1; // 1 per shared resource + (MPowerInput-derived) iSharedResource2; + ... + }; +

The InitResources() function would +do at least two things:

    +
  • enable an appropriate +set of simple resources at boot time

  • +
  • initialise the shared +power resource tracking objects, i.e. the instances of your MPowerInput derived +class(es).

  • +

The function would be called by the Variant or ASSP implementation +of Asic::Init3() or Asic:Init1().

The Modify() function +is an example of how to deal with power resources that are either on or off. +The function would take bit masks, where a bit represents a separate controllable +power resource. The first bit mask would represent the set of power resources +to be turned on, while the second would represent the set of power resources +to be turned off. This assumes that the function could behave synchronously. +Drivers for peripherals that use a set of these controllable power resources, +would call Modify() to turn the relevant controllable power +resources on or off.

As an example, the most common method of switching +clock resources on or off is by setting and clearing bits in a hardware register. +A base port could choose to implement common code for setting bits in registers.

A +shared power resource is further represented by a MPowerInput derived +class. The implementations of MPowerInput::Use() and MPowerInput::Release() would +call Modify() to turn on the shared resource when the usage +count becomes non zero, or turn it off when the usage count reaches zero. +Peripheral drivers would have access to shared resources, and also to the +member functions of the ResourceManager class, through the +ASSP or Variant Interface class function that returns a pointer to it.

The +resource manager, or its functions and members, could be offered as part of +a power controller interface class, the TPowerController class +suggested when we discussed the implementation of the Power +Controller's EnableWakeupEvents() function. +The class would provide an exported function that would give access to the +resource manager. The resource manager class would be made part of the power +controller kernel extension. Peripheral drivers needing access to shared power +resources would then link to the power controller DLL. If the Variant or ASSP +were also to need access to the resource manager, then the resource manager +would have to be initialised much earlier in the kernel start-up sequence. +In this case, we would suggest that the standard power controller kernel extension +entry point defined by DECLARE_STANDARD_EXTENSION() be +replaced with a custom entry point that might look like this:

GLDEF_C TInt KernelModuleEntry(TInt aReason) + { + if(aReason==KModuleEntryReasonVariantInit0) + { + ResourceManager* c = new ResourceManager (); // create Resource Manager + return c ? KErrNone : KErrNoMemory; + } + else if(aReason==KModuleEntryReasonExtensionInit0) + { + (create DPowerController and Battery Monitor and Power HAL handler) + } + return KErrNone; // gets here from calling with KModuleEntryReasonExtensionInit1 + } +

The Variant or ASSP would also need to link to the +power controller DLL.

The following base port software architecture +could be applied to the power supply arrangement as illustrated in the hardware +block diagram above (see the beginning of this section at Controllable +Power Resources):

+Base port software architecture + +
+
Multi-level, +composite and asynchronous power resources

Some power resources +may have more than one operational level. For example, it is possible that +an input clock to a peripheral can be operated at a nominal value corresponding +to the fully active state, and may be lowered to another level corresponding +to the power saving state.

The same could apply to the input voltages +that the peripheral can operate on. The control model suggested above for +simple resources may not be appropriate. A suggested alternative would have +these multi-Level resources implementing an interface that offers a public +enumeration to cover all possible usage levels at which the resource can be +used, and APIs such as:

class MultiLevelResource + { + enum TResourceLevel + { + EOperationalLevel1, + EOperationalLevel2, + . . . + ELowPowerLevel1, + ELowPowerLevel2, + . . . + }; + void UseToLevel(); + void ReleaseToLevel(); + TResourceLevel GetCurrentLevel(); + . . . + };

More importantly, it is possible that resources may +have to be operated in combination with other resources. For example, some +peripherals may have more than one input clock, and on transition between +power states, these clocks may have to be changed simultaneously.

If +the resources to be actuated simultaneously are simple resources, then the +model above with a Modify() call that takes a bit mask and +allows more than one resource to be changed at a time may be appropriate. +If the resources to be actuated are shared or multi-level, or have to be represented +individually, then another interface will have to be defined to allow modifying +more than one of them simultaneously.

Modifying some resources may +not be an instantaneous operation. For example, it may take a non-negligible +amount of time to stabilise an input clock that has just been modified.

The +nature of EKA2 strongly discourages actively waiting (or “spinning”) inside +drivers; instead it is suggested that the multithreading capabilities of EKA2 +kernel side code and the synchronisation mechanisms available be used to solve +the problem of having the driver code having to wait for a resource to stabilise +before proceeding with its use.

As an example, let us assume that +the multi-level resource mentioned above has a non-negligible delay associated +with any level changes:

    +
  • If the length of time +to wait for a power resource to stabilise is known, and is the order of a +few milliseconds or less, or the driver executes on its unique kernel thread +(not used by any other kernel-side code), then the best solution would be +to sleep the driver thread, by calling NKern::Sleep(aTime) for +the specified length of time after issuing a call to UseToLevel() (or ReleaseToLevel()).

  • +
  • When the length of time +to wait for a power resource to stabilise increases, then sleeping the driver +thread may become a problem if the driver executes in a DFC queue used by +other drivers, which is often the case. This is because blocking that thread +means that no other drivers can run. Here, the best solution is for the driver +to create another thread and DFC queue, by calling Kern::DfcQInit(), +and whenever it needs to change the resource, queue a DFC on that queue, which +will issue the calls to UseToLevel() (or ReleaseToLevel()) +and then sleep the thread.

  • +
  • If the length of time +to change a power resource cannot be known in advance, but the hardware provides +an indication of completion of the change, for example, in the form of an +interrupt, then the solution may involve the driver code waiting on a Fast +Mutex, which is signalled by the completion event (in code belonging to the MultiLevelResource derived +object).

  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-3C34724F-B476-5329-B0B1-6D5A34294979.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-3C34724F-B476-5329-B0B1-6D5A34294979.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,21 @@ + + + + + +Interrupt +Dispatcher TutorialDescribes how to implement the Interrupt Dispatcher part +of the ASSP/Variant. +Interrupt +Dispatcher +Interrupt +Service Routines (ISR) +Symbian OS Internals - Chapter 6 Interrupts +and Exceptions + \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-3CB74FE6-272E-4176-BC51-E36103CADB09-master.png Binary file Adaptation/GUID-3CB74FE6-272E-4176-BC51-E36103CADB09-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-3CB74FE6-272E-4176-BC51-E36103CADB09_d0e94075_href.png Binary file Adaptation/GUID-3CB74FE6-272E-4176-BC51-E36103CADB09_d0e94075_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-3E85C075-436F-5D2E-B1F7-0C9EC6D382E3.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-3E85C075-436F-5D2E-B1F7-0C9EC6D382E3.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,46 @@ + + + + + +Source +Code OrganisationDescribes the platform-independent files of the bootstrap. +

The generic files are stored in the os/kernelhwsrv/kernel/eka/ directory.

+

The files are:

+
    +
  • kernel/bootstrap.mke - +Generic part of the makefile, written for GNU make. Works for both ARM and +X86 bootstrap builds.

  • +
  • include/e32rom.h - +C++ Header file describing the layout of the ROM header and the ROM file system.

  • +
  • include/kernel/kernboot.h - +C++ Header file describing the interface between the bootstrap and the kernel, +mainly the definition of super page fields. Applicable to both ARM and X86.

  • +
  • include/kernel/arm/bootcpu.inc - +Assembler include file giving CPU-specific definitions for ARM.

  • +
  • include/kernel/arm/bootdefs.h - +C++ Header file containing some internal bootstrap definitions for ARM.

  • +
  • include/kernel/arm/bootmacro.inc - +Assembler include file containing some general-purpose macro definitions for +ARM.

  • +
  • include/kernel/arm/bootstrap.lnk - +Linker script file for GNU linker; used when building ARM bootstrap using +GNU tools.

  • +
  • include/memmodel/epoc/<model>/arm/mmboot.h - +C++ Header file containing memory-model-specific definitions shared with bootstrap.

  • +
  • kernel/arm/bootcpu.s - +Source file containing routines which are specific to a particular ARM CPU +rather than generic to all ARM CPUs.

  • +
  • kernel/arm/bootutils.s - +Source file containing lots of useful subroutines such as memory copy, memory +fill, generic MMU mapping code, generic memory allocator, and so on.

  • +
  • kernel/arm/bootmain.s - +Source file containing top-level bootstrap code.

  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-3F0053A7-6EE2-5B59-81C2-27EC3CC7820A-master.png Binary file Adaptation/GUID-3F0053A7-6EE2-5B59-81C2-27EC3CC7820A-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-3F0053A7-6EE2-5B59-81C2-27EC3CC7820A_d0e9276_href.png Binary file Adaptation/GUID-3F0053A7-6EE2-5B59-81C2-27EC3CC7820A_d0e9276_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-3F47E907-975A-5739-9B03-042CB90D675D.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-3F47E907-975A-5739-9B03-042CB90D675D.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,16 @@ + + + + + +Port Implementation +TutorialDescribes the steps to implement a port of the DMA Framework. +Concepts + + \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-3FE9C184-1880-51E1-B045-3C2EA4BE204A-master.png Binary file Adaptation/GUID-3FE9C184-1880-51E1-B045-3C2EA4BE204A-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-3FE9C184-1880-51E1-B045-3C2EA4BE204A_d0e78117_href.png Binary file Adaptation/GUID-3FE9C184-1880-51E1-B045-3C2EA4BE204A_d0e78117_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-40880992-B177-4584-84B4-6F6CF096E423-master.png Binary file Adaptation/GUID-40880992-B177-4584-84B4-6F6CF096E423-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-40880992-B177-4584-84B4-6F6CF096E423_d0e96877_href.png Binary file Adaptation/GUID-40880992-B177-4584-84B4-6F6CF096E423_d0e96877_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-40F2BC43-5022-5F4E-B445-56FEF43FEB8B.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-40F2BC43-5022-5F4E-B445-56FEF43FEB8B.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,71 @@ + + + + + +Code +OrganizationDescribes the MultiMediaCard Controller source code provided by +Symbian platform +
Platform independent +layer

The location of the source code and the header files for +the platform independent layer of the MultiMediaCard +controller, i.e. the generic DLL, provided by Symbian platform called epbusm.dll, +is as follows:

+ + + +

+

Source location

+

Source files

+
+ +

Peripheral bus layer source code.

+

...\e32\drivers\pbus\

+
    +
  • spbus.cpp

  • +
  • pbusmedia.cpp

  • +
+
+ +

Peripheral bus layer header files and inline functions.

+

...\e32\include\drivers\

+
    +
  • pbus.h

  • +
  • pbus.inl

  • +
  • pbusmedia.h

  • +
+
+ +

MultiMediaCard layer source code.

+

...\e32\drivers\pbus\mmc

+
    +
  • +
  • session.cpp

  • +
  • stack.cpp

  • +
+
+ +

MultiMediaCard layer header files and inline functions.

+

...\e32\include\drivers\

+
    +
  • mmc.h

  • +
  • mmc.inl

  • +
  • mmc_ifc.h

  • +
+
+ + +
+
Platform specific +layer

The suggested location of the source code and the header +files for the platform specific layer of the MultiMediaCard controller, i.e. the variant DLL, provided by you, +and usually called epbusmv.dll, is the variant specific +directory. This is the directory ...\<VAR>\specific\.

How +you organize source and header files within this directory is up to you.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-423537D5-2C8A-5C26-8D7B-60446E95F681.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-423537D5-2C8A-5C26-8D7B-60446E95F681.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,72 @@ + + + + + +Interrupt +Layer InitialisationThis topic describes how to implement the Asic::Init1() and Asic::Init3() functions +to initialise interrupts. +
In first phase +initialisation

During first phase initialisation of start-up, the +kernel calls the ASSP's implementation of Asic::Init1(). +For the template reference board, where the ASSP is split into a common, ASSP +layer and a device-specific (variant) layer, interrupt handling is initialised +in the ASSP layer, specifically in TemplateAssp::Init1(), +defined in ...\template_assp\template_assp_priv.h, and +implemented in ...\template_assp\assp.cpp.

Note +that interrupts are disabled during first phase initialisation.

Within +your implementation of Init1(), do the following:

    +
  • Initialise the ISR table.

    It is useful to initialise the ISR table so +that each interrupt is bound, by default, to the Spurious interrupts handler, with the 32-bit parameter taking the +interrupt number.

    For example,

    ... +const TInt KInterruptSourceCount = 32; +SInterruptHandler IsrHandlers[KInterruptSourceCount]; +... + +for( TInt i = 0; i < KInterruptSourceCount; ++i ) + { + IsrHandlers[i].iIsr = SpuriousHandler; + IsrHandlers[i].iPtr = (TAny*)i; + }

    where the spurious interrupt handler function might be +implemented as:

    void SpuriousHandler(TAny* aId) + { + Kern::Fault("SpuriousInt", (TInt)aId); // handle unexpected interrupt. + } +

    On the template reference board, the ISR table is initialised +by TemplateInterrupt::Init1() in ...\template_assp\interrupts.cpp, +and this is called by TemplateAssp::Init1().

  • +
  • Register the dispatcher +functions. The Symbian platform kernel needs to know the location of the IRQ +and FIQ dispatchers. It provides the two functions: Arm::SetIrqHandler() and Arm::SetFiqHandler(), +which the Variant layer must call, passing the addresses of the IRQ and FIQ +dispatchers.

    On the template reference board, the registration is +done by TemplateInterrupt::Init1() in ...\template_assp\interrupts.cpp.

    void TemplateInterrupt::Init1() + { + // + // need to hook the ARM IRQ and FIQ handlers as early as possible + // and disable and clear all interrupt sources + // + ... + DisableAndClearAll(); + Arm::SetIrqHandler((TLinAddr)TemplateInterrupt::IrqDispatch); + Arm::SetFiqHandler((TLinAddr)TemplateInterrupt::FiqDispatch); + } +
  • +
  • Bind any ISRs that handle +chained or pseudo interrupts

  • +
+
In third phase +initialisation

During third phase initialisation of start-up, the +kernel calls the ASSP's implementation of Asic::Init3().

Note +that interrupts are enabled during third phase initialisation.

Within +your implementation of Init3(), if you need to, call Interrupt::Enable() on +any of the interrupt sources that are bound to a chained or pseudo ISR dispatcher. +You don't need to do this if you are enabling and disabling the main interrupt +on demand as the chained or pseudo-interrupts are enabled and disabled.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-42F8FA5A-BBE4-50DE-917E-D05755019FEC.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-42F8FA5A-BBE4-50DE-917E-D05755019FEC.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,232 @@ + + + + + +Personality Layer DesignProvides some guidelines for the design of a personality +layer for real time Applications for the Kernel. +
Memory +management

The personality layer assumes that the RTA will +run in a single flat address space in which there is neither protection +between different parts of the application nor protection of any hardware +or CPU resource from any part of the application. For example, any +part of the application code can access any I/O port, and can disable +interrupts.

To get this behaviour under the Kernel Architecture +2, the RTA must run in supervisor mode in the kernel address space. +The obvious way to do this is to make the RTA together with the personality +layer a kernel extension. This also ensures that it is started automatically +early on in the boot process.

In general the RTA will have +its own memory management strategy and will not wish to use the standard +Symbian platform memory management system. To achieve this, the personality +layer will allocate a certain fixed amount of RAM for use by the real +time application at boot time. For a telephony stack this will be +around 128K - 256K. This can be done either by including it in the +kernel extension's .bss section, or by making +a one-time allocation on the kernel heap at boot time. Depending on +the RTA requirements, the personality layer can manage this area of +RAM (if the RTOS being emulated provides memory management primitives) +or the RTA can manage it.

+
Threads +and mapping thread priorities

A nanokernel thread will +be used for each RTOS thread

A priority mapping scheme will +be required to map RTOS priorities, of which there are typically 64 +to 256 distinct values, to nanokernel priorities. As long as the RTA +does not use more than 35 threads running simultaneously, which is +usually the case, it should be possible to produce a mapping scheme +that allows each thread to have a distinct priority, if needed. If +this limit is exceeded, it will be necessary to fold some priorities +together.

Note that any attempt to increase the number of +priorities supported by both the nanokernel and the Symbian platform +kernel would be prohibitively expensive in terms of RAM usage.

+
Communication +between Symbian platform and the RTOS Environments

To allow +the functionality of the RTA to be available to Symbian platform applications, +it is necessary that a mechanism exist by which Symbian platform code +and the RTA may communicate with each other. In practice this means:

    +
  • it must be possible +for a Symbian platform thread to cause an RTOS thread to be scheduled +and vice-versa

  • +
  • it must be possible +for data to be transferred between Symbian platform and RTOS threads +in both directions.

  • +

It will usually be possible for a Symbian platform thread +to make standard personality layer calls (the same calls that RTOS +threads would make) in order to cause an RTOS thread to be scheduled. +This is because the nanokernel underlies both types of thread and +most 'signal' type operations (i.e. those that make threads ready +rather than blocking them) can be implemented using operations which +make no reference to the calling thread, and which are therefore not +sensitive to which type of thread they are called from.

The +standard personality layer calls will not work in the other direction, +since it will not be possible for a Symbian platform thread to wait +on a personality layer wait object. The most straightforward way for +RTOS threads to trigger scheduling of a Symbian platform thread would +be to enque a DFC on a queue operated by a Symbian platform thread. +Another possibility would be for the Symbian platform thread to wait +on a fast semaphore which could then be signalled by the RTOS thread. +However the DFC method fits better with the way device drivers are +generally written. A device driver will be necessary to mediate communication +between Symbian platform user mode processes and the RTA since the +latter runs kernel side.

All data transfer between the two +environments must occur kernel side. It will not be possible for any +RTOS thread to access normal user side memory since the functions +provided for doing so access parts of the DThread structure representing the Symbian platform calling thread, for +example to perform exception trapping. Some possibilities for the +data transfer mechanism are:

    +
  • A fairly common +architecture for real time applications involves a fixed block size +memory manager and message queues for inter-thread communication. +The memory manager supports allocation and freeing of memory in constant +time. The sending thread allocates a memory block, places data in +it and posts it to the receiving thread's message queue. The receiving +thread then processes the data and frees the memory block, or possibly +passes the block to yet another thread. It would be a simple proposition +to produce such a system in which the memory manager could be used +by any thread. In that case a Symbian platform thread could pass messages +to RTOS threads in the same way as other RTOS threads. Passing data +back would involve a special type of message queue implemented in +the personality layer. When a message was sent to a Symbian platform +thread a DFC would be enqueued. That DFC would then process the message +data and free the memory block as usual. This scheme combines the +data transfer and scheduling aspects of communication.

  • +
  • Any standard +buffering arrangement could be used between the RTA and the device +driver (e.g. circular buffers). Contention between threads could be +prevented using nanokernel fast mutexes, on which any thread can wait, +or by the simpler means of disabling preemption or disabling interrupts. +It will also be possible for RTOS threads to make use of shared I/O +buffers for transfer direct to user mode clients, provided that these +buffers are set up by the Symbian platform device driver thread. This +may be useful as a way to reduce copying overhead if bulk data transfer +is necessary between the two domains.

  • +
+
Synchronisation/communication +primitives

The nanokernel does not support most of the +synchronisation and communication primitives provided by a standard +RTOS. Any such primitives required by the RTA will have to be implemented +in the personality layer. This means that the personality layer needs +to define new types of object on which threads can wait. This in turn +means that new nanokernel thread states (N-state) must be defined +to signify that a thread is waiting on an object of the new type. +In general, each new type of wait object requires an accompanying +new nanokernel thread state.

Blocking a thread on a wait object

To make a thread +block on a new type of wait object, call the nanokernel function Kern::NanoBlock(), passing the maximum time for which the +thread should block, the new N-state value, and a pointer to the wait +object.

Use the TPriListLink base class of NThreadBase to attach the thread to a list of threads waiting +on the object. Note that this must be done after calling Kern::NanoBlock(). As preemption is disabled before this +function is called, a reschedule will not occur immediately, but will +be deferred until preemption is reenabled.

State handler

Every thread that can use a new type of wait object, must +have a nanokernel state handler installed to handle operations on +that thread when it is waiting on that wait object. A nanokernel state +handler is a function that has the following signature:

void StateHandler(NThread* aThread, TInt aOp, TInt aParam);
    +
  • aThread is a pointer to the thread involved.

  • +
  • aOp is one of the NThreadBase::NThreadOperation values +that indicates which operation is being performed on the thread.

  • +
  • aParam is a parameter that depends on aOp.

  • +

Note that the state handler is always called with preemption +disabled.

The possible values of aOp are:

+ + + +

aOp value

+

Description

+
+ +

ESuspend

+

Called if the thread is suspended while not in a critical +section and not holding a fast mutex. Called in whichever context NThreadBase::Suspend() is called from.

aParam contains the requested suspension count.

+
+ +

EResume

+

Called if the thread is resumed while actually suspended, +and the last suspension has been removed. Called in whichever context NThreadBase::Resume() is called from.

aParam contains no additional information.

+
+ +

EForceResume

+

Called if the thread has all suspensions cancelled while +actually suspended. Called in whichever context NThreadBase::ForceResume() is called from.

aParam contains no additional +information.

+
+ +

ERelease

+

Called if the thread is released from its wait. This call +should make the thread ready if necessary. Called in whichever context NThreadBase::Release() was called from.

aParam is the value passed into NThreadBase::Release() to be used as a return code.

If aParam is +non-negative, this indicates normal termination of the wait condition.

If aParam is negative, it indicates early or +abnormal termination of the wait; in this case the wait object should +be rolled back as if the wait had never occurred. For example, a semaphore's +count needs to be incremented if aParam is negative, +since in that case the waiting thread never acquired the semaphore.

+
+ +

EChangePriority

+

Called if the thread's priority is changed. Called in whichever +context NThreadBase::SetPriority() is called from. +This function should set the iPriority field of the +thread, after doing any necessary priority queue manipulations.

aParam contains the new priority.

+
+ +

ELeaveCS

+

Called in the context of the thread concerned if the thread +calls NKern::ThreadLeaveCS() with an unknown iCsFunction that is negative but not equal to ECsExitPending.

aParam contains the value of iCsFunction.

+
+ +

ETimeout

+

Called if the thread's wait time-out expires and no time-out +handler is defined for that thread. Called in the context of the nanokernel +timer thread (DfcThread1). This should cancel the wait and arrange +for an appropriate error code to be returned. The handler for this +condition will usually do the same thing as the handler for ERelease with a parameter of KErrTimedOut.

aParam contains no additional information.

+
+ + +

See the code in ...\e32\personality\example\... for practical examples.

Releasing the thread

When a thread's wait condition +is resolved, the nanokernel function NThreadBase::Release() should be called. This takes a single TInt parameter.

The parameter is usually KErrNone, if the +wait condition is resolved normally. A typical example is where the +semaphore on which the thread is waiting, is signalled. A negative +parameter value is used for an abnormal termination, and in this case, +the wait object may need to be rolled back.

NThreadBase::Release() should be called with preemption disabled. It performs the following +actions:

    +
  • sets the NThreadBase::iWaitObj field to NULL

  • +
  • cancels the +wait timer if it is still running

  • +
  • stores the supplied +return code in NThreadBase::iReturnCode

  • +
  • calls the state handler passing ERelease and the return +code. If the return code is negative this should remove the thread +from any wait queues and roll back the state of the wait object. In +any case it should call NThreadBase::CheckSuspendThenReady() to make the thread ready again if necessary.

  • +
+
Thread +scheduling following a hardware interrupt

Most RTOS allow +interrupt service routines (ISRs) to perform operations such as semaphore +signal, queue post, set event flag directly, usually using the same +API as would be used in a thread context. The Kernel Architecture +2 nanokernel does not allow this; ISRs can only queue an IDFC or DFC.

The way to get round this limitation is to incorporate an IDFC +into each personality layer wait object. The personality layer API +involved then needs to check whether it is being invoked from an ISR +or a thread and, in the first case, it queues the IDFC. It may need +to save some other information for use by the IDFC, for example, it +may need to maintain a list of messages queued from ISRs, a count +of semaphore signals from ISRs or a bit mask of event flags set by +ISRs. Checking for invocation from an ISR can be done either by using NKern::CurrentContext(), or by checking the CPSR directly; +if doing the latter note that any mode other than USR or SVC on the +ARM counts as interrupt context.

Hardware interrupts serviced +by the RTA will need to conform to the same pattern as those serviced +by Symbian platform extensions or device drivers. This means that +the standard preamble must run before the actual service routine and +the nanokernel interrupt postamble must run after the service routine +to enable reschedules to occur if necessary. This can be done by calling Interrupt::Bind() as provided by the base port during RTA +initialisation (possibly via a personality layer call if it must be +called from C code). See also Interrupt Dispatcher +Tutorial.

+
+ +Personality Layer for Real Time Applications + +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-431A08D4-46DD-5A9D-B2A4-3D58C9B1E9E7-master.png Binary file Adaptation/GUID-431A08D4-46DD-5A9D-B2A4-3D58C9B1E9E7-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-431A08D4-46DD-5A9D-B2A4-3D58C9B1E9E7_d0e18839_href.png Binary file Adaptation/GUID-431A08D4-46DD-5A9D-B2A4-3D58C9B1E9E7_d0e18839_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-4353940E-C77B-4080-86AD-7DBE52B0A27B.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-4353940E-C77B-4080-86AD-7DBE52B0A27B.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,49 @@ + + + + + +SDIO +Interface Quick StartProvides a collection of documents that describe the SDIO client +interface API. +
SDIO tutorials

The +client interface guide describes the generic procedure for using SDIO in a +kernel-side device driver.

SDIO +Client Interface Guide

The Bluetooth example describes a reference +client driver using Bluetooth

SDIO +BT Example

The other tutorials describe the SDIO classes and commands +in more detail

    +
  • DSDIOREGInterface +Class Tutorial

  • +
  • DSDIOSession +Class Tutorial

  • +
  • DSDIOStack Class +Tutorial

  • +
  • TSDIOCard Class +Tutorial

  • +
  • TSDIOFunction +Class Tutorial

  • +
  • TSDIOInterrupt +Class Tutorial

  • +
  • SDIO Commands +Tutorial

  • +
+
Purpose +

SDIO is an input/output protocol used to communicate with SDIO +(Secure Digital) cards and other media such as Bluetooth adapters and GPS +receivers.

+
Intended audience

This +document is intended to be used by device driver writers.

+
ArchitectureSymbian +platform implements SDIO as part of a larger framework involving SD cards, +which are a type of MMC (multimedia) card. For this reason, to use SDIO in +a device driver you will need to use classes representing SD and MMC cards +and the associated communications stack even if you only want the basic I/O +functionality.
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-43782364-0865-43D0-BC89-D63BA9912FB6.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-43782364-0865-43D0-BC89-D63BA9912FB6.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,174 @@ + + + + + +Basic ManagementThis document describes how device drivers should manage shared +chunks. +
Creation

A +shared chunk is created in kernel space. The user is given a handle to the +shared chunk to access it, and can pass the handle to other process or other +drivers. Chunks are represented by DChunk objects on the +kernel side and by RChunk on the user side.

A shared +chunk is created by using Kern::ChunkCreate(), which takes +a TChunkCreateInfo argument that sets the chunk properties.

Chunk +creation should be done in a critical section, created using NKern::ThreadEnterCS() and NKern::ThreadLeaveCS(). The size of the chunk should be in multiples of MMU pages, which can be +calculated using Kern::RoundToSize(n), where n is +the actual size that needs to be rounded.

/** + Create a transmit shared chunk of specified size. + + @param aChunkSize + size of the chunk to be created + + @return KErrNone on success, standard error code on failure + */ +TInt DExUartPhysicalChannel::CreateTxChunk(TUint aChunkSize) + { + ... + // Round up the transmit chunk size to the page size. + // Kern::RoundToPageSize() rounds up the argument to the size + // of a MMU page. The size of one MMU page can be found out by + // calling Kern::RoundToPageSize(1). + + size=Kern::RoundToPageSize(aChunkSize); + + // Thread must be in critical section + NKern::ThreadEnterCS(); + ... + // Create the chunk. Example is given in next code snippet + ... + // Commit the chunk. Example is given in following sections + ... + // Thread can leave the critical section + NKern::ThreadLeaveCS(); + } + +TInt DExUartPhysicalChannel::CreateTxChunk(TUint aChunkSize) + { + ... + NKern::ThreadLeaveCS(); // Enter the critical section + + // TChunkCreateInfo holds the parameters required to create a + // chunk and is used by Kern::ChunkCreate() + TChunkCreateInfo info; + + // ESharedKernelMultiple specifies that a chunk which may be opened by + // any number of user side processes + info.iType=TChunkCreateInfo::ESharedKernelMultiple; + info.iMaxSize= size; // Chunk size + + // This specifies the caching attributes for the chunk. It can + // be no caching or fully caching (TMappingAttributes enum + // type). If the MMU does not support the requested attributes, + // then a lesser cached attribute will be used. The actual + // value used is returned in aMapAttr of Kern::ChunkCreate() + info.iMapAttr=EMapAttrFullyBlocking; // No Caching, suitable for DMA + + // Set to true if the chunk is to own its committed memory. + // In this case all memory committed to the chunk will come + // from the system's free pool and will be returned there when + // the chunk is destroyed. If the chunk will be committed to + // physical address, then EFalse can be set. + info.iOwnsMemory=ETrue; // using RAM pages + + // As chunk destruction is asynchronous we can have + // a DFC, if required, specifying a callback function to get + // the chunk destroy notification exactly. This is used if any + // follow up cleaning has to be done after chunk destruction. + info.iDestroyedDfc=NULL; // No chunk destroy DFC. + + DChunk* chunk; + TUint32 mapAttr; + // Creates a chunk that can be shared between a user thread and a + // kernel thread. This will be the initial step for a shared + // chunk. Once created, the chunk owns a region of linear + // address space of the requested size. This region is empty + // (uncommitted) so before it can be used either RAM or I/O + // devices must be mapped into it. This is achieved with the + // Commit functions. + // Here iTxChunkKernAddr returns the linear address of the + // chunk created. + // + TInt r=Kern::ChunkCreate(info,chunk,iTxChunkKernAddr, mapAttr); + if (r!=KErrNone) + { + // Thread can leave the critical section + NKern::ThreadLeaveCS(); + return r; + } + ... + }
+
Destruction

To allow a chunk to be properly cleaned +up, a driver should close the chunk when it is no longer required. When a +chunk is closed, the reference count is decremented by one. The chunk gets +destroyed when the reference count becomes zero. Closing the chunk should +be done within a critical section.

The destruction of the chunk happens +asynchronously, and a notification of this can be requested. This is done +using a DFC, by initialising TChunkCreateInfo::iDestroyDfc() with +the DFC object.

/** + Close the transmit chunk, that was already created. This is + called while closing the logical channel + */ +void DExUartPhysicalChannel::CloseTxChunk() + { + // Thread must be in critical section + NKern::ThreadEnterCS(); + + // Atomically get pointer to our chunk and NULL the iChunk + // member. Nkern::SafeSwap() atomically replaces the word + // referenced by aPtr with aNewValue, here NULL. + // + DChunk* chunk = (DChunk*)NKern::SafeSwap(NULL,(TAny*&)iTxChunk); + + if (chunk) + { + // Close the chunk that was created. This should be + // done in a critical section. This function decrements + // a chunk's access count, and, if the count reaches + // zero, the chunk is scheduled for destruction. + // ChunkClose() has to be called the same number of times + // as chunk creation. A mismatch in this will result + // in either a memory leak or a panic. + // + Kern::ChunkClose(chunk); + } + // Thread can leave the critical section + NKern::ThreadLeaveCS(); + }
+
Mapping

Shared chunks must be mapped to memory, +which means that either RAM or an I/O device must be committed to a shared +chunk before it can be used. This maps the chunk to a certain address. The +memory can be physical contiguous RAM pages, an arbitrary set of RAM pages, +a physical region, or a physical region with a list of physical addresses. +The Kernel provides the following APIs for committing these types of memory:

// Commit RAM to a shared chunk. The memory pages to commit are +// obtained from the system's free pool +TInt Kern::ChunkCommit(DChunk *aChunk, TInt aOffset, TInt aSize); + +// Commit RAM to a shared chunk. The memory pages to commit are +// obtained from the system's free pool and will have physically +// contiguous addresses. Used when TChunkCreateInfo::iOwnsMemory +// is ETrue +TInt Kern::ChunkCommitContiguous(DChunk *aChunk, TInt aOffset, + TInt aSize, TUint32 &aPhysicalAddress); + +// Commit memory to a shared chunk. The physical region committed +// is that which starts at the supplied physical address. +// Typically, this region either represents memory mapped I/O, or +// RAM that was set aside for special use at system boot time. +// This is used when TChunkCreateInfo::iOwnsMemory is EFalse. +TInt Kern::ChunkCommitPhysical(DChunk *aChunk, TInt aOffset, + TInt aSize, TUint32 aPhysicalAddress); + +// Commit memory to a shared chunk. The physical region committed +// is determined by the list of physical addresses supplied to +// this function +TInt Kern::ChunkCommitPhysical(DChunk *aChunk, TInt aOffset, + TInt aSize, const TUint32 *aPhysicalAddressList); +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-43852F38-4841-5E6F-927B-A38ED4424F0C.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-43852F38-4841-5E6F-927B-A38ED4424F0C.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,467 @@ + + + + + +Keyword reference (P-R) +

This page lists the keywords starting from P to R.

+
pagedpaged

rombuild and rofsbuild

Use the paged keyword to specify that the executable +is code paged. If an executable is marked as code paged, the pages +are loaded into the RAM on demand one page after another. This can +reduce application startup time and memory usage.

This is the +same as specifying the pagedcode keyword for an executable.

+
pagedcodepagedcode

rombuild and rofsbuild

Same as paged.

+
pageddatapageddata

rombuild and rofsbuild

Use the pageddata keyword to specify that the +executable is data paged. This controls the paging of both +heap and stacks for an executable. For more fine-grained control of +memory usage, specify the paging of heap and stack data during the +creation of new threads and processes.

+
pagingoverride pagingoverride [NOPAGING | ALWAYSPAGE | DEFAULTUNPAGED | DEFAULTPAGED]

rombuild and rofsbuild

This overrides the code +and data paging settings for all the files, such as EXE and DLL in +an OBY file. It takes a single argument, which can be one of the following:

+ + + +Argument +Purpose + + + + +

NOPAGING

+

To mark all executables as unpaged, irrespective of whether +they are marked as paged or unpaged in the MMP file.

+
+ +

ALWAYSPAGE

+

To mark all executables as paged, irrespective of whether +they are marked as paged or unpaged in the MMP file.

+
+ +

DEFAULTUNPAGED

+

All executables, which are not marked as paged or unpaged +are marked as unpaged by default.

+
+ +

DEFAULTPAGED

+

All executables, which are not marked as paged or unpaged +are marked as paged by default.

+
+ + +

For example, the following entry in the Obey file marks +all the executables as unpaged:

pagingoverride NOPAGING
+
pagingpolicy pagingpolicy [NOPAGING | ALWAYSPAGE | DEFAULTUNPAGED | DEFAULTPAGED]

rombuild and rofsbuild

This overrides the default +settings for both code and data paging. It also overrides the settings +from all the previous levels. This keyword takes a single argument, which +can be one of the possible values listed in pagingoverride.

For example, the following entry in +the Obey file instructs the loader not to page the executables in +the default state:

pagingpolicy NOPAGING
+
payloaduid

payloaduid = <payloaduid>

Identifies +the payload of the SMR partition. This field allows kernel consumers +(such as HCR) at runtime to locate the memory regions that contain +their data.

+
payloadflags

payloadflags = <payloadflags>

Specifies the payload specific flags that are defined at runtime +by the the payload provider tools or user and payload consumer. This +field allows the provider to give metadata to the consumer of the +payload.

+
patchdata patchdata <binary_name> @ <symbolname> <newvalue> +

BUILDROM only

This keyword is introduced +since Symbian OS v9.3, and it enables you to change the value of a +constant that is exported by a binary while building the ROM image.

This means that the value of the constant can be changed without +rebuilding the binary. This is useful for quickly building ROM images +with different values for the constant, allowing you to make comparisons +in behaviour between the ROMs. This keyword must be placed before +or after the binary that it patches in the OBY file.

+ + + +

<binary_name>

+

The name of the binary on the PC and not the name in the +ROM image.

+
+ +

<symbolname>

+

The symbolic name of the constant exported by the binary.

+
+ +

<newvalue>

+

The replacement value. This can be specified either as an +integer or as a hexadecimal value.

It is assumed that the +exported constant is an integer that is either 1 byte, 2 bytes or +4 bytes in length, which means that the size of this replacement value +must not exceed the capacity of the constant to represent it.

+
+ + +

For example, if a DLL named dllA.dll is created based on the header file dllA.h and +source file dllA.cpp:

//dllA.h +IMPORT_C int bar(); +... + //dllA.cpp +#include “dllA.h” +EXPORT_C extern const unsigned int foo = 0x1234; +EXPORT_C int bar () + { + return foo; + ... + } +

then an executable file can import this constant; +for example:

#include <e32cons.h> +#include <e32base.h> +#include “dllA.h” +... +int importValue = bar(); +... +

If you add the following statement to the .oby file to change the value of constant "foo" while +building the ROM, then the actual value of foo accessed +by the executable file is 0x100, and not 0x1234 as specified when DllA was originally +built.

patchdata dllA @ foo 0x100

Notes:

    +
  • The value of +the constant in the source is not changed. It is only its value in +the copy of the binary incorporated into the ROM image that is changed.

  • +
  • Do not define +a patchable constant (exported data) in the source file in which it +is referred to, because the compiler may inline it. If a constant +is inlined, it cannot be patched. Hence, the constant must be defined +in a separate source file and must be referred to in other source +files by using the extern qualifier.

  • +
+
patched patched

rombuild only

This is used when sectioning a +ROM for language variants etc. If an executable is to be replaced, +make it patched in the first section of the ROM and include a replacement +in the top section of the ROM, after the section keyword.

This keyword appears at the point +in the obey file where the ROM is to be split. All files before this +line appear in the first (constant) section and files after appear +in the second (patch/language) section.

+
platsecdiagnostics platsecdiagnostics [on | off]

rombuild only

This is a keyword that affects +Symbian platform security when building a ROM.

It controls +whether or not diagnostic messages are emitted when a capability or +other platform security policy check fails. A diagnostic message takes +the general form:

*PlatSec* ERROR - xxxxx

if platform security is enforced

*PlatSec* WARNING - xxxxx

if platform security is NOT enforced.

The string +xxxxx represents the text of the message that describes the capability +being violated or the security policy check that is failing.

    +
  • Specify on to enable diagnostic messages to be emitted.

  • +
  • Specify off to disable diagnostic messages from being emitted.

  • +
  • If neither on nor off is specified, then on is assumed as a default.

  • +
+
platsecdisabledcaps platsecdisabledcaps [+|-]cap1 [+|- cap2] [+|- cap3] ...[+|-capn]

rombuild only

This is a keyword that affects +Symbian platform security when building a ROM.

It allows capabilities +to be added to, or removed from, all executables in the ROM image.

Specify a list of capability names prefixed either by a + character or a - character. The first +capability name in the list does not need to prefixed by either of +these characters, but if it is omitted a + character +is assumed.

Capabilities preceded by a + character +are added to all executables, while those preceded by a - character are removed from all executables.

Any of the capabilities +listed in the left hand column in the table below can be specified; +follow the corresponding link in the right hand column for a description +of that capability. Note that you can also use:

+ALL

to add all capabilities, and

+NONE

to remove all capabilities.

Note, however, that the combinations -ALL and -NONE are not permitted

+ + + +

+ + + + +Capability + + + +

+

+ + + + +TCapability Enum value + + + +

+ + +

TCB

+

ECapabilityTCB

+
+ +

CommDD

+

ECapabilityCommDD

+
+ +

PowerMgmt

+

ECapabilityPowerMgmt

+
+ +

MultimediaDD

+

ECapabilityMultimediaDD

+
+ +

ReadDeviceData

+

ECapabilityReadDeviceData

+
+ +

WriteDeviceData

+

ECapabilityWriteDeviceData

+
+ +

DRM

+

ECapabilityDRM

+
+ +

TrustedUI

+

ECapabilityTrustedUI

+
+ +

ProtServ

+

ECapabilityProtServ

+
+ +

DiskAdmin

+

ECapabilityDiskAdmin

+
+ +

NetworkControl

+

ECapabilityNetworkControl

+
+ +

AllFiles

+

ECapabilityAllFiles

+
+ +

SwEvent

+

ECapabilitySwEvent

+
+ +

NetworkServices

+

ECapabilityNetworkServices

+
+ +

LocalServices

+

ECapabilityLocalServices

+
+ +

ReadUserData

+

ECapabilityReadUserData

+
+ +

WriteUserData

+

ECapabilityWriteUserData

+
+ +

Location

+

ECapabilityLocation

+
+ + +

For example:

PlatSecDisabledCaps LocalServices+ReadDeviceData+ReadUserData
+
platsecenforcement platsecenforcement [on | off]

rombuild only

This is a keyword that affects +Symbian platform security when building a ROM.

It controls +whether or not platform security is enforced.

    +
  • Specify on to enable platform security enforcement. If enforcement +is enabled, and a capability or other platform security policy check +fails, then the appropriate action for a failed platform security +check occurs.

  • +
  • Specify off to disable platform security enforcement. If +enforcement is disabled, and a capability or other platform security +policy check fails, then the system continues as though the original +platform security check had in fact passed.

  • +
  • If neither on nor off is specified, then on is assumed as a default.

  • +
+
platsecenforcesysbin platsecenforcesysbin [on | off]

rombuild only

This is a keyword that affects +Symbian platform security when building a ROM.

It controls +whether or not to force the location of binary executables into the \Sys\Bin\ directory.

    +
  • Specifying on has the following effects:

      +
    • rombuild places all executables into Z:\Sys\Bin\, and +overrides any file path specified in any of the .IBY files.

    • +
    • the loader only +looks for files in the \Sys\Bin\ directory and +only loads files from the \Sys\Bin\ directory. +If a different path is specified this path is ignored and the \Sys\Bin\ directory is searched.

    • +
  • +
  • Specifying off causes rombuild to place files according +to the file path specified in the .IBY files +and permits the loader to load files from any specified path.

  • +
  • If neither on nor off is specified, then on is assumed as a default.

  • +
+
platsecprocessisolation platsecprocessisolation [on | off]

rombuild only

This is a keyword that affects +Symbian platform security when building a ROM.

It controls +whether or not insecure APIs inherited from EKA1 (Versions 8.1a, 8.0a, +7.0s, and earlier) are to be disabled. These are APIs whose use is +intended to be restricted. The kernel provides run-time checks for +their correct usage.

See the list of APIs affected +by the platsecprocessisolation keyword.

    +
  • Specify on to disable insecure APIs. Incorrect use of this +set of restricted APIs results in diagnostic messages, if platsecdiagnostics is on, and raises panics +or causes errors if platsecenforcement is on.

  • +
  • Specify off to allow insecure APIs.

  • +
  • If neither on nor off is specified then on is assumed as a default.

  • +
+
preferredpreferred

rombuild only

This +keyword specifies that the major version of the executable binary +must be preferred over its minor versions. The minor version specifies +the revision of the executable. The major version enables you to identify +whether two versions of an executable are compatible. The two versions +of an executable can be compatible only if they have same major version.

The executable's header stores minor and major versions of the +executable.

+
primary[[HWVD]] primary[[HWVD]] = <source-file> <destination-image-file> [File-attribute-list] [Override-Attribute-list]

rombuild only

A standard executable file that +is loaded directly, bypassing the file server. The Boot program loads +and gives control to the primary; this is the Kernel.

As with +all standard executable files, this is loaded, relocated and stripped +of its relocation information.

Note that the HWVD is optional but, if specified, must be enclosed within square brackets.

+
priority priority = <hex-number> | <priority-keyword>

rombuild only

Sets the priority of the process. +The priority can be a hexadecimal number, or one of the keywords listed +below. The keywords correspond to the associated priority value.

+ + + +

Keyword

+

Process priority

+
+ +

low

+

EPriorityLow

+
+ +

background

+

EPriorityBackground

+
+ +

foreground

+

EPriorityForeground

+
+ +

high

+

EPriorityHigh

+
+ +

windowserver

+

EPriorityWindowServer

+
+ +

fileserver

+

EPriorityFileServer

+
+ +

realtimeserver

+

EPriorityRealTimeServer

+
+ +

supervisor

+

EPrioritySupervisor

+
+ + +
+
processprocess = <file path of process being attached>

rombuild only

This keyword specifies the process +to which a DLL is attached.

+
reloc reloc = <hex-address>

rombuild only

Overrides the default stack size +for the executable.

+
rem rem <comment>

rombuild and rofsbuild

Defines a comment line. +Text that appears after the rem keyword is interpreted as a comment.

+
rename rename[[HWVD]]= <existing-file> <destination-file> [ full-attribute-list ]

rombuild and rofsbuild

Adding a file and then +renaming it is equivalent to adding it directly at the rename destination. +The existing and destination directories do not have to be the same.

+
RIGHT_NOW RIGHT_NOW

BUILDROM only

A pre-defined substitution. This +is replaced with the exact time in the format dd/mm/yy hh:mm:ss

Note that there is no UNDEFINE facility, and substitutions +are applied in an unspecified order.

+
rofsname rofsname = <filename>

rofsbuild only

Defines the name of the core +image.

+
rofssize rofssize = <size in bytes>

rofsbuild only

Specifies the maximum size of +the core image, or the maximum size of the extension.

+
romalign romalign = <hex-alignment>

rombuild only

The address alignment boundary +for files in the ROM.

This value should be greater than 4 +and a multiple of 4. The recommended value is 0x10. If no value is +specified, rombuild defaults to using a value of +0x1000. If the value specified is not a multiple of 4, it is rounded +off.

+
ROMBUILD_OPTION ROMBUILD_OPTION <command-line-option>

BUILDROM only

Adds additional command line parameters +to the eventual invocation of rombuild. +It is primarily used to specify the -no-header option +for platforms which don't want the 256-byte REPRO header. The ROMBUILD_OPTION keyword can be used multiple times if desired.

+
romchecksum romchecksum = <32 bit hex-number>

rombuild and rofsbuild

The checksum in the final +ROM image is made using the following algorithm:

checksum += romchecksum - sum of 32bit words in ROM image.

+
ROM_IMAGE ROM_IMAGE <id> <name> [size=<rom max size>] [xip | non-xip] [compress | no-compress] [extension]

BUILDROM only

Defines a ROM image.

This +is a ROM configuration feature; up to 8 ROM images can be defined +for a device.

+ + + +

id

+

A value in the range 0..7 to identify the ROM image.

+
+ +

name

+

A name suitable as a suffix for the ROM image, IBY and logs.

+
+ +

non-xip

+

Specifies a non-XIP ROM. If not specified, a XIP ROM is +the default

+
+ +

size = <rom-max-size>

+

Defines the maximum size of the ROM. Not required for XIP +ROMs.

+
+ +

compress

+

Compresses an XIP ROM. If not specified, no compression +is the default behaviour.

+
+ +

extension

+

Defines this image as an extension to the previous image.

+
+ + +

To mark a file for inclusion in a ROM it is prefixed with +the keyword ROM_IMAGE. For example:

ROM_IMAGE[2] data=\private\<process SID>\Apps\Calc\calc.INSTCOL_MBM \private\<process SID>\Apps\Calc\Calc.mbm

A Block of files can be included using '{' '}' +braces, for example:

ROM_IMAGE[2] + { + #include "calc.iby" + #include "word.iby" + } +

File blocks can be nested, for example:

ROM_IMAGE[2] + { + #include "calc.iby" + ROM_IMAGE[0] + { + #include "word.iby" + } + #include "video.iby" + } +
+
romlinearbase romlinearbase = <hex-address>

rombuild only

The virtual address of the start +of ROM, in hex.

This is the address at which the kernel expects +to find the start of the ROM. The recommended value depends on the +memory model:

    +
  • For the Multiple +Memory Model, typically used on ARMV6 based hardware platforms, the +recommended value is 0x80000000.

  • +
  • For the Moving +Memory Model, typically used on ARMV5 based hardware platforms, the +recommended value is 0xF8000000.

  • +
+
romname romname = <rom-file-name>

rombuild only

This is the name of the output +file. It contains the ROM image that rombuild creates.

+
romnameeven romnameeven = <rom-file-name-even> +

rombuild only

rombuild can write two separate ROM images, one containing the odd bytes +of the image and the other the even. This is done if this keyword +and the romnameodd keyword are used to specify the output filenames +for the two half-images. A filename of "*" can be specified, which +means use the file name specified on the romname keyword and append .even.

+
romnameodd romnameodd = <rom-file-name-odd>

rombuild only

rombuild can +write two separate ROM images, one containing the odd bytes of the +image and the other the even. This is done if this keyword and the romnameeven keyword are used to specify the output filenames +for the two half-images. A filename of "*" can be specified, which +means use the file name specified on the romname keyword and append .odd.

+
romsize romsize = <hex-size>

rombuild and rofsbuild

The size of the entire ROM, +in hex, for example, 0x400000 for a 4MB ROM.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-44540C74-CD73-5D8E-A9E0-F90F46B4E7B1.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-44540C74-CD73-5D8E-A9E0-F90F46B4E7B1.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,54 @@ + + + + + +Preventing +And Recovering From Thrashing TutorialDescribes how to reduce the chance of thrashing occurring in demand +memory and how to recover from thrashing. +
Introduction

Thrashing +is a state where the vast majority of the processing time is spent paging +memory in and out of the system and very little is spent useful work. If this +situation persists, then the system performance rapidly becomes unacceptable +and will appear to the user to have hung.

+
Background information

The following is useful background +reading:

    +
  • Thrashing

  • +
+
Thrashing features

When thrashing occurs the device +will appear to do nothing or 'hang' for period. Unlike a deadlock however, +the device can recover from thrashing.

+
Prevention of thrashing

The following can be used +reduce the chance of thrashing:

    +
  • Compress pages in memory to decrease the amount of memory that has +to be paged in and out

  • +
  • Limit the maximum size of each process's paged memory to the minimum +size of the paging cache

  • +
  • Partition the page cache per-process and allocate pages to processes + based on the Working Set Size (WSS) of threads in that process

  • +
  • Swap out the oldest pages in advance to free up memory to cope with +spikes in paging demand

  • +
  • Don't let threads steal pages from other threads

  • +
+
Recovery from thrashing

The possible courses of +action to undertake, should thrashing occur, are :

    +
  • Reboot the device

  • +
  • Kill a thread

  • +
  • Decrease the number +of paged threads running concurrently

  • +
  • Pick one thread with +a high page fault rate and stop other threads stealing pages from the thread's +associated process

  • +
  • Prompt the user-side +memory manager to close down applications.

  • +
+
+Thrashing +guide +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-450BF1D4-85D7-45D4-8893-57DA8F1640E9.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-450BF1D4-85D7-45D4-8893-57DA8F1640E9.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,12 @@ + + + + + +Baseport TemplateDescribes the Baseport Template platform service. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-455ED16F-D288-42C9-AA7A-AE5822F7A5BC.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-455ED16F-D288-42C9-AA7A-AE5822F7A5BC.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,49 @@ + + + + + +Time QuickstartProvides a brief overview of the contents of the Time platform +service. +

Time platform service provides the state of the device +(mobile). It is controlled by a state machine that is SSM. These states +are defined by system state policies within a SSM plug-in and system +state changes are triggered by system-wide property changes or external +requests.

+
+ Concepts
    +
  • MRtcAdaptation: An SPI that allows customizing +of the functionality of Real Time Clock (RTC) adaptation interface.

  • +
  • Alarm Server: manages all alarms on the device and enables +client UI applications to use the services provided by the Alarm Server. +It relies on the Alarm UI to notify, which includes displaying and +playing sounds.

  • +
  • Alarm Client and Alarm Shared: are the static interface DLLs. +Alarm client is the client side of the Alarm Server, which allows +other components to interact with the Alarm Server. The Alarm Shared +facilitates a common format shared across server and its clients for +providing definition for an alarm. It consists of shared objects such +as alarm class, IPC messages, repeat definitions, alarm states.

  • +
  • System State Manager (SSM): manages the state of a device throughout +its lifecycle. SSM extends the existing Generic Start-up Architecture +(GSA) and also manages the system state and the system-wide property.

  • +
+
+ Key uses for hardware implementators +
    +
  • Including session alarms

  • +
  • Adding, updating and deleting alarms.

  • +
  • Performing alarm category-based operations such as retrieval +and deletion.

  • +
+
Key +uses for device creators
    +
  • Activating an alarm on a specific date.

  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-4592D493-A47C-5622-8C03-F24FABB4381C-master.png Binary file Adaptation/GUID-4592D493-A47C-5622-8C03-F24FABB4381C-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-4592D493-A47C-5622-8C03-F24FABB4381C_d0e19271_href.png Binary file Adaptation/GUID-4592D493-A47C-5622-8C03-F24FABB4381C_d0e19271_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-463915EE-25DB-4ABD-AA80-1C10CD242072.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-463915EE-25DB-4ABD-AA80-1C10CD242072.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,16 @@ + + + + + +Register Access Build GuideDescribes how to build the Register Access platform service. +

There are no specific build instructions for Register Access platform +service. Register Access platform is a part of the ASSP layer. You +should use the ROMBUILD commands to build the baseport.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-465D1450-B1EF-568B-B518-34ACE8C1697C-master.png Binary file Adaptation/GUID-465D1450-B1EF-568B-B518-34ACE8C1697C-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-465D1450-B1EF-568B-B518-34ACE8C1697C_d0e9201_href.png Binary file Adaptation/GUID-465D1450-B1EF-568B-B518-34ACE8C1697C_d0e9201_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-4804B6E0-9199-5F3E-984A-4B00B3984E45.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-4804B6E0-9199-5F3E-984A-4B00B3984E45.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,18 @@ + + + + + +Porting the +Power Resource ManagerThis tutorial describes the steps needed to successfully port the +PRM for a particular device. +

The Power Resource Manager (PRM) is a framework for managing system power +resources. This framework improves portability across different platforms +and reduces device driver complexity.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-4862EA2E-6BFE-5E11-B527-7EBA94BB0EA2.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-4862EA2E-6BFE-5E11-B527-7EBA94BB0EA2.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,116 @@ + + + + + +OBY Tutorial Describes the new demand paging keywords available to the +OBY. file. +

Introduction

The new keywords that are available in the OBY file are used +to specify whether an object is paged, and if so what kind of demand +paging it supports.

With the addition of writable +data paging, the list of paging modifiers is shown below:

Procedure

With the addition of writable data +paging, the list of paging modifiers is shown below:

+ + + +

Keyword

+

Behaviour on Symbian platform

+
+ +

paged

+

Enables code and data paging

+
+ +

unpaged

+

Disables code and data paging

+
+ +

pagedcode

+

Enables code paging

+
+ +

unpagedcode

+

Disables code paging

+
+ +

pageddata

+

Enables data paging

+
+ +

unpageddata

+

Disables data paging

+
+ + +

These modifiers appear in OBY files at the end of statements +relating to user-side ROM objects i.e. 'file=', 'dll=', 'data=' +and 'secondary='statements). For example:

file=ABI_DIR\DEBUG_DIR\MyLibrary.dll \sys\bin\MyLibrary.dll unpaged

The data paging keywords only make sense when applied to executable +binary files.

For an executable file, the use of one of the +above keywords in the oby file will override the paging settings in +the mmp file. However this will not be true, if the pagingoverride, codepagingoverride or datapagingoverride keywords are used in the MMP file, in the case of nopaging or alwayspage .

+

Executing +the buildrom command builds with no errors or warnings.

+OBY +file example

An example of an OBY file that uses the new +demand paging keywords is given below:

// +// MyDPConfig.oby +// +// The section below, is used to specify if XIP ROM paging is implemented. +#if !defined PAGED_ROM +#define PAGED_ROM +#endif + +// The sections below, is used to specify if code paging is implemented. +#if !defined USE_CODE_PAGING +// Comment out the next line if code paging is wanted +#define USE_CODE_PAGING +#endif + +#if !defined CODE_PAGING_FROM_ROFS +// Comment out the next line if code paging from primary rofs is wanted +#define CODE_PAGING_FROM_ROFS +#endif + +// The section below, is used to configure the writable data paging and to specify what the +// default paging behaviour is to be. +ROM_IMAGE[0] { +pagedrom +compress +// Min Max Young/Old +// Live Live Page +// Pages Pages Ratio +demandpagingconfig 256 512 3 +pagingoverride defaultpaged + +// This section specifies what the default paging behaviour is to be for code paging. +#if defined USE_CODE_PAGING && !defined USE_DATA_PAGING +codepagingpolicy defaultpaged +#endif + +#if defined USE_DATA_PAGING +#if defined USE_CODE_PAGING +codepagingpolicy defaultpaged +#endif + +datapagingpolicy defaultpaged +#endif +} + +#if defined CODE_PAGING_FROM_ROFS || defined USE_DATA_PAGING +ROM_IMAGE[1] { +pagingoverride defaultpaged +} +#endif + +// Now specify the files to be used +file=ABI_DIR\DEBUG_DIR\MyLibrary.dll \sys\bin\MyLibrary.dll unpaged +
+

The next step is to Build the writable +data paging ROM

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-49379616-C235-598D-AE43-668998AD072B.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-49379616-C235-598D-AE43-668998AD072B.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,362 @@ + + + + + +Process, +Thread, Stack and Memory AttributesReference for users of the debug monitor tool to the attributes +of Kernel objects and memory structure. +
    +
  • Process and thread priorities

  • +
  • Thread state summary

  • +
  • Thread and process exit information summary

  • +
  • Critical threads and processes

  • +
  • Kernel calls and thread context

  • +
  • Stacks

  • +
  • Virtual memory and run addresses

  • +
+
Process and +thread priorities

Internally the scheduler always deals with nanokernel +threads, NThread objects, and their associated priority between +0 (lowest) and 63 (highest). In general, a thread with a higher priority that +is ready to run will always run in preference to threads with a lower priority. +The only exception is where a higher priority thread waits on a nanokernel +fast mutex held by a lower priority thread. In this case, the higher priority +thread will yield to the lower priority thread holding the mutex.

A +Symbian platform thread, a DThread object, has an embedded NThread, +which enables it to be scheduled by the nanokernel.

There are two +ways of setting a priority for Symbian platform thread:

    +
  • using the two-level +priority scheme

  • +
  • using an absolute priority.

  • +

The +two level priority scheme

In this scheme, a Symbian platform thread +priority is relative to the priority of its owning process. By default, Symbian +platform threads inherit the priority of their owning process when they are +created. This priority can be raised or lowered relative to the process priority +- this just sets the thread’s priority to the process priority plus or minus +a specified priority weighting. If the priority of the process is changed, +the priority of its threads will change relative to other threads in the system +but will remain the same relative to each other.

The default priority +of a process is EPriorityForgeround, which is an absolute +priority of 350. Threads by default are created with relative priority EPriorityNormal which +sets them to the same priority as the owning process. The window server lowers +the priority of background UI processes to EPriorityBackground (250).

The +NULL thread, also known as the idle thread, runs at priority 0, and means +that it will only run when there are no other threads ready to run.

Symbian +platform thread priorities map onto NThread priorities in +the range 1 to 31 as shown in the table below.

+ + + +

Thread priority

+

Idle

+

Much Less

+

Less

+

Normal

+

More

+

Much More

+

Real Time

+
+ +

Process priority

+

+

+

+

+

+

+

+
+ +

Low

+

1

+

1

+

2

+

3

+

4

+

5

+

22

+
+ +

Background

+

3

+

5

+

6

+

7

+

8

+

9

+

22

+
+ +

Foreground

+

3

+

10

+

11

+

12

+

13

+

14

+

22

+
+ +

High

+

3

+

17

+

18

+

19

+

20

+

22

+

23

+
+ +

SystemServer1

+

9

+

15

+

16

+

21

+

23

+

25

+

28

+
+ +

SystemServer2

+

9

+

15

+

16

+

21

+

23

+

25

+

28

+
+ +

SystemServer3

+

9

+

15

+

16

+

21

+

23

+

25

+

28

+
+ +

RealTimeServer

+

18

+

26

+

27

+

28

+

29

+

30

+

31

+
+ + +

where:

    +
  • the process priority +values are defined by the internal Symbian platform enum TProcPriority, +defined in ...\e32\include\kernel\kern_priv.h. The symbols +in the table correspond to the symbols in the enum.

  • +
  • the thread priority +values are defined by the internal Symbian platform enum TThrdPriority, +defined in ...\e32\include\kernel\kern_priv.h. The symbols +in the table correspond to the symbols in the enum.

  • +

Absolute +priority scheme

It is possible to set an absolute priority that +is not relative to the process priority; it is not affected by changes in +the process priority.

+
Thread state +summary

This is a brief summary about nanokernel thread states +and Symbian platform thread states.

Nanokernel +thread states

The state of a nanokernel thread is referred to +as the NState (or N-state). This is to disambiguate it from any other state, +such as the state of a Symbian platform thread (referred to as the MState +or M-state).

The states of a nanokernel thread are defined by the +values of the NThreadBase::NThreadState enumeration.

Symbian platform thread states

The state of a Symbian platform +thread is referred to as the MState (or M_state). This is in addition to the +nanokernel N-state, and tracks threads waiting on Symbian platform synchronization +objects. The DThread class representing a Symbian platform +thread is internal to Symbian, but the following table defines its possible +states. The values in the left-hand column are the enumerators of the internal +enumeration DThread::TThreadState.

+ + + +

ECreated

+

The initial state of all Symbian platform threads. It is a transient +state; the thread starts in this state when the DThread object +is created, and stays in that state until it is ready to be resumed, typically +when DLL linkage and memory allocation is complete. At this point, the state +will change to EReady.

+
+ +

EDead

+

This is the final state of a Symbian platform thread. A thread enters +this state when it reaches the end of its exit handler, just before the nanokernel +terminates it. In effect, the thread has exited but has not yet been deleted.

+
+ +

EReady

+

This indicates that the thread is not waiting on, or attached to +any Symbian platform kernel wait object. It does not necessarily imply that +the thread is actually ready to run - this is indicated by the N-state. For +example, a thread that is explicitly suspended or waiting on a nanokernel +wait object (generally a fast semaphore) still has a READY M-state provided +that it is not attached to any Symbian platform wait object.

+
+ +

EWaitSemaphore

+

This indicates that the thread is currently blocked waiting for +a Symbian platform semaphore, and is enqueued on the semaphore’s wait queue. +The thread’s DThread::iWaitObj field points to the semaphore.

For +example, this is the case if the thread calls User::WaitForRequest() or RSemaphore::Wait()

+
+ +

EWaitSemaphoreSuspended

+

This indicates that the thread has been explicitly suspended after +blocking on a Symbian platform semaphore, and is enqueued on the semaphore’s +suspended queue. The thread’s DThread::iWaitObj field points +to the semaphore.

+
+ +

EWaitMutex

+

This indicates that the thread is currently blocked waiting for +a Symbian platform mutex, and is enqueued on the mutex wait queue. The thread’s DThread::iWaitObj field +points to the mutex.

+
+ +

EWaitMutexSuspended

+

This indicates that the thread has been explicitly suspended after +blocking on a Symbian platform mutex, and is enqueued on the mutex suspended +queue. The thread’s DThread::iWaitObj field points to the +mutex.

+
+ +

EHoldMutexPending

+

This indicates that the thread has been woken up from the EWaitMutex +state but has not yet claimed the mutex. The thread is enqueued on the mutex +pending queue and the thread’s DThread::iWaitObj field points +to the mutex.

+
+ +

EWaitCondVar

+

This indicates that the thread is waiting on a condition variable.

+
+ +

EWaitCondVarSuspended

+

This indicates that the thread is suspended while waiting on a condition +variable.

+
+ + +
+
Thread and +process exit information summary

User threads and processes have +“exit information”. When a thread or process terminates the reason for the +termination is found in the exit information. For example, a panic will store +the panic category and reason in the exit information. Exit information has +three parts: the exit type, exit reason and exit category.

Exit type +is defined by the TExitType enum.

When a thread +or process is created, its exit type is set to 3. An exit type of 3 indicates +that the thread is still active, though not necessarily running. If the thread +terminates for any reason, then the exit type is changed to reflect the cause +of the exit.

Once the thread or process has exited, the exit reason +and exit type fields will contain useful information. The contents depends +on the type of exit.

Note that if the main thread in a process exits, +then the process will exit with the same exit information as the thread.

Exit category: Terminate

if RThread::Terminate() or RProcess::Terminate() is +called, then the exit category is Terminate, and the exit +reason is the value of the aReason argument passed to these +functions.

Exit +category: Kill

If RThread::Kill() or RProcess::Kill() is +called, then the exit category is Kill, and the exit reason +is the value of the aReason argument passed to these functions.

Exit category: panic

If a thread panics, then the exit category +is panic, and the exit reason is the panic number. For example +a USER-19 panic would give the following exit information:

exit type = 2 +exit category = “USER” +exit reason = 19 +
+
Critical threads +and processes

Marking a thread or process as “system critical” +means that it is an integral and essential part of the system, for example, +the file server. In effect the thread or process is being declared necessary +for correct functioning of the device. If a system critical thread exits or +panics then the device will reboot; during development it will enter the debug +monitor. A thread can be set as process critical, which means that if it panics +the process will be panicked.

+
Kernel calls +and thread context

When a user thread makes a call into any kernel +code, the kernel code continues to run in the context of the user thread. +This applies to device driver code.

The stack is swapped to a kernel-side +stack and the permissions of the thread are increased to kernel privilege, +but otherwise the user thread is still running. Each thread has a small kernel +stack used to handle kernel calls – it would be dangerous to continue using +the normal thread stack in case it overflows. Some calls are handled in this +state, others – typically device drivers – will post a message to a kernel +side thread to carry out the request.

+
Stacks

When +a process is created, a chunk is allocated to hold the process executable's .data section +(initialised data) and .bss section (zero filled data). Sufficient +space (default 2Mb) is also reserved as user-side stack space for threads +that run in that process.

By default, each thread is allocated 8k +of user-side stack space. A guard of 8k is also allocated.

The stack +area follows the .data and .bss sections, +and each thread's user side stack follows. On ARM processors the stack is +descending, so that as items are added to the stack, the stack pointer is +decremented. This means that if the stack overflows, the stack pointer points +into the guard area and causes a processor exception, with the result that +the kernel panics the thread.

+ +

Return addresses are stored by pushing them on to the stack so at +any point you can trace through the stack looking at the saved return addresses +to see the chain of function calls up to the present function.

The +size of the user-side stack space has an indirect effect on the number of +threads that a process can have. There are other factors involved, but this +is an important one. The limit is a consequence of the fact that a process +can have a maximum of 16 chunks. This means that if threads within a process +can share a heap (allocated from a single chunk), then it is possible to have +a maximum of 128 threads per process [2Mb/(8K + 8K)]. More threads may be +possible if you allow only 4K of stack per thread.

Apart from the +kernel stack attached to each thread, the kernel also maintains stacks that +are used during processing of interrupts, exceptions and certain CPU states. +Interrupts and exceptions can occur at any time, with the system in any state, +and it would be dangerous to allow them to use the current stack which may +not even be valid or may overflow and panic the kernel. The kernel stacks +are guaranteed to be large enough for all interrupt and exception processing.

+
Virtual memory +and run addresses

Symbian platform devices have an MMU which is +used to map the addresses seen by running code to real addresses of memory +and I/O. The MMU in effect creates a virtual memory map, allowing scattered +blocks of RAM to appear contiguous, or for a section of memory to appear at +different addresses in different processes, or not at all.

Symbian +platform uses the MMU to provide memory protection between processes, to allow +sharing of memory, efficient allocation of RAM and to make all processes “see” +the same memory layout. Three different memory models are supported by Symbian +platform on ARM CPUs:

    +
  • moving model: this is +the model familiar from EKA1 where processes are moved to a run-address in +low memory when executing and moved back to a home-address in high memory +when not running.

  • +
  • direct model: this is +used when the CPU does not have an MMU, or is emulating a system without an +MMU. Not normally used, but occasionally useful for development boards

  • +
  • multiple model: only +supported in ARM architecture V6 and above, each process has its own set of +MMU tables. A context switch changes the current MMU table to the new thread’s +table, instead of moving memory about in a single table as with moving model.

  • +

Fixed +processes

For ARM architectures with a virtually-tagged cache, +fixed processes avoid the need to flush the cache on context switches by keeping +all the code and data at a fixed address. This implies that there can only +ever be one instance of each fixed process because the data chunk address +cannot be changed.

Important servers such as the file server and window +server are fixed.

There is no limit to the number of fixed processes +that can be supported. The kernel will attempt to use ARM domains for fixed +process protection, but there are a limited number of domains so when they +are exhausted normal MMU techniques will be used. Domains are slightly faster +in a context switch but this is negligible compared to the real purpose of +the fixed process in avoiding the cache flush.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-4993AF8E-28C3-54BA-8D27-D86E05D39CFD.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-4993AF8E-28C3-54BA-8D27-D86E05D39CFD.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,61 @@ + + + + + +Crash +Logger TechnologyThe Crash Logger contains a logger program that stores system state +information when a crash occurs, and a reader application that can be used +later to get this information +
The +crash logger

When the kernel crashes, control is handed to the +crash logger. It tries to read as much state information as it can reasonably +find, and dumps it to a pre-reserved location in permanent storage flash storage).

Support +exists for dumping information to nor flash and nand flash. +The crash logger must have its own drivers to do this, as it cannot be assumed +that any specific part of the kernel is operating correctly in these circumstances. +These drivers are essentially simplified versions of the standard drivers.

All +monitoring functionality, crash logging and crash debugging is placed in kernel +extensions. Functionality can be enabled or disabled by placing the appropriate +kernel extensions into ROM at ROM build time.

To support both crash +logging and debugging without duplicating code, a common module, exmoncommon.dll, +has been created. This extension contains all of the generic monitoring code, +and supports features such as dumping registers, thread stacks and object +containers and is responsible for registering with the kernel’s crash monitor +entry point:

Epoc::SetMonitorEntryPoint()

This +extension must be placed in ROM before either of the two monitoring extensions, +as they both rely on its functionality. As exmoncommon.dll depends +on the underlying memory model, it is built from the Variant.

After +the common monitoring code registers itself with the kernel, further debugging +extensions may register with the common code. These extensions are called +when the kernel fails, in the order that they register. The maximum number +of extensions currently supported is nine though only two- the interactive +debugger, and the non-interactive crash logger are provided. However, this +is an arbitrary limit set by the macro definition MONITOR_MAXCOUNT in +the file E32\include\kernel\monitor.h, and can be increased +given sensible use cases.

    +
  • exmondebug.dll is +the traditional interactive debugger.

  • +
  • exmonlog.dll is +the crash logger.

  • +

These DLLs are also built from the Variant. In the case of the crash +logger, two separate .mmp files exist:

    +
  • one for NAND flash, +building exmonlognand.dll

  • +
  • one for NOR flash, building exmonlognor.dll

  • +

The rombuild scripts ensure that the crash logger for only one type +of flash is placed into the ROM, and named as exmonlog.dll.

+
The crash reader

At +the next system boot, the crash reader application uses the normal system +flash drivers to read the crash log from the reserved non-filesystem (non-uservisible) +flash area, and to write it into the user-visible file system.

The +output file from the crash reader is a text file, or a compressed GZIP-compatible file.

The +crash reader application is called crashread.exe, which +is built from e32utils\crashread\crashread.mmp.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-4A2E212E-BC1B-5965-9A62-6309CC7CAAAB-master.png Binary file Adaptation/GUID-4A2E212E-BC1B-5965-9A62-6309CC7CAAAB-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-4A2E212E-BC1B-5965-9A62-6309CC7CAAAB_d0e61647_href.png Binary file Adaptation/GUID-4A2E212E-BC1B-5965-9A62-6309CC7CAAAB_d0e61647_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-4A2E212E-BC1B-5965-9A62-6309CC7CAAAB_d0e65116_href.png Binary file Adaptation/GUID-4A2E212E-BC1B-5965-9A62-6309CC7CAAAB_d0e65116_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-4A910E9F-E881-51D7-A84A-CBC6AC343FD1.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-4A910E9F-E881-51D7-A84A-CBC6AC343FD1.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,21 @@ + + + + + +Level +2 Cache MacrosDescribes the macros that define if the phone uses Level 2 cache. +

The macros are used in the platform-specific configuration header file, config.inc, +described in Platform-Specific +Configuration Header.

+
CFG_HasL210CacheCFG_HasL210Cache

Includes +support for the L210 cache in the bootstrap.

+
CFG_HasL220CacheCFG_HasL220Cache

Includes +support for the L220 cache in the bootstrap.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-4AEF7595-17C0-513E-9568-B212E6194388.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-4AEF7595-17C0-513E-9568-B212E6194388.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,163 @@ + + + + + +Record +operationDescribes the operation of the Sound Driver for sound recording. +
Client functions

Many aspects regarding the way +that the Sound Driver recording operates are similar to the way it handles +playback. One difference is how the memory location in the Shared +Chunks for the transfer is determined. In play requests, the client +specifies the source location in the chunk for the transfer having arranged +for the data to be loaded there prior to the request. For record requests, +the client just requests a buffers worth of record data and allows the driver +to decide which buffer to use for the request.

The driver commences +recording when the client issues the first RSoundSc::RecordData() request. +However, unlike playback operation, once recording has commenced, the driver +continues to record data into its available record buffers until it is told +to stop. To stop the driver capturing record data, the client must either +issue RSoundSc::Pause() to temporarily suspend recording, RSoundSc::CancelRecordData() to +terminate record operation, or close the driver channel altogether.

The +client specifies the number and size of the record buffers available to the +driver within the shared chunk by calling either RSoundSc::SetBufferChunkCreate(), +to create a buffer, or RSoundSc::SetBufferChunkOpen() to +open an existing buffer.

When the driver starts recording, all the +buffers in the shared chunk are empty, and the driver can use all of these +available buffers. They are filled one by one, and if the client is slow to +request the recorded data, then once the driver has filled all of the available +empty buffers, it is forced to discard the earliest one filled and re-use +this to continue recording data.

Each time the client requests a buffers +worth of recorded data with RSoundSc::RecordData(), it +is given the earliest one filled. This buffer is now said to be in-use and +unavailable to the driver for capturing. This buffer remains in-use until +it is freed by the client with a call of RSoundSc::ReleaseBuffer().

When +buffers are in use by the client the number of buffers available to the driver +for capture is reduced. If the client is slow to release buffers and the number +of available buffers falls to two then further RSoundSc::RecordData() requests +fail with KErrInUse until the client has freed some buffers. +The driver always needs a working set of at least two buffers in order to +achieve uninterrupted data capture. The driver always has a current buffer +which is actively being filled and another queued in advance. If the client +fails to take buffers at full speed then they are discarded by the driver.

The +driver does not slow down if it runs out of empty buffers.

Buffers

The driver maintains three buffer lists:

    +
  • free list

  • +
  • completed list

  • +
  • in-use list.

  • +

A record buffer can only exist in one of these lists at any time. +The free list contains buffers that are empty and not in use by the client. +Once a buffer has been filled with record data it is moved into the completed +buffer list. Here the buffer remains until it is passed back to the client +in response to a record request. When a client is using the buffer it is deemed +as in-use and is moved to the in-use list. Each time the client successfully +calls RSoundSc::ReleaseBuffer() to free up a buffer then +the driver moves this from the in-use list to the free list.

The driver +also maintains two record buffers which are excluded from any of the three +lists.

    +
  • the current buffer, +the one actively being filled with record data

  • +
  • the next buffer which +becomes the active buffer once the current buffer is filled

  • +

During recording there may be DMA requests pending for both the current +buffer and the next buffers.

+ The record buffer cycle +

The numbers one to five show the buffer cycle under normal operation, +while the letters A to C show error induced operation.

+ +

When recording commences, the driver removes two buffers from the +free list making one the current buffer and the other the next buffer (4 and +5).

When the current buffer is set as filled, the LDD normally adds +this to the completed list (1). If a record error has occurred while recording +to this buffer and it is only partially filled, or even empty then the buffer +is still added to the completed list, as the client needs to be informed of +the error (1). The only exception is in handling record pause, where a record +buffer ends up being completed with no error and with no data added. In this +case the buffer is added straight into the free list (A).

Having added +the current buffer to one of these lists, the driver moves the next buffer +to the current buffer (5) and then obtains a new next buffer (4). In normal +operation this comes from the free list but if the client is slow, this list +may be empty and the buffer is taken from the completed list (B). This is +a buffer overflow situation which is reported to the client as a response +to its next RSoundSc::RecordData() request as KErrOverFlow.

Whenever +a buffer is filled, the driver checks if there is a record request pending +(1). Similarly, when the driver processes a new record request it checks if +a filled buffer is already available. In either case, if a request can be +completed to the client then the earliest buffer completed is returned. If +this buffer was filled successfully then it added to the in-use list (2). +However, if an error occurred whilst filling the buffer then it is returned +straight to the free list instead (C).

Each time the client successfully +calls RSoundSc::ReleaseBuffer() to free up a buffer then +the driver moves this from the in-use list to the free list (3).

+
Audio recording

RecordData()

If +the driver is not already recording data then the first RSoundSc::RecordData() request +is handled in the context of the driver DFC thread, as access to the audio +hardware is required to enable record operation. However, for efficiency, +subsequent record requests from the client are handled entirely in the context +of the calling thread, as access to the audio hardware is not required to +handle the request. The driver only has to check whether there is a filled +record buffer already available. If there is then the driver completes the +request straight away. If not, the driver saves the details of the request +until a filled buffer does become available.

Returning to the case +of a record request where the driver is not already in the process of recording +data, the LDD first checks whether the client has specified or supplied a +shared chunk to the driver channel and has set the audio configuration and +record level. If the buffer configuration has not been specified then the +driver cannot proceed and returns KErrNotReady. If the audio +configuration or record level has not been specified then the LDD applies +default settings to the audio hardware device for each instead by calling +the functions DSoundSc::SetConfig() and DSoundScPdd::SetVolume() on +the PDD.

StartTransfer()

Depending +on the mapping attributes of the shared chunk, the LDD may now need to purge +the region of the record chunk concerned. Next the LDD calls DSoundScPdd::StartTransfer() on +the PDD to allow it to prepare the audio hardware device for record data transfer.

TransferData()

The LDD may need to break down the record buffer +into memory fragments. These specify a physically contiguous region and are +manageable by the PDD as a single transfer. The LDD queues as many transfer +fragments of the current buffer on the PDD as it can accept with a call to DSoundScPdd::TransferData() for +each fragment. If all fragments from the current buffer are accepted by the +PDD then the LDD tries to queue fragments from the next buffer. As with playback, +to support uninterrupted transfer of audio data the PDD must be able to accept +multiple fragments simultaneously. As long as the LDD has transfer fragments +still to queue, it continues to call DSoundScPdd::TransferData() until +the PDD signals that it has temporarily reached its capacity by returning KErrNotReady.

RecordCallBack()

Each time the PDD completes the transfer +of a fragment from a record buffer, it must signal this event back to the +LDD by calling the function DSoundScLdd::RecordCallBack(). +This must always be called in the context of the driver DFC thread. In executing DSoundScLdd::RecordCallback(), +the LDD checks whether the entire transfer for the current buffer is now complete. +If so, depending on the mapping attributes of the shared chunk, the LDD may +need to purge the region of the record client. The LDD attempts to queue further +fragments on the PDD, by calling DSoundScPdd::TransferData(), +which should now have the capability to accept more transfers. So, the PDD +should be written to handle calls to DSoundScPdd::TransferData() within +its call back to DSoundScLdd::RecordCallback().

+
Pause and resume audio recording

The client can +temporarily halt the progress of audio record at any time by issuing DSoundScLdd::Pause(). +To configure the audio hardware device to halt recording, the LDD calls DSoundScPdd::PauseTransfer() on +the PDD. This time, any active transfer should be aborted by the PDD. If a +recording is halted the PDD must signal this event with a single call of the +LDD function DSOundScLdd::RecordCallback(), which reports +back any partial data already received. In this case, if transfer is resumed +later, the LDD issues a new DSoundScPdd::TransferData() request +to commence data transfer after calling DSoundScPdd::ResumeTransfer(). +As access to the hardware is required in both cases, pause and resume are +handled in the context of the driver DFC thread.

+
Error handling during recording

If the PDD reports +an error when setting up the audio hardware device for recording then the +LDD immediately completes the first record request back to the client returning +the error value as the result. It will not restart record data transfer unless +it receives a further record request from the client.

If the PDD reports +an error when commencing the transfer of a record fragment or as the result +of the transfer of a record fragment, then the LDD ceases transfer to that +record buffer and instead reports the error back to the client. The error +is returned in response to the record request which corresponds with that +buffer.

Unexpected errors from the PDD are returned to the LDD via +the functions DSoundScPdd::TransferData() and DSoundScLdd::RecordCallback().

The +LDD does not try to cancel the transfer of other fragments for the same buffer +that are already queued on the PDD, but it ignores their outcome. However, +the LDD does try to carry on with the transfer to other available record buffers.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-4AFDA3FF-38D1-5EFE-B18A-E3EAAA52EB75.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-4AFDA3FF-38D1-5EFE-B18A-E3EAAA52EB75.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,29 @@ + + + + + +Flash +Guide Flash memory is a class of memory that can retain its contents +even after the power has been switched off. +
Introduction

Unlike +ROM, the data in Flash memory can be changed by an application.

+
Flash memory features

Features of Flash memory +are:

    +
  • Writing and erasing of memory has to be undertaken in blocks of memory

  • +
  • Memory contents are retained until erased (regardless of whether the +power has been turned on/off).

  • +
+
Flash memory limitations

The following are limitations +of FLASH memory:

    +
  • There are a finite number of erase-write cycles (usually 100,000).

  • +
  • NAND Flash cannot be executed in place. Instead the contents have to +be loaded into RAM and then executed.

  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-4C4515EA-A5DD-56B4-94B0-EE48D66013F7.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-4C4515EA-A5DD-56B4-94B0-EE48D66013F7.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,40 @@ + + + + + +Read Data from USB using Shared Chunks This tutorial describes how to read shared chunk data from +a USB connection. +
Read data

To read data from the host to +the device (Out) call the function RDevUsbcScClient::ReadDataNotify() to make a request to wait for data in the specified buffer and wait +for it to complete.

If the buffer already has data in it, +it will return immediately with the code KErrCompletion. If there is no data in the buffer an asynchronous request is set +up that will complete when data is available. Note: check the +return code before attempting to wait for the request to complete.

TUsbcScHdrEndpointRecord* epInfo; +TRequestStatus status; + +TUsbcScChunkHeader chunkHeader(gChunk); + +chunkHeader.GetBuffer(0, 2, epInfo); +TInt outBuffNum = epInfo->iBufferNo; + +r = gPort.ReadDataNotify(outBuffNum,status);

The first +parameter required by ReadDataNotify() is the endpoint +buffer number. The endpoint buffer number can be found in the alternate +setting table in the chunk header. The location of the buffer can +be found by looking at the buffer offset table, which is also in the +chunk header.

When the request has completed, process the +data in the buffer that was read from the driver.

The transfer +buffer for an IN endpoint is always pointed to by the iTail member of the endpoint buffer struct SUsbcScBufferHeader. When finished processing the current chunk move iTail to point to the next transfer buffer.

iTransfer = (TUsbcScTransferHeader*) (iHeader->iTail + iBase); +... // Process data +iHeader->iTail = iTransfer->iNext;

If there is no more +data to be read then close the channel and unload the driver.

+
Next steps

When you have finished reading +and writing Close and Unload the Driver.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-4C5DB74E-41A5-53CB-A053-CBBEADD31AFF.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-4C5DB74E-41A5-53CB-A053-CBBEADD31AFF.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,31 @@ + + + + + +ArchitectureDescribes the architecture of the DMA Framework. +

The following diagram shows the main parts of the architecture:

+ + + +

The DMA Framework is implemented as a single DLL, which is split into two +layers:

+
    +
  • a platform independent +layer that implements the behaviour that is common to all hardware

  • +
  • a platform specific +layer that implements the behaviour that is specific to a particular platform.

  • +
+

The DLL is called dma.dll, and is implemented as a +kernel extension, which means that it is loaded very early during system initialisation.

+

The platform specific layer interfaces to the DMA controller hardware via +the I/O port constants and functions exposed by the ASSP DLL and/or Variant +DLL.

+

The clients of the DMA Framework are physical device drivers (PDD).

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-4C8E40EE-8CC9-4737-A28E-A18E89356718.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-4C8E40EE-8CC9-4737-A28E-A18E89356718.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,12 @@ + + + + + +TimeDescribes the Time platform service. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-4CB3C746-606F-4533-8BBB-4A1254A74772-master.png Binary file Adaptation/GUID-4CB3C746-606F-4533-8BBB-4A1254A74772-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-4CB3C746-606F-4533-8BBB-4A1254A74772_d0e94716_href.png Binary file Adaptation/GUID-4CB3C746-606F-4533-8BBB-4A1254A74772_d0e94716_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-4DAC39E0-2EC2-40F7-9AEF-4FDA09F1A151.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-4DAC39E0-2EC2-40F7-9AEF-4FDA09F1A151.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,21 @@ + + + + + +Asynchronous +RequestsThis document discusses the use of asynchronous requests by device +drivers. +

An asynchronous request is typically used to start an operation on a device +that completes at a later point of time. It returns immediately after starting +the operation on the device or making a request to the driver. The user side +thread is not blocked and can continue with other operations, including issuing +other requests (synchronous or asynchronous).

+

A driver lists the available asynchronous request types in an enumeration.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-4E3C086B-25BE-4DAC-9E21-CFC4F8B792A5.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-4E3C086B-25BE-4DAC-9E21-CFC4F8B792A5.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,121 @@ + + + + + +DMA Technology GuideDescribes the Direct Memory Access framework. +
Purpose

The DMA framework provides a generic simple interface for the +clients to access DMA resources in a device. The primary clients are +device drivers that will use the DMA framework to set up DMA transfers. +A device can have more than one DMA controller (DMAC).

+
Architectural +concepts

The key concepts related to DMA framework are:

+DMA Framework + +
+ +
DMA Client
+

A device driver or a kernel object that needs to use the resources +of the DMA framework. On the Symbian platform, the Physical Device +Drivers are the primary clients of the DMA framework.

+
+ +
DMA Platform Service API
+

The generic interface to provide DMA services to the clients.

+
+ +
DMA Import Library
+

The DMA clients link against the dma.lib file.

+
+ +
DMA Platform-Independent Layer (PIL)
+

The platform-independent layer contains the generic framework +independent from the hardware.

+
+ +
DMA Platform-Specific Layer (PSL)
+

The platform-specific layer is specific to the baseport and +the hardware used.

+
+ +
DMA Controller (DMAC)
+

The DMAC is the DMA hardware implementation. The number of +DMAC in the implementation of the DMA Framework depends on the hardware. +The DMAC is a peripheral to the CPU and is programmed to control data +transfers without using the CPU.

+
+
+
DMA +functionality

The key concepts related to functionality +provided by the DMA framework are:

+ +
Scatter/Gather Mode
+

Some DMA controllers transfer data using scatter/gather mode. +In this mode, the operating system creates a DMA descriptor with source +and destination memory addresses and the configuration. The source +and destination data can be a list of scattered memory blocks. The +DMA controller uses this configuration to perform the data transfer.

+
+ +
DMA Descriptors
+

The data structure used by the DMA framework to store the configuration +of the data transfer. These will store details such as source address, +destination address, number of bytes and pointer to the next descriptor, +when the DMA is used to transfer disjoint blocks of data. This structure +is defined in the platform specific layer. The descriptors are always +used to store the configuration even if the DMA controller does not +support scatter/gather mode. When the scatter/gather mode is not supported +by the DMAC, the descriptors used to store the configuration are called +as pseudo-descriptors.

+
+ +
Descriptor Headers
+

The descriptor headers are used to store additional information +about the descriptors. The descriptors are accessed using the descriptor +headers which contain the pointer to the descriptor.

+
+ +
Transfer Request
+

The device drivers configure and initialize a data transfer +using the class DDmaRequest. The data can be transferred +between:

    +
  • memory to memory

  • +
  • memory to peripheral

  • +
  • peripheral to memory

  • +
The transfer request stores the callback function of the clients. +The callback function is used to notify the success or failure of +a data transfer.

+
+ +
DMA Channel
+

The object which represents a single hardware, logical or a +virtual channel. In the DMA platform service API, each DMA channel +is referred to by a 32-bit value called a cookie. Each DMA transfer +is in the form of a description header and its associated DMA descriptor. +The queue of transfer requests (both being transferred and pending) +consists of a linked list of the DMA headers.

+
+ +
DMA Channel Allocator
+

The channel manager controls the opening and closing of DMA +channels. The channel manager functions are defined in the platform +independent layer and implemented in the platform specific layer.

+
+
+
Typical +Uses

The typical use cases of a DMA framework are:

    +
  • programmable data transfer between hardware peripherals and +memory buffers

  • +
  • programmable data transfer of block of data between different +regions of memory

  • +
+
+ +ARM DMA Controller Reference Manual +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-4E6520E8-4BF1-55D1-B643-81B8D2816D1D-master.png Binary file Adaptation/GUID-4E6520E8-4BF1-55D1-B643-81B8D2816D1D-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-4E6520E8-4BF1-55D1-B643-81B8D2816D1D_d0e5246_href.png Binary file Adaptation/GUID-4E6520E8-4BF1-55D1-B643-81B8D2816D1D_d0e5246_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-4FDD1F7B-1A4E-5389-A0A4-22727CD42B5B-master.png Binary file Adaptation/GUID-4FDD1F7B-1A4E-5389-A0A4-22727CD42B5B-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-4FDD1F7B-1A4E-5389-A0A4-22727CD42B5B_d0e9110_href.png Binary file Adaptation/GUID-4FDD1F7B-1A4E-5389-A0A4-22727CD42B5B_d0e9110_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-50217E69-F4A9-4B9F-8608-419783046A1E.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-50217E69-F4A9-4B9F-8608-419783046A1E.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,38 @@ + + + + + +Register Access Quick Start GuideRegister Access is used to read/write/modify values on +only the ASSP hardware. +

The Register Access platform service is used by many of the other +platform services for either reading values from or setting the configuration +of hardware in the device.

+
Getting +started
    +
  • The Register Access Technology Guide describes the key concepts +of the Register Access platform service.

  • +
  • The Register Access Client Interface Guide describes the Register +Access platform service API and its use by device drivers.

  • +
  • The Register Access Implementation section describes the implementation +of the Register Access PSL.

  • +
  • The Register Access Build Guide describes how to include the Register +Access platform service in a ROM image.

  • +
  • The Register Access Tools Guide describes the tools that are specific +to the Register Access platform service.

  • +
  • The Register Access Testing Guide explains how to test the functionality +of the Register Access platform service.

  • +
+
Users

Since this platform service is used by many of the other platform +services, it is of interest to both device driver developers and hardware +implementors.

+AsspRegister class diagram + +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-51514A4B-0220-557B-9F7A-FB110CEFEF10.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-51514A4B-0220-557B-9F7A-FB110CEFEF10.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,722 @@ + + + + + +Shared +ChunksA shared chunk is a mechanism that kernel-side code uses to share +memory buffers safely with user-side code. +

A shared chunk is a mechanism that kernel-side code can use to share memory +buffers safely with user-side code. This topic describes this concept, and +explains how to use the shared chunk APIs.

+
    +
  • What are shared chunks?

  • +
  • Creating a shared chunk

  • +
  • Opening a handle to the shared chunk for user-side access

  • +
  • Discarding a handle

  • +
  • Closing and destroying a shared chunk

  • +
  • Committing memory

  • +
  • Passing data from user-side code to another device driver

  • +
  • Passing data between user-side code

  • +
  • Direct peripheral access to shared chunks

  • +
  • Example code

      +
    • Example: Creating a shared chunk

    • +
    • Example: Opening a handle to the shared chunk for user-side access

    • +
    • Example: Using a DFC to notify destruction of chunk

    • +
    • Example: Committing memory

    • +
  • +
+

You may find it useful to refer to the general sections : Device +Driver Concepts and Device +Driver Framework.

+
What are shared +chunks?

A shared chunk is a mechanism that kernel-side code uses +to share memory buffers safely with user-side code. References to kernel-side +code always mean device driver code.

The main points to note about +shared chunks are:

    +
  • They can be created +and destroyed only by device drivers. It is typical behaviour for user-side +code, which in this context we refer to as the client of the device +driver, to pass a request to the device driver for a handle to a shared chunk. +This causes the device driver to open a handle to the chunk and return the +handle value to the client. Successful handle creation also causes +the chunk's memory to be mapped into the address space of the process to which +the client's thread belongs. Note, however, that the driver dictates when the +chunk needs to be created, and when memory needs to be committed.

  • +
  • Like all kernel-side +objects, a shared chunk is reference counted. This means that it remains in +existence for as long as the reference count is greater than zero. Once all +opened references to the shared chunk have been closed, regardless +of whether the references are user-side or kernel-side, it is destroyed.

  • +
  • User-side code that +has gained access to a shared chunk from one device driver can pass this to +a second device driver. The second device driver must open the chunk +before it can be used.

  • +
  • More than one user-side +application can access the data in a shared chunk. A handle to a shared chunk +can be passed from one process to another using standard handle passing mechanisms. +In practice, handles are almost always passed in a client-server context via +inter process communication (IPC).

  • +
  • Processes that share +the data inside a chunk should communicate the location of that data as an +offset from the start of the chunk, and not as an absolute address. +The shared chunk may appear at different addresses in the address spaces of +different user processes.

  • +
+
Creating a +shared chunk

A shared chunk can be created only by code running +on the kernel-side. This means that it is the device driver's responsibility +to create a chunk that is to be shared by user-side code. There is no user-side +API that allows user-side code to create shared chunks.

The device +driver creates a shared chunk using the Kern::ChunkCreate() function. +It passes to this function a TChunkCreateInfo object containing +the required attributes for that chunk. The most important attribute is the TChunkCreateInfo::ESharedKernelMultiple attribute +that states that a shared chunk is to be created.

Chunks are reference +counted kernel objects. When the chunk is created, the reference count is +set to one.

See Example: +Creating a shared chunk.

+
Opening a handle +to the shared chunk for user-side access

Before user-side code +can access the memory in a shared chunk, the device driver must create a handle +to the chunk and then pass the value back to the user-side. It does this by +calling the Kern::MakeHandleAndOpen() function, passing +the information:

    +
  • a pointer to the user-side +code's thread (or NULL if referring to the current thread)

  • +
  • a pointer to the shared +chunk

  • +

Typically, the device driver does this in response to a request from +the user-side. Kern::MakeHandleAndOpen() also maps the +chunk's memory into the address space of the user-side code's thread.

If +the creation of the handle is successful, the device driver returns the handle value back +to the user-side. The user-side code then assigns the value to an RChunk object +using one of RChunk's base class functions:

    +
  • RHandleBase::SetHandle()

  • +
  • RHandleBase::SetReturnedHandle()

  • +

The user-side code uses RHandleBase::SetReturnedHandle() if +the device driver returns either a positive handle value or a negative error +code. A negative error code means that handle creation has failed.

Opening +a handle to a shared chunk increases the reference count by one.

See Example: +Opening a handle to the shared chunk for user-side access.

+
Closing a handle

After +it has been opened, a device driver may need to perform further operations +before the handle can be returned to the user-side. If these operations fail, +the device driver code may want to unwind the processing it has done, including +discarding the handle it has just created. It does this using the function Kern::CloseHandle().

This +reverses the operation performed by Kern::MakeHandleAndOpen().

+
Closing and +destroying a shared chunk

There is no explicit method for deleting +or destroying shared chunks. Instead, because chunks are reference counted +kernel objects, a device driver can use the function Kern::ChunkClose(). +This function decrements a chunk's access count, and, if the count reaches +zero, the chunk is scheduled for destruction.

The chunk is not be +destroyed immediately. Instead it is done asynchronously. If the device driver +needs to know when the chunk has been destroyed, it must specify a DFC (Deferred +Function Call) at the time the chunk is created. The device driver specifies +the DFC through the TChunkCreateInfo::iDestroyedDfc member. +The DFC is queued to run only when the chunk has finally been destroyed. At +this point it is guaranteed that the memory mapped by the chunk can no longer +be accessed by any code. This is useful in cases where chunks are used to +map I/O devices or other special memory, and the program managing these needs +to know when they are free to be reused.

Note: For each call +to Kern::ChunkCreate() and Kern::OpenSharedChunk() there +should be exactly one call to Kern::ChunkClose(). +Calling Close() too few times can cause memory leaks. Calling Close() too +many times can cause the chunk to be destroyed while a program is still trying +to access the memory, which causes an application panic for user code and +a system crash for kernel code.

+
Committing +memory

After a shared chunk has been created it owns a region of +contiguous virtual addresses. This region is empty, which means that it is +not mapped to any physical RAM or memory mapped I/O devices.

Before +the chunk can be used, the virtual memory must be mapped to real physical +memory. This is known as committing memory.

Committing RAM +from the system free memory pool

You can commit RAM taken from +the system free memory pool using the following ways:

    +
  • by committing an arbitrary +set of pages. Use the function Kern::ChunkCommit().

  • +
  • by committing a set +of pages with physically contiguous addresses. Use the function Kern::ChunkCommitContiguous().

  • +

Committing specified physical addresses

You can commit +specific physical addresses, but only if you set the data member TChunkCreateInfo::iOwnsMemory to EFalse when +you create the shared chunk - see Creating +a shared chunk.

You can use the following ways to do this:

    +
  • by committing a region +of contiguous addresses. Use the function Kern::ChunkCommitPhysical() with +the signature:

    TInt Kern::ChunkCommitPhysical(DChunk*, TInt, TInt, TUint32)
  • +
  • by committing an arbitrary +set of physical pages. Use the function Kern::ChunkCommitPhysical() with +the signature:

    TInt Kern::ChunkCommitPhysical(DChunk*, TInt, TInt, const TUint32*)
  • +

Note: the same physical memory can be committed to two different RChunk s +or shared chunks at the same time, where each RChunk has +a different owner, as long as your turn OFF the caches.

+
Passing data +from user-side code to another device driver

User-side code that +has access to a shared chunk from one device driver may want to use this when +it communicates with another device driver. To enable this, the second device +driver needs to gain access to the chunk and the addresses used by the memory +it represents.

The second driver must open a handle on the shared +chunk before any of its code can safely access the memory represented by that +chunk. Once it has done this, the reference counted nature of chunks means +that the chunk, and the memory it represents, remains accessible until the +chunk is closed.

The general pattern is:

    +
  • the first device driver +creates the shared chunk.

    See Creating +a shared chunk.

  • +
  • the user-side gets the +handle value from the first device driver and calls SetHandle() or SetReturnedHandle() on +an RChunk object [the functions are members of RChunk's +base class RHandleBase (see RHandleBase::SetHandle() and RHandleBase::SetReturnedHandle()].

    See Opening +a handle to the shared chunk for user-side access.

  • +
  • the user-side passes +the handle value to the second device driver. This value is obtained +by calling Handle() on the RChunk object. +[the function is a member of RChunk's base class RHandleBase (see RHandleBase::Handle()].

  • +
  • the second device driver +calls the variant of Kern::OpenSharedChunk() with the signature:

    DChunk* Kern::OpenSharedChunk(DThread*,TInt,TBool)

    to +open a handle to the shared chunk.

    Note: there are situations +where the second device driver cannot use this variant of Kern::OpenSharedChunk() because:

      +
    • The user-side application +may have obtained data by using a library API that uses shared chunks internally, +but which only presents a descriptor based API to the user application. For +example, an image conversion library may perform JPEG decoding using a DSP, +which puts its output into a shared chunk, but that library supplies the user +application with only a descriptor for the decoded data, not a chunk handle.

    • +
    • The communication channel +between the user-side application and the device driver supports descriptor +based APIs only, and does not have an API specifically for shared chunks. +The API items presented by the File Server are an example of this situation.

    • +

    The second device driver will only have the address and size of the +data (usually a descriptor). If the driver needs to optimise the case where +it knows that this data resides in a shared chunk, it can use the variant +of Kern::OpenSharedChunk() with the signature:

    DChunk* Kern::OpenSharedChunk(DThread*,const TAny*,TBool,TInt&)

    to +speculatively open the chunk.

  • +

Getting the virtual address of data in a shared chunk

Before +device driver code can access a shared chunk that is has opened, it must get +the address of the data within it. Typically, user-side code will pass offset +and size values to the driver. The driver converts this information into an +address, using the function Kern::ChunkAddress().

Getting +the physical address of data in a shared chunk

Device driver +code can get the physical address of a region within a shared chunk from the +offset into the chunk and a size value. This is useful for DMA or any other +task that needs a physical address. Use the function Kern::ChunkPhysicalAddress() to +do this.

Getting chunk attributes and checking for uncommitted +memory

As a shared chunk may contain uncommitted regions of memory +(gaps), it is important that these gaps are detected. Any attempt to access +a bad address causes an exception. You can use the function Kern::ChunkPhysicalAddress() to +check for uncommitted regions of memory.

+
Passing data +between user-side code

User-side code can access data in a shared +chunk once it has opened a handle on that chunk. Handles can be passed between +user processes using the various handle passing functions. This most common +scenario is via client-server Inter Process Communication (IPC).

Passing +a handle from client to server

The client passes the handle to +the shared chunk as one of the four arguments in a TIpcArgs object. +The server opens this using the RChunk::Open() variant +with the signature:

RChunk::Open(RMessagePtr2 aMessage,TInt aParam,TBool isReadOnly, TOwnerType aType) +

Passing a handle from server to client

The +server completes the client message using the chunk handle:

RMessagePtr2::Complete(RHandleBase aHandle)

The +client then assigns the returned handle value to an RChunk by +calling:

RChunk::SetReturnedHandle(TInt aHandleOrError)

Note:

    +
  • Processes that share +data within shared chunks must specify the address of that data as an offset from +the start of the chunk, and not as an absolute address. This is because the +chunk may appear at different addresses in the address spaces of different +user processes.

  • +
  • Once a chunk is no longer +needed for data sharing, user applications should close the handle they have +on it. If they do not, the memory mapped by the chunk can never be freed.

  • +

See Using +Client/Server.

+
Direct peripheral +access to shared chunks

When DMA or any other hardware device accesses +the physical memory represented by a shared chunk, the contents of CPU memory +cache(s) must be synchronised with that memory. Use these functions for this +purpose:

    +
  • Cache::SyncMemoryBeforeDmaWrite()

  • +
  • Cache::SyncMemoryBeforeDmaRead()

  • +

Note: both these functions take a TUint32 type +parameter, identified in the function signatures as TUint32 aMapAttr. +This is the same TUint32 value set on return from calls to +either Kern::ChunkPhysicalAddress() or Kern::ChunkCreate().

+
Example code

This +section contains code snippets that show shared chunks in use. Most of the +code is intended to be part of a device driver. A few snippets show user-side +code and the interaction with device driver code.

    +
  • Example: Creating a shared chunk

  • +
  • Example: Opening a handle to the shared chunk for user-side access

  • +
  • Example: using a DFC to notify destruction of chunk

  • +
  • Example: committing memory

  • +

Example: Creating +a shared chunk

This code snippet shows how a device driver creates +a shared chunk. The class DMyDevice has been given responsibility +for creating the chunk:

/** +The device or other object making use of shared chunks +*/ +class DMyDevice + { + ... + TInt CreateChunk(); + void CloseChunk(); +private: + void ChunkDestroyed(); +private: + TBool iMemoryInUse; + DChunk* iChunk + TUint32 iChunkMapAttr; + TLinAddr iChunkKernelAddr; + ... + } /* +Address and size of our device's memory +*/ +const TPhysAddr KMyDeviceAddress = 0xc1000000; // Physical address +const TInt KMyDeviceMemorySize = 0x10000; + +/** +Create a chunk which maps our device's memory +*/ +TInt DMyDevice::CreateChunk() + { + // Check if our device's memory is already in use + if(iMemoryInUse) + { + // Wait for short while (200ms) in case chunk is being deleted + NKern::Sleep(NKern::TimerTicks(200)); + // Check again + if(iMemoryInUse) + { + // Another part of the system is probably still using our memory, so... + return KErrInUse; + } + } + + // Enter critical section so we can't die and leak the objects we are creating + // I.e. the TChunkCleanup and DChunk (Shared Chunk) + NKern::ThreadEnterCS(); + + // Create chunk cleanup object + TChunkCleanup* cleanup = new iChunkCleanup(this); + if(!cleanup) + { + NKern::ThreadLeaveCS(); + return KErrNoMemory; + } + + // Create the chunk + TChunkCreateInfo info; + info.iType = TChunkCreateInfo::ESharedKernelMultiple; + info.iMaxSize = KMyDeviceMemorySize; + info.iMapAttr = EMapAttrFullyBlocking; // No caching + info.iOwnsMemory = EFalse; // We'll be using our own devices memory + info.iDestroyedDfc = cleanup; + DChunk* chunk; + TInt r = Kern::ChunkCreate(info, chunk, iChunkKernelAddr, iChunkMapAttr); + if(r!=KErrNone) + { + delete cleanup; + NKern::ThreadLeaveCS(); + return r; + } + + // Map our device's memory into the chunk (at offset 0) + + r = Kern::ChunkCommitPhysical(chunk,0,KMyDeviceMemorySize,KMyDeviceAddress); + if(r!=KErrNone) + { + // Commit failed so tidy-up... + + // We, can't delete 'cleanup' because it is now owned by the chunk and will + // get run when the chunk is destroyed. Instead, we have to Cancel it, which + // prevents it from doing anything when it does run. + cleanup->Cancel() + // Close chunk, which will then get deleted at some point + Kern::ChunkClose(chunk); + } + else + { + // Commit succeeded so flag memory in use and store chunk pointer + iMemoryInUse = ETrue; + iChunk = chunk; + } + + // Can leave critical section now that we have saved pointers to created objects + NKern::ThreadLeaveCS(); + + return r; + } + +/** +Close the chunk which maps our device's memory +*/ +TInt DMyDevice::CloseChunk() + { + // Enter critical section so we can't die whilst owning the chunk pointer + NKern::ThreadEnterCS(); + + // Atomically get pointer to our chunk and NULL the iChunk member + DChunk* chunk = (DChunk*)NKern::SafeSwap(NULL,(TAny*&)iChunk); + + // Close chunk + if(chunk) + Kern::CloseChunk(chunk); + + // Can leave critical section now + NKern::ThreadLeaveCS(); + } +

Implementation notes

    +
  • a TChunkCreateInfo object +is created, populated and passed to Kern::ChunkCreate(). +This is information that Symbian platform needs to create the chunk. To create +a shared chunk, TChunkCreateInfo::iType must be +set to TChunkCreateInfo::ESharedKernelMultiple.

  • +
  • If the device architecture +allowed the device driver function DMyDevice::CreateChunk() to +be called in a re-entrant manner, you would need to protect this code using +a mutex. Such a situation might arise when a logical channel is shared between +two threads, or two logical channels are created on the same device. There +may also be other cases where a mutex is needed.

    See also:

      +
    • The Symbian platform mutex

    • +
    • Kern::MutexCreate()

    • +
    • Kern::MutexWait()

    • +
    • Kern::MutexSignal()

    • +
  • +
  • The line:

    info.iDestroyedDfc = cleanup;

    in +the function DMyDevice::CreateChunk() and code following +the comment

    // Create chunk cleanup object

    sets +the DFC that runs when the shared chunk is finally closed. See Example: using a DFC to notify destruction of chunk for the DFC code +itself.

  • +

Example: Opening +a handle to the shared chunk for user-side access

These code snippets +show user-side code making a request to a device driver to open handles on +two shared chunks.

The code snippets assume that the chunks have already +been created.

User-side

The user-side interface to +a device driver is always a class derived from RBusLogicalChannel, +and is provided by the device driver. Here, this is the RMyDevice class. +In real code, the class would offer much more functionality, but only the +relevant function members and data members are shown:

/** +Client (user-side) interface to the device driver. +*/ +class RMyDevice : public RBusLogicalChannel + { + ... +public: + TInt OpenIoChunks(RChunk& aInputChunk,RChunk& aOutputChunk); + ... +private: + /** Structure to hold information about the i/o buffers */ + class TIoChunkInfo + { + public: + TInt iInputChunkHandle; + TInt iOutputChunkHandle; + }; + // Kernel-side channel class is a friend... + friend class DMyDeviceChannel; + ... + }; +

You call the function OpenIoChunks() to:

    +
  • issue a request to the +driver to create handles to two chunks

  • +
  • get handles to those +shared chunks so that they can be accessed by user-side code.

  • +
TInt RMyDevice::OpenIoChunks(RChunk& aInputChunk,RChunk& aOutputChunk) + { + // Send request to driver to create chunk handles. + TIoChunkInfo info; + TInt r=DoControl(EOpenIoChunks,(TAny*)&info); + // Set the handles for the chunks + aInputChunk.SetHandle(info.iInputChunkHandle); + aOutputChunk.SetHandle(info.iOutputChunkHandle); + + return r; + } +

Implementation notes

    +
  • The request is passed +to the driver as a synchronous call; it calls the base class function RBusLogicalChannel::DoControl(). +This means that the call does not return until the driver has created (or +failed to create) the handles to the shared chunks. The call is synchronous +because the creation of the handles does not depend on the hardware controlled +by the driver, so there should be minimal delay in its execution.

  • +
  • The driver returns the +handle numbers in the TIoChunkInfo object; specifically +in its iInputChunkHandle and iOutputChunkHandle data +members.

    To access the shared chunks, user-side code needs handles +to them. Handles to chunks are RChunk objects.

    The +final step is to set the returned handle numbers into the RChunk objects +by calling SetHandle(). This function is provided by RChunk's +base class RHandleBase.

    See handles for +background information.

  • +
  • In this example the +return value from RBusLogicalChannel::DoControl() is not +checked. In practice you need to do so.

  • +
+Shared chunks implementation + +

Device driver (kernel) side

This is example code +snippet shows the device driver side handling of the request made by the user-side +to open handles on two shared chunks.

The request is handled by the OpenIoChunks() function +in the device driver's logical channel. The logical channel is represented +by a class derived from DLogicalChannelBase. In this example, +this is the DMyDeviceChannel class.

Details of how +a user-side call to RMyDevice::OpenIoChunks() results in +a call to the driver's DMyDeviceChannel::OpenIoChunks() function +are not shown. Passing +requests from user-side to kernel-side in The +Logical Channel explains the principles.

/** + Kernel-side Logical Channel for 'MyDevice' +*/ +class DMyDeviceChannel : public DLogicalChannelBase + { + ... +private: + TInt OpenIoChunks(RMyDevice::TIoChunkInfo* aIoChunkInfoForClient); +private: + DChunk* iInputChunk; + TInt iInputChunkSize; + DChunk* iOutputChunk; + TInt iOutputChunkSize; + ... + }; +

The following code snippet is the implementation of DMyDeviceChannel::OpenIoChunks().

/** + Called by logical channel to service a client request for i/o chunk handles +*/ +TInt DMyDeviceChannel::OpenIoChunks(RMyDevice::TIoChunkInfo* aIoChunkInfo) + { + // Local info structure we will fill in + RMyDevice::TIoChunkInfo info; + + // Need to be in critical section whilst creating handles + NKern::ThreadEnterCS(); + + // Make handle to iInputChunk for current thread + TInt r = Kern::MakeHandleAndOpen(NULL, iInputChunk); + // r = +ve value for a handle, -ve value is error code + if(r>=0) + { + // Store InputChunk handle + info.iInputChunkHandle = r; + + // Make handle to iOutputChunk for current thread + r = Kern::MakeHandleAndOpen(NULL, iOutputChunk); + // r = +ve value for a handle, -ve value is error code + if(r>=0) + { + // Store OutputChunk handle + info.iOutputChunkHandle = r; + // Signal we succeeded... + r = KErrNone; + } + else + { + // Error, so cleanup the handle we created for iInputChunk + Kern::CloseHandle(NULL,info.iInputChunkHandle); + } + } + + // Leave critical section before writing info to client because throwing an + // exception whilst in a critical section is fatal to the system. + NKern::ThreadLeaveCS(); + + // If error, zero contents of info structure. + // (Zero is usually a safe value to return on error for most data types, + // and for object handles this is same as KNullHandle) + if(r!=KErrNone) + memclr(&info,sizeof(info)); + + // Write info to client memory + kumemput32(aIoChunkInfo,&info,sizeof(info)); + + return r; + } +

Implementation notes

    +
  • The function calls Kern::MakeHandleAndOpen() twice, +once for each shared chunk. A NULL value is passed as the first parameter +in both calls to this function instead of an explicit DThread object. +This creates the handles for the current thread. Although this code is running +in kernel mode, the context remains the user thread.

  • +
  • The first handle created +is closed if the second handle cannot be created:

    if(r>=0) + { + ... + } + else + { + // Error, so cleanup the handle we created for iInputChunk + Kern::CloseHandle(NULL,info.iInputChunkHandle); + }
  • +
  • The handle values are +written back into the TIoChunkInfo structure using the kumemput32() function. +See the EKA2 references in Accessing +User Memory in Migration +Tutorial: EKA1 Device Driver to Kernel Architecture 2.

  • +

Example: Using +a DFC to notify destruction of a chunk

This set of code snippets +shows how to set up a DFC that notifies a device driver when a shared chunk +has finally been destroyed.

/** +Example class suitable for use as a 'Chunk Destroyed DFC' when +creating Shared Chunks with Kern::ChunkCreate() +*/ +class TChunkCleanup : private TDfc + { +public: + TChunkCleanup(DMyDevice* aDevice); + void Cancel(); +private: + static void ChunkDestroyed(TChunkCleanup* aSelf); +private: + DMyDevice* iDevice; + }; + +/** +Contruct a Shared Chunk cleanup object which will signal the specified device +when a chunk is destroyed. +*/ +TChunkCleanup::TChunkCleanup(DMyDevice* aDevice) + : TDfc((TDfcFn)TChunkCleanup::ChunkDestroyed,this,Kern::SvMsgQue(),0) + , iDevice(aDevice) + {} + +/** +Cancel the action of the cleanup object. +*/ +void TChunkCleanup::Cancel() + { + // Clear iDevice which means that when the DFC gets queued on chunk destruction + // our ChunkDestroyed method will do nothing other than cleanup itself. + iDevice = NULL; + } + +/** +Callback function called when the DFC runs, i.e. when a chunk is destroyed. +*/ +void TChunkCleanup::ChunkDestroyed(TChunkCleanup* aSelf) + { + DMyDevice* device = aSelf->iDevice; + // If we haven't been Cancelled... + if(device) + { + // Perform any cleanup action required. In this example we call a method + // on 'MyDevice' which encapsulates this. + device->ChunkDestroyed(); + } + + // We've finished so now delete ourself + delete aSelf; + } +

Implementation notes

    +
  • The DFC is an item of +information that is passed to Kern::ChunkCreate() when +the shared chunk is created. See Example: +Creating a shared chunk to see how the two sets of code connect.

  • +
  • Ensure that the code +implementing this DFC is still loaded when the DFC runs. As you cannot know +when a chunk will be destroyed, the code should reside in a kernel extension.

  • +

Example: committing +memory

This code snippet shows how memory is committed. It is +based on the implementation of the class DBuffers, which +represents a group of buffers hosted by a single chunk.

/** + Class representing a group of buffers in the same chunk +*/ +class DBuffers + { +public: + DBuffers(); + ~DBuffers(); + TInt Create(TInt aBufferSize,TInt aNumBuffers); +public: + DChunk* iChunk; /**< The chunk containing the buffers. */ + TLinAddr iChunkKernelAddr; /**< Address of chunk start in kernel process */ + TUint32 iChunkMapAttr; /**< MMU mapping attributes used for chunk */ + TInt iBufferSize; /**< Size of each buffer in bytes */ + TInt iOffsetToFirstBuffer; /**< Offset within chunk of the first buffer */ + TInt iOffsetBetweenBuffers; /**< Offset in bytes between consecutive buffers */ + }; /** Constructor */ +DBuffers::DBuffers() + : iChunk(NULL) + {} + +/** Destructor */ +DBuffers::~DBuffers() + { + if(iChunk) Kern::ChunkClose(iChunk); + } + +/** + Create the chunk and commit memory for all the buffers. + @param aBuffserSize Size in bytes of each buffer + @param aNumBuffers Number of buffers to create +*/ +TInt DBuffers::Create(TInt aBufferSize,TInt aNumBuffers) + { + // Round buffer size up to MMU page size + aBufferSize = Kern::RoundToPageSize(aBufferSize); + iBufferSize = aBufferSize; + + // Size of one MMU page + TInt pageSize = Kern::RoundToPageSize(1); + + // We will space our buffers with one empty MMU page between each. + // This helps detect buffer overflows... + + // First buffer starts one MMU page into chunk + iOffsetToFirstBuffer = pageSize; + + // Each buffer will be spaced apart by this much + iOffsetBetweenBuffers = aBufferSize+pageSize; + + // Calculate chunk size + TUint64 chunkSize = TUint64(iOffsetBetweenBuffers)*aNumBuffers+pageSize; + + // Check size is sensible + if(chunkSize>(TUint64)KMaxTInt) + return KErrNoMemory; // Need more than 2GB of memory! + + // Enter critical section whilst creating objects + NKern::ThreadEnterCS(); + + // Create the chunk + TChunkCreateInfo info; + info.iType = TChunkCreateInfo::ESharedKernelMultiple; + info.iMaxSize = (TInt)chunkSize; + info.iMapAttr = EMapAttrCachedMax; // Full caching + info.iOwnsMemory = ETrue; // Use memory from system's free pool + info.iDestroyedDfc = NULL; + TInt r = Kern::ChunkCreate(info, iChunk, iChunkKernelAddr, iChunkMapAttr); + if(r==KErrNone) + { + // Commit memory for each buffer... + + TInt offset = iOffsetToFirstBuffer; // Offset within chunk for first buffer + + // Repeat for each buffer required... + while(aNumBuffers--) + { + // Commit memory at 'offset' within chunk + r = Kern::ChunkCommit(iChunk,offset,aBufferSize); + if(r!=KErrNone) + break; + + // Move 'offset' on to next buffer + offset += iOffsetBetweenBuffers; + } + + if(r!=KErrNone) + { + // On error, throw away the chunk we have created + Kern::ChunkClose(iChunk); + iChunk = NULL; // To indicate that 'this' doesn't have any valid buffers + } + } + + // Finished + NKern::ThreadLeaveCS(); + return r; + } +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-51C5DC6C-0CEE-5F44-8578-AEFBEF90FA4D.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-51C5DC6C-0CEE-5F44-8578-AEFBEF90FA4D.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,226 @@ + + + + + +READIMAGE +

READIMAGE is a command-line tool that provides readable data from +a ROM, ROFS, or E32 image. It can also generate an IBY file from a +SIS file which can be used to generate a data drive image.

+
Command +syntax

Run the following command to use the READIMAGE tool:

readimage [options] <image filename> or <SIS +filename>

where:

    +
  • <image +filename> is an input image file

  • +
  • <sis +filename> is an input .sis file.

  • +

Reading ROM, ROFS and E32 images

Run the following +command to read a ROM, ROFS, or E32 image:

readimage +options <ROM/ROFS/E32 imagefile>

The command +line options are as follows:

+ + + +Options +Description + + + + +

-o

+

Indicates output file name.

+
+ +

-d

+

Displays header information about the input image.

+
+ +

-s

+

Displays the directory structure of the input image.

+
+ +

-v

+

Displays image headers and the directory structure of the +input image.

+
+ +

-e

+

Displays the E32 image from the input ROM or ROFS image.

+
+ +

-h

+

Displays help information.

+
+ +

-z <path>

+

Extracts all files from the given image to the specified +location.

+
+ +

-l <logfile name>

+

Logs the image contents in a file.

+
+ +

-x <pattern>

+

Extracts a single or a set of files from a ROM or ROFS image +into the current directory. The pattern contains set of file names. +For more information about <pattern>, see Extracting a set of files.

+
+ +

-r

+

Recursively extracts the files from ROM or ROFS image. This +option is always used with the -x option.

+
+ + +

Note: Options are not case-sensitive. READIMAGE +reports an error if an argument is not passed for the -x or -z option.

Extracting one file

The command below +extracts all the files from sample.img to the C:\test location.

readimage -z C:\test\ +sample.img

Extracting a set of files with +wildcard ?

The READIMAGE tool provides the -x option +to extract one or more files from a ROM or ROFS image, based on a +pattern that matches the name of the file. A question mark(?) indicates +to match one instance of any character in a file name, within the +directory.

The command below extracts all the .exe files from the \sys\bin directory present in +the sample.img file, whose file name consists +of two characters.

readimage -x \sys\bin\??.exe +sample.img

Extracting a set of files with +wildcard *

The READIMAGE tool provides the -x option +to extract one or more files from a ROM or ROFS image, based on a +pattern that matches the name of the file. A star sign(*) indicates +to match zero or more instances of any character in a file name, within +the directory.

The command below extracts all the .exe files from the \sys\bin directory present in the sample.img file, into the current directory.

readimage -x \sys\bin\*.exe sample.img

The command +below extracts all the .exe files from the \sys\bin +directory present in the sample.img file, into +the C:\test location.

readimage -x \sys\bin\*.exe +-z C:\test sample.img

The command below extracts +all the .dll files from the \sys\bin\ directory and its sub-directories +present in the sample.img file, into the current directory.

readimage -x \sys\bin\*.dll -r sample.img

Generating an IBY file from a SIS file

Run the +following command to generate an .iby file from +a .sis file:

readimage -sis2iby +[-tmpdir <path> -outdir <path>] <sisfile>

The following command-line options are supported when generating +an .iby file from a .sis file:

+ + + +Options +Description + + + + +

<sisfile>

+

Input .sis file.

+
+ +

-sis2iby

+

Used to generate .iby file for the +given .sis file.

+
+ +

-tmpdir <path>

+

Extracts contents of the .sis file +to the specified directory.

+
+ +

-outdir <path>

+

Generates .iby file in the specified +directory.

+
+ + +

To generate an .iby file from the +given .sis file, READIMAGE performs the steps +as follows:

    +
  1. Reports an error +if the .sis file is invalid or missing.

  2. +
  3. Extracts the +contents of the .sis file into a specified directory, +or the current directory if the path is not specified. A .pkg script file is extracted from the sis file.

  4. +
  5. Creates an .iby file in the specified directory or the current directory +based on the .pkg file.

  6. +

The .sis file is created using the package +(PKG) script file. A .pkg file is a text file +containing statements that define the information needed by the installation +(.sis ) file creation utility, MAKESIS.

For more information about creating .sis file, +see MakeSIS Installation file generator syntax. For more information on the +.pkg file format, see PKG File in +the Symbian +C++ Developer Library.

READIMAGE extracts the .pkg file from the .sis file. It +then uses the .pkg file as input to generate +the .iby file.

Languages and Package-header +section

The details of Languages and Package-header +sections are written in the .iby file as comments.

    +
  • .pkg file

    &EN +# {"HelloWorld application"}, (0xe8000091), 1, 0, 0, TYPE=SA
  • +
  • .iby file

    // Generated IBY file for the package file: \dump\hwapp\hwapp.pkg +// Languages: EN +// Header: "HelloWorld application" (0xe8000091)
  • +

Install-file section

In the Install-file +section, the standard installation files, which are specified with +the installation option FF, are written using the FILE or DATA OBEY file keywords. The File keyword is used if the file is an E32 image, Otherwise, +the Data keyword is used.

    +
  • .pkg file

    "file0" - "!:\sys\bin\HelloWorld.exe", FF, VR +"file1" - "!:\private\<process SID>\Apps\AGENDA\Ericsson.txt", FF, VR
  • +
  • .iby file

    file = "\test\dump\hwapp\file0" "\sys\bin\HelloWorld.exe" +data = "\test\dump\hwapp\sis0\file1" "\private\<process SID>\Apps\AGENDA\Ericsson.txt"
  • +

Embedded-SIS section

The details of +the Embedded-SIS section are written using #include pre-processor directive.

    +
  • .pkg file

    @"sis0.sis", (0x101f7771) +@"sis1.sis", (0x101f7773)
  • +
  • .iby file

    #include "sis0.sis" +#include "sis1.sis"
  • +

Conditions-block section

In the Conditions-block +section, the IF statements are written using the #if - #else +- #endif pre-processor directive block.

The condition-primitives +and the functions in the .pkg file are written +as pre-processor macros.

The relational and logical operator +keywords are written using the appropriate operators.

    +
  • .pkg file

    ;Display 2 options to the user +! ({"Option1", "Option1"}, {"Option2", "Option2"}) +;Conditional installation +IF option1 + "file0" - "!:\private\10000005\import\InstTest\option1.txt"; +ENDIF +IF option2 + "file0" - "!:\private\10000005\import\InstTest\option2.txt"; +ENDIF +;Conditional installation +IF (MANUFACTURER) = (1) + "file1" - "!:\sys\bin\HelloWorld.exe" +ELSEIF (MANUFACTURER) = (4) + "file1" - "!:\sys\bin\HelloWorld1.exe" +ELSE + "file1" - "!:\sys\bin\HelloWorld2.exe" +ENDIF + +
  • +
  • .iby file

    //Install Options: "OPTION1" "OPTION1" "OPTION2" "OPTION2" +#if defined (option1) + data = "s:\test\hwapp\file0" +"\private\10000005\import\InstTest\option1.txt"; +#endif +#if defined (option2) + data = "s:\test\hwapp\file0" +"\private\10000005\import\InstTest\option2.txt"; +#endif + +#if (MANUFACTURER) = (1) + file = "s:\test\hwapp\file1" "\sys\bin\HelloWorld.exe" +#elseif (MANUFACTURER) = (4) + file = "s:\test\hwapp\file1" "\sys\bin\HelloWorld1.exe" +#else + file = "s:\test\hwapp\file1" "\sys\bin\HelloWorld2.exe" +#endif
  • +

Note: Using the .iby file with +the condition-block statements for the creation of ROM and ROFS images +needs appropriate macro definitions. For the preceding examples, the +macros are defined as follows:

#define option1 //selecting option1 block +#define MANUFACTURER 4 //selecting second conditional block
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-52583CC7-483E-54B5-8094-F0F61BD46B7F.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-52583CC7-483E-54B5-8094-F0F61BD46B7F.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,105 @@ + + + + + +Configuration: Attribute Definition FilesDescribes the format of configuration files. +

The attributes that can be used on a device are defined in two +configuration files. .

+
Config.hcf +file

The purpose of this file, config.hcf, is to define the attributes that have meaning on this hardware. It specifies +whether attributes:

    +
  • are read-only

  • +
  • can be read +and written

  • +
  • are simply stored +by the HAL - the non-derived attributes

  • +
  • require calls +to other components to obtain or set their values - the derived attributes.

  • +

The file must be created in the ...\Variant\hal\... directory.

Note that:

    +
  • all supported +attributes must have an entry in the Config file config.hcf

  • +
  • all non-derived +attributes also need an entry in theValues file values.hda.

  • +

The build system uses the Perl script halcfg.pl to convert text information in the Config file into a C++ source +file before the C++ compiler is invoked. The generated binary maps +to the data members defined in the HalInternal class. Note that this class is internal to Symbian.

After initial +implementation, any changes to the files will be picked up by the +supplied makefile, ...\hal\config.mke. The necessary +changes are made to the generated config.cpp file +when the HAL is built.

Any additional functions must be added +to the implementation file by hand, e.g. in a file called imp.cpp. However, this would be unusual because all likely +functions are already implemented in ...\hal\src\userhal.cpp.

The config file consists of a number of lines of text in +the form:

<attrib> [:<prop1>, <prop2>, ...] = <implementation>

where the pair of square brackets indicates optional items.

<attrib>

This is one of the values of the enumeration HALData::TAttribute in the source file ...\hal\inc\hal_data.h

<prop1>, <prop2>,...

These are optional property +specifications defined by the enumeration HALData::TAttributeProperty in the source file ...\hal\inc\hal_data.h. +Where more than one property is specified, they are separated by commas. +If specified, the initial colon is required. Currently, only the two +properties EValid and ESettable are defined. Note that any substring which is not ambiguous within +the enumerated type is acceptable; matching is not case sensitive.

The property EValid is defined implicitly +for all attributes that appear in the Config file. It indicates that +the attribute is meaningful on this platform. Attributes that do not +appear in the Config file do not have this property, and calls to HAL::Get() or HAL::Set() which refer +to those attributes return KErrNotSupported.

The property ESettable, means that an attribute +is modifiable. Calls to HAL::Set() for attributes +without this property return KErrNotSupported.

<implementation>

Defines whether an attribute is derived. It can be:

    +
  • 0, which means +that the specified attribute is not derived, but is just a constant +stored by the HAL.

  • +
  • the name of +a function used to implement HAL::Get() and HAL::Set() for that specified attribute.

  • +

Comments

The order in which attributes are defined +is not important. Comments may be included by starting a line with +//. A comment must be on its own line and cannot be appended +to an attribute specification.

+
Values.hda +file

The purpose of this file, values.hda, is to specify the initial values of the non-derived attributes, those attributes which are simply stored in, and +retrieved from, the HAL. It must be created in the ...\variant\hal\... directory.

The build system uses the Perl script halcfg.pl to convert text information in the Values file +into a C++ source file before the C++ compiler is invoked.

After initial implementation, any changes to the file will be picked +up by the supplied makefile, ...\hal\config.mke. The necessary changes are made to the generated values.cpp file when the HAL is built.

Any additional functions must +be added to the implementation file by hand, e.g. in a file called imp.cpp. However, this would be unusual because all likely +functions are already implemented in ...\hal\src\userhal.cpp.

The values file consists of a number of lines of text in +the form:

<attrib> = <value>

<attrib>

This is one of the values of the enumeration HALData::TAttribute defined in the header file ...\hal\inc\hal_data.h.

<value>

This is the initial value of the attribute. +It may be specified in various ways, but depends on the attribute, +and may be one of the following:

    +
  • a decimal integer +constant

  • +
  • a hexadecimal +integer constant, by prepending 0x

  • +
  • an enumerated +value for those attributes that have a corresponding enumeration in ...\hal\inc\hal_data.h. Note that any substring which +is not ambiguous within the enumerated type is acceptable; matching +is not case sensitive. For example, intel would be +an acceptable abbreviation for EManufacturer_Intel in the enumeration HALData::TManufacturer.

  • +
  • bit1 ++ bit2 + ... + bitn, for those attributes with corresponding +bitmask enumerations in ...\hal\inc\hal_data.h, and declared with the bitmask pseudo-keyword. bit1, bit2 etc. are values of the enumeration. +Any substring which is not ambiguous within the bitmask type is acceptable +and matching is not case sensitive.

  • +

Comments

The order in which attributes are defined +is not important. Comments may be included by starting a line with +//. A comment must be on its own line and cannot be appended +to an attribute specification.

Attributes EMachineUid and EManufacturer should be allocated UID values +in the normal way. These values should be placed in the values file +and in product specific header files, not in ...\hal\inc\hal_data.h.

+
Example +of a non-derived attribute

A line similar to the following +in the values.hda file defines the machine Uid +to the HAL, and shows how a value is paired to an attribute.

EMachineUid= 0x1000a682

A line similar to the following in the config.hcf file indicates that the value is not derived but is simply stored +by the HAL.

EMachineUid= 0
+
Example +(1) of a derived attribute

The following line in the config.hcf file shows how to configure the API for the +display contrast. This states that the display contrast is settable, +and that the function to do this is called ProcessDisplayContrast.

EDisplayContrast : set = ProcessDisplayContrast
+
Example +(2) of a derived attribute

The following lines in the config.hcf file shows how to configure the API for the +display size.

EDisplayXPixels=ProcessDisplayCurrentModeInfo +EDisplayYPixels=ProcessDisplayCurrentModeInfo

This +is read only information, so the entries do not contain the "set" +keyword. The values are derived via the API function ProcessDisplayCurrentModeInfo, and there is no corresponding entry in values.hda.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-52702561-DA37-5381-BA0D-76D9A41B2760.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-52702561-DA37-5381-BA0D-76D9A41B2760.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,274 @@ + + + + + +ROFSBUILD Obey File StructureA ROFSBUILD obey file consists of a number +of sections, each defining a ROFS image. +

A ROFS image is used to store code that is not part of the Core +OS section. The File Server uses ROFS (the Read-Only File System) +to access this, and ROFS uses a Media Driver to read the data from +the NAND Flash device and to load this into RAM for access or execution. +The Composite File System combines this media area with the Core OS +media area and presents the two as a single read-only drive Z:.

+

A ROFS image contain the following main sections:

+
    +
  • a CoreImage section that specifies the existing core image to be used as the +base for generating the extension image.

  • +
  • an ExtensionRomSection that defines the ROM image that extends the core image.

  • +
+

The structure is defined as:

+ObeyFile : CoreImageStatement [ ExtensionRomSection ] +CoreImage : coreimage = <CoreImageFileName> +ExtensionRomSection : ObeyStatementList +ObeyStatementList : ObeyStatement | ObeyStatement ObeyStatementList +ObeyStatement : RomStatement | FileStatement +
    +
  • See RomStatement

  • +
  • See FileStatement

  • +
  • See coreimage keyword

  • +
+
RomStatement

A RofsStatement is one of the following:

+ + + +

autosize =

+

<block-size>

+
+ +

extensionrofs

+

+
+ +

extensionrofsname =

+

<filename>

+
+ +

externaltool =

+

<toolname>

+
+ +

rofsname =

+

<filename>

+
+ +

rofsize =

+

<size-in-bytes>

+
+ +

version =

+

[ <major> ] [ .<minor> ] [ (<build>) + ]

+
+ +

romsize =

+

<hex-size>

+
+ +

romchecksum =

+

<base-checksum>

+
+ +

time =

+

dd/mm/yyyy hh:mm:ss

+
+ +

trace =

+

<32bit-hex-number>

+
+ +

pagingoverride

+

[NOPAGING | ALWAYSPAGE | DEFAULTUNPAGED | + DEFAULTPAGED]

+
+ +

pagingpolicy

+

[NOPAGING | ALWAYSPAGE | DEFAULTUNPAGED | + DEFAULTPAGED]

+
+ +

patchdata =

+

<DLLname>@<symbolname> <newvalue>

+
+ +codepagingpolicy +

[NOPAGING | ALWAYSPAGE | DEFAULTUNPAGED | DEFAULTPAGED]

+
+ +datapagingpolicy +

[NOPAGING | ALWAYSPAGE | DEFAULTUNPAGED | DEFAULTPAGED]

+
+ +codepagingoverride +

[NOPAGING | ALWAYSPAGE | DEFAULTUNPAGED | DEFAULTPAGED]

+
+ +datapagingoverride +

[NOPAGING | ALWAYSPAGE | DEFAULTUNPAGED | DEFAULTPAGED]

+
+ +dataimagename = +

<image name>

+
+ +dataimagefilesystem = +

<FAT16 | FAT32>

+
+ +dataimagesize = +

<size in bytes>

+
+ +volume = +

<volume label>

+
+ +sectorsize = +

<size in bytes>

+
+ +fattable = +

<number of FAT tables>

+
+ + +
+
FileStatement FileStatement : FileSpecificationStatement | ControlStatement | RomDirectoryStatement

A ControlStatement is one of the following:

+ + + +

rem

+

<comments>

+
+ +

stop

+

+
+ + +

A FileSpecificationStatement is one of +the following:

+ + + +

data[[HWVD]] =

+

<Source-file> <destination-file> [ FileAttributeList ]

+
+ +

file[[HWVD]] =

+

<Source-file> <destination-file> [ FileAttributeList] [OverrideAttributeList ] [paged | +unpaged]

+
+ +

filecompress[[HWVD]] =

+

<source-file> <destination-image-file> [FileAttributeList][OverrideAttributeList]

+
+ +

fileuncompress[[HWVD]] =

+

<source-file> <destination-image-file> [FileAttributeList][OverrideAttributeList]

+
+ + +

A RomDirectoryStatement is one of the +following:

+ + + +

hide[[HWVD]] =

+

<existing-file>

+
+ +

alias[[HWVD]] =

+

<existing-file> <destination-file> + [ FileAttributeList ]

+
+ +

rename[[HWVD]] =

+

<existing-file> <destination-file> [ FileAttributeList ]

+
+ + +
+
FileAttributeList FileAttributeList : FileAttribute | FileAttribute FileAttributeList

A FileAttribute is one of the following:

+ + + +

attrib =

+

[ s | S ][ h | H ][ r | R | w | W ] | hide

+
+ +

exattrib =

+

U

+
+ + +
+
OverrideAttributeList

OverrideAttributeList : OverrideAttribute | OverrideAttribute OverrideAttributeList

An overrideAttribute is one of the following:

+ + + +capability = +

<capability>

+
+ +paged + + + +unpaged + + + +pagedcode + + + +unpagedcode + + + +pageddata + + + +unpageddata + + + +

stack =

+

<hex-size>

+
+ +

heapmin =

+

<hex-size>

+
+ +

heapmax =

+

<hex-size>

+
+ +

priority =

+

<hex-number> | <keyword>

+
+ +

uid1 =

+

<uid value>

+
+ +

uid2 =

+

<uid value>

+
+ +

uid3 =

+

<uid value>

+
+ + +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-529757E6-ABF2-5C5C-A995-7DED6D298F52.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-529757E6-ABF2-5C5C-A995-7DED6D298F52.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,76 @@ + + + + + +DesignThis topic describes how to design the USB client controller +for different types of USB hardware. +

On most hardware platforms, the variant is split into a common, +or ASSP, layer and a device specific, or variant, layer; for example, +the Symbian port for the template board is split into a core layer +for the ASSP (in ...\template_assp\...) and code +specific to the template board (in ...\template_variant\...).

+

On some hardware configurations, the USB platform-specific layer +functionality is not only dependent on the USB device controller (in +the ASSP) but also on the variant. As an example, the USB cable connection/disconnection +notification mechanism is not defined in the USB specification. This +means that some USB device controllers have a mechanism for detecting +the status of a cable connection that is internal to the ASSP, while +for other controllers the mechanism is variant specific, and requires +software support in the variant layer.

+

In the template example port, the ASSP layer is implemented by +the TemplateAssp class defined in ...\template_assp\template_assp_priv.h. This class defines a number of pure virtual functions that act +as the interface to the cable connection status mechanism.

+class TemplateAssp : public Asic + { + + ... + /** + * USB client controller - Some example functions for the case that USB cable detection and + * UDC connect/disconnect functionality are part of the variant. + * Pure virtual functions called by the USB PSL, to be implemented by the variant (derived class). + * If this functionality is part of the ASSP then these functions can be removed and calls to them + * in the PSL (./pa_usbc.cpp) replaced by the appropriate internal operations. + */ + virtual TBool UsbClientConnectorDetectable()=0; + virtual TBool UsbClientConnectorInserted()=0; + virtual TInt RegisterUsbClientConnectorCallback(TInt (*aCallback)(TAny*), TAny* aPtr)=0; + virtual void UnregisterUsbClientConnectorCallback()=0; + virtual TBool UsbSoftwareConnectable()=0; + virtual TInt UsbConnect()=0; + virtual TInt UsbDisconnect()=0; + +

In the template example port, the variant layer is implemented +by the Template class defined in ...\template_variant\inc\variant.h. The variant layer provides the implementation for these USB pure +virtual functions.

+NONSHARABLE_CLASS(Template) : public TemplateAssp + { + + ... + /** + * USB client controller - Some example functions for the case that USB cable detection and + * UDC connect/disconnect functionality are part of the variant. + * These virtual functions are called by the USB PSL (pa_usbc.cpp). + * If this functionality is part of the ASSP then these functions can be removed as calls to them + * in the PSL will have been replaced by the appropriate internal operations. + */ + virtual TBool UsbClientConnectorDetectable(); + virtual TBool UsbClientConnectorInserted(); + virtual TInt RegisterUsbClientConnectorCallback(TInt (*aCallback)(TAny*), TAny* aPtr); + virtual void UnregisterUsbClientConnectorCallback(); + virtual TBool UsbSoftwareConnectable(); + virtual TInt UsbConnect(); + virtual TInt UsbDisconnect(); + +

The implementation for these functions can be found in ...\template_variant\specific\variant.cpp.

+

The USB port also needs interrupt handling code to deal with USB +external interrupts. See the Interrupt Dispatcher +Tutorial for details about how to do this.

+This may be done by others as a specialist porting activity. +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-52B8098A-7695-5EA6-B58F-D730A445C583-master.png Binary file Adaptation/GUID-52B8098A-7695-5EA6-B58F-D730A445C583-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-52B8098A-7695-5EA6-B58F-D730A445C583_d0e77443_href.png Binary file Adaptation/GUID-52B8098A-7695-5EA6-B58F-D730A445C583_d0e77443_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-535C66C9-8B45-4DF3-8404-8ED03ABB4799-GENID-1-2-1-10-1-5-1-9-1-1-7-1-4-1-11-1.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-535C66C9-8B45-4DF3-8404-8ED03ABB4799-GENID-1-2-1-10-1-5-1-9-1-1-7-1-4-1-11-1.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,78 @@ + + + + + +TSDIOInterrupt +Class TutorialDescribes the TSDIOInterrupt API class. +
Description

The TSDIOInterrupt class +provides the client with the ability to enable, disable, bind and unbind to +an SDIO interrupt. There is no Clear() method provided as it is the responsibility +of the client device driver to clear the appropriate interrupt through its DSDIORegInterface class +documented here.

+ + + +

Header file

+

interrupt.h

+
+ +

Source code file

+

interrupt.cpp

+
+ +

Required libraries

+

epbussdio.lib

+
+ +

Class declaration

+

class TSDIOInterrupt

+
+ + +
+
Bind()

The +function declaration for the Bind() method is:

IMPORT_C TInt Bind(TSDIOIsr aIsr, TAny* aPtr);

Description

Binds the TSDIOIsr callback to the function's interrupt. +Once bound, the interrupt should be enabled for the function by a call to +Enable().

Parameters

+ + + +

TSDIOIsr aIsr

+The ISR used to handle the function's interrupt. +
+ +

TAny* aPtr

+User defined data for use within the ISR. +
+ + +

Return value

KErrNone if successful, KErrAlreadyExists if +an ISR already bound to the function's interrupt, or a standard Symbian platform +error code.

+
Unbind()

The +function declaration for the Unbind() method is:

IMPORT_C TInt Unbind();

Description

Unbinds +the callback from the interrupt controller, replacing the callback with a +dummy handler.

Parameters

None.

Return value

KErrNone if +successful, otherwise a standard Symbian platform error code.

+
Enable()

The +function declaration for the Enable() method is:

IMPORT_C TInt Enable();

Description

Enables +the function's interrupt by setting the appropriate IEN bit in the CCCR. Note +that this only unmasks the global function interrupt. It is the responsibility + of the client to perform any function-specific interrupt enabling that may +be required.

Parameters

None.

Return value

KErrNone if +successful, otherwise a standard Symbian platform error code.

+
Disable()

The +function declaration for the Disable() method is:

IMPORT_C TInt Disable();

Description

Disables the function's interrupt by clearing the appropriate IEN bit in +the CCCR. Note that this only masks the global function interrupt. It is +the responsibility of the client to perform any function-specific interrupt +disabling that may be required.

Parameters

None.

return +value

KErrNone if successful, otherwise a standard +Symbian platform error code.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-535C66C9-8B45-4DF3-8404-8ED03ABB4799-GENID-1-2-1-10-1-5-1-9-1-1-7-1-4-1-4-1.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-535C66C9-8B45-4DF3-8404-8ED03ABB4799-GENID-1-2-1-10-1-5-1-9-1-1-7-1-4-1-4-1.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,78 @@ + + + + + +TSDIOInterrupt +Class TutorialDescribes the TSDIOInterrupt API class. +
Description

The TSDIOInterrupt class +provides the client with the ability to enable, disable, bind and unbind to +an SDIO interrupt. There is no Clear() method provided as it is the responsibility +of the client device driver to clear the appropriate interrupt through its DSDIORegInterface class +documented here.

+ + + +

Header file

+

interrupt.h

+
+ +

Source code file

+

interrupt.cpp

+
+ +

Required libraries

+

epbussdio.lib

+
+ +

Class declaration

+

class TSDIOInterrupt

+
+ + +
+
Bind()

The +function declaration for the Bind() method is:

IMPORT_C TInt Bind(TSDIOIsr aIsr, TAny* aPtr);

Description

Binds the TSDIOIsr callback to the function's interrupt. +Once bound, the interrupt should be enabled for the function by a call to +Enable().

Parameters

+ + + +

TSDIOIsr aIsr

+The ISR used to handle the function's interrupt. +
+ +

TAny* aPtr

+User defined data for use within the ISR. +
+ + +

Return value

KErrNone if successful, KErrAlreadyExists if +an ISR already bound to the function's interrupt, or a standard Symbian platform +error code.

+
Unbind()

The +function declaration for the Unbind() method is:

IMPORT_C TInt Unbind();

Description

Unbinds +the callback from the interrupt controller, replacing the callback with a +dummy handler.

Parameters

None.

Return value

KErrNone if +successful, otherwise a standard Symbian platform error code.

+
Enable()

The +function declaration for the Enable() method is:

IMPORT_C TInt Enable();

Description

Enables +the function's interrupt by setting the appropriate IEN bit in the CCCR. Note +that this only unmasks the global function interrupt. It is the responsibility + of the client to perform any function-specific interrupt enabling that may +be required.

Parameters

None.

Return value

KErrNone if +successful, otherwise a standard Symbian platform error code.

+
Disable()

The +function declaration for the Disable() method is:

IMPORT_C TInt Disable();

Description

Disables the function's interrupt by clearing the appropriate IEN bit in +the CCCR. Note that this only masks the global function interrupt. It is +the responsibility of the client to perform any function-specific interrupt +disabling that may be required.

Parameters

None.

return +value

KErrNone if successful, otherwise a standard +Symbian platform error code.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-535E5C2A-DCFD-4BCB-B26B-11E88BDB8A8A.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-535E5C2A-DCFD-4BCB-B26B-11E88BDB8A8A.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,295 @@ + + + + + +TDmac Derived Class ImplementationImplementing the hardware-specific DMA controller. +

The TDmac class is part of the PIL. It is a +container for the DMA controller's channels, descriptors and descriptor +headers. It also defines virtual functions for operations that require +a PSL implementation.

+

You need to derive TDmac for each distinct type +of DMA controller on your device, and implement these virtual functions.

+

+ + + +Function +Mandatory/Conditional +Description + + + + +Transfer() +Mandatory +For single buffer and scatter/gather, this starts the DMA transfer. +For double buffer, this prepares the next fragment to transfer while +a current transfer is in operation + + +StopTransfer() +Mandatory +Stop the specified channel synchronously. Must not return to +the PSL implementation until the channel has stopped. + + +IsIdle() +Mandatory +Returns ETrue if specified channel is idle, +otherwise EFalse + + +MaxTransferSize() +Optional +Takes the parameters and evaluates the maximum transfer size +in bytes. + + +MemAlignMask() +Optional +This applies to DMA v1 only. + + +InitHwDes() +Optional +For scatter-gather, initialise the array of memory areas and +set up the first block of data to be transferred. + + +ChainHwDes() +Optional +For scatter-gather, add additional blocks of data to transfer +to the list of memory areas. + + +AppendHwDes() +Optional +For scatter-gather, add to the array of memory areas while +the transfer is active. This is used in particular for streaming data +where new descriptors can be added to the end of the chain while data +earlier in the train is being transferred. E.g. video streaming. + + +UnlinkHwDes() +Optional +For scatter-gather, remove items from the array of memory areas. + + +FailNext() +Optional +For a sequence of memory transfers, tell the next one to fail. + + +MissNextInterrupts() +Optional +DMA transfers start on the next interrupt, but sometimes you +want to skip the next interrupt for synchronisation or other reasons. + + +Extension() +Optional +Pass a command from the application/client down to the DMA +chipset. Hardware dependent. + + + +

+
Implement +the mandatory controller virtual functions

The TDmac class contains several pure virtual functions that +must be implemented by the PSL implementation:

    +
  • TDmac::Transfer()
  • +
  • TDmac::StopTransfer()
  • +
  • TDmac::IsIdle()
  • +

These functions start and stop transfers on a DMA channel +and are the main interface between the PIL and the PSL. The implementation +of these functions depends on the hardware available for performing +DMA, and on the characteristics used to specify a DMA transfer:

    +
  • the source and +destination addresses
  • +
  • the burst size
  • +
  • the maximum transfer +size
  • +
  • the transfer width, +i.e. number of bits per memory access
  • +
  • the memory alignment +and endianness.
  • +

The DMA Framework manages the transfer descriptors according +to the descriptor parameter passed into the TDmac constructor by the derived class constructor; the descriptor parameter +is a TDmac::SCreateInfo structure. The per-request +transfer parameters are passed into the descriptors for each request +issued by a driver.

+
The +transfer function: Transfer()

This function initiates a +previously constructed request on a specific channel. This is the +template implementation:

+void TTemplateDmac::Transfer(const TDmaChannel& aChannel, const SDmaDesHdr& aHdr) +// +// Initiates a (previously constructed) request on a specific channel. +// + { + const TUint8 i = static_cast&<TUint8&>(aChannel.PslId()); + TDmaDesc* pD = HdrToHwDes(aHdr); + + __KTRACE_OPT(KDMA, Kern::Printf("&>TTemplateDmac::Transfer channel=%d des=0x%08X", i, pD)); + + // Load the first descriptor address into the DMAC and start it + // by setting the RUN bit. + (void) *pD, (void) i; + + } +
+
The +stop transfer function: StopTransfer()

This is the template +implementation:

void TTemplateDmac::StopTransfer(const TDmaChannel& aChannel) +// +// Stops a running channel. +// + { + const TUint8 i = static_cast&<TUint8&>(aChannel.PslId()); + + __KTRACE_OPT(KDMA, Kern::Printf("&>TTemplateDmac::StopTransfer channel=%d", i)); + + } +
+
The +function: IsIdle()

IsIdle() returns +the state of a given channel. This is the template implementation:

TBool TTemplateDmac::IsIdle(const TDmaChannel& aChannel) +// +// Returns the state of a given channel. +// + { + const TUint8 i = static_cast&<TUint8&>(aChannel.PslId()); + + __KTRACE_OPT(KDMA, Kern::Printf("&>TTemplateDmac::IsIdle channel=%d", i)); + + return ETrue; + } +
+
Implement +the non-mandatory controller virtual functions

The following +auxiliary functions are used to implement the scatter-gather transfer +mode behavior by creating and manipulating the linked list of transfer +fragment headers that describe a given scatter-gather transaction. +They are called by the TDmac base class functions +when the instance of the TDmac derived class reports +itself as being capable of scatter-gather operations.

    +
  • TDmac::InitHwDes()
  • +
  • TDmac::ChainHwDes()
  • +
  • TDmac::AppendHwDes()
  • +
+
First +scatter-gather support function: InitHwDes()

This is a +function for creating a scatter-gather list. From the information +in the passed-in request, the function sets up the descriptor with +that fragment's:

    +
  • source and destination +address
  • +
  • size
  • +
  • driver/DMA controller +specific transfer parameters: memory/peripheral, burst size, transfer +width.
  • +

This is the template implementation:

void TTemplateDmac::InitHwDes(const SDmaDesHdr& aHdr, TUint32 aSrc, TUint32 aDest, TInt aCount, + TUint aFlags, TUint32 aPslInfo, TUint32 /*aCookie*/) +// +// Sets up (from a passed in request) the descriptor with that fragment's source and destination address, +// the fragment size, and the (driver/DMA controller) specific transfer parameters (mem/peripheral, +// burst size, transfer width). +// + { + TDmaDesc* pD = HdrToHwDes(aHdr); + + __KTRACE_OPT(KDMA, Kern::Printf("TTemplateDmac::InitHwDes 0x%08X", pD)); + + // Unaligned descriptor? Error in generic layer! + __DMA_ASSERTD(IsHwDesAligned(pD)); + + pD-&>iSrcAddr = (aFlags & KDmaPhysAddrSrc) ? aSrc : Epoc::LinearToPhysical(aSrc); + pD-&>iDestAddr = (aFlags & KDmaPhysAddrDest) ? aDest : Epoc::LinearToPhysical(aDest); + pD-&>iCmd = DcmdReg(aCount, aFlags, aPslInfo); + pD-&>iDescAddr = TDmaDesc::KStopBitMask; + } +
+
Second +scatter-gather support function: ChainHwDes()

If the framework +needs to fragment the client’s request, either because of the transfer +size or because the memory is not a single contiguous block, then +the framework calls this function. It chains hardware descriptors +together by setting the next pointer of the original descriptor to +the physical address of the descriptor to be chained. It assumes that +the DMAC channel is quiescent when called.

This is the template +implementation:

void TTemplateDmac::ChainHwDes(const SDmaDesHdr& aHdr, const SDmaDesHdr& aNextHdr) +// +// Chains hardware descriptors together by setting the next pointer of the original descriptor +// to the physical address of the descriptor to be chained. +// + { + TDmaDesc* pD = HdrToHwDes(aHdr); + TDmaDesc* pN = HdrToHwDes(aNextHdr); + + __KTRACE_OPT(KDMA, Kern::Printf("TTemplateDmac::ChainHwDes des=0x%08X next des=0x%08X", pD, pN)); + + // Unaligned descriptor? Error in generic layer! + __DMA_ASSERTD(IsHwDesAligned(pD) && IsHwDesAligned(pN)); + + pD-&>iDescAddr = DesLinToPhys(pN); + } +
+
Third +scatter-gather support function: AppendHwDes()

This function +is called by the TDmac base class when a driver +request is called for a channel that is still active, i.e. where the +intent is to provide data streaming so that the target device is constantly +provided with data; for example, an audio device playing a track. +In this case, the function provided by the derived class must:

    +
  • stop the DMAC to +prevent any corruption of the scatter-gather list while appending +the new fragment descriptor
  • +
  • append the new +descriptor
  • +
  • re-enable the channel, +ideally before the target has detected the gap in service.
  • +

This is the template implementation:

void TTemplateDmac::AppendHwDes(const TDmaChannel& aChannel, const SDmaDesHdr& aLastHdr, + const SDmaDesHdr& aNewHdr) +// +// Appends a descriptor to the chain while the channel is running. +// + { + const TUint8 i = static_cast&<TUint8&>(aChannel.PslId()); + + TDmaDesc* pL = HdrToHwDes(aLastHdr); + TDmaDesc* pN = HdrToHwDes(aNewHdr); + + __KTRACE_OPT(KDMA, Kern::Printf("&>TTemplateDmac::AppendHwDes channel=%d last des=0x%08X new des=0x%08X", + i, pL, pN)); + // Unaligned descriptor? Error in generic layer! + __DMA_ASSERTD(IsHwDesAligned(pL) && IsHwDesAligned(pN)); + + TPhysAddr newPhys = DesLinToPhys(pN); + + const TInt irq = NKern::DisableAllInterrupts(); + StopTransfer(aChannel); + + pL-&>iDescAddr = newPhys; + const TTemplateSgChannel& channel = static_cast&<const TTemplateSgChannel&&>(aChannel); + TDmaDesc* pD = channel.iTmpDes; + + (void) *pD, (void) i; + + NKern::RestoreInterrupts(irq); + + __KTRACE_OPT(KDMA, Kern::Printf("&<TTemplateDmac::AppendHwDes")); + } +
+
+DMA +Technology Guide +DMA +Implementation Guide +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-53649311-4465-48B5-8D07-A65515950040.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-53649311-4465-48B5-8D07-A65515950040.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,67 @@ + + + + + +Data +Transfer across Memory BoundariesThis document describes how to read from and write to user-side +memory from a kernel thread context or a user thread. +

When a driver reads or writes data from or to a user-side program, the +data must be copied between user address space and Kernel address space. The +Kernel provides a number of APIs that allow this to be done safely. The API +to use depends on whether the request is serviced in a user thread context, +or in a Kernel thread context.

+
From +kernel space

To read and write data to the user space from +a kernel thread context, use Kernel APIs such as Kern::ThreadDesRead(), Kern::ThreadRawRead(), Kern::ThreadDesWrite(), and Kern::ThreadRawWrite(). The data can be handled +as descriptors or as raw memory.

The Kernel also provides other APIs +to safely read the information about a descriptor in another thread's address +space. Kern::ThreadGetDesInfo() returns the length, maximum +length, and a pointer to the descriptor's buffer. The length and maximum length +can also be obtained specifically by using Kern::ThreadGetDesLength() and Kern::ThreadGetDesMaxLength().

TInt DExDriverLogicalChannel::DoControl(TInt aFunction, TAny* a1, TAny* /*a2*/) + { + ... + // To read the buffer descriptors from user space + r=Kern::ThreadDesRead(iClient,a1,iTxBuffer,0,0); + ... + // To write the buffer descriptors to user space + r=Kern::ThreadDesWrite(iClient,(TDes8*)a1,iRxBuffer,0); + ... + } // Read the descriptor maximum length from the user thread (iClient) +// using the kernel API Kern::ThreadGetDesMaxLength(). This API +// gets the maximum length of a descriptor in another thread's +// address space. Kern::ThreadGetDesInfo() can also be used to +// get length, maximum length and pointer to the descriptor's +// buffer. +// +iCount=Kern::ThreadGetDesMaxLength(iClient,aData);
+

From user space

When +executing a read or write operation in the context of a user thread, use the +following APIs:

    +
  • kumemget()

  • +
  • kumemput()

  • +
  • umemget()

  • +
  • umemput()

  • +

Kernel APIs are also available to do copy operations using descriptors:

    +
  • Kern::KUDesGet()

  • +
  • Kern::KUDesPut()

  • +
  • Kern::KUDesInfo()

  • +
  • Kern::KUdesSetLength()

  • +

Kern::InfoCopy() can be used to copy a descriptor +safely in a way that enables forward and backward compatibility. It is typically +used for copying capability packages.

void DExDriverLogicalDevice::GetCaps(TDes8& aCaps) const + { + // device capabilities are packaged to a buffer + TPckgBuf<RExDriver::TUartCaps> caps; + caps().iVersion=iVersion; + // Copy the device capabilities to the user thread using the + // Kernel API + Kern::InfoCopy(aCaps,caps); + }
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-5392507E-45FF-4B20-B257-E58E23685295-master.png Binary file Adaptation/GUID-5392507E-45FF-4B20-B257-E58E23685295-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-5392507E-45FF-4B20-B257-E58E23685295_d0e410_href.png Binary file Adaptation/GUID-5392507E-45FF-4B20-B257-E58E23685295_d0e410_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-53944506-5CA2-52BA-8D5A-9EE72092612B.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-53944506-5CA2-52BA-8D5A-9EE72092612B.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,28 @@ + + + + + +BootstrapDescribes what is the bootstrap and how to implement it for a specific +platform. +

The bootstrap is a program that the phone runs after a hardware reset. +The task of the bootstrap is to prepare a basic environment for the kernel +to run. If the phone uses NAND Flash, then the NAND Flash Core Loader loads +and starts the bootstrap.

+

Symbian platform divides the bootstrap into a platform-independent layer +that can be used with any ARM device, and a platform-specific layer that you +must implement when you create a new phone.

+
+Flash Translation +Layer Technology +Base Starter + +System Startup +Overview +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-54042C84-6216-5930-9CBF-BAF635CECD4D.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-54042C84-6216-5930-9CBF-BAF635CECD4D.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,62 @@ + + + + + +Power +HAL Handler TutorialUser-side programs can get and set a number of system attributes +about power using the HAL interface. +

The base port must provide and register a HAL handler to handle these attributes.

+

The power attributes are in the EHalGroupPower HAL group. +The handler provides a kernel-side implementation to deal with the user-side +calls to HAL::Get() and HAL::Set() when +one of the following parameters is passed:

+
    +
  • HALData::EPowerGood

  • +
  • HALData::EPowerBatteryStatus

  • +
  • HALData::EAccessoryPower

  • +
  • HALData::EPowerBackup

  • +
  • HALData::EPowerBackupStatus

  • +
  • HALData::EPowerExternal

  • +
  • HALData::EPenDisplayOn

  • +
  • HALData::ECaseSwitchDisplayOn

  • +
  • HALData::ECaseSwitchDisplayOff

  • +
+

A typical application will have a user side monitor that periodically calls HAL::Get(), +passing HALData::EPowerBatteryStatus to get the charge +level of the battery.

+

Typically, the handler is implemented as part of a DPowerHal derived +object, which is created by the entry point of the base port power kernel +extension. The object is, therefore, part of the power controller kernel extension.

+
Implementation +notes
    +
  • The DPowerHal derived +object constructor must register with the power manager by calling Register().

  • +
  • If there is some power-related +data that can be accessed via the HAL component and that persists through +power cycles (On/Off), it should be initialised here. Typically the TOnOffInfoV1 data +member of the Variant-specific TActualMachineConfig (usually +found in mconf.h file under the platform directory) contains +some of that persistent data.

  • +
  • The handler itself is +the function PowerHalFunction(), and must be fully implemented +in the base port.

  • +
  • The kernel hooks up +the handler to service the HAL functions at boot-time.

  • +
  • The power Hal functions +that the Handler can handle are enumerated by TPowerHalFunction. +Not all of these functions need to be handled. If not handled, the kernel +returns KErrNotSupported when the HAL function is called +with the relevant parameter. It is left to the base port to decide which functions +are relevant.

  • +
+
+ +User-Side Hardware Abstraction +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-552530EB-1287-542D-AED3-125387B485C1.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-552530EB-1287-542D-AED3-125387B485C1.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,59 @@ + + + + + +ArchitectureDescribes the architecture of the Digitizer Driver. +

The architecture has two layers:

+ + + + +

A platform-independent layer that:

+
    +
  • processes digitiser +samples

  • +
  • issues pen movement +events to the kernel

  • +
  • maintains a buffer of +digitiser readings

  • +

This layer implements behaviour that can be expected to be the same +across all platforms.

Symbian provides this.

+
+ +

A platform specific layer that is responsible for:

+
    +
  • the conversion between +screen and digitiser coordinates

  • +
  • the implementation of +low level calibration

  • +
  • the gathering of raw +digitiser data samples

  • +
  • power management.

  • +

This layer implements behaviour that can vary between platforms and +therefore needs to be implemented by the port.

The bulk of the effort +here is the definition and implementation of a class derived from the Symbian +defined DDigitiser class; the derived class implements +the pure virtual functions defined by DDigitiser.

You +provide this.

+
+ + +
+

The template port provides a framework for implementing the platform specific +part of the digitiser. The diagram below shows the overall relationship:

+ + + +

The standard Symbian platform ports all follow the same general pattern, +including the H2. However, the H2 board implementation has two levels in its +platform specific layer (an ASSP and a variant layer) and uses different source +file names (e.g. digitizer.cpp), but, nevertheless, the +same general pattern applies.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-5686E787-537F-5B32-B719-34EF5B7F0D37-master.png Binary file Adaptation/GUID-5686E787-537F-5B32-B719-34EF5B7F0D37-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-5686E787-537F-5B32-B719-34EF5B7F0D37_d0e18814_href.png Binary file Adaptation/GUID-5686E787-537F-5B32-B719-34EF5B7F0D37_d0e18814_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-57989FF8-5E8F-4C8A-9D38-169AFCA4C078.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-57989FF8-5E8F-4C8A-9D38-169AFCA4C078.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,116 @@ + + + + + +Baseport Template Implementation GuideDescribes the use of the Baseport Template in porting Symbian +platform. +
General +procedure

The Baseport Template is a minimal +baseport for the Symbian platform that implements the basic functionality +of a baseport without supplying any hardware specific code. It provides +a skeleton of a working baseport, which base porters can modify in +accordance with the instructions in the comments. Porting involves +abstraction from hardware and must be performed in a set sequence +(for example, the abstraction in the drivers depends on previous abstraction +in HAL which depends on previous abstraction in ASIC and so on). Many +of the header files are not in the Baseport Template files but are +held elsewhere in the code base, for example, ..\e32\include\kernel\arm\

+
File +structure

The files which make up the Baseport +Template are divided between two directories, ASSP and Variant containing +two classes of the same names. This division represents a fundamental +feature of the kernel architecture which you are recommended to retain +in your implementation of the port. The baseport involves implementing +functions to run on the target hardware, but it is useful to distinguish +between functionality specific to the CPU (ARM etc) and functionality +specific to peripherals with their own processors. ASSP functions +must be implemented in accordance with the device hardware, while +Variant functions correspond to off chip peripherals. The distinction +is not absolutely mandatory (it is possible just to provide a Variant +layer) but strongly recommended and assumed in many other areas of +the porting process.

A port with an ASSP/Variant architecture +is implemented with two C++ classes and two .mpp files.

    +
  • ...\template_assp\assp.cpp

  • +
  • ...\template_assp\katemplate.mmp

  • +
  • ...\template_variant\specific\variant.cpp

  • +
  • ...\template_variant\vtemplate.mmp

  • +

For more information see the Base Porting Guide.

+
+
Bootstrap

The bootstrap is the code that runs after a hardware +reset, to initialize the basic system services that enable the kernel +to run. Parts of it must be written in assembler (either GNU or ARM) +and are specific to the device hardware, while others are written +in C++ and are automatically translated into assembler. Bootstrap +is implemented as the bootstrap/template.s file.

This is supplied as an example only: implementation is entirely +dependent on the target hardware.

For more information see the Base Porting Guide.

+
Interrupt +dispatcher

The Symbian platform is a real time +interrupt driven operating system. To port it you need to determine +the number and function of the interrupts in your port and implement +the interrupt dispatcher to handle them. Interrupt service routines +(ISRs) are held in an array of class SInterruptHandler as a member of the TemplateInterrupt class defined +in template_assp_priv.h. ISRs are associated +with individual interrupt sources defined in the ASSP layer by functions +of the Interrupt class such as Bind() and Unbind().

    +
  • ...\template_assp\template_assp_priv.h

  • +
  • ...\template_assp\interrupts.cpp

  • +

For more information see the Base Porting Guide.

+
+ ASIC

The Asic class +contains initialization functions which must be called early in the +boot process. ASSP is derived from Asic and Variant from the ASSP derivation.

    +
  • ...\template_assp\template_assp.h

  • +
  • ...\template_assp\template_assp.cpp

  • +

For more information see the Base Porting Guide.

+
+ HAL

The HAL class +abstracts items of hardware specific functionality. You must implement +functions to get and set hardware specific attributes in accordance +with the hardware used on the target device. The attributes are defined +in config.hcf and values.hda configuration files.

    +
  • ...\template_variant\hal\config.hcf

  • +
  • ...\template_variant\hal\values.hda

  • +

The attributes are modified by get and set functions called +HAL handlers defined in the relevant hardware drivers.

For more +information see the Base Porting Guide.

+
+ Drivers

The rest of the work involves +porting drivers. A typical implementation would include these drivers:

    +
  • DMA Framework

      +
    • ...\template_assp\dmapsl.cpp

    • +
    • ...\template_assp\dma.mpp

    • +

  • +
  • Digitizer Driver

      +
    • ...\template_variant\specific\xyin.cpp

    • +
    • ...\template_variant\exxytemplate.mmp

    • +

  • +
  • Keyboard Driver

      +
    • ...\template_variant\exkey_inttemplate.mmp

    • +
    • ...\template_variant\specific\keyboard_interrupt.cpp

    • +

  • +
  • LCD Extension

      +
    • ...\template_variant\specific\lcd.cpp

    • +
    • ...\template_variant\exlcdtemplate.mmp

    • +

  • +
  • Serial Port Driver

      +
    • ...\template_variant\specific\uart.cpp

    • +
    • ...\template_variant\datxtemplate.mmp

    • +

  • +
  • Sound Driver

      +
    • ...\template\template_variant\specific\soundsc_rx.cpp

    • +
    • ...\template\template_variant\specific\soundsc_tx.cpp

    • +
    • ...\template\template_variant\soundsctemplate.mmp

    • +

  • +
  • USB Client Driver Technology

      +
    • ...\template_assp\pa_usbc.cpp

    • +
    • ...\template_assp\usbcc.mmp

    • +

  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-583F70B4-5C8C-54FA-A869-E6F073DE1FD6.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-583F70B4-5C8C-54FA-A869-E6F073DE1FD6.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,58 @@ + + + + + +Interrupt::Enable() +and Interrupt::Disable()The functions Interrupt::Enable() and Interrupt::Disable() are +used by device drivers to enable and disable the interrupt source in the interrupt +controller hardware. +

+

An Interrupt +ID is passed to the functions to identify the interrupt source. All +requests for enabling and disabling interrupts should go to these functions +in the Interrupt class so that device drivers should never +need to know where the interrupt is actually implemented. The general rule +is that the interrupt ID is tagged in some way to allow these functions to +decide whether the interrupt refers to the ASSP layer or to the Variant layer. +These functions are implemented in the ASSP layer.

+

The implementation of these functions is completely dependent on the interrupt +hardware. In the template port, Interrupt::Enable() is implemented +in ...\template_assp\interrupts.cpp. The relevant part +is:

+EXPORT_C TInt Interrupt::Enable(TInt anId) + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("Interrupt::Enable id=%d",anId)); + TInt r=KErrNone; + // if ID indicates a chained interrupt, call variant... + if (anId<0 && ((((TUint)anId)>>16)&0x7fff)<(TUint)KNumTemplateInts) + r=TemplateAssp::Variant->InterruptEnable(anId); + else if ((TUint)anId>=(TUint)KNumTemplateInts) + r=KErrArgument; + else if (TemplateInterrupt::Handlers[anId].iIsr==TemplateInterrupt::Spurious) + r=KErrNotReady; + else + { + // + // TO DO: (mandatory) + // + // Enable the corresponding Hardware Interrupt source + // + } + return r; + } + +

Interrupts that 'belong' to the Variant Layer are passed to that layer +through the call to:

+r =TemplateAssp::Variant->InterruptEnable(anId); +

Interrupt::Disable() follows the same general pattern.

+

The Variant layer equivalent of this function, Template::InterruptEnable(), +in ...\template_variant\specific\variant.cpp, also follows +the same pattern.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-58AA7257-0951-42AB-9B6E-AAF63343FEFA-GENID-1-2-1-10-1-5-1-5-1-1-7-1-9-1-5-1.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-58AA7257-0951-42AB-9B6E-AAF63343FEFA-GENID-1-2-1-10-1-5-1-5-1-1-7-1-9-1-5-1.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,88 @@ + + + + + +DMA Channel OperationsDescribes how a device driver should open and close a DMA +channel. +
Open

To use a DMA channel it has to be opened. TDmaChannel::Open() must be called to open the channel, and the required information +provided in a TDmaChannel::SCreateInfo structure. +The actual DMA channel selection is done by the hardware specific +layer.

/** + Initializes the DMA for transmit. This function does all the + required generic initialization to use the DMA framework. This + function does not have any variant specific initialization. + + @return KErrNone on success, else standard error code on failure + */ +TInt DExDriverUartTxDma::Init() + { + ... + + // Initialize the channel information to select and configure the DMA + // channel + TDmaChannel::SCreateInfo info; + info.iCookie = (TUint); + info.iDesCount = 1; // For single buffered transfers + info.iDfcPriority = 4; // Set the priority of this DFC for DMA + info.iDfcQ = iUartComm->DfcQ(); // DFCQ onto which this request + // has to be queued + + // DMA channel has to be opened before doing any operations on + // the channel. TDmaChannel::Open() opens the DMA channel as + // set by info passed and selected by the hardware-specific layer. + + r = TDmaChannel::Open(info, iTxDmaChannel); + if (r!=KErrNone) + { + return r; + } + ... + }
+
Close

A DMA channel has to be closed after completing all the DMA operations. +This releases the DMA channel for other resources and peripherals. +To close a previously opened channel, the channel should be idle, +with no pending requests. So, before closing, call TDmaChannel::CancelAll(), which cancels the current request and any pending DMA requests. +This should then be followed by closing the channel using TDmaChannel::Close().

/** + Destructor. Deinitializes the member variables, cancels any + requests, closes the channel, deletes the DMA requests, frees the + hardware chunks allocated. + */ + +DExDriverUartTxDma::~DExDriverUarttxDma() + { + ... + // if DMA channel is existing, cancel all requests on it. + // + if (iTxDmaChannel) + { + // TDmaChannel::CancelAll() cancels the current request and + // any pending requests on the DMA channel + // + iTxDmaChannel->CancelAll(); + } + ... + + if(iTxDmaChannel) + { + // Close the DMA channel. TDmaChannel::Close() closes a + // previously opened channel. All the requests on this + // channel should have been cancelled prior to this, i.e. + // TDmaChannel::CancelAll() should have been called before + // this call. + // + iTxDmaChannel->Close(); + } + ... + }

To stop DMA without closing the channel, simply +cancel the request.

+
+DMA +Channels +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-58AA7257-0951-42AB-9B6E-AAF63343FEFA-GENID-1-2-1-9-1-6-1-8-1-7-1-4-1.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-58AA7257-0951-42AB-9B6E-AAF63343FEFA-GENID-1-2-1-9-1-6-1-8-1-7-1-4-1.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,88 @@ + + + + + +DMA Channel OperationsDescribes how a device driver should open and close a DMA +channel. +
Open

To use a DMA channel it has to be opened. TDmaChannel::Open() must be called to open the channel, and the required information +provided in a TDmaChannel::SCreateInfo structure. +The actual DMA channel selection is done by the hardware specific +layer.

/** + Initializes the DMA for transmit. This function does all the + required generic initialization to use the DMA framework. This + function does not have any variant specific initialization. + + @return KErrNone on success, else standard error code on failure + */ +TInt DExDriverUartTxDma::Init() + { + ... + + // Initialize the channel information to select and configure the DMA + // channel + TDmaChannel::SCreateInfo info; + info.iCookie = (TUint); + info.iDesCount = 1; // For single buffered transfers + info.iDfcPriority = 4; // Set the priority of this DFC for DMA + info.iDfcQ = iUartComm->DfcQ(); // DFCQ onto which this request + // has to be queued + + // DMA channel has to be opened before doing any operations on + // the channel. TDmaChannel::Open() opens the DMA channel as + // set by info passed and selected by the hardware-specific layer. + + r = TDmaChannel::Open(info, iTxDmaChannel); + if (r!=KErrNone) + { + return r; + } + ... + }
+
Close

A DMA channel has to be closed after completing all the DMA operations. +This releases the DMA channel for other resources and peripherals. +To close a previously opened channel, the channel should be idle, +with no pending requests. So, before closing, call TDmaChannel::CancelAll(), which cancels the current request and any pending DMA requests. +This should then be followed by closing the channel using TDmaChannel::Close().

/** + Destructor. Deinitializes the member variables, cancels any + requests, closes the channel, deletes the DMA requests, frees the + hardware chunks allocated. + */ + +DExDriverUartTxDma::~DExDriverUarttxDma() + { + ... + // if DMA channel is existing, cancel all requests on it. + // + if (iTxDmaChannel) + { + // TDmaChannel::CancelAll() cancels the current request and + // any pending requests on the DMA channel + // + iTxDmaChannel->CancelAll(); + } + ... + + if(iTxDmaChannel) + { + // Close the DMA channel. TDmaChannel::Close() closes a + // previously opened channel. All the requests on this + // channel should have been cancelled prior to this, i.e. + // TDmaChannel::CancelAll() should have been called before + // this call. + // + iTxDmaChannel->Close(); + } + ... + }

To stop DMA without closing the channel, simply +cancel the request.

+
+DMA +Channels +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-592B6D20-4ABA-5C79-9734-D18E2CE4A86C.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-592B6D20-4ABA-5C79-9734-D18E2CE4A86C.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,166 @@ + + + + + +Writable +Data Paging OverviewOverview of data paging, the next phase in Symbian's implementation +of demand paging. +
Purpose

Writable +data paging allows the demand paging of any user-side data (for example thread +stacks and heaps). Writable data paging makes use of a fixed size backing +store to page out data. The backing store may use a NAND flash partition or +an embedded MMC (eMMC).

The aim of data paging is to enable more memory-hungry +use cases without increasing the amount of physical RAM present in the device.

For +example, data paging enables:

    +
  • running applications +that are not designed with the memory constraints of embedded devices in mind, +for example applications ported from other environments with writable data +paging (such as a PC).

  • +
  • running multiple applications +at the same time where previously there would not have been enough memory.

  • +

Data paging offers no performance increase, unlike code paging +which can speed up application loading by reading only the necessary pages +into RAM.

However, writable data paging does have +the following limitations:

    +
  • It is only possible +to page the following types of memory:

      +
    • user heaps,

    • +
    • user thread stacks,

    • +
    • private chunks,

    • +
    • global chunks,

    • +
    • static data.

    • +
  • +
  • A single memory object +(e.g. a heap, stack, DLL or chunk) is the smallest granularity at which paging +can be configured

  • +
  • No attempt will be made +to page kernel-side data

  • +
  • No attempt will be made +to implement memory mapped files (e.g. posix's mmap)

  • +
  • No attempt will be made +to implement any kind of paging on the emulator.

  • +
+
Required background

This +document assumes that the reader is familiar with the concept of Demand +Paging, and the existing implementation of ROM and code paging in Symbian +platform.

+
Key concepts +and terms
+ +
Page
+

Memory is managed in fixed size units called pages. The size of a page +is usually determined by the hardware, and for ARM architectures this is 4K.

+
+ +
Paged in or Paged out
+

If a given page of memory is present in RAM it is said to be paged +in (or just 'present'), as opposed to paged out.

+
+ +
Paging in
+

The process of moving a page of memory from being paged out to being +paged in.

+
+ +
Paging out
+

The process of moving a page of memory from being paged in to being +paged out.

+
+ +
backing store
+

The external media used to hold paged out pages is referred +to as the swap area. This area may be much larger than physical RAM, +although a factor of around twice as large is considered normal in existing +systems.

+
+ +
Working set
+

The term working set is defined as the memory accessed during +a given time period.

+
+ +
Pinning
+

Pinning pages refers to paging in demand-paged memory and forcing +it to remain in RAM until it is unpinned at a later time.

+
+
+
Classes

The +following classes are affected by the use of writable data demand paging:

The +following classes are involved in the use of threads and processes:

+ + + +

Class

+

Description

+
+ +

RThread

+

This class is used to handle threads.

+
+ +

RProcess

+

This class is used to handle processes.

+
+ +

TThreadCreateInfo

+

Used to specify the attributes of a new thread.

+
+ + +

These classes are used in handling memory:

+ + + +

Class

+

Description

+
+ +

RChunk

+

Handle a chunk.

+
+ +

TChunkCreateInfo

+

A structure that specifies the type and properties of the chunk +that is to be created.

+
+ +

TChunkHeapCreateInfo

+

A structure that specifies the type and properties of a chunk with +a heap within it.

+
+ +

UserHeap

+

A set of functions that are used to create heaps.

+
+ + +

The following classes are used in client/server communication:

+ + + +

Class

+

Description

+
+ +

CServer2

+

The abstract base class for servers.

+
+ +

TIpcArgs

+

A client/server class that clients use to package arguments that +are to be sent to a sever.

+
+ + +
+
+Flexible +Memory Model Overview +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-59322A4F-B9CB-5997-B843-C4A80F8D42F1.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-59322A4F-B9CB-5997-B843-C4A80F8D42F1.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,19 @@ + + + + + +AdaptationAdaptation is the software side of adding new hardware +to a device, including drivers and interfaces. +

This content is provided under our joint company non-disclosure +agreement. All content included in the documentation set is confidential +and can only be used for the limited purpose of viewing it as a potential +documentation solution. It cannot be redistributed or reused for any +purpose.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-59FF3BFE-21E2-554D-99EC-1A1D34AAEB7C-master.png Binary file Adaptation/GUID-59FF3BFE-21E2-554D-99EC-1A1D34AAEB7C-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-59FF3BFE-21E2-554D-99EC-1A1D34AAEB7C_d0e35295_href.png Binary file Adaptation/GUID-59FF3BFE-21E2-554D-99EC-1A1D34AAEB7C_d0e35295_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-5B24741C-7CE0-58E8-98C9-1D1CACCD476F.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-5B24741C-7CE0-58E8-98C9-1D1CACCD476F.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,106 @@ + + + + + +Fair Scheduling and File Caching BackgroundThis document describes the fair scheduling and file caching +features of the File Server. +
Fair +scheduling

The current design of the file server supports +the processing of client requests concurrently, as long as those requests +are made to different drives in the system. For example, a read operation +may take place on the NAND user area partition while a write operation +to the MMC card takes place concurrently.

However, requests +to the same drive are serialized on a first-come first-served basis, +which under some circumstances leads to bad user experience. For example:

    +
  1. An incoming +call arrives while a large video file is being written to the NAND +user area by an application that writes the file in very large chunks.

  2. +
  3. In order to +display the caller’s details, the phone needs to read from the contacts +database which is also stored on the NAND user area.

  4. +
  5. The write operation +takes a very long time to complete, so the call is lost.

  6. +

This is one of many scenarios where the single threaded nature +of the file server may lead to unresponsive behavior. In order to +improve the responsiveness of the system, the Symbian platform implements +a fair scheduling policy that splits up large requests into more manageable +chunks, thus providing clients of the file server with a more responsive +system when the file server is under heavy load.

See Enabling fair scheduling.

+
Read +caching

Read caching aims to improve file server performance +by addressing the following use case:

    +
  • A client (or multiple clients) issues repeated requests to +read data from the same locality within a file. Data that was previously +read (and is still in the cache) can be returned to the client without +continuously re-reading the data from the media.

  • +

Read caching is of little benefit for clients/files +that are typically accessed sequentially in large blocks and never +re-read.

There may be a small degradation in performance +on some media due to the overhead of copying the data from the media +into the file cache. To some extent this may be mitigated by the affects +of read-ahead, but this clearly does not affect large (>= 4K) reads +and/or non-sequential reads. It should also be noted that any degradation +may be more significant for media where the read is entirely synchronous, +because there is no scope for a read-ahead to be running in the file +server drive thread at the same time as reads are being satisfied +in the context of the file server’s main thread.

+
Demand +paging effects

When ROM paging is enabled, the kernel maintains +a live list of pages that are currently being used to store +demand paged content. It is important to realize that this list also +contains non-dirty pages belonging to the file cache. The implication +of this is that reading some data into the file cache, or reading +data already stored in the file cache, may result in code pages being +evicted from the live list.

Having a large number of clients +reading through or from the file cache can have an adverse effect +on performance. For this reason it is probably not a good idea to +set the FileCacheSize property to too large a value +– otherwise a single application reading a single large file through +the cache is more likely to cause code page evictions if the amount +of available RAM is restricted. See Migration Tutorial: +Demand Paging and Media Drivers.

+
Read-ahead +caching

Clients that read data sequentially (particularly +using small block lengths) impact system performance due to the overhead +in requesting data from the media. Read-ahead caching addresses this +issue by ensuring that subsequent small read operations may be satisfied +from the cache after issuing a large request to read ahead data from +the media.

Read-ahead caching builds on read caching by detecting +clients that are performing streaming operations and speculatively +reading ahead on the assumption that once the data is in the cache +it is likely to be accessed in the near future, thus improving performance.

The number of bytes requested by the read-ahead mechanism is initially +equal to double the client’s last read length or a page, for example, +4K (whichever is greater) and doubles each time the file server detects +that the client is due to read outside of the extents of the read-ahead +cache, up to a pre-defined maximum (128K).

+
Write +caching

Write caching is implemented to perform a small +level of write-back caching. This overcomes inefficiencies of clients +that perform small write operations, thus taking advantage of media +that is written on a block basis by consolidating multiple file updates +into a single larger write as well as minimizing the overhead of metadata +updates that the file system performs.

By implementing write +back at the file level, rather than at the level of the block device, +the possibility of file system corruption is removed as the robustness +features provided by rugged FAT and LFFS are still applicable.

Furthermore, by disabling write back by default, allowing the +licensee to specify the policy on a per drive basis, providing APIs +on a per session basis and respecting Flush and Close operations, +the risk of data corruption is minimized.

The possibility +of data loss increases, but the LFFS file system already implements +a simple write back cache of 4K in size so the impact of this should +be minimal.Write caching must be handled with care, as +this could potentially result in loss of user data.

Database +access needs special consideration as corruption may occur if the +database is written to expect write operations to be committed to +disk immediately or in a certain order (write caching may re-order +write requests).

For these reasons, it is probably safer to +leave write caching off by default and to consider enabling it on +a per-application basis. See Enabling read and write caching.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-5BD2D468-838A-49BC-BA92-F41102D37CBC.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-5BD2D468-838A-49BC-BA92-F41102D37CBC.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,16 @@ + + + + + +Generic ImplementationAdaptation software providing a realization of the Client +Interface. The Generic Implementation is also known as the Platform +Independent Layer (PIL). +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-5C17A2E7-DE18-5CFB-A5D5-421D427CD5DD.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-5C17A2E7-DE18-5CFB-A5D5-421D427CD5DD.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,33 @@ + + + + + +Code OrganisationThis topic describes the source code for interrupt driven +keyboard drivers and related libraries. +

This topic describes the source code for interrupt driven keyboard +drivers and related libraries that Symbian platform provides.

+
Keyboard +driver

In a reference board port, the .mmp file for the keyboard driver is ...\template_variant\exkey_inttemplate.mmp. This is one of the PRJ_MMPFILES referenced in the template variant's bld.inf file in the ...\template_variant\... directory, and means that the keyboard driver is built as part of +the Variant.

The source for the driver is contained entirely +within ...\template_variant\specific\keyboard_interrupt.cpp.

+
Key +translation DLL (ektran.dll)

This DLL is part of Symbian +platform generic code and is built as part of the Text Window Server +component.

The mmp file is located in Symbian platform generic +code in ...\e32\wserv\ektran.mmp, which defines +the location of the source files, header files and other dependencies.

+
Keyboard +mapping DLL (ekdata.dl)

The DLL is platform specific. It +is built as part of the Variant.

The mmp file has a name with +format cakd xx .mmp, where xx is the suffix that identifies the Variant in the +Variant specific .oby file. In the template port, +the mmp file has the name cakdtemplate.mmp.

The source code for the tables is located in keymap.cpp, and is located in the Variant specific directory. The template +port provides outline code.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-5C223AD5-4676-58B4-B3A5-066F6B69AA4D.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-5C223AD5-4676-58B4-B3A5-066F6B69AA4D.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,26 @@ + + + + + +Local Media +SubsystemProvides the logical device driver for the internal and removable +storage media on a phone. +

Local Media Subsystem uses +physical device drivers, called media drivers, that manage the storage media +hardware. A base port can implement new media drivers and implement ports +of the media drivers that are supplied in Symbian platform.

+
+ +File Server + +File Systems + +Media Drivers +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-5CCF303A-B7D5-570D-9BE8-29DFBE184995.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-5CCF303A-B7D5-570D-9BE8-29DFBE184995.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,79 @@ + + + + + +Porting OverviewThis topic describes the typical steps that you will need +to do to create a base port. +

The easiest way to create a base port is to take the supplied template +port and expand it to suit your own hardware configuration(s). The +template port, is an outline, but working, framework that you can +modify to suit your own hardware.

+

The template port can be found under the sf/os/kernelhwsrv/bsptemplate/ directory. For more information about the template port see Kernel & Hardware Quick Start Guide.

+
Set +up the environment

The first thing to do is to set up your +environment for building, downloading onto your hardware, and testing +that the port works.

+
Build, +download, and test the supplied template port

As supplied, +the template port is designed to boot on any hardware. It should boot +successfully, but clearly, the system can do nothing more at this +time. A successful boot shows that your build environment has been +set up correctly.

+
Copy +and rename the Template port

When porting the base to a +new platform, you will need to code and build the Variant. This provides +those hardware dependent services required by the kernel. In nearly +all ports, this is split into an ASSP DLL and a Variant DLL. We usually +refer to the ASSP layer and the Variant layer.

It is desirable +that code that depends only on the properties of the ASSP be segregated +from code that depends on details of the system outside the ASSP, +so that multiple systems that use the same ASSP can share common code.

For example, in the template reference port, the ..\template_assp\... directory contains source code that contains the ASSP code, whereas +the ...\template_variant\... directory contains +the code specific to the template board.

+
Code +the Bootstrap

The bootstrap consists of several generic +source and header files supplied as part of Symbian platform, and +a set of platform specific files. You need to create these platform +specific files as part of a base port.

For details, see Bootstrap.

The updated port can then be built, downloaded and tested.

+
Implement +the interrupt dispatcher

An interrupt is a condition that +causes the CPU to suspend normal execution, enter interrupt handling +state and jump to a section of code called an interrupt handler. The +ASSP/Variant part of the base port must implement an interrupt dispatcher +class to manage interrupts.

For details, see the Interrupt Dispatcher +Implementation Tutorial.

The updated port can then +be built, downloaded and tested.

+
Implement +the Asic class

The Kernel requires that the ASSP/Variant +part of the base port provides an implementation of the Asic interface. This defines a small number of hardware-specific functions +that are used by the Kernel.

For details, see the Asic Class Tutorial.

The updated port can then be +built, downloaded and tested.

+
Port +the User-Side Hardware Abstraction (HAL)

The User-Side +Hardware Abstraction (HAL) component provides a simple interface for +programs to read and set hardware-specific settings, for example, +the display contrast. A base port must define the attributes that +clients can use on a phone, and implement any functions that are required +to get and set the attributes.

For details, see User-Side Hardware Abstraction.

+
Port +the other drivers

The remaining drivers can now be ported. +Go and see:

    +
  • DMA Framework

  • +
  • Digitizer Driver

  • +
  • Keyboard Driver

  • +
  • LCD Extension

  • +
  • Local Media Subsystem

  • +
  • Power Management

  • +
  • Serial Port Driver

  • +
  • Sound Driver

  • +
  • USB Client Driver +Technology

  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-5CF162CA-4395-58AC-A318-2BF178276A57-master.png Binary file Adaptation/GUID-5CF162CA-4395-58AC-A318-2BF178276A57-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-5CF162CA-4395-58AC-A318-2BF178276A57_d0e69352_href.png Binary file Adaptation/GUID-5CF162CA-4395-58AC-A318-2BF178276A57_d0e69352_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-5E24CFFD-1F87-4B77-B7A0-59A419ADBC90.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-5E24CFFD-1F87-4B77-B7A0-59A419ADBC90.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,12 @@ + + + + + +IIC Describes the Inter-Integrated Circuit (IIC) platform service. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-5E358AB4-03A7-5859-ABF2-A8B64B74AF56.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-5E358AB4-03A7-5859-ABF2-A8B64B74AF56.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,39 @@ + + + + + +Vector Floating Point Architecture (VFP)Describes the implementation of the ARM Vector Floating +Point Architecture (VFPv2) on Symbian platform. +

ARM provide a hardware floating point coprocessor that provides +floating point computation that is fully compliant with IEEE Std 754-1985.We +refer to the coprocessor as the VFP unit.

+

Symbian platform supports the use of VFPv2 on platforms where the +required hardware is present in both RunFast mode and in IEEE-without-exceptions mode. See ARM's Vector Floating-point +Coprocessor Technical reference Manual for more details on the coprocessor, +its architecture, and its execution modes.

+

You should read Floating point support in Symbian^3 Tools Guide +> Building. The guide contains information about applications +and user-side code, which is also applicable to code running on the +kernel side. However there are a number of restrictions that must +be observed:

+
    +
  • You cannot use VFP instructions in any interrupt service routine.

  • +
  • You cannot use VFP instructions when the kernel is locked, for example, in +an IDFC or after calling NKern::Lock()

  • +
  • You cannot use VFP instructions in any section of code which runs with a fast +mutex held.

  • +
+

Using VFP instructions in these situations can lead to data being +corrupted, or the kernel panicking. If you rely on the compiler to +generate VFP instructions, rather than using inline assembler, it +is extremely important that you do not use any floating point values +in these situations. The compiler may generate VFP instructions for +the most trivial floating point operations and even for simple assignments.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-5EB03086-A87D-5588-8927-7A7F8DB38366.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-5EB03086-A87D-5588-8927-7A7F8DB38366.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,16 @@ + + + + + +Port Implementation +TutorialThis section describes how to implement a port of the bootstrap. +Concepts + + \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-5F35ED29-18A0-4764-B84D-B43BF23BF44F.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-5F35ED29-18A0-4764-B84D-B43BF23BF44F.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,72 @@ + + + + + +Time Testing GuideDescribes how to test a Time SHAI implementation. +

There is no conformance testing suite for the Time platform service. +So, this is a list of tests that have to be conducted to check that +the Time platform service is working correctly:

+
Time +Tests

The following table is a list of the tests that need +to be carried out in order to test the Time SHAI implementation.

+ + + + +

No.

+

Functionality To Test

+

Description

+

Correct Result

+
+ + + +

1

+

The Real Time Clock (RTC) works correctly.

+

Check the output from the RTC with a reliable clock.

+

The date and time should be identical.

+
+ +

2

+

Validating the RTC.

+

The function MRtcAdaptation::ValidateRtc() is called.

+

The KErrorNone should be returned in the +variable passed in the second argument.

+
+ +

3

+

Setting the wake-up alarm.

+

The function MRtcAdaptation::SetWakeupAlarm()

+

The wake-up alarm should start at the set time.

+
+ +

4

+

Un-set the wake-up alarm.

+
    +
  1. Set the wake-up +alarm to a known date and time.

  2. +
  3. Execute the +function MRtcAdaptation::UnsetWakeupAlarm() to +cancel the wake-up alarm.

  4. +
+

The wake-up alarm will not go off at the original preset +time.

+
+ +

5

+

Cancel a request.

+

As for the above, except that the function MRtcAdaptation::Cancel() is called instead ofMRtcAdaptation::UnsetWakeupAlarm().

+

The wake-up alarm will not go off at the original preset +time.

+
+ + +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-5F614B75-056D-5798-AE06-8DA6E9ED6834.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-5F614B75-056D-5798-AE06-8DA6E9ED6834.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,38 @@ + + + + + +Set the Interface Descriptors A short document that describes how to set the interface descriptors.
Introduction

Before setting the interface descriptors, get the device and endpoint capabilities of the USB Device Controller (UDC) hardware.

  • Get device capabilities,

  • Define the interface data,

  • Set the interface,

  • Finalise the interface.

Get device capabilities

Use RDevUsbcScClient::DeviceCaps() to get the device capabilities and RDevUsbcScClient::EndpointCaps() to get the endpoint capabilities.

TUsbDeviceCapsV01 is the structure used to return the device capabilities.

TUsbDeviceCaps d_caps; +TInt r = gPort.DeviceCaps(d_caps);

RDevUsbcScClient::EndpointCaps() returns the object TUsbEndpointData which contains a TUsbEndpointCaps object and a boolean variable that indicates whether the endpoint is in use. TUsbEndpointCaps contains the endpoint capabilities as reported by the driver.

TUsbcEndpointData data[KUsbcMaxEndpoints]; +TPtr8 dataptr(reinterpret_cast<TUint8*>(data), sizeof(data), sizeof(data)); +r = gPort.EndpointCaps(dataptr);

Note: Endpoint zero is only supported as a control endpoint. The capabilities of endpoint zero are not included in the list of endpoint cababilities returned.

Define the interface data

Before calling RDevUsbcScClient::SetInterface(), the class, subclass and protocol must be defined in the TUsbcScInterfaceInfo object. TUsbcScInterfaceInfo is in the TUsbcScInterfaceInfoBuf package buffer.

In the example below we set the interface data in the TUsbcScInterfaceInfo object.

TUsbcScInterfaceInfoBuf ifc; + +// Endpoint zero +ifc().iEndpointData[0].iType = KUsbEpTypeBulk; +ifc().iEndpointData[0].iDir = KUsbEpDirIn; +ifc().iEndpointData[0].iSize = KUsbEpSize64; + +//Endpoint 1 +ifc().iEndpointData[1].iType = KUsbEpTypeBulk; +ifc().iEndpointData[1].iDir = KUsbEpDirOut; +ifc().iEndpointData[1].iSize = KUsbEpSize64; + +_LIT16(string, "T_USBCSC Interface"); +ifc().iString = const_cast<TDesC16*>(&string); +ifc().iTotalEndpointsUsed = 2; +ifc().iClass.iClassNum = 0xff; +ifc().iClass.iSubClassNum = 0xff; +ifc().iClass.iProtocolNum = 0xff; + +// Tell the driver that this setting is interested in Ep0 requests: +ifc().iFeatureWord |= 0;

TUsbcScInterfaceInfo contains the following data members:

  • iEndpointData is is an array of n TUsbcScEndpointInfo elements where n = iTotalEndpointsUsed,

    For each endpoint the TUsbcScEndpointInfo object must, at the very least, contain:

    • The endpoint type (iType), direction (iDir) and maximum packet size (iSize) must be specified to claim each endpoint.

    • The members iBufferSize and iReadSize help with performance tuning and memory optimisation. For example, a capture of 64KB may be an optimal size to pull off the bus without incurring timeout penalties in the PSL. Some classes may benefit from having multiple captures in the endpoint buffer, so iBufferSize would be some multiple of iReadSize.

    • iExtra and iPairing allow for possible future support of classes that require pairing of endpoints by physical address and function. Note: This is not yet supported and any attempt to pair endpoints will result in failure to create the interface.

  • iString is a TDesC16,

    A description string for the interface.

  • iTotalEndpointsUsed is a TUint,

    This number is all the endpoints you wish to use excluding endpoint zero. For example, if you wish to use 4 endpoints and the control endpoint, this value is should be four.

    Note: If you wish to implement a control-only interface then this value should be zero.

  • iClass is of type TUsbcClassInfo,

    Sets the class type for this interface.

  • iFeatureWord is 32 flag bits used for specifying miscellaneous interface features.

    See Allocate Resources for Endpoints.

Set the interface

To set the interface pass the initialised TUsbcScInterfaceInfoBuf to RDevUsbcScClient::SetInterface().

// Set up the interface. +r = gPort.SetInterface(0, ifc);

The interface number passed to SetInterface() along with TUsbcScInterfaceInfoBuf distinguishes between alternate interfaces. If alternate interfaces are not used then this value is always zero. When used, the value must be one greater than that of the proceeding alternate interface.

Note: The whole Setting interface descriptors section up to this point should be repeated for the number of alternative settings required.

Finalise the interface

RDevUsbcScClient::RealizeInterface() is called after SetInterface() has been called for all alternative settings.

On success, a chunk handle is created and passed back through aChunk.

RChunk gChunk; +r = gPort.RealizeInterface(gChunk);

If you are using the Buffer Interface Layer (BIL) then use FinalizeInterface() instead of RealizeInterface(). FinalizeInterface() has the same effect a calling RealizeInterface(), except that the BIL owns the RChunk handle. This function must be used if you want to use any other BIL method.

RChunk *tChunk = &gChunk; +gPort.FinalizeInterface(tChunk);

Note: Calling RealizeInterface() or FinalizeInterface() invalidates all further calls to SetInterface(). All alternative settings must have been initialised before calling these functions.

After you have set the interface descriptors you could optionally Allocate Resources for Endpoints or go straight to Re-Enumerate.

\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-5FB6BEFD-579B-4139-B54D-9CDCF2198A14.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-5FB6BEFD-579B-4139-B54D-9CDCF2198A14.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,13 @@ + + + + + +Interrupt ImplementationDescribes the implementation of the Interrupt platform +service. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-5FDAF564-6BE1-544A-B5C0-E0D6E25D82E7-master.png Binary file Adaptation/GUID-5FDAF564-6BE1-544A-B5C0-E0D6E25D82E7-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-5FDAF564-6BE1-544A-B5C0-E0D6E25D82E7_d0e15107_href.png Binary file Adaptation/GUID-5FDAF564-6BE1-544A-B5C0-E0D6E25D82E7_d0e15107_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-6060F138-CEB6-482A-B0E9-BBBE261568B0.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-6060F138-CEB6-482A-B0E9-BBBE261568B0.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,99 @@ + + + + + +Baseport Template OverviewThis section provides a summary of the Baseport Template +platform service. +
What +is the Baseport Template

The Baseport Template is a reference +board template, which provides a basic framework consisting of base +parts of the Symbian platform. This framework can be modified to suit +your hardware configurations.

The Baseport Template code is +categorized into Application Specific Standard Product (ASSP) layer +and variant layer. The ASSP layer provides the source code for hardware-specific +functions (for example, GPIO, DMA, IIC, USB Client Controller) that +are used by the kernel. This layer is implemented by the TemplateAssp class. The variant layer provides common peripheral +control functions such as power, bootstrap, keymap, keyboard and sound +that other extensions and device drivers can use. This layer is implemented +by the Template class.

ASSP and variant layers +provide control functions for hardware which is used by multiple devices. +This is done by placing Baseport Template code in a single DLL, called +the Variant DLL (ecust.dll). For hardware architectures +based on an ASSP, you can allow multiple phone types that use the +same ASSP to share the common code. To achieve this, implement the +common ASSP code in a kernel extension, and ecust.dll implements the code that is specific to each variant.

+
Purpose +of the Baseport Template

The Baseport Template is mostly +useful in creating a baseport and testing the software. The following +is a list of some of the key uses of the Baseport Template.

The Baseport Template is useful in handling:

    +
  • data exchange between devices connected to the bus

  • +
  • data copy between memory locations or between memory location +and peripheral

  • +
  • communication interface between the microprocessor components

  • +
  • hardware events and registers

  • +
  • USB functions of the device

  • +
  • power resources

  • +
  • phone restart after a hardware reset

  • +
  • shared chunks of camera and sound physical device driver

  • +
  • CPU idle operations

  • +
  • HAL, interrupt and keyboard functions

  • +
  • data storage based on NOR type flash memory

  • +
  • variant specific initialization (not the same as ASSP specific +initialization).

  • +
+
Users +of Baseport TemplateThe Baseport Template documentation cover +users who:
    +
  • manufacture devices and want to develop software and get an +early debug output.

  • +
  • develop baseport. See Base Porting Guide for base porting details

  • +
+
Baseport +Template details

The following table lists the Baseport +Template details:

+ + + +

DLL

+

Library

+

Description

+
+ + + +

katemplate.dll

+

None

+

ASSP DLL. This DLL is made up of the following template +files and can be found under ...template\asspandvariant\template_assp\ directory:

    +
  • template_assp.cpp

  • +
  • interrupts.cpp

  • +
  • assp.cpp

  • +
  • register.cpp

  • +
  • template_assp.cia

  • +
  • interrupts.cia

  • +
  • assp.cia

  • +

+
+ +

ecust.dll

+

None

+

Variant DLL. This DLL is made up of the following template +files and can be found in ...template\asspandvariant\template_variant\ directory:

    +
  • variant.cpp

  • +
  • variant.cia

  • +

+
+ + +
+
+Base +Porting Guide +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-60949ACD-AAA9-540E-85AE-BB173382D548-master.png Binary file Adaptation/GUID-60949ACD-AAA9-540E-85AE-BB173382D548-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-60949ACD-AAA9-540E-85AE-BB173382D548_d0e13468_href.png Binary file Adaptation/GUID-60949ACD-AAA9-540E-85AE-BB173382D548_d0e13468_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-610E0C09-F014-4DA2-8411-D7A0CDAF5BBB-master.png Binary file Adaptation/GUID-610E0C09-F014-4DA2-8411-D7A0CDAF5BBB-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-610E0C09-F014-4DA2-8411-D7A0CDAF5BBB_d0e90471_href.png Binary file Adaptation/GUID-610E0C09-F014-4DA2-8411-D7A0CDAF5BBB_d0e90471_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-6114133F-E738-4DF1-8308-B09C02B9CEEA.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-6114133F-E738-4DF1-8308-B09C02B9CEEA.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,279 @@ + + + + + +DMAv2 Interface OverviewDescribes the interfaces provided by the DMAv2 platform +service. +
Client +functions

The clients that require to use the DMA framework +functionality use the DDmaRequest class functions +to request DMA transfers. The clients should not set any parameters +directly but use functions of the DDmaRequest class.

+ + + +API +Description + + + + +DDmaRequest::DDmaRequest(TDmaChannel& aChannel, +TCallback, TAny*, TInt) +The constructor for the DDmaRequest class. + + +DDmaRequest::Fragment(const TDmaTransferArgs& +aTransferArgs) +Split request into a list of fragments small enough to be fed +to the DMA Controller. The size of the fragment should be less than +or equal to the maximum transfer size supported by the DMA controller. + + +DDmaRequest::Queue() +Asynchronous transfer request. + + +DDmaRequest::ExpandDesList(TInt) +Add new descriptors to the existing list. The function is to +be used by the clients that require to build a custom descriptor list. + + +DDmaRequest::ExpandSrcDesList(TInt) +Add new descriptors to the existing source port descriptor +list. + + +DDmaRequest::ExpandDstDesList(TInt) +Add new descriptors to the existing destination port descriptor +list. + + +DDmaRequest::FreeDesList() +Free resources associated with this request. + + +DDmaRequest::FreeSrcDesList() +Free resources associated with this request from the source +port descriptor chain. + + +DDmaRequest::FreeDstDesList() +Free resources associated with this request from the destination +port descriptor chain. + + +DDmaRequest::EnableSrcElementCounting(TBool) +Enables the functionality for counting the transferred source +elements. + + +DDmaRequest::EnableDstElementCounting(TBool) +Enables the functionality for counting the transferred destination +elements. + + +DDmaRequest::DisableSrcElementCounting() +Disables the functionality for counting the transferred source +elements. + + +DDmaRequest::DisableDstElementCounting() +Disables the functionality for counting the transferred destination +elements. + + +DDmaRequest::TotalNumSrcElementsTransferred() +Get the number of transferred elements at the source port. +This function can only be used if the counting is enabled. + + +DDmaRequest::TotalNumDstElementsTransferred() +Get the number of transferred elements at the destination port. +This function can only be used if the counting is enabled. + + +DDmaRequest::FragmentCount() +Returns the number of fragments that are created by this transfer +request. + + +DDmaRequest::SrcFragmentCount() +Returns the number of source port fragments that are created +by this transfer request. + + +DDmaRequest::DstFragmentCount() +Returns the number of destination port fragments that are created +by this transfer request. + + +TDmaChannel::Open(const SCreateInfo& aInfo, TDmaChannel*& +aChannel) +Open a specified channel. + + +TDmaChannel::Close() +Close a previously opened channel. + + +TDmaChannel::LinkToChannel(TDmaChannel* aChannel) +Logically link a channel with the specified argument. When +the argument is NULL the channel is unlinked. + + +TDmaChannel::Pause() +Pause an active transfer. + + +TDmaChannel::Resume() +Resume transfer on this channel. + + +TDmaChannel::CancelAll() +Cancel current and all pending requests. + + +TDmaChannel::MaxTransferLength(TUint aSrcFlags, TUint +aDstFlags, TUint32 aPslInfo) +Get the maximum transfer length of the current channel. + + +TDmaChannel::AddressAlignMask(TUint aTargetFlags, +TUint aElementSize, TUint32 aPslInfo) +Get the address or memory alignment mask. + + +TDmaChannel::DmacCaps() +Get the reference to the structure that contains the features +and the capabilities of the DMAC associated with the current channel. + + +TDmaChannel::IsrRedoRequest(TUint32 aSrcAddr=KPhysAddrInvalid, +TUint32 aDstAddr=KPhysAddrInvalid, TUint aTransferCount=0, TUint32 +aPslRequestInfo=0, TBool aIsrCb=ETrue) +Repeat the current transfer request with modified parameters. + + +TDmaChannel::IsQueueEmpty() +Check if the current transfer queue is empty. + + +TDmaChannel::PslId() +Get the PSL specific ID of the current channel. This function +is used for debugging by the PIL. + + +TDmaChannel::FailNext(TInt) +Force to fail the next transfer request. This function is for +testing purpose only. + + +TDmaChannel::MissNextInterrupts(TInt) +Force the DMAC to miss one or more interrupts. + + +TDmaChannel::Extension(TInt aCmd, TAny* aArg) +Allows PSL to extend the DMA API with a channel specific functionality. + + +TDmaChannel::StaticExtension(TInt aCmd, TAny* aArg) +Allows PSL to extend the DMA API with a channel independent +functionality. + + + +
+
DMA +controller implementationThe TDmac class +provides the functions of a DMA controller: + + + +API +Description + + + + +TDmac::Transfer(const TDmaChannel& aChannel, const +SDmaDesHdr& aHdr) +Initiate a transfer request on a specified channel. + + +TDmac::StopTransfer(const TDmaChannel& aChannel) +Stop a data transfer on a specified channel. + + +TDmac::IsIdle(const TDmaChannel& aChannel) +Get the state of a specified channel. + + +TDmac::Extension() +Implement a platform specific functionality per channel. + + + +
+
Channel +manager implementation

The DmaChannelMgr class provides functions to open and close the channels by the PIL. +Implement the following functions in the PSL:

+ + + +API +Description + + + + +DmaChannelMgr::Open(TUint32 aOpenId, TBool aDynChannel, +TUint aPriority) +Open a channel with a specified channel ID. + + +DmaChannelMgr::Close() +Close a channel. + + + +
+
DMA +channel implementation

The TDmaChannel class provides the functions to implement a DMA channel. There are +three types of DMA channels that be can be implemented as described +below.

+ + + +Class +Description + + + + +TDmaSbChannel +Class to implement a single buffer channel. + + +TDmaDbChannel +Class to implement a double buffer channel. + + +TDmaSgChannel +Class to implement a scatter-gather channel. + + +TDmaAsymSgChannel +Channel class for controllers using asymmetric descriptor lists. + + + +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-616C3426-A8C4-5653-912D-7150944E5836.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-616C3426-A8C4-5653-912D-7150944E5836.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,95 @@ + + + + + +Keyword reference (G-O) +

This page lists the keywords starting from G to O.

+
heapmax heapmax = <hex-size>

rombuild only

Overrides the default maximum +heap size for the executable.

+
heapmin heapmin = <hex-size>

rombuild only

Overrides the default minimum +heap size for the executable.

+
hide[[HWVD]] hide[[HWVD]] = <existing-file>

rombuild and rofsbuild

Marks the existing file +as hidden. The file is still available to resolve DLL static links.

+
_HIDE__ECOM_PLUGIN _HIDE__ECOM_PLUGIN(<local build directory>, <rom binary directory>, <local epoc32\data\Z directory>, <rom resources directory>, <DLL filename>, <resource filename>)

BUILDROM only

Specifies an ECom plug-in, consisting +of an implementation DLL and an ECom registration resource file, to +be hidden in the ROM and in the SPI file.

Symbian platform +code does not use this keyword directly. Instead, it uses the macro HIDE_ECOM_PLUGIN defined in \epoc32\rom\include\header.iby. This macro allows the plug-in to be specified more briefly in the +following form:

HIDE_ECOM_PLUGIN(<DLL name>,<resource file name>)

For example:

HIDE_ECOM_PLUGIN(foo.dll,12345abc.rsc)

This feature allows BUILDROM to hide the ECom +plug-ins. In particular, BUILDROM hides the DLL associated +with the specified plug-in. The resource registration files that are +passed using the macro are marked as hidden in the SPI file should +you choose to generate one. BUILDROM implements this +feature using the spidatahide keyword.

As part of the ROM building process, +it is possible to add support for multiple languages. This affects +how ECom resource files are specified by BUILDROM:

    +
  • If an SPI file +is being created, the HIDE_ECOM_PLUGIN lines are +processed at an intermediate BUILDROM stage to produce:

    spidatahide=MULTI_LINGUIFY( EXT sourcename ) <spi-id> <target-spi-dir>

    During the BUILDROM localisation stage, these +lines become:

    spidatahide = <source-file> <spi-id> <target-spi-dir>
  • +
  • If an SPI file +is not being created, the HIDE_COM_PLUGIN lines are +processed at an intermediate BUILDROM stage to produce:

    hide=MULTI_LINGUIFY(EXT sourcename)

    During the BUILDROM localisation stage, these +lines become:

    hide=sourcename.EXT for the default extension +hide=sourcename.Enn for all the language codes nn
  • +
+
hcrdata

hcrdata = <hcrdata>

Specifies +the location of an HCR data file which is included in +the SMR partition image.

+
imagename

imagename = <imagename>

Creates +an SMR partition image.

<section id="GUID-178037D5-6040-4767-A185-0BC91B084770"><title>keepIAT</title +><codeblock>keepIAT</codeblock><p><i>rombuild only</i></p><p>Retains +old-style Import Address Table.</p></section>
+
kerneldataaddress kerneldataaddress = <hex-address>

rombuild only

Kernel data/bss chunk base virtual +address.

The recommended value is 0x64000000.

+
kernelconfig kernelconfig <bit-of-kervel-config> <on | off>

rombuild only

This keyword sets the specified bit +of the kernel configuration flag to ON or OFF. The value of <bit-of-kervel-config> must be between 0 and 31.

+
kernelheapmax kernelheapmax = <hex-size>

rombuild only

Maximum size of the Kernel's heap.

The Kernel heap grows in virtual address space until this value +is reached: It can then grow no further. The value is rounded up to +a multiple of the virtual address space mapped by a single page directory +entry - on ARM CPUs this is 1MB. Usually 1 page directory entry's +worth of RAM is specified. The default value is 0x100000; this is +used if none is supplied.

+
kernelheapmin kernelheapmin = <hex-size>

rombuild only

Minimum size of the Kernel heap, +allocated immediately when the Kernel boots. Specify either a minimal +value or a working set size based on envisaged use.

The recommended +value is 0x10000, and is the default value if none is explicitly supplied.

+
kernelromname kernelromname = <rom-file-name>

rombuild only

ROM image on which an extension +ROM is based. This keyword is only valid for extension ROMs

+
kerneltrace kernelTrace = <32 bit hex-number | decimal number> [<32 bit hex-number | decimal number>]{0,7}

rombuild only

Initial value for the kernel trace +mask. You can supply upto eight separate 32 bit masks in order to +enable higher trace flags. The bit values are defined in nk_trace.h, and only apply to a debug Kernel.

To define kernel trace in an .oby file is optional. +The default value is set as 0x80000000 if kernel +trace is not defined. This default value allows the kernel to raise +a panic when an error occurs during runtime. If an invalid value is +set, Buildrom removes the invalid value. For example, if kernel trace +has only 1 invalid bit mask value, Buildrom removes it and resets +the default value.

+
LANGUAGE_CODE LANGUAGE_CODE NN

BUILDROM only

Localisation support. Specifies +the Symbian 2-digit codes for languages to be supported in this ROM. +The keyword may be used as many times as necessary.

+
maxunpagedsize maxunpagedsize <maximum_size_of_unpaged_data>

rombuild only

Sets the maximum value for the +size of uncompressed unpaged data for which you can flash the image. +If the size of the unpaged data is greater than maximum_size_of_unpaged_data, a warning message is displayed.

+
memmodel memmodel = moving | direct | multiple <chunk size> <page size>

rombuild only

Specifies the memory model to +be used at runtime together with the chunk size and the page size.

+
multikernel multikernel

rombuild only

Specifies that the ROM image has +multiple kernel executables. These kernels are specified with multiple +primary keywords in the files-section.

Note that this keyword +is mutually exclusive with singlekernel keyword.

+
MULTI_LINGUIFY <xxx>=MULTI_LINGUIFY(EXT <sourcename> <destname>)

BUILDROM only

Localisation support. During the +localisation pass, the MULTI_LINGUIFY lines are expanded into one +line per language code.

For example, the line:

data=MULTI_LINGUIFY( EXT sourcename destname )

is expanded to the lines:

data=sourcename.Enn destname.EXT +data=sourcename.Enn destname.Enn

The first line is +for the default language code; the remaining lines are for all other +language codes.

This provides support for the BaflUtils::NearestLanguageFile() function, which performs a similar mapping from language codes to +filenames.

+
nowrapper nowrapper

rombuild only

Specifies that no ROM wrapper +is required.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-622D6337-E60A-5252-8B2B-BA8232927453-master.png Binary file Adaptation/GUID-622D6337-E60A-5252-8B2B-BA8232927453-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-622D6337-E60A-5252-8B2B-BA8232927453_d0e29152_href.png Binary file Adaptation/GUID-622D6337-E60A-5252-8B2B-BA8232927453_d0e29152_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-627FC480-AF4F-4B23-8671-6E0A0DABA0EF.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-627FC480-AF4F-4B23-8671-6E0A0DABA0EF.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,44 @@ + + + + + +Baseport Template Testing GuideExplains how to test the Baseport Template implementation. +

There is no conformance testing suite available for Baseport Template. +However, Kernel testing (E32) and File system testing (F32) tests +should be run with 100% pass rate for any successful baseport. The +E32 and F32 tests are written to test the generic base code using +very minimal hardware services. As a result, if the baseport cannot +pass the minimal requirements of the base code, it is unlikely that +it will be suitable for running a production device.

+
Baseport +Template tests

The Baseport Template is designed to boot +on any hardware. It should boot successfully, but clearly, the system +can do nothing more at this time. A successful boot shows that your +build environment has been set up correctly.

You can conduct +a series of tests to check if the template works correctly. To test +different functionality of the template, see:

    +
  • DMA +Testing Overview for information on DMA testing.

  • +
  • SDIO +Implementation Testing Guide for information on SDIO testing.

  • +
  • Kernel +API Validity Checks for information on testing the Kernel APIs.

  • +
  • Performance +Logging for information on writing trace logs and testing the +performance.

  • +
  • Validation for information on how to test a USB port.

  • +
  • Testing +the PRM PSL for information on how to test the Power Resource +Manager (PRM).

  • +
  • Platform +Specific Layer Validation for information on how to test a +port of the MMC Controller.

  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-63456B20-3A61-554A-BBA4-C23B176E39A8.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-63456B20-3A61-554A-BBA4-C23B176E39A8.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,433 @@ + + + + + +Pre-Conditions +and Post-Conditions for Kernel APIsReference documentation for kernel side function APIs, specifies +a wide variety of pre-conditions and post-conditions. +
    +
  • A pre-condition is +something that must be true before using the function.

  • +
  • A post-condition is +something that is true on return from the function.

  • +
+

Such conditions are expressed using a standard phrase, wherever possible, +and this section explains what those conditions mean.

+

Where more than one pre-condition is stated for a given function, then +you can assume that all pre-conditions apply. In this sense, there is an implied +AND relation between conditions. For example, in the description of the function DObject::AppendFullName(), +the following pre-conditions apply:

+No fast mutex can be held. +Call in a thread context. +

Both conditions must be true before calling the functions.

+

There are exceptions to this rule, where a precondition applies only if +some other factor is true. For example, in the description of the function DObject::TraceAppendName(), +you will find the following pre-conditions:

+Call either in a thread or an IDFC context, if aLock=TRUE +Call in any context, if aLock=FALSE. +

Clearly, only one pre-condition will apply, depending on the supplied value +of the aLock argument.

+

A few conditions are self-explanatory, and these are not included in these +lists.

+

NOTE that some familiarity with kernel side programming is assumed.

+
    +
  • Pre-conditions

  • +
  • Post-conditions

  • +
+
Pre-conditions

This +describes the meaning of each precondition, and tries to provide insight as +to why it needs to be satisfied, and explains what you need to do to ensure +that the preconditions are met.

    +
  • Calling thread must be in a critical section

  • +
  • Calling thread must not be in a critical section

  • +
  • Calling thread can either be in a critical section or not

  • +
  • No fast mutex can be held

  • +
  • Kernel must be locked

  • +
  • Kernel must be unlocked

  • +
  • Kernel can be locked or unlocked

  • +
  • Kernel must be locked, with lock count 1

  • +
  • Interrupts must be enabled

  • +
  • Interrupts must be disabled

  • +
  • Interrupts can either be enabled or disabled

  • +
  • System lock must be held

  • +
  • System lock must not be held

  • +
  • Call in a thread context

  • +
  • Call in an IDFC contex

  • +
  • Call either in a thread or an IDFC context

  • +
  • Call in any context

  • +
  • Do not call from an ISR

  • +
  • The calling thread must own the semaphore

  • +
  • The calling thread must not be explicitly suspended

  • +
  • The calling thread must hold the mutex

  • +
  • Call only from ISR, IDFC or thread with the kernel locked

  • +
  • Call only from IDFC or thread with the kernel locked

  • +
  • Do not call from thread with the kernel unlocked

  • +
  • Do not call from ISR or thread with the kernel unlocked

  • +
  • Thread must not already be exiting

  • +
  • Property has not been opened

  • +
  • Property has been opened

  • +
  • Must be called under an XTRAP harness or calling thread must not be in a +critical section

  • +
  • DObject::Lock fast mutex held

  • +
  • DCodeSeg::CodeSegLock mutex held

  • +
  • Any kind of lock can be held

  • +
  • Call only from Init1() in base port

  • +
  • The various parameters must be valid. The PIL or PSL will fault the kernel +if not

  • +
  • The request is not being transferred or pending

  • +
  • Wait on TimerMutex before calling this

  • +
  • Message must be in ACCEPTED state

  • +
  • Queue must not be in asynchronous receive mode

  • +
  • Container mutex must be held

  • +
  • Thread container mutex must be held

  • +
  • Process container mutex must be held

  • +

Calling thread must be in +a critical section

Critical sections are sections of code that +leave the kernel in a compromised state if they cannot complete. A thread +enters a critical section by calling NKern::ThreadEnterCS() and +leaves it by calling NKern::ThreadLeaveCS().

While +in a critical section, the thread cannot be suspended or killed. These actions +are deferred until the end of the critical section. If a thread takes an exception +while inside a critical section, this is treated as fatal to the system, and +cause a Kern::Fault().

The described function must +be in a critical section when called.

Calling thread must not +be in a critical section

Critical sections are sections of code +that leave the kernel in a compromised state if they cannot complete. A thread +enters a critical section by calling NKern::ThreadEnterCS() and +leaves it by calling NKern::ThreadLeaveCS().

While +in a critical section, the thread cannot be suspended or killed. These actions +are deferred until the end of the critical section. If a thread takes an exception +while inside a critical section, this is treated as fatal to the system, and +cause a Kern::Fault().

There are some functions winthin +the system that must NOT be in a critical section when called. This +applies to the described functions.

Calling thread can either +be in a critical section or not

Critical sections are sections +of code that leave the kernel in a compromised state if they cannot complete. +A thread enters a critical section by calling NKern::ThreadEnterCS() and +leaves it by calling NKern::ThreadLeaveCS().

While +in a critical section, the thread cannot be suspended or killed. These actions +are deferred until the end of the critical section. If a thread takes an exception +while inside a critical section, this is treated as fatal to the system, and +cause a Kern::Fault().

When this pre-condition applies +to the described function, it means that it does not matter whether the code +is in a critical section or not.

No fast mutex can be held

A +thread can hold no more than one fast mutex at any given time. The described +function uses a fast mutex, which means that on entry to the function, the +calling thread must not hold another one.

Kernel must be locked

Many +kernel side functions run with interrupts enabled, including code that manipulates +global structures, such as the thread ready list. To prevent such code from +being reentered and potentially corrupting the structure concerned, a lock +known as the kernel lock (sometimes referred to as the preemption lock) is +used.

Sections of code that need to be protected against rescheduling +call NKern::Lock(). Interrupt Service Routines (ISRs) can +still run but no other thread (or IDFC) can run until the kernel is unlocked +by a call to NKern::Unlock().

The pre-condition +means that the kernel lock must be set before calling the described function.

Kernel must be unlocked

Many +kernel side functions run with interrupts enabled, including code that manipulates +global structures, such as the thread ready list. To prevent such code from +being reentered and potentially corrupting the structure concerned, a lock +known as the kernel lock (sometimes referred to as the preemption lock) is +used.

Sections of code that need to be protected against rescheduling +call NKern::Lock(). Interrupt Service Routines (ISRs) can +still run but no other thread (or IDFC) can run until the kernel is unlocked +by a call to NKern::Unlock().

The pre-condition +means that the kernel lock must NOT be set when the described function +is called.

Kernel can be locked or +unlocked

Many kernel side functions run with interrupts enabled, +including code that manipulates global structures, such as the thread ready +list. To prevent such code from being reentered and potentially corrupting +the structure concerned, a lock known as the kernel lock (sometimes referred +to as the preemption lock) is used.

Sections of code that need to +be protected against rescheduling call NKern::Lock(). Interrupt +Service Routines (ISRs) can still run but no other thread (or IDFC) can run +until the kernel is unlocked by a call to NKern::Unlock().

The +pre-condition means that it does not matter whether the kernel lock is set +or unset when the described function is called.

Kernel must be locked, with +lock count 1

Many kernel side functions run with interrupts enabled, +including code that manipulates global structures, such as the thread ready +list. To prevent such code from being reentered and potentially corrupting +the structure concerned, a lock known as the kernel lock (sometimes referred +to as the preemption lock) is used.

Sections of code that need to +be protected against rescheduling call NKern::Lock(). Interrupt +Service Routines (ISRs) can still run but no other thread (or IDFC) can run +until the kernel is unlocked by a call to NKern::Unlock().

In +addition, calls to NKern::Lock() and NKern::Unlock() are +counted. The count value is zero when the kernel is unlocked; a call to NKern::Lock() adds +one to the count value, and a call to NKern::Unlock() subtracts +one from the count value.

The pre-condition means that there must +be exactly one call to Kern::Lock() that has not yet had +a matching call to Kern::Unlock().

See also NFastMutex::Wait().

Interrupts must be enabled

This +pre-condition states that interrupts must be enabled before calling the described +function.

Possible reasons why interrupts may need to be enabled include:

    +
  • the function needs interrupts +to occur; for example, it may wait for timer ticks.

  • +
  • the function may take +a long or potentially unbounded time to run, so interrupts need to be enabled +to guarantee bounded interrupt latency.

  • +

See also the function NKern::RestoreInterrupts() and +the associated function NKern::DisableInterrupts().

Interrupts must be disabled

This +pre-condition states that interrupts must be disabled before calling the described +function.

See also the function NKern::DisableInterrupts() and +the associated function NKern::RestoreInterrupts().

Interrupts can either be +enabled or disabled

This pre-condition states that it does not +matter whether interrupts are enabled or disabled before calling the described +function.

System lock must be held

The +system lock is a specific fast mutex that only provides exclusion against +other threads acquiring the same fast mutex. Setting, and acquiring the system +lock means that a thread enters an implied critical section.

The major +items protected by the system lock are:

    +
  • DThread member +data related to thread priority and status.

  • +
  • the consistency of the +memory map; on the kernel side, the state of user side memory or the mapping +of a process is not guaranteed unless (a) you are a thread belonging to the +process that owns the memory or (b) you hold the system lock.

  • +
  • the lifetime of DObject type +objects and references to them, including handle translation in Exec dispatch.

  • +

Note that the system lock is different from the kernel lock; the +kernel lock protects against any rescheduling. When the system lock is set, +the calling thread can still be pre-empted, even in the locked section.

The +system lock is set by a call to NKern::LockSystem().

The +pre-condition means that the system lock must be set before calling the described +function.

System lock must not be +held

See the pre-condition System +lock must be held for a brief description of the system lock.

The +system lock is unset by a call to NKern::UnlockSystem().

The +pre-condition means that the system lock must not be set before calling the +described function.

Call in a thread context

This +pre-condition means that the described function must be called directly, or +indirectly, from a DFC or a thread. The thread can be a user thread or a kernel +thread.

Call in an IDFC contex

This +pre-condition means that the described function must be called directly, or +indirectly, from an IDFC.

Note that when calling a function from an +IDFC:

    +
  • the kernel is locked, +so pre-emption is disabled

  • +
  • user memory cannot be +accessed

  • +
  • the function cannot +block or wait.

  • +

Call either in a thread +or an IDFC context

This pre-condition means that the described +function can be called directly, or indirectly, from an IDFC, a DFC or a thread. +The thread can be a user thread or a kernel thread.

Note that when +calling a function from an IDFC:

    +
  • the kernel is locked, +so pre-emption is disabled

  • +
  • user memory cannot be +accessed

  • +
  • the function cannot +block or wait.

  • +

Call in any context

This +pre-condition means that the described function can be called directly, or +indirectly, from an IDFC, a DFC or a thread, or it can be called from an Interrupt +Service Routine (ISR).

A thread can be a user thread or a kernel thread.

Note +that when calling a function from an IDFC:

    +
  • the kernel is locked, +so pre-emption is disabled

  • +
  • user memory cannot be +accessed

  • +
  • the function cannot +block or wait.

  • +

Do not call from an ISR

This +pre-condition means that the described function must not be called from an +Interrupt Service Routine (ISR).

Note that ISRs have the following +characteristics:

    +
  • they have an unknown +context

  • +
  • they must not allocate +or free memory

  • +
  • they cannot access user +memory

  • +
  • they must not call functions +that interfere with critical sections of code.

  • +

The calling thread must +own the semaphore

A semaphore can be waited on only by the thread +that owns it. This precondition is needed when the described function calls +a semaphore wait function.

The calling thread must +not be explicitly suspended

This refers to nanokernel threads, +not Symbian platform threads. The described function must not be used if the +thread is in the suspended state. One of the possible reasons for this is +that the described function does not check the thread's suspend count.

A +thread may be created suspended, or the thread may be put into a suspended +state using NThreadBase::Suspend(). If you don't know whether +or not the thread is suspended, use NThreadBase::CheckSuspendThenReady().

See +also NThreadBase::Resume() and NThreadBase::ForceResume().

Note +that these functions are for use only in an RTOS personality layer.

The calling thread must +hold the mutex

The calling thread has waited for a mutex and acquired +it. This precondition is needed when the thread is about to release the mutex, +ie call one of the Signal() functions.

Call only from ISR, IDFC +or thread with the kernel locked

See the pre-condition Kernel must be locked.

Call only from IDFC or thread +with the kernel locked

See the pre-condition Kernel must be locked.

Do not call from thread +with the kernel unlocked

See the pre-condition Kernel must be unlocked.

Do not call from ISR or +thread with the kernel unlocked

See the pre-condition Kernel must be unlocked.

Thread must not already +be exiting

The pre-condition means that the described function +should not be called after the thread has been killed.

In EKA2, threads +do not die immediately, they are placed on a queue to be deleted later.

Functions +with this pre-condition are not likely to used in a device driver.

Property has not been opened

A +property is a single value used by “Publish and Subscribe”. Each property +must be opened before it can be used. To open a property, use either RPropertyRef::Attach() or RPropertyRef::Open(). Once opened, the property cannot be opened again.

The pre-condition +means that the property must NOT already be open when the described +function is called.

Property has been opened

A +property is a single value used by “Publish and Subscribe”. Each property +must be opened before it can be used. To open a property, use either RPropertyRef::Attach() or RPropertyRef::Open(). Once opened, the property cannot be opened again.

The pre-condition +means that the property must already be open before calling the described +function.

Must be called under an +XTRAP harness or calling thread must not be in a critical section

Each +Symbian platform thread can be associated with a kernel-side +exception handler, set using XTRAP(); for example, to detect bad memory accesses.

The +described function can legitimately cause an exception, and the pre-condition +means that

either:

    +
  • the described function +should be called inside an XTRAP() harness to catch the exception

  • +

or

    +
  • the thread must not +be in a critical section, because exceptions are not allowed inside them. +If a thread takes an exception while inside a critical section, this is treated +as fatal to the system, and causes a Kern::Fault().

  • +

DObject::Lock fast mutex +held

The described function accesses an object whose internal +data needs to be protected by the specified fast mutex.

The operations +of:

    +
  • obtaining an object’s +name

  • +
  • setting an object's +name

  • +
  • setting an object's +owner

  • +

are all protected by the global fast mutex, DObject::Lock. +This is done to avoid inconsistent results caused by, for example, one thread +renaming an object while another is reading its name or full name.

Setting +the owner is protected as the owner's name is part of the object's full name.

DCodeSeg::CodeSegLock mutex +held

The DCodeSeg::CodeSegLock mutex protects +the global code graph from simultaneous accesses. Wait on this mutex before +calling the described function, e.g. by calling DCodeSeg::Wait().

Any kind of lock can be +held

The described function can be called with any kind of lock.

Call only from Init1() in +base port

The pre-condition means that the described function +can only be called during the first phase of kernel initialisation, i.e. during +execution of the Base Port implementation of Asic::Init1(). +See the Board Support +Packages Quick Start.

This condition may apply because the +described function:

    +
  • must be called before +any context switch

  • +
  • must be called before +the MMU is turned on.

  • +

The various parameters must +be valid. The PIL or PSL will fault the kernel if not

This pre-condition +refers to a DMA request.

The parameters used when calling the described +function must be as specified. If they are not, the platform independent layer +or the platform specific layer cannot recover and will cause the kernel to +fault, i.e. the device will reset.

The request is not being +transferred or pending

This pre-condition refers to a DMA request.

The +described function must not be called if a DMA request has already been set +up, or is in progress. A possible reason for this is that the described function +resets parameters that have been already setup.

Wait on TimerMutex before +calling this

The TimerMutex mutex protects the +timer queues. Wait and signal operations on the timer mutex are accomplished +with the static functions TTickQ::Wait() and TTickQ::Signal(). +This precondition is necessary when the described function manipulates the +timer queue.

Message must be in ACCEPTED +state

This pre-condition indicates that the message has been read +by the receiving thread. It is not attached to a message queue but is currently +in use by the receiving thread.

Queue must not be in asynchronous +receive mode

This pre-condition refers to kernel side message +queues. A kernel thread can receive messages:

    +
  • asynchronously by calling TMessageQue::Receive()

  • +
  • by polling, by calling MessageQue::Poll()

  • +

A possible reason for this precondition is that the queue is about +to be polled.

The queue may be polled either:

    +
  • before the first Receive() is +issued

  • +
  • while processing a message +but before Receive() is called again

  • +

Container mutex must be +held / Thread container mutex must be held / Process container mutex must +be held

Each of the containers is protected by a mutex.

The +pre-condition means that the calling thread must acquire the relevant mutex +before calling the described function. Object containers are DObjectCon types, +and the relevant mutexes are acquired and freed by calling Wait() and Signal() on +the container object.

+
Post-conditions

A +post condition describes what is true on return from a kernel API function.

    +
  • Calling thread is in a critical section

  • +
  • Calling thread is not in a critical section

  • +
  • No fast mutex is held

  • +
  • Kernel is locked

  • +
  • Kernel is unlocked

  • +
  • Kernel is locked, with lock count 1

  • +
  • Interrupts are enabled

  • +
  • Interrupts are disabled

  • +
  • System lock is held

  • +
  • The calling thread holds the mutex

  • +
  • Container mutex is held

  • +
  • Thread container mutex is held

  • +
  • Process container mutex is held

  • +
  • DCodeSeg::CodeSegLock mutex held

  • +

Calling thread is in a critical +section

The code is in a critical section on return from the function.

See +also the pre-condition: Calling +thread must be in a critical section.

Calling thread is not in +a critical section

The code is NOT in a critical section +on return from the function.

See also the pre-condition: Calling thread must not be in a critical section.

No fast mutex is held

A +thread can hold no more than one fast mutex at any given time. A fast mutex +is NOT held on exit from the function.

Kernel is locked

The +post-condition means that, on exit from the described function, the kernel +lock is on. The described function might have explicitly set the kernel lock +or, more commonly, the lock was set before entry to the described function, +and has not been unset by that function.

See also the pre-condition Kernel +must be locked.

Kernel is unlocked

The +kernel is NOT locked on exit from the described function. The described +function might have explicitly unset the kernel lock or, more commonly, the +lock was not set before entry to the described function, and has not been +set by that function.

See also the pre-condition Kernel must be unlocked.

Kernel is locked, with lock +count 1

See the pre-condition Kernel +must be locked, with lock count 1.

Interrupts are enabled

This +post-condition states that interrupts are enabled on return from the described +function.

See the pre-condition Interrupts +must be enabled

Interrupts are disabled

This +post-condition states that interrupts are disabled on return from the described +function.

See the pre-condition Interrupts +must be disabled

System lock is held

This +post-condition states that the system lock is held on return from the described +function.

The system lock is a specific fast mutex that only provides +exclusion against other threads acquiring the same fast mutex. Setting, and +acquiring the system lock means that a thread enters an implied critical section.

The +major items protected by the system lock are:

    +
  • DThread member +data related to thread priority and status.

  • +
  • the consistency of the +memory map; on the kernel side, the state of user side memory or the mapping +of a process is not guaranteed unless (a) you are a thread belonging to the +process that owns the memory or (b) you hold the system lock.

  • +
  • the lifetime of DObject type +objects and references to them, including handle translation in Exec dispatch.

  • +

System lock is different from the kernel lock; the kernel +lock protects against any rescheduling. When the system lock is set, the calling +thread can still be pre-empted, even in the locked section.

The +system lock is set by a call to NKern::LockSystem(), and +unset by call to NKern::UnlockSystem().

The calling thread holds +the mutex

The calling thread has waited for a mutex and acquired +it. On return from the described function, the thread still holds the mutex.

See +also the pre-condition The +calling thread must hold the mutex.

Container mutex is held +/ Thread container mutex is held / Process container mutex is held

Each +of the containers is protected by a mutex.

The post-condition means +that the calling thread has the relevant mutex on return from the described +function. This is most likely because the mutex was acquired before entering +the described function.

Object containers are DObjectCon types, +and the relevant mutexes are acquired and freed by calling Wait() and Signal() on +the container object.

DCodeSeg::CodeSegLock mutex +held

The DCodeSeg::CodeSegLock mutex protects +the global code graph from simultaneous accesses.

This post condition +means that the mutex is held on exit. The most common situation is that the +mutex was acquired before entry to the described function. Relinquish the +mutex by calling DCodeSeg::Signal().

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-6381BC82-3060-5023-8221-79B18CCB2CDB.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-6381BC82-3060-5023-8221-79B18CCB2CDB.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,14 @@ + + + + + +Writable Data +Paging GuidesContains guides that describe various aspects of writable data +paging in more detail. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-63CDD34D-936A-459C-B40B-495696204722.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-63CDD34D-936A-459C-B40B-495696204722.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,148 @@ + + + + + +Baseport Template Quick StartThis document describes how to get started with the Baseport +Template and also, briefly explains the baseport architecture. +

The Baseport Template is the most important part of the system, +since it consists of the kernel and essential peripherals.

+
Getting +started with the Baseport Template

The Baseport Template +Client Interface Guide describes the Baseport +Template APIs.

The Baseport Template +Build Guide section describes how to build the Baseport Template +platform service.

The Baseport Template +Configuration Guide section describes how to configure the +Baseport Template platform service.

The Baseport Template +Testing Guide section describes how to test the Baseport Template +platform service.

The Baseport Template +Tools Guide section describes the tools that are specific to +the Baseport Template platform service.

+
Baseport +architecture

The simplified architecture of the Baseport +Template platform service and how it fit into the Symbian platform +is shown below:

+The system architecture (simplified) + +

In the above diagram, the following are not part of the Baseport +Template:

+ + + +

Legend

+

Purpose

+
+ + + +

EUSER

+

User library

+
+ +

EWSRV

+

Window server

+
+ +

EFILE

+

File server

+
+ +

ESTART

+

Initializes the file system

+
+ +

HAL

+

Hardware Abstraction Layer

+
+ +

MMU

+

Memory Management Unit

+
+ + +

In the above diagram, the following are part of the Baseport +Template:

+ + + +

Legend

+

Purpose

+
+ + + +

Kernel

+

The kernel

+
+ +

1

+

Variant PDD

+
+ +

2

+

Debugging PDD

+
+ +

3

+

Serial comms PDD

+
+ +

4

+

LCD PDD

+
+ +

5

+

Digitizer PDD

+
+ +

6

+

Power control PDD

+
+ +

7

+

Keyboard PDD

+
+ +

8

+

Keyboard map PDD

+
+ +

9

+

Log Flash File System (LFFS) PDD

+
+ +

10

+

Sound PDD

+
+ +

11

+

Camera PDD

+
+ +

12

+

I2S PDD

+
+ +

13

+

IIC PDD

+
+ + +
+
Key +users of the Baseport Template

The Baseport Template is +of interest to engineers who are to port the Symbian platform to a +new hardware platform. Along with engineers that are producing drivers +that will cover the functionality in the above table. This document +is of interest to:

    +
  • Device driver and kernel-side component developers

  • +
  • Hardware implementors and base port developers.

  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-647ADEDA-AB5A-548F-93C3-D099EAE6A030-master.png Binary file Adaptation/GUID-647ADEDA-AB5A-548F-93C3-D099EAE6A030-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-647ADEDA-AB5A-548F-93C3-D099EAE6A030_d0e17089_href.png Binary file Adaptation/GUID-647ADEDA-AB5A-548F-93C3-D099EAE6A030_d0e17089_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-654A788A-526A-4C3F-838C-05B09F0D5445.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-654A788A-526A-4C3F-838C-05B09F0D5445.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,109 @@ + + + + + +Interrupt Technology GuideDescribes the concepts of the Interrupts platform service. +

The Interrupt platform service provides an interface to the kernel +and device drivers to associate interrupt with an Interrupt Service +Routine (ISR). There are three levels of interrupt management:

    +
  1. CPU level: Control +of interrupts available only to the kernel.

  2. +
  3. Controller level: +Control provided by functions of the Interrupt class.

  4. +
  5. Device level: +Control of hardware sources that are managed by a device specific +control scheme.

  6. +

+
+ Key concepts
+ +
Interrupt
+

An interrupt is a hardware or a software event that may need +to be serviced. An example of a hardware interrupt is a key press +.

+
+ +
Interrupt ID
+

The unique ID of an interrupt source. The interrupt ID are +defined by the developers creating ASSP and variant.

+
+ +
Spurious interrupts
+

Interrupts not associated with an Interrupt Service Routine +are called the spurious interrupts. The spurious interrupts are handled +by a spurious interrupt handler which is only used for debugging.

+
+ +
ISR
+

An Interrupt Service Routine (ISR ) is the function to handle +an interrupt. ISR is not a class member. ISR provides the minimum +processing such as storing data that may not be available later and +requests a DFC for further processing.

+
+ +
Interrupt priority
+

The Interrupt platform service allows developers to set a priority +for each interrupt source. The meaning of the priority value depends +on the hardware and the baseport implementation.

+
+ +
Interrupt dispatch
+

When an interrupt is received by the system, it calls the associated +ISR. This is called interrupt dispatch. The interrupt dispatch is +provided by the implementation of the interrupt class +in the ASSP layer.

+
+ +
ISR table
+

The table that maps the interrupt ID and the associated ISR. +The ISR table is implemented by the developers creating the baseport +variant.

+
+ +
Binding
+

The process of associating an interrupt ID with an ISR. Unbinding +removes the association.

+
+ +
Chained interrupts
+

The output of a low priority interrupt controller is provided +as an input to a higher priority interrupt controller.

+
+
+ +
Pseudo-interrupts
+

Pseudo-interrupts correspond to multiple interrupt sources +sharing a single input to an interrupt controller but requiring separate +ISRs to service them. The ISRs cannot all be bound to the single real +interrupt and are therefore bound to the pseudo-interrupt instead.

+
+
+ +
IRQs and FIQs
+

An IRQ (interrupt request) is the signal generated by an item +of hardware or software to request an interrupt from the processor. +An FIQ (fast IRQ) is an IRQ with high priority on systems +which support prioritization of requests.

+
+
+
Typical +uses

The Interrupt platform service allows the kernel and +device drivers to :

    +
  • associate an ISR with an interrupt ID

  • +
  • enable/disable a specific interrupt

  • +
  • clear pending actions on a specific interrupt

  • +
  • change the priority of a specific interrupt.

  • +
+
+Interrupt +Implementation Guide +Handling +Interrupts +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-6597A895-37D5-51D1-86B3-E74F6E845899-master.png Binary file Adaptation/GUID-6597A895-37D5-51D1-86B3-E74F6E845899-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-6597A895-37D5-51D1-86B3-E74F6E845899_d0e23392_href.png Binary file Adaptation/GUID-6597A895-37D5-51D1-86B3-E74F6E845899_d0e23392_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-65CDCA83-C726-5173-8E46-B8981D1D7B02.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-65CDCA83-C726-5173-8E46-B8981D1D7B02.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,62 @@ + + + + + +Battery +Monitor Implementation TutorialA base port can implement code to monitor the battery of the phone +and to provide notifications when the battery power is low. +

The battery monitor code is implemented in the power controller kernel +extension.

+

Note: to implement battery monitor code, the battery monitor hardware must +be accessible to the Application CPU of the phone.

+

Typically, your battery monitor class would derive from the DBatteryMonitor class, +defined as:

+class DBatteryMonitor + { +public: + IMPORT_C DBatteryMonitor(); + IMPORT_C void Register(); +public: + virtual TSupplyStatus MachinePowerStatus() = 0; + virtual void SystemTimeChanged(TInt anOldTime, TInt aNewTime) = 0; + }; +

Symbian platform considers that batteries can be in one of 4 possible logical +states, defined by the TSupplyStatus enum. It is up to the +implementor of the battery monitor component to map these logical states to +points on the main battery discharge curve.

+

There are two pure virtual functions to be implemented:

+
    +
  • DBatteryMonitor::MachinePowerStatus()

  • +
  • DBatteryMonitor::SystemTimeChanged()

  • +
+

We also suggest that the battery monitor component offer a public function +prototyped as:

+void SupplyInfo(TSupplyInfoV1& si); +

to supply information about the state of the main battery and the backup +battery (if there is one), or external power to user side components that +may require it (e.g. a user-side power monitor component that is used to track +the state of batteries and initiate an orderly shutdown if it reaches a critically +low level), and is usually called by the EHalGroupPower handler +for EPowerHalSupplyInfo in response to calling HAL::Get() with EPowerGood, EPowerBatteryStatus, EPowerBackupStatus, and EPowerExternal. +Such a function would need to fill in a subset of the fields defined by TSupplyInfoV1.

+
DBatteryMonitor::MachinePowerStatus() virtual TSupplyStatus MachinePowerStatus() = 0;

This +should read and return the logical state of the main battery or, if external +power is connected, it should return EGood.

When +is it called?

The function is called by peripheral drivers via +a call to Kern::MachinePowerStatus() before starting lengthy +operations or operations that may result in a substantial increase in power +consumption.

Implementation issues

A suggested implementation +would have the function reading the state of the main battery, or whether +external power is connected, and mapping to one of the logical states defined +by TSupplyStatus. When requested by the power manager it +returns the logical state.

+
DBatteryMonitor::SystemTimeChanged() virtual void SystemTimeChanged(TInt anOldTime, TInt aNewTime) = 0;

This +function is now deprecated, and you should just define an empty implementation.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-65F012C2-19BA-474E-8E94-D0E89DADF7B8.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-65F012C2-19BA-474E-8E94-D0E89DADF7B8.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,56 @@ + + + + + +Multiple +Unit SupportThis document describes how to support multiple units of hardware +with a single device driver. +
Supporting +multiple units

An LDD can support more than one device by +providing a separate channel to each device.

There can be more than +one PDD associated with a given LDD, where each PDD supports a different variation +of a similar device.

Alternatively, a single PDD can be designed to +support multiple instances of an identical device by supporting more than +one channel. For example, a platform that contains two identical UARTS could +support these by providing a PDD that can open a channel on either (or both) +UARTs.

Where a driver supports multiple devices on a platform, then +it uses a unit number to distinguish between each instance of the device. +Clients open a channel to the driver for a particular unit. The following +shows an example of this, and the example driver function that creates the +channel:

// User application opens the driver for unit1 +RExDriverChannel ldd; +r = ldd.Open(KUnit1); +test(r==KErrNone); // User side wrapper function to driver API +inline TInt RExDriverChannel::Open(TInt aUnit) + { + return DoCreate(KDriverName,VersionRequired(), + aUnit,NULL,NULL,EOwnerThread); + }
+
System information

The +driver must inform the framework that it supports the use of unit numbers. +A driver can use unit numbers to ensure that it only opens on one unit. This +is done by setting the DLogicalDevice::iParseMask bitmask +with the KDeviceAllowUnit flag.

// Logical Channel Second stage constructor +DExDriverLogicalDevice:: DExDriverLogicalDevice () + { + iParseMask = KDeviceAllowPhysicalDevice | KDeviceAllowUnit; + ... + }
+
Unit number +validation

The device driver framework validates if the driver +supports unit numbers. In the following example, the PDD checks if the unit +number passed is valid.

TInt DExH4PhysicalDevice::Validate(TInt aUnit, const TDesC8* +/*aInfo*/, const TVersion& aVer) + { + ... + if (aUnit<0 || aUnit>=KNumUarts) + return KErrNotSupported; + }
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-660A8E4C-F930-415C-8CCC-CB1DCCAA2442.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-660A8E4C-F930-415C-8CCC-CB1DCCAA2442.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,37 @@ + + + + + +InterruptsThis document describes how device drivers use interrupts. +
+

Devices generate interrupts to indicate hardware events. Generally +drivers provide an interrupt service routine (ISR) to handle the interrupts +and perform the required responses to the events. Symbian provides an Interrupt class +(implemented by the ASSP) with an API to bind and unbind an interrupt source +and an ISR.

// Bind the interrupt source ID and interrupt service routine +TInt Bind(TInt aId, TIsr aIsr, TAny* aPtr); +// Unbind the interrupt +TInt Unbind(TInt aId); +// Enable interrupts on device interrupt source +TInt Enable(TInt aId); +// Disable interrupts on device interrupt source +TInt Disable(TInt aId); +// Clear the device interrupt +TInt Clear(TInt aId); +// Set the priority of the interrupt +TInt SetPriority(TInt aId, TInt aPriority);

Interrupt handling +is typically done in a PDD, as device hardware access is done at that level. +Interrupt handling is generally done in two stages in the driver. High priority +and short time running tasks are done in the ISR, and the remaining processing +is deferred for handling later.

Interrupt handling is a blocking high +priority task and needs to take a minimal amount of time. The Kernel will +be in an indeterminate state and puts restrictions on doing various operations.

+
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-669C77A3-89BA-5321-ABB1-4356A5FE478C.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-669C77A3-89BA-5321-ABB1-4356A5FE478C.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,21 @@ + + + + + +Sound DriverDescribes how to create a port of the sound driver for your phone +hardware. +

The Sound Driver is a device driver that controls the audio hardware of +a phone. Symbian platform provides a User-Side API, a Logical Device Driver, +and a base class for physical channels. You must provide a PDD that implements +the physical channels that interface to the sound hardware on your phone.

+
+Integrated + Interchip Sound +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-66E5F769-1156-54CA-94BC-8912159A1240.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-66E5F769-1156-54CA-94BC-8912159A1240.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,62 @@ + + + + + +Testing +the PRM PSLThis document describes using the test suite for the PRM. +
Purpose

Use this test suite to ensure that your +Power Resource Manager implementation runs correctly.

Introduction

T_PRMACCTST is +a test application that verifies the resources registered with the PSL of +the PRM. For more information refer to the description of individual test +cases in e32test/resourceman/acctst/t_prmacctst.cpp.

The +following tasks are preformed by the test suite:

    +
  • enumerate all registered +resources,

  • +
  • check that resources +behave consistently with their properties,

  • +
  • ensure that resources +are reset to their default level when not in use,

  • +
  • ensure all actual resources +dependencies have been declared (only the extended version of the PRM allows +dependencies).

  • +

To ensure that single-user resources are available to the test application, T_PRMACCTST is +coupled with a kernel extension, D_PRMACCTST that takes control +of such resources immediately after the PRM has been initialised. It then +releases the resources when the test application ends.

+
Using the test suite

The instructions to run the +PRM acceptance test suite are as follows:

    +
  1. build the test code +in e32test/resourceman/acctst,

  2. +
  3. build a rom for H4HRP +of type prmacctst in e32/rombuild:

    rom +-v=h4hrp -I=armv5 -b=urel -t=prmacctst

    This command generates +a self-starting ROM. The test output is captured from the default debug port +of the device.

  4. +

To build a manual test ROM (so the test application does not run +automatically), use the -d=MANUALROM option. The usual ESHELL +command prompt will be displayed and the test application can be run by calling T_PRMACCTST.

Note: +This test must be run with minimal required components because the test driver +is a kernel extension and takes control of all single-user resources during +its entry point. This test randomly changes the state of all the resources +between a minimum and maximum value. If there are any restrictions on a resources +state change (i.e. the resource state can be only be changed to a certain +value) then that resource should not be registered while running this test.

+
+Porting the +Power Resource Manager +Implement +the controllable power resources +Implement +the PSL for the target +Port client +drivers to use the PRM +Debugging +the PRM +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-66FD040B-133E-57CF-80DD-9369F62709C6.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-66FD040B-133E-57CF-80DD-9369F62709C6.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,336 @@ + + + + + +Implement +the PSL for the targetThis document describes how to implement the Platform Specific +Layer for the Power Resource Manager. +
Purpose

The PSL must be implemented in order for +the PRM and the hardware to be able to communicate.

Introduction

The +PSL side of the Resource Controller should be derived from the class DPowerResourceController.

+
Implementing the PSL

The following tasks are +covered in this tutorial:

    +
  • Create an entry point,

  • +
  • Override the pure virtual functions,

  • +
  • Create static resources that support dependencies,

  • +
  • Initialise the pools,

  • +
  • Registering with the Power Controller.

  • +

Create an entry +Point

The PIL layer of the PRM offers the following macro. This +needs to be invoked from the PSL. The macro calls the DoInitController() and DoInitResources() functions +implemented by the PSL.

/** +Extension entry point +*/ +DECLARE_RESOURCE_MANAGER_EXTENSION() + { + __KTRACE_OPT(KBOOT, Kern::Printf("CreateController called")); + return new DH4PowerResourceController; + }

If the PRM is a PDD the entry point +is as follows:

static DH4PowerResourceController TheController; +DECLARE_STANDARD_PDD() + { + TInt r = DPowerResourceController::InitController(); + if® == KErrNone) + r = TheController->InitResources(); + if® == KErrNone) + return new DResConPddFactory; + return NULL; + }

Override +the pure virtual functions

Override the virtual functions of the DPowerResourceController base +class:

    +
  • DoInitController(),

  • +
  • DoRegisterStaticResources().

  • +

Here is an example H4 HRP implementation:

class DH4PowerResourceController : DPowerResourceController + { +public: + DH4PowerResourceController(); + TInt DoInitController(); + TInt DoRegisterStaticResources(DStaticPowerResource**& aStaticResourceArray, TUint16& aStaticResourceCount); +private: + static DStaticPowerResource* iResources[];

DoInitController()

Override DPowerResourceController::DoInitController() so that it creates +a DFC queue and then invokes the base class function DPowerResourceController::SetDfcQ(). DoInitController() should +also initialise the pools by invoking DPowerResourceController::InitPools() passing +the platform defined sizes for the pools of clients, client levels and request +objects. DoInitController() is called by the PSL +during its initialisation. Below is the reference implementation code.

#define KERNEL_CLIENTS 0x2 // Expected number of kernel clients (MMC and Sound_SC) +#define USER_CLIENTS 0x0 // No user side clients expected. +#define CLIENT_LEVELS 0x8 // Expected resource state change of 8 resources +#define REQUESTS 0x0 // No asynchronous operation (state change or read) expected. + +TInt DH4PowerResourceController::DoInitController() + { + // Create a DFC queue and then invoke SetDfcQ() +__KTRACE_OPT(KRESMANAGER, Kern::Printf(">DH4PowerResourceController::DoInitController\n")); + + // NKern::ThreadEnterCS(); // Not needed, as this is executed during kernel boot which is done within a critical section. + TInt r = Kern::DfcQCreate(iDfcQ,28,&KResThreadName); + + // NKern::ThreadLeaveCS(); + if (KErrNone!=r) return r; + SetDfcQ(iDfcQ); + r = InitPools(KERNEL_CLIENTS,USER_CLIENTS,CLIENT_LEVELS,REQUESTS); +__KTRACE_OPT(KRESMANAGER, Kern::Printf("<DH4PowerResourceController::DoInitController\n")); + return r; + }

DoRegisterStaticResources()

DoRegisterStaticResources() is called by the PIL during its initialisation. Override the pure virtual +function DPowerResourceController::DoRegisterStaticResources() so +that it:

    +
  • creates all the static +resources in the kernel heap,

  • +
  • creates an array of +pointers to the static resources (indexed by their id),

  • +
  • sets the passed pointer +(aStaticResourceArray) to point to the created array of pointers,

  • +
  • updates the count of +the static resources (in aStaticResourceCount).

  • +

The reference implementation is below:

TInt DH4PowerResourceController::DoRegisterStaticResources(DStaticPowerResource**& aStaticResourceArray, TUint16& aStaticResourceCount) + { + aStaticResourceCount = 0; + __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DH4PowerResourceController::DoRegisterStaticResources\n")); + aStaticResourceArray = (DStaticPowerResource**) new (DStaticPowerResource*[EH4ResourceCount]); + if(!aStaticResourceArray) + return KErrNoMemory; + + DH4MmcFclkResource *pMmcFclk = new (DH4MmcFclkResource); + if (!pMmcFclk) + return KErrNoMemory; + aStaticResourceArray[EMmcFclkRes] = pMmcFclk; + + DH4MmcIclkResource *pMmcIclk = new (DH4MmcIclkResource); + if (!pMmcIclk) + CLEAN_AND_RETURN(KErrNoMemory, EMmcIclkRes) + aStaticResourceArray[EMmcIclkRes] = pMmcIclk; + + DH4MmcClkResource *pMmcBusClk = new (DH4MmcClkResource); + if (!pMmcBusClk) + CLEAN_AND_RETURN(KErrNoMemory, EMmcClkRes) + aStaticResourceArray[EMmcClkRes] = pMmcBusClk; + + DH4MmcCtrllerPwrResource *pMmcCtrlrPwr = new (DH4MmcCtrllerPwrResource); + if (!pMmcCtrlrPwr) + CLEAN_AND_RETURN(KErrNoMemory, EMmcCtrlrPwrRes) + aStaticResourceArray[EMmcCtrlrPwrRes] = pMmcCtrlrPwr; + + DH4MmcPowerResource *pMmcPwr = new (DH4MmcPowerResource); + if (!pMmcPwr) + CLEAN_AND_RETURN(KErrNoMemory, EMmcPwrRes) + aStaticResourceArray[EMmcPwrRes] = pMmcPwr; + + DH4SndFclkResource *pSndFclk = new (DH4SndFclkResource); + if (!pSndFclk) + CLEAN_AND_RETURN(KErrNoMemory, ESndFclkRes) + aStaticResourceArray[ESndFclkRes] = pSndFclk; + + DH4SndIclkResource *pSndIclk = new (DH4SndIclkResource); + if (!pSndIclk) + CLEAN_AND_RETURN(KErrNoMemory ,ESndIclkRes) + aStaticResourceArray[ESndIclkRes] = pSndIclk; + + DH4SndMClkResource *pSndMclk = new (DH4SndMClkResource); + if (!pSndMclk) + CLEAN_AND_RETURN(KErrNoMemory, ESndMClkRes) + aStaticResourceArray[ESndMClkRes] = pSndMclk; + + aStaticResourceCount = EH4ResourceCount; + + __KTRACE_OPT(KRESMANAGER, Kern::Printf("<DH4PowerResourceController::DoRegisterStaticResources, Total resources:%d\n", EH4ResourceCount)); + + return KErrNone; + }

Create +static resources that support dependencies

If there are static +resources that support dependencies then the PSL must implement the function DPowerResourceController::DoRegisterStaticResourcesDependency(). Note: Static resources that support dependencies are only available +in the extended version of the library. See setup +and configuration.

The function DoRegisterStaticResourcesDependency():

    +
  • creates all static resources +that support dependencies in kernel heap,

  • +
  • creates an array of +pointers to them,

  • +
  • establishes the dependencies +between them (using the resource's DStaticPowerResourceD::AddNode() function), +See creating +dependencies between static resources for a description of AddNode() and +the SNode structure.

  • +
  • sets the passed pointer +(aStaticResourceDArray) to point to the array of pointers +to static resource with dependency,

  • +
  • updates the count of +the static resource that supports dependency in aStaticResourceDCount.

  • +

This function is called by the PIL during PRM initialisation. Below +is an example:

/** +This function creates all static resources that support dependencies and establishes the dependencies between them. This is called by the PIL. +This is the dependency tree input: + ResourceA <---------> ResourceD <-------> ResourceE <--------> ResourceC + | | + | | + | | + ResourceF ResourceG +*/ +TInt DSimulatedPowerResourceController::DoRegisterStaticResourcesDependency(DStaticPowerResourceD**& aStaticResourceDArray, TUint16& aStaticResourceDCount) + { + aStaticResourceDArray = (DStaticPowerResourceD**) new (DStaticPowerResourceD*[MAX_DEPENDENT_RESOURCE_COUNT]); + if(!aStaticResourceDArray) + return KErrNoMemory; + + DStaticPowerResourceD* pR = NULL; + + pR = new DMLSLGLSPDependResource(); + if(!pR) + CLEAN_AND_RETURN(iStaticResDependencyCount, aStaticResourceDArray, KErrNoMemory) + aStaticResourceDArray[iStaticResDependencyCount++] = pR; + + pR = new DMLSIGLSNDependResource(); + if(!pR) + CLEAN_AND_RETURN(iStaticResDependencyCount, aStaticResourceDArray, KErrNoMemory) + aStaticResourceDArray[iStaticResDependencyCount++] = pR; + + pR = new DBSIGLSPDependResource(); + if(!pR) + CLEAN_AND_RETURN(iStaticResDependencyCount, aStaticResourceDArray, KErrNoMemory) + aStaticResourceDArray[iStaticResDependencyCount++] = pR; + + pR = new DMLSHIGLSPDependResource(); + if(!pR) + CLEAN_AND_RETURN(iStaticResDependencyCount, aStaticResourceDArray, KErrNoMemory) + aStaticResourceDArray[iStaticResDependencyCount++] = pR; + + pR = new DBSHLGLSNDependResource(); + if(!pR) + CLEAN_AND_RETURN(iStaticResDependencyCount, aStaticResourceDArray, KErrNoMemory) + aStaticResourceDArray[iStaticResDependencyCount++] = pR; + + pR = new DMLSHLGLSNDependResource(); + if(!pR) + CLEAN_AND_RETURN(iStaticResDependencyCount, aStaticResourceDArray, KErrNoMemory) + aStaticResourceDArray[iStaticResDependencyCount++] = pR; + + // Establish resource dependencies + if(CreateResourceDependency(aStaticResourceDArray)) + CLEAN_AND_RETURN(iStaticResDependencyCount, aStaticResourceDArray, KErrNoMemory) + + iDependencyResources = aStaticResourceDArray; + + aStaticResourceDCount = iStaticResDependencyCount; + return KErrNone; + } + +// This function establishes above dependency between static dependent resource +TInt DSimulatedPowerResourceController::CreateResourceDependency(DStaticPowerResourceD** pResArray) + { + iNodeArray = new SNode[10]; + SNode* pN1; + SNode* pN2; + iNodeCount = 0; + + if(!iNodeArray) + return KErrNoMemory; + // Create Dependency between Resource A and Resource D + pN1 = &iNodeArray[iNodeCount++]; + pN2 = &iNodeArray[iNodeCount++]; + CREATE_DEPENDENCY_BETWEEN_NODES(pN1, pN2, pResArray[0], pResArray[1], 1, 1) + + // Create Dependency between Resource D and Resource F + pN1 = &iNodeArray[iNodeCount++]; + pN2 = &iNodeArray[iNodeCount++]; + CREATE_DEPENDENCY_BETWEEN_NODES(pN1, pN2, pResArray[0], pResArray[2], 1, 3) + + // Create Dependency between Resource D and Resource E + pN1 = &iNodeArray[iNodeCount++]; + pN2 = &iNodeArray[iNodeCount++]; + CREATE_DEPENDENCY_BETWEEN_NODES(pN1, pN2, pResArray[0], pResArray[3], 3, 2) + + // Create Dependency between Resource E and Resource C + pN1 = &iNodeArray[iNodeCount++]; + pN2 = &iNodeArray[iNodeCount++]; + CREATE_DEPENDENCY_BETWEEN_NODES(pN1, pN2, pResArray[3], pResArray[4], 1, 1) + + // Create Dependency between Resource E and Resource G + pN1 = &iNodeArray[iNodeCount++]; + pN2 = &iNodeArray[iNodeCount++]; + CREATE_DEPENDENCY_BETWEEN_NODES(pN1, pN2, pResArray[3], pResArray[5], 1, 2) + + return KErrNone; + } + +#define CREATE_DEPENDENCY_BETWEEN_NODES(pN1, pN2, pRes1, pRes2, priRes1, priRes2) \ + pN1->iPriority = priRes1; \ + pN1->iResource = pRes1; \ + pN1->iPropagatedLevel = 0; \ + pN1->iVisited = EFalse; \ + pN2->iPriority = priRes2; \ + pN2->iResource = pRes2; \ + pN2->iPropagatedLevel = 0; \ + pN2->iVisited = EFalse; \ + pN1->iResource->AddNode(pN2); \ + pN2->iResource->AddNode(pN1);

Creating +dependencies between static resources

DStaticPowerResourceD::AddNode() is +used to establish a dependency between static resources. Dependencies between +static resources cannot be removed.

AddNode() takes +a pointer to an SNode object that contains the dependent +resource information. This passed node pointed is added to the resource dependency +list within the class DStaticPowerResourceD. Note: +the kernel panics if the specified dependency priority is already in use.

Information +within SNode includes:

    +
  • iResource is +a pointer to dependent resource,

  • +
  • iPriority is +the priority of the dependency resource. This is used by the PRM when propagating +the resource change,

  • +
  • iSpare is +reserved for future use,

  • +
  • iNext is +a pointer to next node in the list.

  • +

The members iPropagatedLevel, iRequiresChange and iVisited are +used internally by the PRM.

To link to dynamic resources that support +dependency use the PRM function RegisterResourceDependency() as +described in creating +resource dependencies.

Initialise +the pools

Pools are implemented as singly linked lists during +the initialisation of the PRM. The PSL initialises the pools by invoking DPowerResourceController::InitPools() and +passing the platform defined sizes for the pools of kernel side clients, user +side clients, client levels and requests. See the example DoInitController() implementation.

The PRM has three +types of pools:

    +
  • client pools to store +client information,

  • +
  • request pools to send requests for operation on long latency resource +to the Resource Controller thread,

  • +
  • client level pools to capture the resource level request by each client +for a resource.

  • +

If the client pool is set to zero, then the PRM will not allow a +client of that type to register. For example, if the kernel side clients pool +is set to zero, then the PIL will not allow any kernel side clients to register. +The size of the client pools to specify depends on how many kernel side device +drivers (clients) and user side clients will access PRM and size of request +pool depends on the number of long latency resource available in the system. +Size of client level pool depends on number of clients that will request a +resource state change. If the client pools are exhausted the PIL will try +to increase the size of the pool. The size of the pool never decreases.

Registering with the Power +Controller

The Resource Controller must call DPowerController::RegisterResourceController() to +register itself with the Power Controller. RegisterResourceController() sets +the iResourceControllerData.iResourceController data member +within DPowerController to the passed Resource Controller +pointer and sets iResouceControllerData.iClientId to the +client ID used by the Power Controller when calling the Resource Controller's +APIs.

The platform specific implementation of the Power Controller +overrides the RegisterResourceController() function. See DPowerController::RegisterResourceController().

Idle power management

The resource controller's APIs +cannot be called from a NULL thread. However, the PSL may need to know the +state of the resources from a NULL thread to take the system to appropriate +power states. To allow access to this information the PRM provides the virtual +function DPowerResourceController::RegisterResourcesForIdle().

+
+Porting the +Power Resource Manager +Implement +the controllable power resources +Port client +drivers to use the PRM +Debugging +the PRM +Testing the +PRM PSL +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-670B0580-B81B-4211-A4C0-23A2D8EDF96C.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-670B0580-B81B-4211-A4C0-23A2D8EDF96C.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,24 @@ + + + + + +Time Build GuideHow to build a Time platform service. +

The Time platform service is a plug-in to the System State Manager.

+
Requirements
    +
  • System state manager

  • +
  • You must be familiar with building ROM for the Symbian platform.

  • +
+
Reference +code

A reference template is provided at os/devicesrv/sysstatemgmt/systemstateplugins/adptplugin/inc/rtcadaptationref.h. Use the reference code as a guide to implement on +the hardware.

Note that the reference source code is not supported +on the emulator.

+
Building +a ROM

The system state manager plug-ins are built as a DLL.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-6752A77F-B1D1-49BE-A672-5DDE3B7976BF.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-6752A77F-B1D1-49BE-A672-5DDE3B7976BF.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,32 @@ + + + + + +Other +Synchronisation APIsThis document describes APIs other than the nanokernel which device +drivers use for synchronisation. +

The Kernel provides APIs to wait in blocked state, unblocked state, and +nanokernel APIs to get the tick period, timer ticks, to sleep on nanothread, +and so on.

+// Wait for a length of time specified in nanoseconds +// This is a blocking call, and is not generally recommended +// to be used. It should be used only for very short periods. +// +Kern::NanoWait(TUint32 aInterval); + +// This API polls at specified regular intervals, for a +// specified number of attempts. A function implementing the polling +// operation is called at these intervals. This does not block the +// thread. The poll period is in milliseconds. +// +TInt Kern:: PollingWait(TPollFunction aFunction, TAny *aPtr, + TInt aPollPeriodMs, TInt aMaxPoll); + +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-6786C7D8-34B9-496C-890E-03DE018D2DE1.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-6786C7D8-34B9-496C-890E-03DE018D2DE1.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,85 @@ + + + + + +IIC Testing GuideDescribes how to test an IIC platform service implementation +

The IIC bus has a standard IIC +bus specification v2-1 Jun 2000. For generic testing, there +is also an IIC test harness.

+
IIC +test source files

The following test code is available to +test an IIC port.

+ + + + +

File

+

Description

+

Location

+

Usage

+
+ + + +

t_iic.exe

+

This file interacts with test-specific LDD to instigate +tests of functionality that would normally be invoked by kernel-side +device driver clients of the IIC

+

/sf/os/kernelhwsrv/kerneltest/e32test/iic/t_iic.cpp

+

Mandatory

+
+ +

iic_client_ctrless.ldd

+

Kernel-side proxy LDD acting as a client of the IIC.

+

/sf/os/kernelhwsrv/kerneltest/e32test/iic/t_iic.cpp

+

Mandatory

+
+ +

iic_slaveclient_ctrless.ldd

+

Kernel-side proxy LDD acting as a slave client of the IIC.

+

/sf/os/kernelhwsrv/kerneltest/e32test/iic/t_iic.cpp

+

Mandatory

+
+ +

iic_client.ldd

+

Kernel-side proxy LDD acting as a client of the IIC.

+

/sf/os/kernelhwsrv/kerneltest/e32test/iic/t_iic.cpp

+

Mandatory

+
+ +

iic_slaveclient.ldd

+

Kernel-side proxy LDD acting as a slave client of the IIC.

+

/sf/os/kernelhwsrv/kerneltest/e32test/iic/t_iic.cpp

+

Mandatory

+
+ + +

The above test system consists of the executable (t_iic.exe) +and associated ldd files. The default version of t_iic.exe is used +to test that the platform independent layers of the IIC component +work correctly. The default version only works on the emulator, so +the layer below the SHAI is a series of stubs. In order for this test +harness to work with actual hardware, extensive modification to t_iic.exe +will have to be undertaken.

+
Test +application use cases

The IIC test application is used to +test:

    +
  • The basic master channel functionality.

  • +
  • The master channel data handling for transaction functionality.

  • +
  • The master channel preamble and multi-transaction functionality.

  • +
  • The slave channel capture and release APIs.

  • +
  • The slave channel capture for receive and transmit of data.

  • +
  • That MasterSlave channels can only be used for one mode at +a time.

  • +
+
Limitations

The IIC test application has the following known limitations:

    +
  • This test suite does not work on hardware.

  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-67CFF27B-55AF-42AC-95AF-E71A7C54039E.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-67CFF27B-55AF-42AC-95AF-E71A7C54039E.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,67 @@ + + + + + +Sample +Device DriversThis document describes the steps and options for coding a device +driver, and how to use APIs to access the services provided by the Symbian +platform kernel. +

Illustrations of the use of APIs are taken from a number of example device +drivers. These are summarised below. All of the drivers implement support +for serial communications over a UART. They are designed to show a number +of different implementation techniques.

+ + + + +

Name

+

Key functionality

+
+ +

exdriver_pio

+

Shows a simple driver running on a kernel DFC thread. It polls for +data using a timer.

Timers discusses +timers in detail.

+
+ +

exdriver_int

+

Illustrates the use of interrupts and asynchronous request handling.

Asynchronous Requests describes +how to implement handling of asynchronous requests.

Interrupt +Service Routine (ISR) describes how to write ISRs to handle interrupts +from hardware devices.

+
+ +

exdriver_dma

+

Illustrates the use of DMA (Direct Memory Access).

DMA describes how +to use DMA for fast copying of data from memory to memory, and between memory +and peripherals.

+
+ +

exdriver_chnk

+

Illustrates shared chunks and synchronization in a multi-thread +context.

Shared +Chunks describes how to share data efficiently without the overhead +of memory copy operations.

+
+ +

exdriver_sync

+

Illustrates synchronous request handling, and the use of the DLogicalChannelBase base +class for LDDs.

User +Requests and Synchronisation discusses the options for how LDDs can +handle requests.

+
+ + +
+

The source code for the example device drivers is delivered as part of +the Symbian platform source code on kits, using the directory structure described +previously in the Source +Directory Structure section.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-6843109A-1567-5287-9AFF-3AE5E80334AF.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-6843109A-1567-5287-9AFF-3AE5E80334AF.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,192 @@ + + + + + +Keyword reference (S-Z) +

This page lists the keywords starting from S to Z.

+
secondary secondary = <source-file> <destination-image-file> [File-attribute-list] [Override-Attribute-list]

rombuild only

A standard executable file that +is loaded by the kernel; this is the file server. All subsequent files +can be loaded through the file server.

As with all standard +executable files, this is loaded, relocated and stripped of its relocation +information.

+
section

rombuild only

ROMs can be sectioned into two +parts allowing the upper part of the ROM to be switched for language +variations and file patching. This is independent of the extension +ROM mechanism.

This keyword appears at the point in the obey +file where the ROM to be split. All files before this line appear +in the first (constant) section: Files after appear in the second +(patch/language) section.

+
SECTION2 SECTION2 <anything>

BUILDROM only

Provides support for rombuild's capability to create ROMs divided into two sections.

The +two sections are termed the upper and lower section. The upper section +can be replaced without needing to change the lower section. This +facility is most often used to put localised resource files into the +upper section. This keyword provides BUILDROM's support +for gathering marked obey source lines and placing them in the upper +section of the ROM.

All lines beginning with the SECTION2 keyword are removed from the .iby file and +are placed into a separate list with the SECTION2 keyword removed. When BUILDROM encounters the section keyword, the accumulated SECTION2 list is inserted after the section line, and subsequent SECTION2 keywords +are removed as they occur. If no section keyword is found the accumulated SECTION2 list is emitted after the end of the input file(s).

For +example:

LANGUAGE_CODE 01 +LANGUAGE_CODE 10 +DEFAULT_LANGUAGE 10 +file=sourcedir\myapp.dll destdir\myapp.dll +SECTION2 REM bitmaps for myapp +SECTION2 bitmap=MULTI_LINGUIFY( MBM sourcedir\myapp destdir\myapp ) +file=sourcedir\myengine.dll destdir\myengine.dll +section 0x800000 +file=sourcedir\example destdir\example +SECTION2 data=sourcedir\example2 destdir\example2 +

becomes:

file=sourcedir\myapp.dll destdir\myapp.dll +file=sourcedir\myengine.dll destdir\myengine.dll + +section 0x800000 +REM bitmaps for myapp +data=sourcedir\myapp.M01_rom destdir\myapp.M01 +data=sourcedir\myapp.M10_rom destdir\myapp.MBM + +file=sourcedir\example destdir\example +data=sourcedir\example2 destdir\example2 +

See also MULTI_LINGUIFY.

+
sectorsize sectorsize=<number of bytes>

rofsbuild only

Configures the number of bytes +in each sector for the file system in data-drive images.

+
singlekernel singlekernel

rombuild only

Specifies that this ROM image +has one kernel executable within it. This is the default.

Note that this keyword is mutually exclusive with multikernel keyword.

+
sisfile sisfile = <source-file>

BUILDROM only

Specifies the sis files to be installed on the data drive.

Note: A +directory containing sis files can also be provided +as input to this keyword.

+
spidata spidata = <source-file> <original-destination-file> <spi-id> <target-spi-dir>

BUILDROM only

Specifies input files used to +create a static plug-in information (SPI) file.

Its parameters +are:

+ + + +

source-file

+

The location of the source file. This is the resource file +to build into the SPI file.

+
+ +

original-destination-file

+

The location that the resource should be placed in if the +SPI file is not created.

+
+ +

spi-id

+

Name of the SPI file in which the resource should be stored. +For ECom, this is ecom.spi.

+
+ +

target-spi-dir

+

The directory in which to create the SPI file in the ROM +image.

+
+ + +

An SPI file concatenates several resource files together. +It is currently used to record the ECom plug-ins that are in ROM. +This allows the ECom framework to register the ROM-based plug-ins +without having to scan the file system for individual resource files. +IBY files are not expected to use the spidata keyword +directly for this purpose: instead, they should use the ECOM_PLUGIN macro (see __ECOM_PLUGIN) which BUILDROM converts to +the required spidata statement.

Note that +creation of SPI files is optional (see BUILDROM). +If it is switched on:

    +
  • the spidata statements are processed to determine which SPI +files need to be created. spitool is +called to create an SPI file, and a data statement is generated in +the final IBY file to include an SPI file in ROM.

  • +
  • copies of each +SPI file are placed in the same directory as the created ROM image. +This is necessary for the possibility of creating extension/composite +ROMs.

  • +
  • any resource +files included in an SPI file are not placed in the ROM image. This +avoids duplication and an unnecessary increase in the size of the +ROM.

  • +

If SPI creation is switched off all resource files are placed +in the ROM image in the locations specified by the <original-destination-file> parameters of the spidata statements.

+
spidatahide spidatahide = <source-file> <spi-id> <target-spi-dir>

BUILDROM only

Specifies the files that need +to be marked as hidden in the static plug-in information (SPI) file, +to hide the associated ECom plug-in in the ROM.

Its parameters +are:

+ + + +

source-file

+

The location of the source file to be marked as hidden in +the SPI file.

+
+ +

spi-id

+

The SPI file name in which the resource should be stored. +For ECom, this is ecom.spi or ecom.snn.

+
+ +

target-spi-dir

+

The directory in which to create the SPI file in the ROM +image.

+
+ + +

The file is marked as hidden in the SPI file by writing +the data length of the file as 0. A resource language file can be +overridden using this keyword in the IBY file. If you intend to hide +both the resource file and the DLL, use the HIDE_ECOM_PLUGIN macro (see _HIDE__ECOM_PLUGIN), which enables BUILDROM to generate the required spidatahide statement.

Note that creation of SPI files is optional (see BUILDROM). +If BUILDROM is allowed to generate the SPI files, +the spidatahide statements are processed to determine +which resource file should be hidden in the SPI files that are to +be created. The BUILDROM calls the spitool to create an SPI file, and a data statement is +added to the final .IBY file to include the SPI +file in the ROM.

+
srecordbase srecordbase = <hex-address>

rombuild only

Destination address for S-record +download.

+
srecordfilename srecordfilename = <srec-file-name>

rombuild only

rombuild can +write an image in Motorola S-record format. This happens if a name +for the output file is specified here. A filename of "*" can be specified, +which means use the file name specified on the romname keyword and append .screc.

+
stack stack = <hex-size>

rombuild only

Overrides the default stack size +for the executable.

+
stackreserve stackreserve = <hex-size>

rombuild only

Overrides the maximum size of +the stack.

+
stop stop

rombuild and rofsbuild

Stops processing the +obey file. The rom image is not generated.

+
time time = dd/mm/yyyy hh:mm:ss

rombuild and rofsbuild

If specified, overwrites +the date-time stamp of the ROM image with this value. If not specified, +the image is time and date stamped from the system clock of the build +PC.

+
TODAY TODAY

BUILDROM only

A pre-defined substitution. This +is replaced with today's date in the format dd/mm/yy

Note that there is no UNDEFINE facility, and substitutions +are applied in an unspecified order.

+
trace trace = <32 bit hex-number>

rombuild and rofsbuild

Turns on rombuild tracing. +This is internal to Symbian.

+
uid1 uid1 = <uid-value>

rombuild only

Overrides the first UID for the +executable.

+
uid2 uid2 = <uid-value>

rombuild only

Overrides the second UID for the +executable.

+
uid3 uid3 = <uid-value>

rombuild only

Overrides the third UID for the +executable.

+
unicode unicode

rombuild only

Indicates that this is a Unicode +build; this is the default if not present and ascii is not coded.

+
unpaged

unpaged

rombuild and rofsbuild

Use the unpaged keyword to specify that the executable +is not paged. This is the same as specifying both unpagedcode and unpageddata keywords for an executable.

+
unpagedcode

unpagedcode

rombuild and rofsbuild

Use the unpagedcode keyword to specify that +the executable is not code paged.

+
unpageddata

unpageddata

rombuild and rofsbuild

Use the unpageddata keyword to specify that +the data in the executable is not data paged.

+
variant[[HWVD]] variant[[HWVD]] = <source-file> <destination-image-file> [File-attribute-list] [Override-Attribute-list]

rombuild only

Defines hardware variants.

It should be applied to the variant DLL. The ecust.dll of each hardware variant to be supported, and must specify a suitable HWVD. Note that the HWVD must be enclosed within square +brackets.

+
version version = [ <major> ] [ .<minor> ] [ (<build>) ]

rombuild and rofsbuild

The ROM version number +as represented by its three component values.

+
volume volume=<volume label>

rofsbuild only

Configures the volume label for +the file system in data-drive images.

+
WARNING WARNING <anything at all>

BUILDROM only

Prints the rest of the line following +the WARNING keyword to standard output, and reports the source file +name and the line number.

+
zdriveimagename zdriveimagename = <image name.img>

BUILDROM only

Specifies the name of the Z drive +description image file( ROM, ROFS, extension ROFS or CORE image).

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-68446E8E-129C-444A-836A-EF8F56BFE0BC.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-68446E8E-129C-444A-836A-EF8F56BFE0BC.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,72 @@ + + + + + +Handling InterruptsDescribes how a device driver can use interrupts. +

The clients +of the Interrupt platform service must know the following:

    +
  • ISR function

  • +
  • Interrupt ID

  • +

+

Interrupts +are sent by hardware to indicate an event has occurred. Interrupts +typically cause an Interrupt Service Routine (ISR) to be executed. +The Interrupt platform service specifies the interface APIs for setting +up the ISRs and connecting them to specific Interrupt IDs. Interrupt +handling is a blocking high priority task and needs to take a minimal +amount of time. While the ISR is executed the kernel will be in an +indeterminate state and this puts restrictions on doing various operations, +such as allocating heap storage.

The device driver provides +an ISR to handle an interrupt and perform the required response to +the events. Symbian platform provides an Interrupt class (implemented by the ASSP) with an API to bind and unbind an +Interrupt ID with an ISR.

An Interrupt ID is identified by +number, defined as a TInt type. Typically, the ASSP +layer may define this number for each interrupt in a header file and +export it so that it can be included and used by device drivers. Alternatively, +device drivers may be required to retrieve the appropriate Interrupt +ID from the Hardware Configuration Repository (HCR). The scheme used +is implementation dependent.

+ +Call Interrupt::Bind(TInt, TIsr, TAny*) with appropriate Interrupt +ID, ISR and argument to be passed to the ISR. This function binds +the interrupt to the ISR. + +Assign the +priority to the Interrupt if needed using the Interrupt::SetPriority(TInt, +TInt) function. + +Enable the +interrupt by calling the Interrupt::Enable(TInt) function. This function is called when the device driver is ready +to handle hardware events. +

An ISR is a static function that will be executed when an +interrupt is received by the interrupt handler. The interrupt handler +executes the ISR that is bound to the received Interrupt ID. It performs +the actions necessary to service the event of the peripheral that +generated the interrupt. The ISR must either remove the condition +that caused the interrupt or call Interrupt::Disable() otherwise the machine will hang. The device driver may queue a DFC +within the ISR to perform deferred processing.

+
+Once the +DFC processing is completed, it is a good practice to enable the interrupt +if it is disabled, using Interrupt::Enable(TInt) function. + +At the point +when the PDD of the device driver gets unloaded, unbind the ISR from +the specified Interrupt Id using Interrupt::Unbind(TInt) function by passing Interrupt ID as the parameter. + +
+

The device +driver is able to handle interrupts.

+
+Interrupt +Client Interface Guide +Interrupt +Technology Guide +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-6873E764-4132-46C8-8444-6301CF4D2033.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-6873E764-4132-46C8-8444-6301CF4D2033.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,68 @@ + + + + + +DMA Hardware InterfaceDescribes the interface between the DMA hardware and the +DMA platform service. +
Introduction

This document describes the functionality that the DMA hardware +has to provide in order to be compliant with the DMA platform service.

+
Interface +limitations

None

+
Adaptation +dependencies

Dependent on the Application Specific Standard +Product (ASSP) chip that is being used.

+
The +interface

In order to use the DMA platform service, the +following information is required:

    +
  • The location of the data source.

  • +
  • The location of the data destination.

  • +
  • The channel to be used.

  • +
  • The amount of data to be transferred.

  • +
  • How much data is to be transferred at once (packet size).

  • +
  • Synchronization setup

  • +
  • Interrupt settings

  • +

How the above settings relate to the operation of the DMA +is shown in the diagram below:

+DMA settings + +

The settings listed above will now be discussed in more detail.

Location of the data source

This specifies where +data is to be transferred from (the source). This can be one of the +following:

    +
  • Memory

  • +
  • Peripheral

  • +

If the source location is a peripheral, then its port will +have to be specified along with the location of the data source.

Location of the data destination

This specifies the +final location of the data to be transferred (the destination). As +with the location of the data source, this can be one of the following:

    +
  • Memory

  • +
  • Peripheral

  • +

If the destination is to be a peripheral, then the port configuration +will have to be specified along with the location of the destination.

Channel

The DMA platform service transfers data over +channels which are configured independently. The priority order of +the each channel is specified in the DMA platform service API.

Amount of data to be transferred

This setting specifies +the amount of data that is to be transferred from the source to the +destination.

Data packet size

Data is transferred +in packets of a specified size. The acceptable values are:

    +
  • 4 bytes

  • +
  • 8 bytes

  • +
  • 16 bytes

  • +
  • 32 bytes

  • +
  • 64 bytes

  • +
  • 128 bytes

  • +

Synchronization settings

These specify how the +transfer between the source and destination is to be controlled. This +is used when either the source or the destination can only take part +in a data transfer depending on external events. The synchronization +can be set up to be one of the following:

    +
  • No synchronized transfer

  • +
  • Synchronize the transfer after a preset number of bytes

  • +

Interrupt settings

These are used to specify +how the DMA and/or specific channels should react to interrupt events.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-687997B5-BDFD-49D1-947B-4AB21C3AF58C.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-687997B5-BDFD-49D1-947B-4AB21C3AF58C.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,23 @@ + + + + + +The +Running ModelThis document describes the model by which a device driver handles +requests. +
+

Once a logical channel and a physical channel, if appropriate, have +been created and initialised, the driver is ready to handle requests.

On +the kernel-side, requests can be handled by one or more kernel-side threads, +allowing for rich and complex behaviour. Alternatively, if appropriate, a +request can be handled by code running in the context of the client user-side +thread, but running in supervisor mode.

There are two kinds of request, +synchronous and asynchronous.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-690F943E-7459-4FBA-B33C-258969D7759A-master.png Binary file Adaptation/GUID-690F943E-7459-4FBA-B33C-258969D7759A-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-690F943E-7459-4FBA-B33C-258969D7759A_d0e93193_href.png Binary file Adaptation/GUID-690F943E-7459-4FBA-B33C-258969D7759A_d0e93193_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-6A4FE3A3-2E5D-51BB-8272-5995586291E9.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-6A4FE3A3-2E5D-51BB-8272-5995586291E9.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,222 @@ + + + + + +LCD Extension Implementation TutorialThis topic describes how to create an LCD Extension. +

The topic uses a reference board port named template_variant as an example implementation.

+
Build +environment

In the template reference board port, the .mmp file for the LCD Extension is ...\template_variant\lcdtemplate.mmp. This is one of the PRJ_MMPFILES referenced in +the template variant's bld.inf file in the ...\template_variant\... directory, and means that the +LCD Extension is built as part of the Variant.

The source +for the driver is contained entirely within ...\template_variant\specific\lcd.cpp.

The driver is defined as a kernel extension and is loaded +early in the boot sequence.

+
Initialization

The driver functionality is almost entirely encapsulated by the DLcdPowerHandler class. This is a power handler class derived +from DPowerHandler. An instance of DLcdPowerHandler is created when the extension is loaded.

DLcdPowerHandler is defined within the source file itself ...\template_variant\specific\lcd.cpp.

As the driver is a kernel extension, it must have a DECLARE_STANDARD_EXTENSION() statement. In the template +port, this is implemented as follows:

DECLARE_STANDARD_EXTENSION() + { + __KTRACE_OPT(KPOWER,Kern::Printf("Starting LCD power manager")); + + // create LCD power handler + TInt r=KErrNoMemory; + DLcdPowerHandler* pH=new DLcdPowerHandler; + if (pH) + r=pH->Create(); + + __KTRACE_OPT(KPOWER,Kern::Printf("Returns %d",r)); + return r; + } +

This simply creates an instance of the DLcdPowerHandler class and then calls its Create() function which +implements the display setup. This function should do the following:

    +
  • map the video +RAM

  • +
  • setup the video +info structure

  • +
  • install the +HAL handler

  • +
  • install the +power handler.

  • +

Map the video RAM

The frame buffer is a DPlatChunkHw object, and should be mapped as globally accessible, +readable and writeable. It should not be mapped as writeback +cached, it should be either not-cached or write-through. The advantage +of write through is that it allows the use of the write buffer.

TInt DLcdPowerHandler::Create() + { + ... + + // map the video RAM + TInt vSize = ((TemplateAssp*)Arch::TheAsic())->VideoRamSize(); + ivRamPhys = TTemplate::VideoRamPhys(); // EXAMPLE ONLY: assume TTemplate interface class + TInt r = DPlatChunkHw::New(iChunk,ivRamPhys,vSize,EMapAttrUserRw|EMapAttrBufferedC); + if ® != KErrNone) + return r; + ... +

If the frame buffer resides in main RAM and there +is no restriction on which physical addresses may be used for it, +physical RAM for the frame buffer should be reserved by using Epoc::AllocPhysicalRam().

If the frame buffer does +not reside in main RAM, there is no problem about reserving it.

If the frame buffer must reside at a specific address in main +RAM, there are two strategies available for reserving it:

    +
  • If no conflicts +are permitted between the frame buffer and memory allocations made +during the kernel boot (for example, if the frame buffer must reside +at the end of main memory), simply use Epoc::ClaimPhysicalRam(). This function just marks a region of physical RAM as allocated, +returning an error if any part of the region has already been used.

  • +
  • The required +physical RAM region can be reserved in the bootstrap. The correct +place to do this is in the implementation of the boot table function BTF_Reserve when writing platform-specific source code for +the bootstrap. See the Bootstrap Port Implementation +Tutorial for more detail and look at ...\template_variant\bootstrap\template.s for a concrete example.

  • +

Note that all Symbian platform base ports currently create +a second frame buffer for a secure screen. However, as platform security +is not yet implemented, this is wasteful of RAM and should be omitted.

Set up the video +information structure

The video information structure +is used to define several aspects of the display including display +size, bits per pixel and address of the frame buffer. This structure +is the class TVideoInfoV01 defined in the header +file ...\eka\include\videodriver.h and exported +to ...\epoc32\include.

TInt DLcdPowerHandler::Create() + { + ... + // setup the video info structure, this will be used to remember the video settings + iVideoInfo.iDisplayMode = KConfigLcdInitialDisplayMode; + iVideoInfo.iOffsetToFirstPixel = Lcd_Mode_Config[KConfigLcdInitialDisplayMode].iOffsetToFirstVideoBuffer; + iVideoInfo.iIsPalettized = Lcd_Mode_Config[KConfigLcdInitialDisplayMode].iIsPalettized; + iVideoInfo.iOffsetBetweenLines = Lcd_Mode_Config[KConfigLcdInitialDisplayMode].iOffsetBetweenLines; + iVideoInfo.iBitsPerPixel = Lcd_Mode_Config[KConfigLcdInitialDisplayMode].iBitsPerPixel; + + iVideoInfo.iSizeInPixels.iWidth = KConfigLcdWidth; + iVideoInfo.iSizeInPixels.iHeight = KConfigLcdHeight; + iVideoInfo.iSizeInTwips.iWidth = KConfigLcdWidthInTwips; + iVideoInfo.iSizeInTwips.iHeight = KConfigLcdHeightInTwips; + iVideoInfo.iIsMono = KConfigLcdIsMono; + iVideoInfo.iVideoAddress=(TInt)pV; + iVideoInfo.iIsPixelOrderLandscape = KConfigLcdPixelOrderLandscape; + iVideoInfo.iIsPixelOrderRGB = KConfigLcdPixelOrderRGB; + ... + }

Install the HAL handler

Control of the display is +done by using the HAL, the Hardware Abstraction Layer.

The DLcdPowerHandler class provides the implementation for the +HAL handler for the HAL function group EHalGroupDisplay and this needs to be registered with the kernel by calling Kern::AddHalEntry().

TInt DLcdPowerHandler::Create() + { + ... + // install the HAL function + r=Kern::AddHalEntry(EHalGroupDisplay, halFunction, this); + if (r!=KErrNone) + return r; + ... + }

See User-Side Hardware Abstraction for more detailed information +on the HAL.

Install the power handler

A call must be made to +the Add() function, which is supplied by the DPowerHandler base class of DLcdPowerHandler, to register the handler with the power manager.

TInt DLcdPowerHandler::Create() + { + ... + // install the power handler + // power up the screen + Add(); + ... + }
+
HAL +handler implementation

Requests to get and set hardware +attributes are made through calls to HAL::Get() and HAL::Set(). These two HAL functions take +a value that identifies a hardware attribute, one of the HALData::TAttribute values.

For the LCD Extension, +the relevant hardware attributes are: EDisplayMode, EDisplayBitsPerPixel, EDisplayIsPalettized, EDisplayIsMono, EDisplayMemoryAddress, EDisplayMemoryHandle, EDisplayOffsetToFirstPixel, EDisplayOffsetBetweenLines, EDisplayXPixels, EDisplayYPixels, EDisplayPaletteEntry and EDisplayOffsetBetweenLines.

The HAL +handler is registered with the kernel as the handler for the THalFunctionGroup::EHalGroupDisplay group. The HAL handler +itself takes a function ID, which is one of the TDisplayHalFunction enumerators.

A call to HAL::Get() and HAL::Set() that takes one of the hardware attributes relevant +to the LCD Extension is ultimately routed to a call to this HAL handler +function passing an appropriate function ID. The association between +the hardware attribute and the function ID is the responsibility of +the accessor functions.

See User-Side Hardware Abstraction for more information on the +way this works in general.

The HAL handler is implemented +as a case statement, switching on the function ID. For example, the +following code fragment taken from DLcdPowerHandler::HalFunction() gets and sets the brightness:

TInt DLcdPowerHandler::HalFunction(TInt aFunction, TAny* a1, TAny* a2) + { + TInt r=KErrNone; + switch(aFunction) + { + + ... + case EDisplayHalSetDisplayBrightness: + if(!Kern::CurrentThreadHasCapability(ECapabilityWriteDeviceData, + __PLATSEC_DIAGNOSTIC_STRING("Checked by Hal function EDisplayHalSetDisplayBrightness"))) + return KErrPermissionDenied; + r=SetBrightness(TInt(a1)); + break; + + case EDisplayHalDisplayBrightness: + kumemput32(a1,&iBrightness,sizeof(iBrightness)); + break; + ... +

where SetBrightness() is implemented +as:

TInt DLcdPowerHandler::SetBrightness(TInt aValue) + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("SetBrightness(%d)", aValue)); + + if (aValue >= KConfigLcdMinDisplayBrightness && aValue <= KConfigLcdMaxDisplayBrightness) + { + iBrightness=aValue; + + // TO DO: (mandatory) + // set the brightness + // + return KErrNone; + } + return KErrArgument; + } +

If an attribute does not have an implementation, the +HAL handler function should return KErrNotSupported.

For platform security, the code only allows the attribute +to be set if the current thread has been authorized to write system +data. Otherwise, it returns KErrPermissionDenied.

Switch on and switch off operations

All of the HAL +operations are seen to be synchronous by the user side. However there +are some operations such as turning the display on and off which may +need to be implemented asynchronously.

The display on/off +code is implemented using synchronous kernel-side messages. There +is only one message per thread and the thread always blocks while +a message is outstanding. This means it is possible to make an asynchronous +operation appear synchronous.

When turning on the screen the +kernel-side message is queued and this thread is blocked until the +message is completed, which happens when the display has been turned +on.

If a display needs to be turned on and off truly asynchronously +(for example, if millisecond timer waits are required during the process +of turning on the display), the above functionality must be changed +so that the complete occurs when the display is truly on.

Accessing the video information structure

When any +part of the video information structure is read or written to, this must +be done within a critical section to prevent potential collisions +with other threads attempting to access the structure concurrently. +A fast mutex is used to ensure that only one thread can access the +video information at any one time, as the code segment below shows.

TInt DLcdPowerHandler::GetCurrentDisplayModeInfo(TVideoInfoV01& aInfo, TBool aSecure) + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("GetCurrentDisplayModeInfo")); + NKern::FMWait(&iLock); + if (aSecure) + aInfo = iSecureVideoInfo; + else + aInfo = iVideoInfo; + NKern::FMSignal(&iLock); + return KErrNone; + } +
+
Power +handler implementation

The DPowerHandler class defines the interface that the driver must implement to provide +power handling behaviour. For the template reference board, the LCD +Extension defines and implements the DLcdPowerHandler class derived from DPowerHandler.

Note:

    +
  • DPowerHandler::PowerDown() and DPowerHandler::PowerUp()

    These functions +are called in the context of the thread that initiates power down +or power up, and synchronization is required, typically by means of +power up and power down DFCs.

  • +
  • DPowerHandler::PowerUpLcd() and DPowerHandler::PowerDownLcd()

    These +functions generally queue DFCs which then call platform-specific functions +to power the display up and down.

  • +
  • DPowerHandler::PowerUpDone() and DPowerHandler::PowerDownDone()

    When +power up or down is complete, the interface supplies a set of acknowledgment +functions which must be called when the change of state has taken +place.

  • +
+
+LCD +Extension Architecture +Implementing +Dynamic DSA Allocation +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-6AC01B10-92C1-4E56-813B-6853DFCF3386-GENID-1-2-1-10-1-5-1-5-1-1-7-1-9-1-4-1.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-6AC01B10-92C1-4E56-813B-6853DFCF3386-GENID-1-2-1-10-1-5-1-5-1-1-7-1-9-1-4-1.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,44 @@ + + + + + +DMA RequestsDescribes how device drivers use DMA requests to initiate +a DMA transfer. +

DMA transfer requests are the way in which a device driver sets +up and initiates a DMA transfer. A transfer request internally comprises +a linked list of DMA descriptor headers and is associated with a single +DMA channel. A transfer request also stores an optional client-provided +callback function, which can be invoked when the whole request completes, +whether successfully or not. A DMA request can be in any of the four +states: Not configured, Idle, Being transferred, and Pending. However, +these states are not used by the driver.

+

A device driver creates a DMA request by specifying a DMA channel +and an optional DMA callback function to be called after the request +completion. A DMA request must be fragmented.

+

The following shows the creation of a DMA request:

+TInt DExDriverUartTxDma::Init() + { + ... + // A DMA request has to be created for any DMA transfer. This + // specifies the channel on which the DMA request shall be + // made, the service callback function to be called after the + // request completion (TxDmaService), and an object pointer that will be passed + // as an argument to DMA request service function (this). + // A DMA request is a list of fragments small enough to be + // transferred in one go by the DMA Controller. + // + iTxDmaRequest = new DDmaRequest(*iTxDmaChannel, TxDmaService, this); + if(iTxDmaRequest == NULL) + { + return KErrNoMemory; + } + ... + } +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-6AC01B10-92C1-4E56-813B-6853DFCF3386-GENID-1-2-1-9-1-6-1-8-1-7-1-5-1.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-6AC01B10-92C1-4E56-813B-6853DFCF3386-GENID-1-2-1-9-1-6-1-8-1-7-1-5-1.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,44 @@ + + + + + +DMA RequestsDescribes how device drivers use DMA requests to initiate +a DMA transfer. +

DMA transfer requests are the way in which a device driver sets +up and initiates a DMA transfer. A transfer request internally comprises +a linked list of DMA descriptor headers and is associated with a single +DMA channel. A transfer request also stores an optional client-provided +callback function, which can be invoked when the whole request completes, +whether successfully or not. A DMA request can be in any of the four +states: Not configured, Idle, Being transferred, and Pending. However, +these states are not used by the driver.

+

A device driver creates a DMA request by specifying a DMA channel +and an optional DMA callback function to be called after the request +completion. A DMA request must be fragmented.

+

The following shows the creation of a DMA request:

+TInt DExDriverUartTxDma::Init() + { + ... + // A DMA request has to be created for any DMA transfer. This + // specifies the channel on which the DMA request shall be + // made, the service callback function to be called after the + // request completion (TxDmaService), and an object pointer that will be passed + // as an argument to DMA request service function (this). + // A DMA request is a list of fragments small enough to be + // transferred in one go by the DMA Controller. + // + iTxDmaRequest = new DDmaRequest(*iTxDmaChannel, TxDmaService, this); + if(iTxDmaRequest == NULL) + { + return KErrNoMemory; + } + ... + } +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-6B2221F2-A598-4677-A2D3-40FF27C7373F.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-6B2221F2-A598-4677-A2D3-40FF27C7373F.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,14 @@ + + + + + +SDIO Tools GuideDescribes the tools required for SDIO implementation. +

There are no specific tools required to use or implement SDIO.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-6B9041F7-79A6-5CCA-9B4D-B8EF377FD378.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-6B9041F7-79A6-5CCA-9B4D-B8EF377FD378.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,45 @@ + + + + + +Building +ROM Tutorial Describes how to build a ROM that will use demand paging. It assumes +that the configuration files have been suitably modified. +

This is the final +step required to build a ROM that can use Writable Data Paging (WDP). The +previous steps required to produce a ROM image that can use Writable Data +Paging (WDP) are:

    +
  • Configuration +Tutorial

  • +
  • oby +tutorial

  • +
  • mmp tutorial

  • +

It is assumed that the both the configuration files and the +media drivers have been modified to use demand paging.

+ + +If the new OBY file appears before base.iby, then +no change to the configuration of the rombuild command is needed. + + +If the new OBY file appears after base.iby, then USE_DATA_PAGING must +be defined on the command line (along with PAGED_ROM, USE_CODE_PAGING +and CODE_PAGING_FROM_ROFS) + USE_DATA_PAGING, PAGED_ROM, USE_CODE_PAGING and CODE_PAGING_FROM_ROFS are +macros that are used to indicate which types of paging is to be used. If they +are specified in the parameter list for buildrom (with -D in fount of it) +then that type of paging will be implemented. + + +

Executing the buildrom +command builds the ROM image with no errors or warnings.

+buildrom example

An +example of a buildrom command that produces a demand paging ROM is:

buildrom –D_NAND2 -DWITH_FLEXIBLE_MM –DPAGED_ROM –DUSE_CODE_PAGING –DCODE_PAGING_FROM_ROFS –DUSE_DATA_PAGING h4hrp techview MyDPConfig
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-6C27AAD6-EB88-53AF-8E04-921A957042CF.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-6C27AAD6-EB88-53AF-8E04-921A957042CF.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,16 @@ + + + + + +ConceptsDescribes the technology, architecture, and behaviour of the Digitizer +Driver. +Port Implementation + Tutorial + \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-6C74A8B4-50B6-486C-A75F-A50636F4C566.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-6C74A8B4-50B6-486C-A75F-A50636F4C566.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,47 @@ + + + + + +Register Access OverviewProvides a summary of the Register Access platform service. +

The Register Access platform service is intended for use in writing +device drivers. Writing device drivers involves frequent access to +hardware registers for reading, writing and modifying them.

+
+ What is a register

A register is +a memory location on the ASSP hardware to store data that relates +to the operation of that hardware. For example, a register can be +a counter, or a bit field, or the next sequence number or the next +byte or word of data that has arrived over a bus.

The Symbian +platform provides access functions for registers that have the following +sizes:

    +
  • 8–bit

  • +
  • 16–bit

  • +
  • 32–bit

  • +
  • 64–bit

  • +

+
What +functions are available

There are three types of function +provided for register access:

    +
  • Read - get the value of a register

  • +
  • Write - write a value to a register

  • +
  • Modify - use bitmasks to clear or set specific +bits in a register

  • +

Each function takes a first argument of a TLinAddr which is an address. The device driver only needs to know the address, +and the size of the register. The implementation of the Register Access +must map the exposed physical hardware register to a linear address.

Each type of function (read, write, modify) has 8–bit, 16–bit, +32–bit and 64–bit versions.

The Modify functions +take two bitmasks as parameters, to specify which bits to clear to +zero (clear mask) and which bits to set to one (set mask). This means +that you could call Modify16(myaddress, 0xC000,0x000F) and the top two bits would be set to zero, the bottom four bits +would be set to one, and the ten bits in the middle would retain their +current value.

See Register Access Client +Interface Guide for more details on each function and how to +use them.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-6CCF249B-DEDD-4E0B-A081-0FCD9FCCBB5A.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-6CCF249B-DEDD-4E0B-A081-0FCD9FCCBB5A.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,32 @@ + + + + + +SDIO +Quick Start GuideProvides a collection of documents that describe SDIO (Secure Digital +Input Output). +
Getting started +with SDIO

The SDIO overview provides a description of the basic +concepts relevant to SDIO.

SDIO +Overview

The technology guide provides a description of the technologies +used by SDIO.

SDIO +Technology Guide

The interface overview document provides a description +to the SDIO adaptation APIs.

SDIO +Interface Guide

The implementation overview describes +how SDIO is included in a build of the Symbian platform.

SDIO +Implementation Guide
+
Architecture

The +following illustration shows the basic architecture of SDIO.

+ +
+
Technologies

SDIO +is a standard that combines an SD (Secure Digital) card and an I/O device +to produce a peripheral that can use an SD slot.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-6CE68645-D8C5-52E1-88B3-76AEFB80DE51.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-6CE68645-D8C5-52E1-88B3-76AEFB80DE51.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,60 @@ + + + + + +Peripherals +As Power ResourcesPeripherals that provide services to other peripherals can be considered +as power resources from the point of view of the client driver. +

As they can offer a service to more than one other peripheral, we suggest +that the driver that manages them presents a MPowerInput derived +interface to client peripheral drivers, providing Use() and Release() functions +that can be used by dependent peripheral drivers to issue power requests. +The driver for the peripheral providing that interface may then use the built-in +usage counting feature to control the peripheral power state.

+

A typical example of a shared Peripheral is an Inter-Component serial Bus +(I2C, SPI, etc):

+class MySharedPeripheral : public MPowerInput , (other parent classes) + { +public: + // from MPowerInput + void Use(); + void Release(); + TUint GetCount(); + ... + (other methods and data members required to model the interface) + }; + +

Special care must be taken to not create circular dependencies, for example, +Peripheral A depends on Peripheral B, which depends on Peripheral C which +depends on Peripheral A. Such circular dependencies would cause the MPowerInput::Release() mechanism +not to work properly, and preventing the chain of peripherals from powering +down when due.

+

The shared peripheral driver’s power handler asynchronous PowerDown() must +examine the usage count of that peripheral if the power manager issues a PowerDown() request +to the shared peripheral driver’s power handler while the peripheral is still +in use by another driver. In this situation, the shared peripheral driver +must defer powering down until all the dependent peripherals have released +their request on it.

+

Some peripherals may also be represented as power resources to prevent +the base port power saving operations inhibiting their usage. For example, +a base port may consider DRAM to be a shared power resource with the DMA controller, +or the DSP controller as clients. This will allow them to still be able to +access DRAM whilst the CPU is idling, thus stopping the DRAM going into self-refresh +if either one of its clients has pending operations on it.

+

As another example, to save power some base ports might decide to reduce +the refresh rate of the LCD whilst the CPU is idling or even power it down +for short periods and rely on the persistence of the LCD to prevent degredation +of the user experience. However, on a multiple core solution the LCD might +be used by the second core (e.g. DSP), for example, for playing back video +whilst the main CPU is idling. In this situation the LCD should be represented +as a shared power resource and the DSP must be able to request usage of this +resource. The DSP controller software could assert a request on the LCD preventing +the main CPU from initiating the power saving measures.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-6D75968E-53CF-5436-8390-54CA12BCFDE9.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-6D75968E-53CF-5436-8390-54CA12BCFDE9.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,19 @@ + + + + + +ConceptsDescribes the technology, architecture, and behaviour of the Sound +Driver. +

Sound Driver concepts are +described here.

+
+Port Implementation + Tutorial +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-6DE69F29-45B0-5E62-AA13-DA4041B1BC46.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-6DE69F29-45B0-5E62-AA13-DA4041B1BC46.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,99 @@ + + + + + +Factory +ImplementationDescribes how to implement a factory. +

The Serial Port Driver PDD must provide a factory class to create channels. +The purpose of the PDD factory is to create the physical channel. For the +Uart, this is defined by the DDriverComm class, which is +derived from DPhysicalDevice. The class is defined in the +Uart source code:

+class DDriverComm : public DPhysicalDevice + { +public: + DDriverComm(); + virtual TInt Install(); + virtual void GetCaps(TDes8 &aDes) const; + virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion &aVer); + virtual TInt Validate(TInt aUnit, const TDesC8* anInfo, const TVersion &aVer); + }; + +

This implements the four virtual functions that the base class defines, +as well as a default constructor.

+
Install()

Install() sets +the driver name. The name is the way that the physical device is identified. +The name is the same as the LDD name, but followed by a dot and a short string +to represent the physical device. If you have similar existing source, just +copy from there. The function is implemented as:

TInt DDriverComm::Install() + { + return SetName(&KPddName); + } +

In the template port, the name is the string Comm.Template.

See +also DPhysicalDevice::Install()

+
GetCaps()

GetCaps() returns +the capabilities of the physical driver factory (not the driver object). +Since driver factories all produce polymorphic objects there is no point in +differentiating between them so the function should ignore the passed in descriptor +reference. The driver object’s capabilities are returned by the DComm derived Caps() function.

GetCaps() +can be implemented as a stub function, i.e.:

Void DDriverComm::GetCaps(TDes8& /* aDes */) + { + }

See also DPhysicalDevice::GetCaps()

+
Validate()

Validate() verifies +that the physical driver version is compatible with the caller’s version. +This function can be copied in its entirety from any current driver source. +It also checks that the unit number used to create a physical channel object +is valid, typically checking that the number lies within a valid range.

TInt DDriverComm::Validate(TInt aUnit, const TDesC8* /*anInfo*/, const TVersion& aVer) + { + if ( + (!Kern::QueryVersionSupported(iVersion,aVer)) || + (!Kern::QueryVersionSupported(aVer,TVersion(KMinimumLddMajorVersion,KMinimumLddMinorVersion,KMinimumLddBuild))) + ) + return KErrNotSupported; + if (aUnit<UART_UNIT_OFFSET || aUnit>=(UART_TOTAL_NUMBER_UNITS+UART_UNIT_OFFSET)) + return KErrNotSupported; + return KErrNone; + } +

Note that iVersion is a data member in the +base class DPhysicalDevice.

See also:

    +
  • DPhysicalDevice::Validate()

  • +
  • Kern::QueryVersionSupported()

  • +
+
Create()

Create() creates +and returns a pointer to the physical channel object through the DBase *& +type argument. In the case of serial device drivers, a physical channel is +an instance of a class derived from DComm, which is itself +derived from DBase.

Implementing this function +may involve:

    +
  • setting up any port +related hardware; for example, defining GPIO pins as UART port I/O

  • +
  • initialising the UART +device itself; for example, enabling UART clock sources

  • +
  • binding any interrupt +resources to the UART Interrupt Service Routine (ISR).

  • +

The function sets a reference argument to point to the newly instantiated +physical channel object, but returns an error code if object allocation or +initialisation fails, i.e. the call to the physical channel object’s DoCreate() function +fails. Error codes are returned to the caller.

This code is typical, +and can be copied from any current source.

TInt DDriverComm::Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion& aVer) + { + DCommXXX* pD=new DCommXXX; + aChannel=pD; + TInt r=KErrNoMemory; + if (pD) + r=pD->DoCreate(aUnit,anInfo); + return r; + } +

where DCommXXX is a DComm derived +class.

Customisation depends on the functions in the DCommXXX::DoCreate() function.

+
+Interrupt +Dispatcher Tutorial +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-6E1DE1E4-1B09-541C-8708-9126E69B42CE.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,609 @@ + + + + + +Power +Resource Manager (PRM)Describes the Power Resource Manager. +
    +
  • Introduction

  • +
  • Concepts

  • +
  • User-side

  • +
  • Kernel-side

  • +
+
Introduction

The +Power Resource Manager (PRM) integrates the Symbian device driver with existing +power control and functions used for resource state changing and querying. +It defines an exported API that device drivers and other users of power resources +(represented by kernel-side components) can use to control the state of power +resources. The PRM assists the development of device drivers by removing the +need to understand the complexities of platform specific power resource management +by providing a simple to use generic framework.

The PRM also allows +user-side clients to gain access to the services. Clients of the PRM can:

    +
  • request information +on the clients and resources registered with PRM

  • +
  • get the current state +of the resources

  • +
  • request changes to the +state of power resources

  • +
  • request notification +of changes (i.e. power-down or change clock frequency) to the power resources +that they depend on.

  • +

The following diagram shows the generic and customisable parts of +the framework:

    +
  • exported kernel level +API (PowerResourceManager)

  • +
  • base virtual class for +Power Resource Controller (DPowerResourceController)

  • +
  • PDD required for user-side +proxy client

  • +
  • platform specific implementation +of resource control at the level of register interface to hardware resource +controller (DXXXPowerResourceController)

  • +
+ +
+
Concepts
    +
  • Power resources

  • +
  • Clients

  • +

Power resources

A +power resource is anything that has an effect on power consumption. These +are typically platform specific and either physical or logical. Physical power +resources are provided by hardware: for example, clocks, outputs from voltage +regulators, switched power domains and performance levels. Logical power resources +do not directly map to hardware components, but their state has an effect +on overall power consumption. In this category we include, for example, shared +buses and devices that provide services to other components.

Power +resources can be further categorised based on:

    +
  • Number of clients

    A power resource can have a single user or it can +be shared. There is no limit to the number of clients sharing a resource. +If the resource is shared, then a request system is used. This comprises a +list of client +level objects, one for each client requesting a level on the resource. +The resource level is determined by a set of rules which govern whether a +request is accepted or declined.

  • +
  • States

    The resource +state may be binary, multi-level or multi-property. A binary state +is either On or Off and a multi-level state can change either discretely or +continuously between a minimum (which could be Off) and a maximum value (which +could be fully On).

    A multi-property resource has different properties +across different portions of the operating curve. For example, the level may +be controllable within the ‘operational’ part of that curve but have different +discrete fixed states for the ‘idle’ or ‘sleep’ modes of operation.

  • +
  • Execution time

    The +execution time of a resource can be either instantaneous or long latency. +An instantaneous resource can be operated almost immediately (no longer than +a few system clock cycles, comparable to a CPU instruction execution time). +Operations on long latency resources take a significant time to complete (a +non-negligible amount of CPU clock cycles).

    Power resources may be +long latency for state change operations and instantaneous for obtaining the +current state. This is typically the case of a PLL (Phase Locked Loop) device +(definition +from Wikipedia), which requires time to stabilise after a frequency +change is initiated but whose current output frequency can be read from a +register. Note: instantaneous operations may pre-empt operations on +long latency resources, and requests to get the state of a shared resource +may be issued while a state change is underway. If the read operation is instantaneous +and the change is long latency, care must be taken (at the PSL level) to not +return inconsistent values.

    Other power resources may be long latency +on both state change and state read operations. This is typically the case +for any resources accessed through an inter-IC bus (even if their operation +is instantaneous).

  • +
  • Resource sense

    Each +client sharing a resource may have a different requirement on its state. The +resource sense is used to determine whose requirement prevails.

    + + + +

    Positive sense

    +

    Can have their value increased without affecting their sharers.

    The +level is set to the highest level that is requested. The highest requirement +for binary resources is the On state.

    +
    + +

    Negative sense

    +

    Can have their value decreased without affecting their sharers.

    The +level is set to the lowest level that is requested. The lowest requirement +for binary resources is the Off state.

    +
    + +

    Custom sense

    +

    May be increased or decreased freely by some privileged sharers +but not by others, which are bound by the requirement of the privileged sharers.

    The +decision to change the prevailing level (or binary state) depends on the privileges +of the client and past usage of the resource. This decision is made by the +PSL custom +function implementation.

    +
    + + +
  • +
  • Static or Dynamic

    Most +power resources are known at device creation time, so their control should +be addressed by such components as the Variant or ASSP. These resources are +registered during the creation of the Resource Controller; these are static +resources. Resources controlled by device drivers (internal or external) are +only registered at driver-creation time using the registration and deregistration +API provided by the PRM; these are known as dynamic resources.

    Note: +Dynamic resources are only available when you use the extended library. See setup +and configuration.

  • +

Physical resources may belong to one or more of these categories, +for example, a multilevel resource may be shared between different clients +and take a significant time to change state (long latency).

External +devices may include and control their own power resources. In some cases, +an external device can function as a bus expander, allowing other devices +to be connected, and eventually share the power resources it controls.

Caching the prevailing level

The +PRM caches the prevailing level of each resource as well as the client that +requested it. The cached state is guaranteed to be the state that the resource +was in when the last request to change or read the state from its hardware +was issued.

On resource state read operations, the PRM allows clients +to select the cached state instead of the current state of the hardware resource. +A cached state read is always an instantaneous operation executed in the context +of the calling client thread (even for long latency resources).

However, +care must be taken as the cached state may not be the state the resource is +at that moment. For example, a resource can be non-sticky: when it is turned +on it stays on during an operation but then automatically switches itself +off.

The consistency of the cached state relies on all resource state +operations being requested through the Power +Resource Controller.

Dynamic +resources

A generic layer provides basic functionality for static +resources an extended version of the PRM provides APIs for dynamic resources +and resource dependencies. These dynamic resource and resource dependent APIs +are only available through the extended library resmanextended.lib.

A +dynamic resource is registered with the PRM using PowerResourceManager::RegisterDynamicResource(). +This function is also used to register a dynamic resource that supports dependencies +between resources.

TInt RegisterDynamicResource(TUint aClientId, DDynamicPowerResource* aResource, TUint& aResourceId)

Pass the ID of the client that requests the dynamic resource and the +dynamic resource (DDynamicPowerResource) to register. The +PRM sets aResourceId to the resource ID of this resource. +Dynamic resources that support dependencies are derived from the class DDynamicPowerResourceD.

Deregistering a dynamic resource

Use PowerResourceManager::DeRegisterDynamicResource() to +deregister a dynamic resource from the PRM. You can also use the function +to deregister a dynamic resource that supports a dependency.

TInt DeRegisterDynamicResource(TUint aClientId, TUint aResourceId, TInt* aState)

aState is a pointer to the final state that the resource is set +to before deregistration if this value is NULL the state of the resource is +changed to its default.

Changing resource state on a dynamic resource

Because a dynamic +resource can deregister from the PRM it is necessary to indicate to clients +that this has happened. Any remaining notification requests are completed +with a -2 in the client field of the callback function. This indicates that +this notification is because the resource has been deregistered and not because +the notification conditions have been met. When a client recieves a notification +of this type the request notification should be cancelled using CancelNotification().

Resource dependencies

A +resource may register a dependency on another resource. At least one of the +resources must be a dynamic resource. Request a dependency between resources +with PowerResourceManager::RegisterResourceDependency().

TInt RegisterResourceDependency(TUint aClientId, SResourceDependencyInfo* aResDependecyInfo1, SResourceDependencyInfo* aResDependencyInfo2)

This function is passed the ID of the client that sets the resource dependency +and the dependency information of the resource (SResourceDependencyInfo). SResourceDependencyInfo contains +the resource ID and the priority of the dependency.

The kernel will +panic if a closed loop dependency is found for the specified dependency or +if a resource with same dependency priority is already registered.

Use GetNumDependentsForResource() to +retrieve the number of resources that depend on the specified resource directly +and GetDependentsIdForResource() to return the IDs of all +the dependent resources.

Deregistering +resource dependencies

Use PowerResourceManager::DeRegisterResourceDependency() to +remove a dependency. This function takes the ID of the client that requests +the deregistration of the resource dependency and the IDs of the linked resources.

TInt DeRegisterResourceDependency(TUint aClientId, TUint aResourceId1, TUint aResourceId2)

Note: These functions are only available when you use the extended +library.

Changing +resource state on a dependent resource

A resource state can change +when the state of any of its dependent resources changes. A state change causes +a notification if the requested conditions are met. The client ID in the callback +function is updated with the ID of the resource that triggered this resource +change (bit 16 of the ID is set for dependency resource; this is used to distinguish +between a resource ID and a client ID).

Clients

The +PRM has both user and kernel-side clients. Kernel-side clients are:

    +
  • device drivers

  • +
  • performance scaling +and/or performance monitoring and prediction components

  • +

User-side clients are:

    +
  • user-side system-wide +power management framework

  • +
  • other power-aware servers +and power-aware applications

  • +

Clients register with the PRM by name. Clients can request to allocate +and reserve client level objects and request message objects after registering +with PRM.

Client level objects

Client +level objects represent a client requesting a level on a resource. They are +used by resources to set the current level of the resource and the current +owner of the resource level.

Each resource has a doubly linked list +on which client level objects are held. When a client requests a level for +the first time, a new client level object is added to the list; however, if +the client already has an object on the list, this object is adjusted to reflect +the change in the required level.

The following rules determine whether +the change is allowed on positive and negative sense resources:

    +
  • If the requested change +is in the direction permitted by the resource sense and would result in exceeding +the prevailing level, the change is allowed.

    The new prevailing level +is recorded, and the previous prevailing level and the requirements other +clients have on the resource remain on record.

  • +
  • If the requested change +is not in the direction permitted by the resource sense, but the client requesting +the change is the owner of the prevailing level, the resource state changes +up to next highest for a positive sense resource, or lowest for a negative +sense resource.

    This value is now the prevailing level and the client +that requested it remains the owner of the prevailing level.

  • +
  • If the requested change +is not in the direction permitted by the resource sense, and the client requesting +the change is not the owner of the prevailing level, the change is not allowed.

    Even +though the request was rejected, the client's existing requirement is adjusted +to reflect the request.

  • +

Prevailing levels are recorded by either adjusting the previous requirement +for the client that requested it or, if it is the first time this client requests +a level, a new requirement is created.

Notifications

A +client may request a state change notification from a resource. Notifications +can be conditional or unconditional; conditional notifications specify a threshold +on the resources state, which when crossed in the direction specified, triggers +the notification.

Notifications are always issued post resource change +and invoke callback functions executed in the context of the requesting client +thread. The process of notifying a client involves queuing a DFC in that clients' +thread. The notification object encapsulating the DFC must be created in kernel +heap and passed to the notification API by the client that requested the notification. +The client may share the same callback function between several notifications, +but a unique DFC must be created and queued per notification.

Because +notifications result in DFCs being queued, it is not possible to guarantee +that all changes of resource state are notified. If the resource state changes +again before the first DFC runs, a separate notification cannot be generated. +It is also not possible to guarantee that by the time the notification callback +runs, the resource state is still the same as the state that caused the notification +to be issued: it is the responsibility of the driver to read the resource +state after receiving a notification.

+
User-side
    +
  • Introduction

  • +
  • Initialisation

  • +
  • Getting power resource information

  • +
  • Requesting notifications

  • +
  • Changing the state of power resources

  • +

Introduction

The RBusDevResManUs user-side +API makes relevant PRM functionality available to user-side applications that +have power-aware features.

RBusDevResManUs is derived +from RBusLogicalChannel, the user-side handle to a logical +channel base class, and presents the user-side interface to a kernel-side +LDD. The LDD is built as resman.ldd.

The API +enables concurrent access by multiple clients, with one channel supported +for each. Sharing of channels between threads is not supported.

To +open a channel on the user-side API a client must exhibit the PlatSec capability PowerMgt.

If a client wishes to access information +on kernel-side clients of the Resource Controller, it must also exhibit the ReadDeviceData capability.

Initialisation

Clients +do not need to explicitly load the kernel-side LDD, as this is a kernel extension +and so is loaded and initialised during kernel initialisation (attempts to +re-load it returns the error code KErrAlreadyExists but initialistation +otherwise appears successful).

Clients open a channel on the LDD by +calling the RBusDevResManUs::Open() method. The client +passes a name to the method - ideally, this is the client’s component name. +It is the client’s responsibility to ensure the name is unique even if multiple +channels are opened.

The client then needs to call the Initialise() method +specifying the number of request objects required. The numbers passed to Initialise() determine +the extent of memory allocation required (in part by the LDD and in addition +by request to the Resource Controller) and also the maximum number of concurrent +client requests supported.

The number of request objects created at +initialisation should be the maximum number of concurrent (asynchronous) requests +that the client expects to have outstanding at any time.

Getting power resource information

RBusDevResManUs::GetResourceInfo() is a method to retrieve the information for a specified resource, which +it returns in a TResourceInfo object. There is also a method +to get all the information for all the resources (GetAllResourcesInfo()). +This function requires the allocation of buffer memory in which the information +for all the resources is returned. GetNoOfResources() returns +the total number of resources available for access.

The example below +shows these functions in use. The amount of resources available are returned +by GetNoOfResources. This figure is used to calculate the +size of the buffer that is populated with the resource information by the GetAllResourcesInfo method.

TInt r = KErrNone; + TUint numResources=0; + if((r=gChannel.GetNoOfResources(numResources))!=KErrNone) + { + // Failed + return r; + } + + RBuf buffer; + if((buffer.Create(numResources*sizeof(TResourceInfo)))!=KErrNone) + { + // Failed + return KErrGeneral; + } + + buffer.SetLength(numResources*sizeof(TResourceInfo)); + + if((r=gChannel.GetAllResourcesInfo(buffer,numResources))!=KErrNone) + { + // Failed + return r; + }

Get the current resource state with GetResourceState(). +Passing ETrue results in the cached state being read rather +than the current hardware state. The cached state is guaranteed to be the +state that the resource was in when it was last changed or read from hardware. +This is why it is important that all change requests are carried out through +the Resource Controller. readValue returns the current prevailing +level and levelOwnerId the ID of the client that owns the +prevailing level. GetResourceState() can be cancelled using CancelGetResourceState() passing +the resource ID of the resource that the original request was on. Use the +method GetResourceIdByName() to get the ID of a resource +from the resource's name.

// Get initial state +TRequestStatus status; +TBool cached = EFalse; +TInt readValue; +TInt levelOwnerId = 0; + +gChannel.GetResourceState(status, gSharedResource, cached, &readValue, &levelOwnerId); +User::WaitForRequest(status);

GetNumClientsUsingResource() and GetNumResourcesInUseByClient() are used to retrieve the numbers of clients using a resource and the number +of resources in use by a client, respectively. GetInfoOnClientsUsingResource() and GetInfoOnResourcesInUseByClient() complement the last two methods by retrieving the resource information for +each resource that is in use by a specified client or retrieving the client +information for each client using the specified resource.

The API +supports receiving a number of concurrent (asynchronous) requests from a client; +the maximum number is determined by the number of resources that were specified +at initialisation. If a client issues a request that exceeds its allocation, +the error code KErrUnderflow is returned.

Some synchronous +methods take a binary value, aIncludeKern, which defaults +to EFalse. If this parameter is set to ETrue, +the API attempts to return information that includes kernel-side clients.

Requesting notifications

Clients +can request to be notified when a resource changes its state using the RBusDevResManUs::RequestNotification() method. +Clients can also request to be notified when a resource reaches a specified +threshold in a specified direction (positive or negative resource sense) using the same method but also passing it threshold +and direction values.

To cancel a notification, use CancelNotification() passing +the resource ID from which the notification was requested. Note: Any +notifications issued by a client must be cancelled before the client deregisters.

It +is not guaranteed that all changes of resource state result in a notification +– a resource may change state more than once before a notification request +is completed. In addition, it is not guaranteed that a resource is in the +same state as it was when the notification was generated. For these reasons, +it is the responsibility of the user-side client to read the state of a resource +after receiving a notification.

Changing the state of power +resources

To change a resource state call the asynchronous ChangeResourceState() method +passing the ID of the resource on which the change is being requested and +the requested state.

CancelChangeResourceState() cancels +all the ChangeResourceState() outstanding requests from the +client on the specified power resource. For each outstanding request, the +request object is removed from the doubly linked list within the Resource +Controller and returned to the request object pool.

+
Kernel-side

The Power Resource Manager component is implemented +as a kernel extension. It has an exported public interface accessible to kernel-side +components. Kernel components link to the resource manager kernel extension +DLL (resman.lib). Extended features are compiled and +exported in an additional library (resmanextended.lib). +The export library is built from the generic layer.

To ease the development +of the PRM including the functionality provided by the generic layer and the +mandatory PSL implementation, the generic layer is compiled into a kernel +library (klib) (resmanpsl.lib for the basic version and resmanextendedpsl.lib for +the extended version) which is included by the PSL to produce the kernel extension.

    +
  • Concepts

  • +
  • Registration and initialisation

  • +
  • Deregistration

  • +
  • Requesting power resource information

  • +
  • Changing the state of power resources

  • +
  • Requesting notifications

  • +

Concepts

    +
  • Requests

  • +
  • Callbacks

  • +

Request messages

Request +message objects represent a request for an operation on a resource by a client. +For example a request to change a resource's level or notification if a resource's +level changes.

The client may attempt to increase its quota by requesting +the allocation of request messages, but this may fail with KErrNoMemory. +A long latency resource request on may fail with KErrUnderflow if +the number of request messages pre-allocated by the client has been exceeded +and no more messages are left in the free pool to satisfy the request.

The +pre-allocation and reservation of client +levels and request messages is synchronously serviced in the context +of the calling client, although this may result in memory allocation that +is not time bound.

See Pre-allocating +client level and request message objects for implementation guidelines.

Callbacks

A +callback object is a customised DFC that is used to signal the completion +of notifications and the PRM's asynchronous APIs. Use the class TPowerResourceCb to +create a resource callback object that encapsulates callback functions.

The +resource callback object is initialised with a callback function TPowerResourceCbFn, +a pointer to data passed to the callback function, the priority of the DFC +within the queue (0 to 7, where 7 is highest) and optionally, a pointer to +the DFC queue that this DFC should use.

inline TPowerResourceCb(TPowerResourceCbFn aFn, TAny* aPtr, TInt aPriority)

This one specifies the DFC queue:

inline TPowerResourceCb(TPowerResourceCbFn aFn, TAny* aPtr, TDfcQue* aQue, TInt aPriority)

The user specified callback function is invoked with five arguments:

    +
  • the ID of the client +is:

      +
    • the client that issued +an asynchronous operation - if the callback function is called as a result +of an asynchronous resource state read operation

    • +
    • the client that is currently +holding the resource - if the callback function is called as a result of an +asynchronous resource state change operation or resource state change notification.

    • +
    • Note:

        +
      • If -1 is passed as the +client ID this specifies that no client is currently holding the resource.

      • +
      • In the extended version +of PRM (see Dynamic and Dependant resources) if -2 is passed as the client +ID in the callback function it signifies that the dynamic resource is deregistering. +With dependency resources, the ID of the dependent resource is passed as the +client ID if the state of the resource (specified in aResourceId) +changes as a result of the dependant resources stage changing (whose ID is +specified in aClientId).

      • +
    • +
      +
    • issued an asynchronous +API (state read or change) which leads to the callback function being called

    • +
    • requested the resource +state change that leads to queuing a notification, which then leads to the +callback function being called.

    • +
  • +
  • the resource ID - a +client may have multiple notifications pending on different resources and +a single callback function. The resource ID can be used to specify which resource +change is being notified

  • +
  • the level of the resource +when either:

      +
    • the callback is called +as a result of a notification of state change

    • +
    • when the callback is +called as a result of a non-blocking form of PowerResourceManager::GetResourceState().

    • +
    • the requested level +for the resource when the callback is called as a result of a non-blocking +form of PowerResourceManager::ChangeResourceState()

    • +
  • +
  • the ID of the resource +level owner

  • +
  • the error code returned +when the callback is called as a result of an asynchronous request to change +the state of the resource. This is not relevant when the callback is called +as a result of a notification of state change

  • +
  • a user defined argument +that is passed to the constructor.

  • +

Cancel an asynchronous request, or its callback, by calling CancelAsyncRequestCallback().

Registration and initialisation

Clients +need to register with the PRM using PowerResourceManager::RegisterClient() before +they can request operations on resources.

Registration happens at +different times for different clients:

    +
  • kernel extensions register +from their entry point during kernel boot

  • +
  • device drivers for internal +or external devices register on opening a channel.

  • +

When a client registers with the PRM, a client link object is removed +from the free pool, populated with the relevant information, and a pointer +to it is added to a container of clients within the PRM. If no free link exists +within the pool, a number of client links are created in kernel heap. As a +result, client registration may fail in out of memory situations. Client links +are never destroyed after the client deregisters, but are released back into +the free pool.

Clients are registered by name; the PRM does not check +that a name is unique unless the DEBUG_VERSION macro is enabled. +The component registering the client should check that the name is unique. +The ID returned is a handle to the client link object that represents the +client in the PRM.

On registration, a client also specifies the type +of ownership (TOwnerType) that applies. This is either:

    +
  • EOwnerThread - +the client ID is only used by the thread that registered the client to call +the PRM APIs

  • +
  • EOwnerProcess - +the client ID is used by all threads in the process to call the PRM APIs.

  • +

The default is EOwnerProcess.

Pre-allocating client level +and request message objects

The controller has an initial pool +of free client levels and request messages whose size can be configured at +build time by the PSL. After registering with the PRM, a client can request +the pre-allocation of a number of client levels and request messages to guarantee +deterministic behaviour (to avoid out of memory failure) of the resource state +change operation using PowerResourceManager::AllocReserve(). +This allocation remains reserved to the specified client until the client +is deregistered from the PRM. The number of client level objects reserved +by a client depends on the number of resources on which a resource state change +will be requested.

A client may issue more than one request, possibly +to the same resource, before the previous one completes, it is therefore more +difficult to determine how many objects to pre-allocate.

It is recommended +that as many request messages as asynchronous long latency resources the client +expects to use are pre-allocated. The free pool should be relied on for the +situations when a resource is requested more than once before the first request +completes.

Deregistration

All +notifications and asynchronous requests must be cancelled before the client +is deregistered, otherwise the kernel will panic. Use the PowerResourceManager::CancelNotification() and CancelAsyncRequestCallback() methods to cancel all pending notifications and asynchronous requests. Notifications +that have been registered with the Controller should be deregistered before +they are deleted as the Controller may attempt to issue them. Deleting a notification +that is still registered with the Controller results in the kernel panicking.

Client +level objects and request objects reserved by the client remain reserved +for that client until it deregisters. When the client is deregistering these +objects are moved to free pool by the PRM.

Client deregistration can +result in a resource state change:

    +
  • If the resource is shared +and the deregistering client owned the prevailing level, the resource state +is moved to the next level according to its sense. If it is a custom sense +resource, the resource state is changed as a result of calling a custom function.

  • +
  • If the resource is not +shared or if it is shared but the client is the only one using it at the time +of deregistration, the resource is moved to the default state. The +default state is only known by the PSL.

  • +

A deregistering client can have a number of active requirements on +a number of resources and more than one of these resources may need to change +state as a result of the client deregistering. The combined operation of deregistering +the client and adjusting the state of all resources it shares executes synchronously. +That is, the client thread is blocked throughout whether the resources whose +state needs to change is instantaneous or long latency.

Getting power resource information

The +resource information can be retrieved using the method PowerResourceManager::GetResourceInfo(), +information can also be retrieved for all of the resources used by the specified +client using GetInfoOnResourcesInUseByClient(). This function +takes a buffer that must be the size of the information structure multipled +by the number of resources in use by the client, this figure can be retrieved +using the method GetNumResourcesInUseByClient(). Specify +the resource ID as zero to retrieve all information from all the clients registered +with PRM.

To get information about clients using a resource, use the +method GetInfoOnClientsUsingResource(). Use the number +of clients using a resource using GetNumClientsUsingResource(). +Specify the client ID as zero to retrieve all information from all the resources +registered with PRM.

Use PowerResourceManager::GetResourceState() to +retrieve resource state information. This function can be called synchronously +or asynchronously. Asynchronous calls require the client to create a callback +object in the kernel heap or data section. The synchronous GetResourceState() call.

TInt GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached, TInt& aState, TInt& aLevelOwnerId);

The asynchronous GetResourceState() call.

TInt GetResourceState(TUint aClientId, TUint aResourceId, TBool aCached, TPowerResourceCb& aCb);

If executing asynchronously, the callback function encapsulated in the +callback object (called in the client’s context) is invoked when the state +of the resource is available. The third argument of the callback function +carries the resource state. If this function is called with aCached set +as ETrue, then the callback function is called in the context +of the calling thread both for instantaneous and long latency resources, thus +blocking the calling thread throughout.

For instantaneous resources, GetResourceState() executes +in the context of the calling thread and, if specified, the callback function +is called after getting the state of the requested resource. The calling thread +is blocked throughout.

GetResourceState() takes +a boolean value that determines from where the requested resource state information +is retrieved:

    +
  • ETrue - the resource +state is the cached value, this value is returned faster but is not guaranteed +to be correct

  • +
  • EFalse - the resource +state is read from the resource, this value takes longer to return, but is +much more likely to be correct.

  • +

Changing the state of power +resources

The PowerResourceManager::ChangeResourceState() method +is used to request a change on a resource. When a state change is requested +on a shared resource, only the minimum state change that satisfies the request +is guaranteed.

TInt ChangeResourceState(TUint aClientId, TUint aResourceId, TInt aNewState, TPowerResourceCb* aCb=NULL);

The values passed to the method are:

    +
  • the ID of the client +requesting the change

  • +
  • the ID of the resource +that the change is to take place

  • +
  • the new state of the +resource

  • +
  • a pointer to the resource +callback object.

  • +

The requested state is either a binary value for a binary resource, +an integer level for a multilevel resource or some platform specific token +for a multi-property resource. The pointer to the callback object is defined +by the class TPowerResourceCb; its use is optional and +is treated by synchronous and asynchronous resources as described below.

Changing resource state on a long latency resource

If the +callback object is specified, then ChangeResourceState() is +executed asynchronously and returns immediately. The actual resource change +happens in the resource controller thread and the callback function encapsulated +in the callback object is called after the resource is changed.

If +the callback object is NULL, then ChangeResourceState() executes +synchronously, meaning the client thread is blocked until the resource state +has changed. The PRM panics if the synchronous version of this API for long +latency resources is called from DFC thread 0.

Changing resource state on an instantaneous resource

On an +instantaneous resource ChangeResourceState() always executes +synchronously.

If a callback object is specified, then the callback +function encapsulated in the callback object is called from the client thread +after the resource change and before returning from the function.

Use CancelAsyncRequestCallBack() to +cancel change requests on a resource. When the client no longer requires a +level on a resource use the method DeRegisterClientLevelFromResource() to +remove a client level object from a resource.

Requesting notifications

Clients +can request notification of a state change on a resource. Notifications are +issued post resource change and invoke the callback function encapsulated +in a notification object. The callback is executed in the context of the requesting +client thread.

The parameters passed to PowerResourceManager::RequestNotification() are:

    +
  • the ID of the client +requesting the notification

  • +
  • the ID of the resource +for which notification of state changes is being requested

  • +
  • a reference to a notification +object encapsulating a callback function called whenever a resource state +change takes place.

  • +

A notification may be unconditional or conditional. An unconditional +notification request notifies the client each time the state changes. A conditional +notification request notifies the client when a threshold has been met in +the direction specified. A conditional notification has these additional parameters:

    +
  • aThreshold - the level +of the resource state that triggers the notification

  • +
  • aDirection - the direction +the resource state change that triggers a notification:

      +
    • EFalse - the resource +state is equal to or below the threshold

    • +
    • ETrue - the resource +state is equal to or above the threshold.

    • +
  • +

The client must create the notification object (DPowerResourceNotification) +in the kernel heap or data section. Note: The client may share the +same callback function between several notifications but a unique DFC must +be created and queued for each notification.

Because notifications +result in DFCs being queued, it is not possible to guarantee that all resource +state changes are notified. If the resource state changes again, before the +first DFC runs, it does not generate a separate notification. It is also not +possible to guarantee that by the time the notification callback runs the +resource state is still the same state that caused the notification to be +issued. The client should read the resource state after receiving a notification.

Use CancelRequestNotification() to +cancel a notification request. It takes a reference to the notification object +associated with the original notification request that is being cancelled.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-6E208C69-AC2C-4A7A-8203-2C4C3F2E54F5.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-6E208C69-AC2C-4A7A-8203-2C4C3F2E54F5.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,60 @@ + + + + + +Binding +and UnbindingThis document describes how device drivers bind and unbind interrupts. +

To handle events, the interrupt source and the ISR have to be registered +with the OS: this is called binding the interrupt. An interrupt +has to be unbound when its use is complete.

+
Binding

An +interrupt source ID is bound with the driver's interrupt service routine. +This is done using the function Interrupt::Bind() in the second +stage constructor of the physical channel. Interrupt binding can fail +if the source has been already used or bound.

TInt DExUartPhysicalChannelH4::DoCreate(TInt aUnit, const TDesC8* aInfo, const TVersion& aVer) + { + ... + // Bind the interrupt service routine (ISR) to a specific + // interrupt ID. When the ISR is called, the value aPtr, + // (here this object) is passed as the argument. The ISR + // must be a static void function, taking a single TAny* + // parameter: void Isr(TAny* aParam). Interrupt::Enable() + // must be called to start receiving interrupts. Bind() + // returns KErrInUse if the ISR is already bound. + // + TInt r = Interrupt::Bind(iIrqId,UartIsr,this); + if (r!=KErrNone) + { + KDBG(Kern::Printf("DExUartPhysicalChannel::Interrupt Binding + for UART failed")); + return r; + } + + return KErrNone; + }
+
Unbinding

An +interrupt is unbound by calling Interrupt::UnBind(), which +de-registers the interrupt source and routine. This must be done before or +during physical channel destruction. Unbinding an interrupt does not disable +its source. Interrupts have to be disabled explicitly before unbinding to +avoid spurious interrupts.

/** + Physical channel destructor. Delete and free any objects created and + allocated by the physical channel. This is called by the + framework while unloading the driver (PDD). + */ +DExUartPhysicalChannelH4::~DExUartPhysicalChannelH4() + { + // Unbind the UART interrupt. Interrupt::Unbind() frees the + // interrupt service routine (ISR) function from the specified + // interrupt ID. + // + Interrupt::Unbind (iIrqId); + }
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-6E89E787-749D-5AC5-957D-967B4B9ACD74.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-6E89E787-749D-5AC5-957D-967B4B9ACD74.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,121 @@ + + + + + +Using +the BIL InterfaceThis tutorial describes how to use the Buffer Interface Layer (BIL) +to read and write shared chunks form the client driver. +

The BIL +is a thin layer over the LDD APIs that removes the need for the class driver +to handle buffers directly. The BIL is consistent between different class +drivers and reduces the buffer related understanding needed to use the USBSc +LDD.

Using the BIL is optional to the class driver, but very highly +recommended.

Before completing these steps you must have followed +the procedure from + the beginning of the tutorial set through to +RDevUsbcScClient::FinalizeInterface()

+ + Open each endpoint +object. + +Use the function RDevUsbcScClient::OpenEndpoint() for +each endpoint object. +TEndpointBuffer iEpBuf; +const TUint KWriteEp = 1; + +gPort.OpenEndpoint(iEpBuf, KWriteEp); + OpenEndpoint() fills the provided endpoint buffer +(iEpBuf) for use with the given endpoint number (KWriteEp). +This endpoint will be opened on the current alternate interface setting. + + + Reading with an OUT endpoint. +To read with an endpoint call TEndpointBuffer::GetBuffer() to +request data from the BIL. +r = iEpBuf.GetBuffer(scReadData, readSize, readZlp, aStatus); +The first parameter passed to GetBuffer() can be either +a pointer to the transfer buffer or the offset of the transfer data within +the shared chunk. +This function allows the BIL to expire any previously retrieved transfer +on this endpoint so that it can be used again for new transfers. If the transfer +or the LDD are not ready then aStatus is set to pending. +If no transfer is available then the variable passed in the first parameter +is set to NULL or 0 depending on the API. Call this function again on completion, +to wait for data again. +The function GetBuffer() returns: + + + + KErrCompletion if data could be retrieved without +a pending request, + + + KErrNone if an asynchronous request was queued. This +function should be called again on completion, + + + KErrEof if the end of the data in the endpoint has +been reached, + + + KErrNotSupported if the endpoint is an IN endpoint. + + +If the host has changed to an alternate setting and you wish to continue +reading and writing data then you must Close() all endpoints +and go to step five Process the next alternate set of endpoints. Otherwise, +if you have finished then go to step four Close each endpoint object. + + + Writing with an IN endpoint. +After filling a shared chunk buffer with some data call TEndpointBuffer::WriteBuffer() to +write the data to endpoint hardware. + WriteBuffer() transmits the provided buffer on the +given endpoint asynchronously. More than one request may be outstanding at +any time. This reduces the time between buffer transfers. +r = iEpBuf.WriteBuffer(buffer, length, ETrue, aStatus); +The first parameter passed to WriteBuffer() can be +either a pointer to the transfer buffer or the offset of the transfer data +within the shared chunk. +If the host has changed to an alternate setting and you wish to continue +reading and writing data then you must Close() all endpoints +and go to step five Process the next alternate set of endpoints. Otherwise, +if you have finished then go to step four Close each endpoint object. + + + Close each endpoint object. +Each endpoint object opened with OpenEndpoint() must +be closed with TEndpointBuffer::Close(). +iEpBuf.Close(); +If the host has changed to an alternate setting and you wish to continue +reading and writing data then you must Close() all endpoints +and go to step five Process the next alternate set of endpoints. Otherwise, +if you have finished data transfer then Close +and Unload the Driver. +If you wish to continue reading and writing data but on an alternate +setting then call RDevUsbcScClient::StartNextOutAlternateSetting(). +Otherwise if you have finished then Close and Unload the Driver. + + + Process the next alternate set of endpoints. +Use the function RDevUsbcScClient::StartNextOutAlternateSetting() to +switch to the next set of endpoints. The alternate interfaces were initialised +with SetInterface(). See Set +the Interface Descriptors. +TInt r = StartNextOutAlternateSetting(ETrue); +Pass ETrue to the function to purge the buffers of any data unread for +the previous setting. + Note: All open endpoints (except EP0) must be closed before this is +called. + + +

When you have finished reading and writing Close +and Unload the Driver.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-6EB38F10-849D-5763-96A0-A0A108982D67-master.png Binary file Adaptation/GUID-6EB38F10-849D-5763-96A0-A0A108982D67-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-6EB38F10-849D-5763-96A0-A0A108982D67_d0e63496_href.png Binary file Adaptation/GUID-6EB38F10-849D-5763-96A0-A0A108982D67_d0e63496_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-6EF762B8-DE93-51C0-8A5D-89FC5289B7D0.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-6EF762B8-DE93-51C0-8A5D-89FC5289B7D0.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,29 @@ + + + + + +MMP Tutorial This tutorial describes how to set the paging options for an individual executable.

The paging options are:

  • code paging
  • data paging
  • both code and data paging

Making executables (either exe or dll) paged is the finest level of control of paging at runtime. In the order of precedence for paging keywords, the values in this file will be overridden by those in the oby file.

The following keywords are used to indicate whether the executable is + unpaged or paged. If the executable is paged then the keywords indicate if code + paging, data paging or both are to be used.

Keyword

Behaviour on Symbion OS v9.6 and later

paged

Enables code and data paging

unpaged

Disables code and data paging

pagedcode

Enables code paging

unpagedcode

Disables code paging

pageddata

Enables data paging

unpageddata

Disables data paging

When using the above keywords, the following points must be considered.

  • The keywords pageddata and unpageddata do not make sense for files that are not executable binaries, and will be ignored.
  • The use of the paged, unpaged, pagedcode and unpagedcode keywords only states the default paging behaviour of the data that is to paged by the executable. The behaviour can be overridden by using the TChunkCreateInfo, RChunk and TChunkHeapCreateInfo API.
  • The keywords in the table above, should appear on a separate line on their own and with no arguments
  • If the build tools are configured to compress executables while building them (this is the default behaviour), then executables marked with paged or the pagedcode keyword will be implicitly byte-pair compressed.
  • If a ROM/ROFS partition defines a pagingoverride, codepagingoverride or datapagingoverride as defaultpaged or defaultunpaged, then the pagability specified in the mmp file will be implemented.
  • If a ROM/ROFS partition has defines pagingoverride, codepagingoverride or datapagingoverride as nopaging or alwayspage, then the pagability specified in the mmp file will be ignored.

Building the executable with the new keyword does not produce any errors or warnings.

mmp file example

Below is an example mmp file with paging:

TARGET dummy.dll +TARGETTYPE DLL + +UID 0x10003d3a +VENDORID 0x12345678 + +SOURCEPATH ../dummy +SOURCE dummy1.cpp dummy2.cpp + +SYSTEMINCLUDE /epoc32/include + +LIBRARY euser.lib + +CAPABILITY PowerMgmt ReadDeviceData WriteDeviceData LocalServices ReadUserData WriteUserData + +UNPAGED

The above mmp file, specifies that the dummy.dll file is not going to use demand paging.

\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-6F82A35E-9F11-591D-AA5C-8F60734A2827.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-6F82A35E-9F11-591D-AA5C-8F60734A2827.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,16 @@ + + + + + +Demand Paging +Guides +

Contains guides that describe various aspects of demand paging in more +detail.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-70041B11-4C03-42C6-9EC2-307E5FF0F626.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-70041B11-4C03-42C6-9EC2-307E5FF0F626.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,165 @@ + + + + + +IIC Interface OverviewProvides a summary of IIC interface. +

The IIC platform service provides APIs for a master channel and +a slave channel. The PIL provides the generic platform independent +functionality.

+
+ Master channel

You must derive a +class from DIicBusChannelMaster and implement certain +pure virtual functions.

+ + + +API +Description + + + + +DIicBusChannelMaster::DoRequest(TIicBusTransaction* +aTransaction) +Gateway function for the PSL implementation. This function +allows the client to request a new channel. + + +DIicBusChannelMaster::DoCreate() +Second phase constructor to create a new channel. + + +DIicBusChannelMaster::HandleSlaveTimeout() +Function to be called in the event of slave time out. Implement +this function to stop the transmission, disable the hardware or call +PIL function CompleteRequest(). + + +DIicBusChannelMaster::CheckHdr() +Function to check if the header of the transaction is valid. + + + +
+
PIL +functions for master channelThe following functions can be +used by the platform specific implementation of the IIC platform services. + + + +API +Description + + + + + DIicBusChannelMaster::Init() +Initialise the child class DIicBusChannelMaster. + + +DIicBusChannelMaster::SetDfcQ() +To set the IIC driver's DFC queue to be used by the DFC of +PIL. + + +DIicBusChannelMaster::StartSlaveTimeOutTimer() +To start a timer to wait for the slave class functions, if +the time expires the HandleSlaveTimeout() call +up function is invoked by the clients. + + +DIicBusChannelMaster::CancelTimeOut() +To cancel the timer monitoring the transactions. + + +DIicBusChannelMaster::CompleteRequest() +To notify the PIL of a completed transaction + + + +
+
Slave +channelYou must derive a class from DIicBusChannelSlave and implement the following pure virtual functions: + + + +API +Description + + + + + DIicBusChannelSlave::DoRequest() +The gateway function to the SHAI implementation layer. + + + DIicBusChannelSlave::DoCreate() +The second phase constructor function to create a new channel. + + + DIicBusChannelSlave::ProcessData() + Called by the PIL in response to the DIicBusChannelSlave::NotifyClient() function. + + + DIicBusChannelSlave::ChechHdr() +The function to validate a configuration. + + + +
+
PIL +function for slave channelThe following are the generic functions +provided by the PIL of the IIC platform service: + + + +API +Description + + + + +DIicBusChannelSlave::DIicBusChannelSlave() +Constructor function for PIL. + + +DIicBusChannelSlave::Init() +Initialise the slave channel. + + +DIicBusChannelSlave::SetMasterWaitTime() +Set the timer to wait for the master channel to respond after +a transmission is started. + + +DIicBusChannelSlave::GetMasterWaitTime() +Get the current delay to wait for the master channel to respond +after a transmission is started. + + +DIicBusChannelSlave::SetClientWaitTime() +Set the timer of the client to respond for the next operation. + + +DIicBusChannelSlave::GetClientWaitTime() +Get the current delay of the client to respond for the next +operation. + + +DIicBusChannelSlave::NotifyClient() +Notify clients of the slave channel events. + + + +

The header file for the IIC can be found here

+
+IIC +Implementation Guide +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-71271D1C-C385-5687-8A90-46E8B590BB1E-master.png Binary file Adaptation/GUID-71271D1C-C385-5687-8A90-46E8B590BB1E-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-71271D1C-C385-5687-8A90-46E8B590BB1E_d0e1517_href.png Binary file Adaptation/GUID-71271D1C-C385-5687-8A90-46E8B590BB1E_d0e1517_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-73B853D5-13E6-54E7-AA8B-C41EEDB5EA7F.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-73B853D5-13E6-54E7-AA8B-C41EEDB5EA7F.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,32 @@ + + + + + + RMdaDevSound-Based +Driver MigrationExplains how to convert an RMdaDevSound -based +sound driver to the current Sound Driver architecture. +

Symbian converted the PDD of the RMdaDevSound based driver +to an RSoundSc version of the PDD. The same procedure was +used for this on all three platforms.

+

PDDs for the RMdaDevSound based driver have a significant +amount of code that is dedicated to creating and managing a circular buffer, DSoundBuffer, +for storing playback or record audio. In the RSoundSc version +of the driver, this is taken care of by the shared chunk and this code can +be discarded.

+

For the remaining PDD code, although the LDD to PDD interface for the RMdaDevSound based +version is similar to the RSoundSc version, it is best +to start by taking a copy of the template port as described in Set +Up , then fill in the sections marked TODO in the template code by +cutting and pasting the relevant code coming from a single function, this +is often called the same in each version of the driver.

+

One complication comes if the RSoundSc version is to +support both record and playback driver channels, as this requires some of +the functionality to be moved to the shared PDD factory object.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-73D9E2F2-5965-479E-97DB-C3773DA0D90C.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-73D9E2F2-5965-479E-97DB-C3773DA0D90C.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,39 @@ + + + + + +Device Driver Quick StartA quick introduction to the device driver documentation. +

Device drivers provide a mechanism for applications and other operating +system functions to access hardware devices without needing to know +how each specific piece of hardware works. In addition device drivers +may be written so that part of the device driver is user-side space +and the rest is kernel-side so that the device driver can access shared +memory and resources that belong to the Kernel.

+
Who +this documentation is for

There are two main sets of users +for device drivers:

    +
  • Application developers that want to use device drivers

  • +
  • Developers that need to create or amend device drivers.

  • +

This documentation set is aimed at the second category +of users. If you are an application developer and want to use a particular +device driver, then you should search for, and read the documentation +for that specific device driver.

+
Device driver framework

The device driver guide explains +the concepts of device driver framework and how to implement a device +driver.

    +
  • For the basic concepts of device driver, see Device Driver Concepts

  • +
  • To write a device driver, see Device Driver Writing +Guide

  • +
  • To use the kernel services in a device driver, see Kernel-Side Services

  • +
  • To debug your device driver implementation, see Debug Monitor Tool

  • +
  • It is important to understand how memory is paged in the system, +so you should also read Demand Paging.

  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-73F220EA-F41F-56A5-BAEB-4A37174CFD1F.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-73F220EA-F41F-56A5-BAEB-4A37174CFD1F.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,117 @@ + + + + + +Power +ManagementDescribes the power management policies. +

The MMC Controller manages the power to the MultiMediaCard hardware.

+
Normal power +up and power down handling

Before card commands can be issued to +a card, three operations are required:

    +
  • power must be applied +to the card, i.e. VDD must be turned on

  • +
  • any requirement from +the power model must be set, e.g. requesting a necessary system clock

  • +
  • the clock to the card +interface must be switched on.

  • +

All three operations are performed as part of the DMMCStack::CIMInitStackSM() state +machine function which then issues the sequence of commands involved in performing +the CIM_UPDATE_ACQ macro to initialize a card stack.

There +are two cases:

    +
  • Local drive requests, +i.e. those originating from a media driver - if the card is not fully powered +up when such a request is received, then the local media device driver automatically +precedes the request with an instruction to the controller to power up the +card. This results in DMMCSocket::InitiatePowerUpSequence() being +called, which in turn invokes the DMMCStack::CIMInitStackSM() state +machine function.

    Once the MultiMediaCard stack has been initialized, +the MultiMediaCard controller calls DPBusSocket::PowerUpSequenceComplete() to +signal the completion of initialization back to the local media driver, and +this can then continue to open a media driver and continue with the original +request.

    This automatic re-powering of the card applies in all situations +which can lead to the card not being powered: media change, machine power +down, card inactivity timeout, VDD power problem etc. In most cases, the process +of restoring power results in the closure of any existing media driver and +a new one opened. As the kernel thread used to perform controller requests +is able to block, this means that no special mechanism is necessary to allow +for this potential long-running power up sequence prior to a request on the +device.

  • +
  • Requests not originating +via a local media device driver, for example device drivers for I/O cards +- if the MultiMediaCard stack is not initialized when the client submits a +session, then the MultiMediaCard controller automatically precedes the request +with a call to the DMMCStack::CIMInitStackSM() state machine +function.

  • +

The MultiMediaCard controller will normally be configured with an +inactivity timer. If a given period elapses where there is no bus activity, +then the controller automatically turns off the card clock, removes any power +requirements on the power model, and then removes power from the cards. This +is the bus power down sequence. The length of this inactivity timeout period +is set in the platform specific layer as part of porting the controller, and +can be disabled completely if required; see the reference to porting the PsuInfo() function +as part of implementing the DMMCPsu +derived class.

Clients of the controller do not need to worry +about re-initializing the stack following such a power down as the controller +does this automatically.

In the event of a PSU voltage check failure, +the controller performs the bus power down sequence. It will not re-power +the problem card and will expect it to be removed.

The power model +calls DPBusSocket::DoPowerDown() when the machine is about +to be normally turned off (due to the off key being pressed or keyboard/touch +screen inactivity). This leads to the function DMMCStack::PowerDownStack() being +called resulting in the bus power down sequence.

When the machine +is powered back up after a normal power off, the power model calls DPBusSocket::DoPowerUp(). +However, the controller normally does not power up the bus, but waits for +the next request from one of its clients before doing so. The only exception +is where a card power up sequence was interrupted by the machine being turned +off.

+
Emergency +power down

In an emergency power down situation, for example, where +a battery is in a critically low power state, the MultiMediaCard controller +performs the normal bus power down sequence as this is not a lengthy operation. +The power model calls DPBusSocket::DoEmergencyPowerDown(), +which results in a call to DMMCStack::PowerDownStack().

However, +there is always a risk that a block being written to a card may become corrupt. +The solution to this problem lies in the hardware architecture. Two possible +solutions are:

    +
  • to provide enough early +warning of power being removed before the battery level becomes too low for +card operation. For example, a catch mechanism on a battery door, making it +slow to remove. This would provide sufficient time for any write operation +in progress to be terminated at the next block boundary before the power supply +is lost.

    Note, however, that the media driver fails any operations +involving write operations to a card when the battery level is becoming dangerously +low, so in general, we are only talking about unexpected battery removal.

  • +
  • to provide a backup +battery so that the failing write operation can be re-retried once a good +battery level has been restored.

  • +

Even with such mechanisms in place, if power is removed in the middle +of a multi-block write operation, then some blocks will contain new data while +others will still contain old data.

+
Media change

When +a door open event is detected by the MultiMediaCard controller, it attempts +to remove power from a card as soon as possible. Power is not removed immediately +if a bus operation is in progress as powering down a card in the middle of +writing a block could leave the block corrupted.

Power is only removed +from a card immediately a door open event occurs if there are no sessions +queued by clients on the controller. If one or more sessions are queued then +these are allowed to complete, with power being removed once the last session +has completed. Any attempt to engage a new session while the door is open +fails with KErrNotReady.

To prevent a card becoming +corrupt because of attempted removal during a write operation, then it is +important that the door mechanism and circuitry gives enough early warning +of a potential card removal before the card is actually removed. This is to +provide sufficient time for any write operation in progress to proceed to +the next block boundary before the card is removed.

Once the door +is closed again, then new sessions can be engaged and power can be re-applied +to the card by the controller. However, power is only restored by the controller +in response to a client request. The Controller does not automatically re-power +a card to resume an operation interrupted by a door open event, no matter +what operation was in progress when the door opened.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-746BD53F-F637-4BC9-91AC-E53BA182B823-master.png Binary file Adaptation/GUID-746BD53F-F637-4BC9-91AC-E53BA182B823-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-746BD53F-F637-4BC9-91AC-E53BA182B823_d0e87730_href.png Binary file Adaptation/GUID-746BD53F-F637-4BC9-91AC-E53BA182B823_d0e87730_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-76A30EC4-4B99-5471-9E80-F853C91485BC.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-76A30EC4-4B99-5471-9E80-F853C91485BC.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,198 @@ + + + + + +Interrupt DispatcherThe ASSP/Variant part of the base port must implement an +interrupt dispatcher to manage interrupts. +

An interrupt source is a hardware device or software action that +can force the CPU to suspend normal execution, enter interrupt handling +state and jump to a section of code called an interrupt handler.

+

Typically, a number of interrupt sources are monitored by an interrupt +controller. This is hardware that generates a single interrupt notification +to the CPU, and provides information about which interrupts are pending, +i.e. which interrupts require action to be taken.

+
ISR

An interrupt service routine, or ISR, is code that deals with +a pending interrupt. The Symbian platform kernel responds to an interrupt +notification by calling an ISR for each pending interrupt. The process +of calling ISRs is called interrupt dispatch.

The ISR is a +single bare function. It is not a class member.

Each ISR takes +a single 32-bit parameter that is, typically, a pointer to an owning +class, although it can be any value that is appropriate. The parameter +is defined as a TAny * type, so a cast is almost +always necessary.

ISRs are usually kept in an ISR table.

+
Interrupt +ID

An interrupt source is identified by number, defined +as a TInt type. Typically, the ASSP layer defines +this number for each interrupt in a header file and exports it so +that it can be included and used by device drivers.

Where +the ASSP layer is split into a common layer and a variant (device +specific) layer, then the variant layer may also define its own set +of interrupt IDs.

This number is usually referred to as the +interrupt ID.

+
Binding +and unbinding

Only one ISR can be associated with each +possible interrupt source. Making this association is known as binding. +ISRs can be bound and unbound during normal operation, but only one +ISR can be bound to an interrupt source at any one time.

A +device driver binds an ISR by calling Interrupt::Bind(), passing the interrupt source ID; similarly, the device driver can +unbind the ISR by calling Interrupt::Unbind(), +also passing the interrupt ID.

+
Dispatching +interrupts

At its simplest, this is the process of deciding +which interrupts are pending and calling the ISR for each.

The following pseudo code shows the general principle:

+ { + FOREVER + { + Get next pending interrupt; + if None + { + return; + } + call ISR for the pending interrupt; + } + } +

In practice the dispatcher may have to do some more +work to communicate with the interrupt controller hardware.

+
Chained +interrupts

A system may have multiple interrupt controllers +to handle a large number of interrupt sources. These are usually prioritised +by connecting the interrupt output of a lower-priority controller +to an interrupt input of a higher-priority controller. This is called +chaining.

+Chained interrupts + +

An interrupt from a lower priority controller will appear +as an interrupt on the highest-priority controller.

When the +interrupt dispatcher of the higher-priority controller detects that +it is the chained interrupt that is pending, the usual way of dealing +with this is to run a secondary dispatcher to determine which interrupt +on the chained controller is pending.

There may be further +levels of chaining before the true source of the interrupt has been +identified.

+
Multiple +interrupt sources and pseudo interrupt sources

It is possible +that a single input to an interrupt controller is shared by several +interrupt sources.

+Multiple interrupt sources + +

It appears necessary to bind multiple ISRs to the same interrupt. +However, this is not possible. There are two ways of dealing with +this:

    +
  • Maintain a list +of all ISRs that are bound to this single interrupt source, and call +all the ISRs in the list when the interrupt is dispatched. This is +most conveniently implemented by binding a single ISR to the interrupt, +which then calls all the real ISRs bound to this interrupt

  • +
  • Create pseudo +interrupts. These are extra interrupt IDs that do not exist in the +interrupt controller, but represent each of the interrupt sources +connected to the single shared interrupt source. An ISR can then be +bound to each pseudo interrupt. The interrupt dispatcher can then +determine which of the sources are actually signalling and call the +appropriate ISR via that pseudo interrupt ID. This is effectively +an implementation of a chained interrupt, and assumes that the interrupt dispatcher +can identify which of the sources is signalling.

  • +
+
Interrupts +in the split ASSP/Variant Configuration

When a common ASSP +extension is used, a device may have additional peripherals external +to the ASSP, and there needs to be a way of allowing extra interrupt +binding and dispatch functions to be added later by the variant layer. +This must be handled by the port as Symbian platform does not provide +any additional API to support this.

Device drivers should +be able to use the Interrupt class functions without +having to know where the interrupt is actually implemented. This implies +that all requests should go to the core implementation of functions +like Interrupt::Bind(), Interrupt::Enable() etc.

To enable the core implementation of these functions +to decide whether an interrupt ID refers to a core interrupt or device +specific interrupt, a common technique is to "tag" the interrupt ID. +A simple way is to use positive numbers to identify core interrupts +and negative numbers to identify device specific interrupts. The ISRs +for device specific interrupts are not stored in the core ISR table, +instead the device specific layer provides its own ISR table.

The general pattern for creating the core-device specific split +is that the core derives an implementation from class Asic, and the device specific part further derives from this core implementation. +The usual technique is to add a set of virtual functions to the core +class that can be derived by the device specific part. The core can +provide default implementations for these functions that would just +return KErrArgument to trap illegal ID numbers. +This API would need functions equivalent to each of the functions +defined by the Interrupt class.

As an example, +the core layer for the template reference board defines a class TemplateAssp that is derived from Asic. TemplateAssp defines the pure virtual functions: InterruptBind(), InterruptUnbind(), InterruptEnable() etc, all with signatures that are the +same for the comparable functions defined by Interrupt, and which are implemented by the Template class.

+Interrupt binding + +
+
Spurious +interrupts

In the Kernel Architecture 2, it is a convention +that unbound interrupts should be bound to a "spurious" interrupt +handler, i.e. an interrupt handler that faults the system indicating +the number of the interrupt. This aids debugging by identifying interrupts +that are enabled without corresponding ISRs.

+
Interrupt +priority

The interrupt architecture supports the concept +of adjustable interrupt priorities. Symbian platform defines the Interrupt::SetPriority() function that can implement this. +The function is passed the ID of the interrupt source to be adjusted +together with a priority value. The meaning of the priority value +is hardware and implementation dependent, and is defined by the port.

+
The +ISR table

The Variant must provide a table where each entry +defines which ISR is bound to which interrupt source. The table must have +enough space for entries for each interrupt source that is known to +the Variant.

When the Variant is split into an ASSP layer +and a Variant layer, the ISR table is put in the ASSP layer and will +not normally include ISRs for the Variant interrupt sources - these +will be handled by separate chained dispatchers in the Variant layer.

Symbian platform provides the SInterruptHandler structure, defined in the header file ...\e32\include\kernel\arm\assp.h to encapsulate the entry for an ISR. The ISR table is, therefore, +just an array of SInterruptHandler items. For example, +if a system has 32 possible interrupt sources, then the ISR table +would be defined as:

... +const TInt KInterruptSourceCount = 32; +SInterruptHandler IsrHandlers[KInterruptSourceCount]; +...

Interrupts are identified in the system by their +interrupt ID number, which is used to index into the ISR table. You +are free to allocate these numbers any way that is convenient for +you.

On the template reference board, for example, the ISR +table is defined as a static data member of the VariantASSPInterrupt class, which is derived from TemplateInterrupt. The class is defined in ...\template_assp\template_assp_priv.h.

class TemplateInterrupt : public Interrupt + { + ... // functions +public: + static SInterruptHandler Handlers[KNumTemplateInts]; + ... + };

where KNumTemplateInts is defined in the same +header file.

Factors that decide the size of the ISR table

The number of entries to be reserved in the ISR table depends +on the following factors:

    +
  • Where the ASSP +is targeted at only a single device, the number of possible interrupts +is usually known, and the table can include an entry for each one.

  • +
  • If any pseudo sources exist, they should be included in the main +table for efficiency, but note that this is not strictly necessary.

  • +

Other factors affecting the ISR table

IRQs +and FIQs may need to be distinguished, although the exact requirement +is hardware dependent. Although the table has one entry for each possible +interrupt source, a possible scheme may be to group IRQs at the start +of the table, and FIQs at the end of the table. If the hardware has +separate interrupt controller hardware for IRQs and FIQs (or at least, +different registers) then you will need to arrange the table so that +you can determine from the interrupt ID whether the interrupt is an IRQ or FIQ.

For example:

+ISR table + +
+
Location +of interrupt handling code

Most of the interrupt dispatching +code is implemented in the ASSP layer. This includes a list of ISRs, +code for adding and removing ISRs, enabling and disabling interrupt +sources, and dispatching ISRs. The kernel only provides a pre-amble +and post-amble.

The kernel defines, but does not implement, +a class called Interrupt that exports interrupt +functionality to device drivers and other kernel code. The class provides +the public API for using interrupts (but not for dispatching them). +The port must provide an implementation for each function defined +by the class.

The class is defined in the header files ...\e32\include\kernel\arm\assp.h, which is exported to ...\epoc32\include\kernel\arm.

See Symbian OS +Internals Book, Chapter 6 - Interrupts and Exceptions

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-772C2721-DD84-54A6-ACE0-ECACC6432B95.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-772C2721-DD84-54A6-ACE0-ECACC6432B95.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,81 @@ + + + + + +Kernel +Objects and Containers Information CommandsDescribes how to use the c and o commands +to get information about kernel objects. +
Kernel objects

Kernel +objects such as DProcess, DThread, DSemaphore, DChunk are +all instances of classes derived from DObject.

To +show basic information about a DObject, use the o command.

To show more detail, use the O command.

As an example, use these commands to show information +about a DProcess object whose address is shown using the i command:

... +TheCurrentDataSectionProcess=6403bb4c +...

o 6403bb4c

This gives:

.o 6403bb4c +PROCESS at 6403bb4c VPTR=f8046c78 AccessCount=6 Owner=00000000 +Full name crash +

All objects derived from DBase have a virtual +table pointer, access count, owner and name. Using the O command on this address would you give you the full process information.

You +can use o to +examine other types of objects, for example chunks. The thread information +for the current data section process shows two chunks:

NumChunks=2 +0: Chunk 6403c044, run 00400000, access count 1 +1: Chunk 64039688, run 00600000, access count 1 +

Using the o command +on the first of these chunk objects gives you the basic information:

.o 6403c044 +CHUNK at 6403c044 VPTR=f8046b50 AccessCount=1 Owner=6403bb4c +Full name crash::$DAT +

Using the O command +gives you more detailed information:

.q 6403c044 +CHUNK at 6403c044 VPTR=f8046b50 AccessCount=1 Owner=6403bb4c +Full name crash::$DAT +Owning Process 6403bb4c +Size 2000, MaxSize 200000, Base 00400000 +Attrib 6, StartPos 0 +Type 6, State 2, Home Base 68900000 +Home Region Offset 00000000 +Home Region Base 68900000 +Home Region Size 00100000 +PTE: 0000055e, PDE: 00000021 00000001 00000001 +NumPdes=1, iPdes=61000010, iHomePdes=61001a24 +PdeBitMap=00000001, PageBitMap=6403c0c8 +Domain -1 +

The information displayed is memory model dependent. +It is shown here for the moving memory model.

Notes:

    +
  • Size 2000, MaxSize 200000, Base 00400000

    The Size field shows the current size of the chunk, +in bytes.

    The MaxSize field shows the maximum size +of the chunk, in bytes.

    The Base field shows the +base address in the run region.

  • +
  • Attrib 6, StartPos 0

    The Attrib field shows the attributes of the chunk.

    The StartPos field +shows the offset, in bytes, between the base address and the start of the +committed area. This is non-zero for double-ended chunks only.

  • +
  • Type 6, State 2, Home Base 68900000

    The Type field shows the type of chunk. This corresponds +to a TChunkType enum value.

    The State field +shows the current state of the chunk. This corresponds to a TChunkState enum +value, which is itself defined within the scope of the Symbian platform internal +class DMemModelChunk.

    The Home Base field +is the base address of the chunk in the home region.

  • +
  • Home Region Offset 00000000 +Home Region Base 68900000 +Home Region Size 00100000 +

    These three lines show the offset, base address and size (the +reserved size) of the chunk in the home region.

  • +
+
Kernel containers

Internally, +the kernel maintains lists of all current objects, organized by type. Each +list is a container, a DObjectCon object, with one for each +object type.

The c command +will walk through all objects in a given list. The type of object is identified +by appending a number after the command. For example, DProcess objects +are identified by the number 1, so to walk through all current DProcess objects +type:

c1

The command effectively executes +a O command +on each object in the "processes" container.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-775901A4-0262-4E14-9E9C-C4E37DFCCF2E.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-775901A4-0262-4E14-9E9C-C4E37DFCCF2E.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,12 @@ + + + + + +OS Base Services Describes the platform services related to OS Base Services. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-782E8D92-0431-50F5-95A0-5B231EBDF391-master.png Binary file Adaptation/GUID-782E8D92-0431-50F5-95A0-5B231EBDF391-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-782E8D92-0431-50F5-95A0-5B231EBDF391_d0e25767_href.png Binary file Adaptation/GUID-782E8D92-0431-50F5-95A0-5B231EBDF391_d0e25767_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-788ECC4B-36B9-493C-A86E-E6C8007074B1.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-788ECC4B-36B9-493C-A86E-E6C8007074B1.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,13 @@ + + + + + +SDIO Describes the Secure Digital Input/Output (SDIO) platform +service. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-78963104-C2B0-4E19-99E5-FEAEB7EA307A.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-78963104-C2B0-4E19-99E5-FEAEB7EA307A.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,12 @@ + + + + + +IIC SHAI Implementation LayerDescribes how to use the IIC SHAI implementation layer. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-795B8649-B6C3-5540-B52A-9B460F35A5B5.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-795B8649-B6C3-5540-B52A-9B460F35A5B5.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,12 @@ + + + + + +ROM PagingDemand Paging documentation related to ROM demand paging. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-79620372-BADC-4826-A3AC-7FDBCFF98DA9.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-79620372-BADC-4826-A3AC-7FDBCFF98DA9.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,12 @@ + + + + + +Device Driver ConceptsThis section describes the Device Driver concepts. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-796CB42C-29AC-5ECC-AC6E-35FC6B8CC84E.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-796CB42C-29AC-5ECC-AC6E-35FC6B8CC84E.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,16 @@ + + + + + +ConceptsThis section describes the technology and architecture +of the USB Client Driver. +Port + Implementation Tutorial + \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-79B2CF91-FB95-5E7C-81CC-235A6A660D88.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-79B2CF91-FB95-5E7C-81CC-235A6A660D88.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,24 @@ + + + + + +MMC ControllerThe MMC Controller provides kernel extensions that manages access +to the MultiMediaCard hardware on behalf of media drivers or any other device +driver. +

This section describes how to create a port of it for your phone hardware. Symbian +platform provides a generic Platform-Independent part of the Controller. You +must provide a Platform-Specific part to implement the interface to the MMC +hardware on your phone.

+
+File Systems + +Local Media +Subsystem +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-7A50630B-2B44-5D27-AA18-3BEEE1453020.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-7A50630B-2B44-5D27-AA18-3BEEE1453020.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,82 @@ + + + + + + The +Paging Algorithm Technology GuideDescribes the paging algorithm used in demand paging. +
Purpose

Kernel +side developers will sometimes need to know the algorithm used to move data +in and out of paged memory.

Intended +Audience:

This document is intended to be read by kernel side +developers.

+
The algorithm

Terminology

Paged memory (virtual addresses and their contents) +is called either:

    +
  • 'live', meaning present +in the cache of physical RAM, or

  • +
  • 'dead', meaning stored +elsewhere in the backing store.

  • +

Physical RAM not being used to hold paged memory is called the free +pool.

Items of paged memory can be reassigned from 'live' to 'dead' +and vice versa. 'Live' items are classed as either 'old' or 'young' for this +purpose.

Paging +out memory

When more RAM is needed and the pool of free memory +is empty then RAM is freed up. This means changing an item of paged memory +from live to dead. The process is called paging out and it involves these +tasks.

    +
  1. The oldest virtual page +is removed from the cache and physically stored elsewhere

  2. +
  3. The MMU marks the virtual +page as inaccessible.

  4. +
  5. The associated page +of RAM cache is returned to the free pool.

  6. +

Paging +in memory

When a program attempts to access dead paged memory, +the MMU generates a page fault and the executing thread is diverted to the +Symbian platform exception handler. This performs the following +tasks.

    +
  1. Obtain a page of RAM +from the free pool. If the free pool is empty, free up some memory by paging +out the oldest live page.

  2. +
  3. Read the contents of +the dead paged memory from its actual location (e.g. NAND flash) and write +them to the page of RAM.

  4. +
  5. Update the live list +described in the next section.

  6. +
  7. The MMU maps the linear +address of the dead paged memory on to the page of RAM.

  8. +
  9. Resume program execution.

  10. +

The +paging cache

The paging cache is only useful if it is used to +hold the pages most likely to be required. The paging subsystem provides for +this by selecting the oldest pages to be paged out making space for new ones +to be paged in.

All live pages are stored in a list called the 'live +page list'. Live pages are labelled 'young' or 'old' and are stored in two +sub-lists, one for each type: the item at the start of the young list is the +youngest item and the one at the end of the old list is the oldest item. The +MMU makes young pages accessible to programs and old pages inaccessible. However, +old pages are different from dead pages because their contents are still held +in RAM.

The young and old lists are maintained in accordance with +these four rules.

    +
  • When a dead page is +paged in (made live) it is added to the start of the young list, becoming +the youngest item.

  • +
  • When a live page must +be paged out (made dead) to free up RAM, the oldest page is selected.

  • +
  • If an old page is accessed +by a program a page fault results because old pages are marked inaccessible. +The paging system handles the fault by turning the page into a young page +('rejuvenating' it). To compensate, the oldest young page is then turned into +an old page ('aging' it).

  • +
  • Efficient operation +requires a stable ratio of young to old pages. If the number of young pages +exceeds a specified ratio of old pages, the oldest young page is turned into +the youngest old page ('aging' it).

  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-7AB0C7E2-8B7C-5CC3-BAA5-15AA59F31181.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-7AB0C7E2-8B7C-5CC3-BAA5-15AA59F31181.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,66 @@ + + + + + +InterpretSIS +

InterpretSIS is a command-line tool used to install SIS files to +a data drive image that can be flashed onto a device's system +drive. It is either invoked through BUILDROM while +creating a data drive image or can be invoked directly.

+

For more information on system drive refer to, +> Symbian Guide > Kernel and Hardware Services Guide > User Library +and File Server > File Server > File Server Client Side > The System +Drive.

+
Command-line +syntax

The syntax for using InterpretSIS is as follows:

InterpretSIS [-v] [-h] [-w off|error|warn|info [-l <logfile>]] [-d <systemdrive>] -c <dir> -z <dir> -s <filename.sis>[,<filename2.sis>, <dir>, ...]

or:

InterpretSIS -p <filename> + + + +

-v

+

Displays verbose output.

+
+ +

-h

+

Displays help.

+
+ +

-w

+

The warning level to report; error by default.

+
+ +

-l

+

The log file to write to; standard error by default.

+
+ +

-d

+

The drive letter of the system drive on the target device; C: by default.

+
+ +

-c

+

A directory on the PC representing the drive on the target +device to which files are installed.

+
+ +

-z

+

A directory on the PC representing the contents of the ROM +(the Z: drive). This needs to be specified so +that InterpretSIS can check any dependencies are +met and to prevent invalid eclipsing.

+
+ +

-s

+

The SIS file(s) to install. Any directory specified will +be searched for SIS files.

+
+ + +

For example:

interpretsis -d c -c c:\epoc32\winscw\c -z C:\epoc32\release\WINSCW\udeb\Z -s sisfile1.sis, directory1, sisfile2.sis -w info

Alternatively, the parameters can be placed in a file, which +is passed to InterpretSIS using the -p option:

InterpretSIS -p <filename>
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-7AB51180-7A1A-40C7-B28F-EA46314A6E5B-GENID-1-2-1-9-1-5-1-4-1.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-7AB51180-7A1A-40C7-B28F-EA46314A6E5B-GENID-1-2-1-9-1-5-1-4-1.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,54 @@ + + + + + +Synchronous +RequestsThis document describes the use of synchronous requests by device +drivers. +
<b>Synchronous +requests</b>

Synchronous requests are typically used to set +or retrieve some information for the device driver. These requests almost +never need to access the hardware itself, and usually complete relatively +quickly. They return only after the completion of the request and the user +side thread is blocked till completion. Synchronous requests are usuallly +initiated by a call to RBusLogicalChannel::DoControl(). +The request is most likely to be executed in the context of the client user-side +thread.

A driver lists its available synchronous requests +in an enumeration, for example:

// Synchronous control messages used with DoControl() +enum TControl + { + EControlConfigure, // Configure the device (UART) + EControlTransmitData, // Transmit data over the device (UART) + EControlReceiveData, // Receive the data from the device + ENumRequests, // Number of synchronous control requests + AllRequests = (1<<ENumRequests)-1 + };
+
Implementation

Drivers +generally implement the DoControl() function in the LDD +to handle the received synchronous messages. The implementation reads the +request type and other passed arguments, and handles the request appropriately. +For example, the following handles RExDriver::EControlConfigure requests:

TInt DExDriverLogicalChannel::DoControl(TInt aFunction, TAny* a1, TAny* /*a2*/) + { + switch (aFunction) + { + case RExDriver::EControlConfigure: + memclr(&c, sizeof(c))); + TPtr8 cfg((TUint8*)&c, 0, sizeof(c))); + r = Kern::ThreadDesRead(iClient,a1,cfg,0,0); + if (r==KErrNone) + Pdd()->Configure(&c); + break; + ... + default: + r = KErrNotSupported; + } + return r; + }
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-7AB51180-7A1A-40C7-B28F-EA46314A6E5B-GENID-1-2-1-9-1-6-1-9-1-5-1.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-7AB51180-7A1A-40C7-B28F-EA46314A6E5B-GENID-1-2-1-9-1-6-1-9-1-5-1.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,54 @@ + + + + + +Synchronous +RequestsThis document describes the use of synchronous requests by device +drivers. +
<b>Synchronous +requests</b>

Synchronous requests are typically used to set +or retrieve some information for the device driver. These requests almost +never need to access the hardware itself, and usually complete relatively +quickly. They return only after the completion of the request and the user +side thread is blocked till completion. Synchronous requests are usuallly +initiated by a call to RBusLogicalChannel::DoControl(). +The request is most likely to be executed in the context of the client user-side +thread.

A driver lists its available synchronous requests +in an enumeration, for example:

// Synchronous control messages used with DoControl() +enum TControl + { + EControlConfigure, // Configure the device (UART) + EControlTransmitData, // Transmit data over the device (UART) + EControlReceiveData, // Receive the data from the device + ENumRequests, // Number of synchronous control requests + AllRequests = (1<<ENumRequests)-1 + };
+
Implementation

Drivers +generally implement the DoControl() function in the LDD +to handle the received synchronous messages. The implementation reads the +request type and other passed arguments, and handles the request appropriately. +For example, the following handles RExDriver::EControlConfigure requests:

TInt DExDriverLogicalChannel::DoControl(TInt aFunction, TAny* a1, TAny* /*a2*/) + { + switch (aFunction) + { + case RExDriver::EControlConfigure: + memclr(&c, sizeof(c))); + TPtr8 cfg((TUint8*)&c, 0, sizeof(c))); + r = Kern::ThreadDesRead(iClient,a1,cfg,0,0); + if (r==KErrNone) + Pdd()->Configure(&c); + break; + ... + default: + r = KErrNotSupported; + } + return r; + }
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-7B0BA327-54A0-4908-B8E3-0C82112EB957-master.png Binary file Adaptation/GUID-7B0BA327-54A0-4908-B8E3-0C82112EB957-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-7B0BA327-54A0-4908-B8E3-0C82112EB957_d0e93167_href.png Binary file Adaptation/GUID-7B0BA327-54A0-4908-B8E3-0C82112EB957_d0e93167_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-7B9D4E46-6AF9-5B77-9BE3-8B1DFAC588BD.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-7B9D4E46-6AF9-5B77-9BE3-8B1DFAC588BD.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,40 @@ + + + + + +Set UpSet up the source code and project files for an implementation +of the USB client controller. +

This topic describes how to set up the source code and project +files for an implementation of the USB client controller.

+

Another more complicated example is implemented in the OMAP/H4 +platform. This platform has two USB device controllers. The code shows +how two UDCs can be supported in the same source and build tree. The +second controller (Fibula) is a High speed USB 2.0 compatible device +controller, the code demonstrates how to support a USB 2.0 UDC and +one or more USB 2.0 Client Devices. See the code in ...\omap-hrp\....

+

The suggested steps are as follows:

+
    +
  1. Decide where +to put the source and header files for the platform-specific layer +. Normally the USB device controller is part of the ASSP, and you +would put the source files in the ASSP directory. For an external +USB device controller, you would use the Variant directory instead.

  2. +
  3. Implement the +platform-specific Layer within your chosen source and header files.

    If you have a header file with a name in the shape of ASSP.h, then you will put USB Device Controller register +definitions and register bit definitions here.

  4. +
  5. Define the .mmp file for the USB client controller (the PDD), and +put this into your chosen directory. Remember that the platform-specific +layer is just part of the USB client controller, and the .mmp file needs to contain a list of all source +files that need to be compiled.

  6. +
  7. Add the name +of the .mmp file (without the file extension) +to your ASSP's .inf file in the PRJ_MMPFILES section. This must be in the same directory. This tells the abld tool about the existence of the .mmp file.

  8. +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-7BB36477-0FE2-51D5-B4C0-86F7265C1B94.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-7BB36477-0FE2-51D5-B4C0-86F7265C1B94.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,16 @@ + + + + + +ReferenceThis topic provides a summary of related documentation for the +Base Starter to which you can refer. +
API +Reference

No published APIs.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-7BCC0EFA-0DD5-4879-BECF-C32D04BC8A39.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-7BCC0EFA-0DD5-4879-BECF-C32D04BC8A39.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,16 @@ + + + + + +SHAI ServiceA service that it intended to be used only by adaptation +code, for example, as part of a SHAI implementation. SHAI services +are rare. +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-7BCDDA55-1460-5411-AFCF-C4640BEB9DE4.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-7BCDDA55-1460-5411-AFCF-C4640BEB9DE4.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,38 @@ + + + + + +Configuration: +HAL (Hardware Abstraction Layer)HAL contains a number of attributes that are related to the Digitizer +Driver. +

These attributes must be appropriately described in the HAL config.hcf file +for your variant. Follow the links to these attribute items for their meaning +and values.

+
    +
  • HALData::EPen

  • +
  • HALData::EPenX

  • +
  • HALData::EPenY

  • +
  • HALData::EPenState

  • +
  • HALData::EPenDisplayOn

  • +
  • HALData::EPenClick

  • +
  • HALData::EPenClickState

  • +
  • HALData::EPenClickVolume

  • +
  • HALData::EPenClickVolumeMax

  • +
+
+ +User Side +Hardware Abstraction +HAL Attributes +and Function IDs +Configuration +Attribute Definition Files + +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-7C064328-8368-4259-9CE1-B8DFE2DF4AAC.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-7C064328-8368-4259-9CE1-B8DFE2DF4AAC.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,12 @@ + + + + + +Fair Scheduling and File CachingThis section shows how to enable and configure file caching. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-7C533836-0D27-5519-BC1D-7153AC8BE4C0.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-7C533836-0D27-5519-BC1D-7153AC8BE4C0.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,47 @@ + + + + + +Media +Driver GuideDescribes the issues that need to be considered, when writing a +media device driver for a writable data demand paging environment. +
Purpose

This +document explains the points that have to be considered when writing a media +driver in an environment that uses writable data paging.

+
Issues to consider

The +main issue to consider when writing a media device driver for a writable demand +paging environment is to avoid page faults from occurring in DFCs, since this +can lead to a deadlock condition between the driver and the client process.

This +can be avoided using the following methods:

    +
  • Use shared chunks.

    Shared +chunks are memory areas that are accessible by both kernel-side and user-side +and they are never paged.

    This is the best solution for drivers that +involve fast throughput such as media drivers.

  • +
  • Use synchronous rather +than asynchronous data transfer

    This could be done by implementing +the following steps:

      +
    1. The client requests +a notification when data is available.

    2. +
    3. The data arrives.

    4. +
    5. The driver writes data +into an internal buffer and completes the client request.

    6. +
    7. The client makes a read +request.

    8. +
    9. The driver writes the +data back to the client in the client thread context.

    10. +

    This approach is easy to implement, however it requires the buffering +of data.

  • +
  • Use the flexible +memory model

    This provides the ability for the memory to be +mapped into a drive's address space as unpaged.

    This is an alternative +to the use of shared chunks.

    However, this is not supported on the +moving or multiple memory models.

  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-7D535B68-CA7F-4796-80FB-AE7A27642A88.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-7D535B68-CA7F-4796-80FB-AE7A27642A88.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,117 @@ + + + + + +SDIO +OverviewSDIO is an Input/Output interface based on the SD card standard. +

The intent behind SDIO is to allow the use of an SD slot for more than +memory cards. SDIO allows I/O devices such as GPS, camera, Wi-Fi, FM radio, +Ethernet, barcode readers and Bluetooth to be plugged into such a slot.

+

However, with space being limited in modern mobile phones, memory card +slots are usually microSD slots - which are too small to accept SDIO or miniSDIO +cards. Also, memory card slots are often internal to the phone which prohibits the +insertion of SDIO cards. Therefore in Symbian devices, SDIO is typically used +only as an internal peripheral bus on all but hardware reference platforms. +Because of its ability to provide high-speed data I/O with low power consumption, +SDIO can be used to connect components such as Wi-Fi and FM radio peripheral +chips to the main processor.

+
Required background

You +must have an understanding of SD card before using SDIO.

+
Architecture +SDIO Architecture + +
+
Description

The +SDIO is divided into key modules described below.

    +
  • Memory card performs the SD or the MMC card operations. It registers +the card driver, initializes the card, and sets permissions for the read and +write operations

  • +
    +
  • SDIO Host controller is the most important module in the SDIO +architecture. It has a driver that allows card initialization, bus width settings, +clock frequency setting, sending and receiving of commands and SDIO interrupt +handling.

  • +
    +
  • General Card Functions contains functions that are useful during +the development of other card drivers. The module supplies the read/write +SDIO/SD/MMC card register operations as well as select/deselect card, read +card status and reset card procedures.

  • +
+
Key Concepts
    +
  • SDIO Interrupts: SDIO Interrupts are level-sensitive interrupts. +They communicate with the host through the SDIO line. The signal is held +active until the host acknowledges the interrupt through some function unique +I/O operation.

  • +
    +
  • SDIO Class Driver: SDIO Driver supports the SDIO Host Controller. +The driver includes functions such as initialization, bus settings, clock +frequency setting, sending and receiving of commands, and SDIO interrupt handling.

  • +
    +
  • SDIO card controller: SDIO card protocol is a super-set of the +SD card protocol. The SDIO Card Controller shares some of its functionality +with the SD controller. The Symbian platform SDIO card controller is implemented +as a set of SDIO card classes, each of which is derived from the corresponding +SD card classes. The SDIO card controller provides support for SDIO cards +within the E32 kernel. It manages access to the SDIO card hardware interface +and provides an API for class drivers to access SDIO card functions.

  • +
+
API summary

This +API is used by the implementers of the class drivers.

+ + + +

API names

+

Description

+
+ + + +

DSDIOSTACK

+

The stack can handle multiple outstanding requests simultaneously. + It schedules these requests onto the bus, thereby putting the appropriate +card into transfer state automatically and running the appropriate state machine +function.

+
+ +

TSDIOCARD

+

This class owns the I/O function objects. It provides access to +an I/O function object provided through the IOFunction(), +which returns a pointer to the object concerned.

+
+ +

DSDIOSESSION

+

This contains functions for setting up a session object to perform +SDIO specific command sequences such as initialization, scheduling, invoking +and submitting the session.

+
+ +

DSDIOREGINTERFACE

+

This contains the APIs that are used most frequently +during the implementation of the SDIO class drivers. It contains member functions +that allow single-byte read or write operations to a given register address +together with the corresponding ones for multi-byte access

+
+ +

TSDIOFUNCTION

+

This contains member functions for access and control of function-specific +features such as function enable, function ready. It also has the member functions +for access and control of FBR features such as CSA access and function block +size.

+
+ +

TSDIOINTERRUPT

+

This contains the usual interrupt object member functions. It provides +the abstraction of a per-function interrupt even though each function actually +shares a single interrupt request signal on the card.

+
+ + +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-7DDF052C-2520-428D-932D-BDB476344575.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-7DDF052C-2520-428D-932D-BDB476344575.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,27 @@ + + + + + +Generated +EventsThis document describes how kernel events are used in communication +with the kernel. +

Drives +can communicate with the Window Server, and through that to user programs, +using events.

Kern::AddEvent() adds an event +to the kernel event queue. This is used typically in drivers such as the keyboard +driver, which raises key events.

TRawEvent event; +event.Set(TRawEvent::EKeyDown, EStdKeyBackspace); +Kern::AddEvent(event);

The kernel event queue maintains a circular +buffer of TRawEvent objects allocated at system initialization. +The Windows Server calls UserSvr::CaptureEventHook() to +register itself to receive such events. The Kernel does not permit any process +other than the Windows Server to register to receive events.

+
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-7E357DA2-67AD-403A-B4E1-7CB83E75136F.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-7E357DA2-67AD-403A-B4E1-7CB83E75136F.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,37 @@ + + + + + +SDIO Build GuideDescribes what is needed to include the SDIO adaptation +in a ROM image. +

When building a ROM image, all the processes and data needed to +execute a build are included in a single file. This file is executed +by the platform when the hardware is powered up.

+
Requirements
    +
  • The SDIO hardware must conform to the SDIO standards and that +the hardware must work correctly.

  • +
  • You must be familiar with building a ROM for the Symbian platform.

  • +
+
Build +time implementation details

None

+
Building +the ROM with SDIO included

To include the SDIO PIL libraries +in the final ROM image, the USE_SDIO_SD_MMC flag +must be included in the list of buildrom parameters.

An example +of the use of this new parameter is:

buildrom h4hrp techview -DUSE_SDIO_SD_MMC

This example produces a ROM.

The iby file that specifies +the SDIO's PSL, must be included in the oby file for the ROM image.

For more information, refer to BUILDROM .

+
Run-time +configuration

Not required

+
+ROM +Tools Overview +BUILDROM + +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-7E3BBB18-3113-4312-AD91-897DE87C58BF.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-7E3BBB18-3113-4312-AD91-897DE87C58BF.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,32 @@ + + + + + +SDIO +PSU Implementation TutorialHow to implement the platform-specific class for the Power Supply +Unit of an SDIO-based hardware component. +

The Power Supply Unit (PSU) functionality is provided by the DSDIOPsu class. +To enable power control in the SDIO Controller, you must implement the PsuInfo() function +in the derived class of the DSDIOPsu class.

+

The iNotLockedTimeOut variable +is used by the "card not locked" functionality and the value is tied to the +reference board inactivity time-out. The iInactivityTimeOut variable +is used to set a time-out value for the sleep mode of the SDIO cards.

+

void DMySdioPsu::PsuInfo(TPBusPsuInfo& anInfo) + { + ... + // Only for SDIO + anInfo.iNotLockedTimeOut = 5; // Power down after 5 seconds of non-use (no clients registered) + anInfo.iInactivityTimeOut = 1; // Enter Sleep mode within 1 Second of inactivity (clients registered) + ... + return; + } +

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-7ECDCF7B-3B2A-561F-9136-04BC4DAE46E4.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-7ECDCF7B-3B2A-561F-9136-04BC4DAE46E4.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,161 @@ + + + + + +ARM +Exception Types, Fault Status Register Values, and Processor Mode ValuesReference for users of the debug monitor tool to ARM exception +types, fault status register values, and processor mode values. +
ARM exception +types

The numeric value in the left hand column is the value of +the ExcId field displayed as a result of entering an f command +in the debug monitor.

+ + + +

00000000

+

Prefetch abort

+
+ +

00000001

+

Data abort

+
+ +

00000002

+

Undefined instruction

+
+ + +
+
Fault status +register values (FSR register)

The lowest 4-bits of the FSR register +indicates the fault generated by the MMU. The FSR register value is displayed +as a result of entering an f command +in the debug monitor.

+ + + +

0

+

Vector exception

+
+ +

1

+

Alignment fault

+
+ +

2

+

Terminal exception

+
+ +

3

+

Alignment fault

+
+ +

4

+

External abort on linefetch for section translation

+
+ +

5

+

Section translation fault (unmapped virtual address)

+
+ +

6

+

External abort on linefetch for page translation

+
+ +

7

+

Page translation fault (unmapped virtual address)

+
+ +

8

+

External abort on non-linefetch for section translation

+
+ +

9

+

Domain fault on section translation (i.e. accessing invalid domain)

+
+ +

A

+

External abort on non-linefetch for page translation

+
+ +

B

+

Domain fault on page translation (i.e. accessing invalid domain)

+
+ +

C

+

External abort on first level translation

+
+ +

D

+

Permission fault on section (i.e. no permission to access virtual +address)

+
+ +

E

+

External abort on second level translation

+
+ +

F

+

Permission fault on page (i.e. no permission to access virtual address)

+
+ + +
+
ARM processor +modes (CPSR register)

The 5 least-significant bits of the CPSR +register indicate the ARM processor mode. The CPSR register value is displayed +as a result of entering an f command +in the debug monitor.

+ + + +

CPSR[4:0]

+

Mode

+

Register set

+
+ +

10000

+

User

+

PC, R14..R0, CPSR

+
+ +

10001

+

FIQ

+

PC, R14_fiq..R8_fiq, R7-R0, CPSR, SPSR_fiq

+
+ +

10010

+

IRQ

+

PC, R14_irq, R13_irq, R12-R0, CPSR, SPSR_irq

+
+ +

10011

+

SVC

+

PC, R14_svc, R13_svc, R12-R0, CPSR, SPSR_sv

+
+ +

10111

+

Abort

+

PC, R14_abt, R13_abt, R12-R0, CPSR, SPSR_abt

+
+ +

11011

+

Undef

+

PC, R14_und, R13_und, R12-R0, CPSR, SPSR_und

+
+ +

11111

+

System

+

PC, R14..R0, CPSR

+
+ + +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-80698E62-E310-59CA-A524-5CF44C437BE4.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-80698E62-E310-59CA-A524-5CF44C437BE4.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,23 @@ + + + + + +Base StarterThe Base Starter is a program that runs when the system starts. +

The program completes the initialization of the File Server, then starts +the System Starter process. You must customize the Base Starter when you create +a port of Symbian platform to a phone. To customize the Base Starter, you +change the configuration files and the Base Starter source code.

+

The Base Starter has often also been called EStart.

+
+ +File Server +System +Starter +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-80E0DB93-A96A-54A8-A201-E11935418BE7.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-80E0DB93-A96A-54A8-A201-E11935418BE7.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,236 @@ + + + + + +State +MachinesDescription of the structure and operation of state machines. +

The MultiMediaCard Controller uses state machines to manage the interactions +with the MultiMediaCard hardware.

+

State machines allows the controller to maintain the state of each submitted +session – allowing it to schedule a second session when the first becomes +blocked, for example.

+

To handle the complex sequence of bus operations involved, the controller +implements a state machine stack, allowing a parent state machine function +to invoke a child state machine function. The state machine stack allows nesting +of children down to a depth of 10 levels.

+

Each session object has its own individual state machine stack because +each session runs its own sequence of bus operations, with the controller +managing these multiple sequences. This means that each session object has +a state machine object, an instance of the TMMCStateMachine class.

+ + + +

The state machine remembers the next state and child function name, and +moves to that state as soon as control returns to the session.

+

The stack chooses the next session to be handled and manages the state +machine through the state machine dispatcher.

+
    +
  • Structure of the state machine stack

  • +
  • Structure of a state machine function

  • +
  • Example of a state machine calling sequence

  • +
+
Structure of +the state machine stack

The stack itself is represented as an array +of TMMCMachineStackEntry objects contained within the state +machine object TMMCStateMachine.

The state machine +maintains a "pointer", TMMCStateMachine::iSP, to the current +state entry. This is not a true pointer, but just a value that indexes into +the array. However, for all practical purposes it has the effect of a pointer. +Each state entry in the stack is thought of as having a parent-child relationship +with the other.

Each state entry maintains three pieces of information:

    +
  • A pointer to the state +machine function.

  • +
  • A variable containing +the current state; the value and meaning of the state is defined by the state +machine function.

  • +
  • A bitmask of TMMCErr defined +error conditions; these are set by the parent state machine function so that +it gets the chance to trap those errors if the child state machine function +returns those errors. Errors are propagated up the stack, and any error conditions +not trapped at any level in the state machine hierarchy leads to the state +machine terminating with that error value.

  • +
+ +

In general, the overall state of the state machine reflects the +state of the current state entry; for example, TMMCStatemachine::State() returns +the state held in the current state entry.

While the flow of control +through a stack can be complex, the following diagram shows a short example +snapshot. Here, the current state in the current stack entry is Sn and +is handled by the function PF(). The code decides to pass +control to the child function CF(), but ensures that, on +completion, the next state in the current stack entry will be Sn+1.

+ +

For example, the DMMCStack::CIMUpdateAcqSM() function +implements the CIM_UPDATE_ACQ macro as defined by the MultiMediaCard System +Specification, and is a typical state machine function.

Most commands +and macros involve one or more asynchronous operations and while such operations +are outstanding, a session is blocked. While a session is blocked, its state +machine dispatch function is not called. As soon an asynchronous event removes +the blocking condition, control returns to the state machine.

+
Structure of +a state machine function

State machine functions are defined and +implemented in the DMMCStack class in pairs: one as a static +function, and the other as a member function. The static variant takes a TAny* pointer +that is cast to a DMMCStack pointer, and the DMMCStack member +function is then called:

TMMCErr DMMCStack::FunctionNameSMST( TAny* aPtr ) + { + return( STATIC_CAST(DMMCStack*,aPtr)->FunctionNameSM() ); + } + TMMCErr DMMCStack::FunctionNameSM() + { + enum states {EStBegin=0, EStNext,…, EStEnd }; // Enumeration of states for this state machine + DMMCSession& s = Session(); + + SMF_BEGIN + // State EStBegin + // Actions for state EStBegin + + SMF_STATE( EStNext ) + // State EStNext + // Actions for state EStNext + + SMF_END + } +

A state machine function can release control and wait to be +re-entered by returning zero. If its session is not blocked then that will +happen immediately. If the state machine function returns non-zero, the session +will be completed with that error code unless the parent state machine function +has explicitly intercepted such an error by setting the trap mask.

    +
  • Important points to note

  • +
  • Blocking on an asynchronous request

  • +

Important points to note

Each +state machine function must define a list of states that can exist. States +are defined as an enumeration whose first and last values must be labelled EStBegin and EStEnd, +respectively. EStBegin must have the value zero. Any other +intermediate states are program defined.

To make the state machine +functions more readable, a number of macros exist to help with the layout +of the function code, and to control program flow. The most basic macros are SMF_BEGIN, SMF_STATE and SMF_END that expand into a switch statement. The above code expands +to:

TMMCErr DMMCStack::FunctionNameSM() +{ +enum states {EStBegin=0, EStNext,…, EStEnd }; // Enumeration of states for this state machine +DMMCSession& s = Session(); + +TMMCStateMachine& m = Machine(); //SMF_BEGIN +const TMMCErr err = m.SetExitCode( 0 ); //SMF_BEGIN +for(;;) //SMF_BEGIN + { //SMF_BEGIN + switch(m.State()) //SMF_BEGIN + { //SMF_BEGIN + case EStBegin: //SMF_BEGIN + { //SMF_BEGIN + if(err) (void)0; //SMF_BEGIN + // State EStBegin + // Actions for state EStBegin + + } //SMF_STATE + case EStNext: //SMF_STATE + { //SMF_STATE + // State EStNext + // Actions for state EStNext + + case EStEnd: //SMF_END + break; //SMF_END + default: //SMF_END + DMMCController::Panic(DMMCController::EMMCMachineState);//SMF_END + } //SMF_END + break; //SMF_END + } //SMF_END +return(m.Pop()); //SMF_END +}

Notes:

    +
  • be aware that SMF_BEGIN +generates an open curly bracket while SMF_STATE generates a corresponding +close bracket, and SMF_END closes the switch statement.

  • +

You need to be aware of the code that is generated by these macros. +In particular, some such as SMF_BEGIN generate an opening curly brace, while +others such as SMF_STATE generate a corresponding close curly brace. Also, +you need to know whether a macro generates a break; or a return; statement. +Lack of awareness here may cause code to be generated that flows from one +case statement to another, which may not be your intent.

    +
  • SMF_BEGIN

  • +
  • SMF_END

  • +
  • SMF_NEXTS

  • +
  • SMF_CALL

  • +
  • SMF_CALLWAIT

  • +
  • SMF_CALLMYS

  • +
  • SMF_CALLMEWR

  • +
  • SMF_INVOKES

  • +
  • SMF_INVOKEWAITS

  • +
  • SMF_WAIT

  • +
  • SMF_WAITS

  • +
  • SMF_RETURN

  • +
  • SMF_EXIT

  • +
  • SMF_EXITWAIT

  • +
  • SMF_JUMP

  • +
  • SMF_JUMPWAIT

  • +
  • SMF_GOTONEXTS

  • +
  • SMF_GOTOS

  • +
  • SMF_STATE

  • +
  • SMF_BPOINT

  • +

Blocking on an asynchronous +request

The state machine can be made to block. This is done so +that you can wait for an asynchronous operation to complete. When the operation +completes, it unblocks the state machine. There are two stages to blocking +a state machine:

    +
  • Call DMMCStack::BlockCurrentSession() to +indicate that the state machine associated with the current session is to +be blocked

  • +
  • Execute one of the SMF_xxxWAIT +macros to return from the current state machine function and wait.

  • +

Note that the state machine function must return by calling +one of the SMF_xxxWAIT macros. It must not poll or sit in a loop! The state +machines are not threaded, and this means that CPU time can only be given +to other tasks if the function returns.

DMMCStack::BlockCurrentSession() takes +an argument describing the type of block. The state machine will only unblock +when an unblock request with the matching argument is called. In the platform +specific layer of the MultiMediaCard controller, you should always set the KMMCBlockOnASSPFunction bit +in the argument passed to BlockCurrentSession().

To +unblock the state machine, call DMMCStack::UnBlockCurrentSession() setting +the KMMCBlockOnASSPFunction bit in the flags argument passed +to the function, and also an error code. This will invoke the state machine +scheduler, which will re-start the state machine.

Note that further +state machine processing must take place in a DFC rather than within the interrupt +service routine (ISR), and this can be forced by ORing the session status, DMMCSession::iState, +with the KMMCSessStateDoDFC bit before unblocking +the session. The bit has the effect of queueing a DFC to resume the state +machine at some later stage, before returning to the ISR.

The following +code shows the idea:

TMMCErr DMMCStackAssp::DoSomethingSM() + { + enum states {EStBegin=0, EStDone,EStEnd }; // enumeration of states for this state machine + + SMF_BEGIN + // start the asynchronous operation + BlockCurrentSession( KMMCBlockOnASSPFunction ); + StartAsynchronousOp(); + + // block and wait. Go to state EStDone when the asynchronous op is complete + SMF_WAITS( EStDone ); + + SMF_STATE( EStDone ) + // operation is complete, check for errors and return from state machine + TInt errors = CheckForHardwareErrors(); + SMF_RETURN( errors ); + + SMF_END + } + void TMMCInterrupt::Service( TAny* aParam ) + { + Session().iState |= KMMCSessStateDoDFC; + UnBlockCurrentSession(KMMCBlockOnASSPFunction, KMMCErrNone); + } +
+
Example of +a state machine calling sequence

This shows the state machine calling +sequence that implements the reading of a single block on a MultiMediaCard, +where the card is not yet selected. Note that the lowest level state machine +function called is IssueMMCCommandSM(), which is implemented +by the base port.

+ +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-812DEBEB-84D0-5BD4-A5BB-5AF6B8384CCF.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-812DEBEB-84D0-5BD4-A5BB-5AF6B8384CCF.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,47 @@ + + + + + +Entry +Point ImplementationDescribes how to implement the entry point function. +

The DMA Framework implements its entry point function in the platform-specific +layer.

+

The entry point for a kernel extension is declared by a

+DECLARE_STANDARD_EXTENSION() +

statement, followed by the block of code that runs on entry to the DLL. +The following code is typical for a port of the DMA Framework , and is taken +from the port for the template reference platform:

+DECLARE_STANDARD_EXTENSION() +// +// Creates and initializes a new DMA controller object on the kernel heap. +// + { + __KTRACE_OPT2(KBOOT, KDMA, Kern::Printf("Starting DMA Extension")); + + return Controller.Create(); + } + +

where Controller is declared as writable static data:

+static TTemplateDmac Controller; +

Create() is a second-phase constructor defined in, and implemented by, +the concrete class derived from TDmac. DMA channels are +attributes of this concrete class because only the platform specific layer +knows what kind of channel to use. This platform specific layer second phase +constructor must call the platform independent layer second phase constructor, TDmac::Create(), +before doing anything else.

+

TDmac::Create() allocates the arrays containing the +descriptors and descriptor headers using the information passed to it by the +platform specific layer in the SCreateInfo struct. This +includes information such as the number of descriptors to be allocated, whether +hardware descriptors are supported and their size etc.

+

Note that if hardware-specific descriptors are used, they are allocated +in a hardware chunk. If pseudo-descriptors are used, they are allocated on +the kernel heap.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-817E0561-6165-5BB1-97F9-AD53CFCDAA56.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-817E0561-6165-5BB1-97F9-AD53CFCDAA56.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,117 @@ + + + + + +Impact +of Data Paging on Kernel-side Code GuideDescribes the kernel-side issues that must be considered when writing +device drivers. +
Purpose

This document explains the impact of data +paging on kernel side code.

Intended +Audience:

This document is intended for device driver writers.

+
Access to user memory

New restrictions on access +to user memory.

+
Access to current thread's address space

Certain +exported and internal APIs access the address space of the current thread +and are subject to restrictions on their use enforced by assertions in the +code. The restrictions are these:

    +
  • The APIs may only be +called from thread context.

  • +
  • They may not be called +while any mutexes are held. There are two particularly important cases when +mutexes are often held:

      +
    • When publish and subscribe +is writing large binary properties to user space, and

        +
      • When the multiple memory +model writes code segments' export directories to user space.

      • +
    • +
  • +
  • The APIs may not be +called when the system lock is held. There are two particularly important +cases when the system lock is often held:

      +
    • When publish and subscribe +is writing large binary properties to user space, and

    • +
    • When the multiple memory +model uses DThread::FastWrite to write to user space.

    • +
  • +

The APIs concerned are these:

    +
  • Kern::KUDesInfo

  • +
  • Kern::KUDesGet

  • +
  • Kern::KUDesPut

  • +
  • Kern::KUDesSetLength

  • +
  • Kern::InfoCopy

  • +
  • umemget(), kumemget(), umemget32(), kumemget32()

  • +
  • umemput(), kumemput(), umemput32(), kumemput32()

  • +
  • umemset(), kumemset()

  • +
  • SafeRead(), KUSafeRead()

  • +
  • SafeWrite(), KUSafeWrite()

  • +
  • KUSafeInc()

  • +
  • KUSafeDec()

  • +
+
Access to another thread's address space

Certain +exported and internal APIs access the address space of another thread and +are subject to restrictions on their use enforced by assertions in the code. +The restrictions are these:

    +
  • The APIs may not be +called when any mutexes are held. One particularly important case of this +is when undertakers are completed and handles written to user space.

  • +

The APIs concerned are these:

    +
  • Kern::ThreadRawRead()

  • +
  • Kern::ThreadRawWrite()

  • +
  • Kern::ThreadDesRead()

  • +
  • Kern::ThreadDesWrite()

  • +
  • Kern::ThreadGetDesLength()

  • +
  • Kern::ThreadGetDesMaxLength()

  • +
  • Kern::ThreadGetDesInfo()

  • +
  • DThread::FastWrite()

  • +
+
Client request completion

In non-paged code it +is usual for a thread to have an asynchronous request outstanding and to complete +it by calling Kern::RequestComplete(). This technique is +not safe in data paged code as it involves writing a status value back into +the thread's address space, but this memory might be paged out and violate +the thread's performance guarantees or cause a mutex order violation.

Instead, +you should use the TClientRequest object to write the request +status within the context of the client thread in the following way.

    +
  1. Create a TClientRequest object +by calling Kern::CreateClientRequest().

  2. +
  3. Call the SetStatus() function +of the TClientRequest object to set the client's request +status.

  4. +
  5. Call Kern::QueueRequestComplete() to +signal the client thread that the request has been queued for completion.

  6. +
  7. When the client thread +next runs, the TRequestStatus value is written back to +it.

  8. +
  9. The TRequestStatus can +now be reused, or destroyed by a call to Kern::DestroyRequest().

  10. +
+
IPC message delivery

In non-paged code it is common +for a client thread to send a message to a server and write it into the address +space of the server. When data paging is enabled, this creates the same risk +of page faults as the completion of asynchronous requests and can be mitigated +by the same techniques as above. In addition, descriptor information (type, +length and maximum length) is read by temporarily switching to the client's +address space, creating additional risk of page faults.

When data +paging is enabled, messages to servers must be pre-parsed and their type, +length and maximum length stored in the message structure. This involves change +to the kernel code but does not impact on user-side code.

+
Kernel event queue

The kernel maintains a queue +of user-input events which is read by the window server. The introduction +of data paging involved a change to the kernel code which responds to the +user-side API UserSver::RequestEvent(). No change to user-side +code is involved.

+
+Code Paging +Overview +Code Paging +Guide +Demand Paging +Overview +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-81C69779-27AE-55E0-ACCF-E4F3E6657427.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-81C69779-27AE-55E0-ACCF-E4F3E6657427.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,16 @@ + + + + + +Concepts describes the technology, architecture, and behaviour of the DMA +Framework. +Port Implementation + Tutorial + \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-81DD805C-90B5-5227-B62B-F2413855BD9A.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-81DD805C-90B5-5227-B62B-F2413855BD9A.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,46 @@ + + + + + +LCD Extension ReferenceThis topic provides a summary of related documentation +for the LCD Extension to which you can refer. +
API +Reference

Kernel Architecture

+ + + +

Item

+

Header

+
+ +

SRectOpInfo

+

videodriver.h

+
+ +

TVideoInfoV01

+

videodriver.h

+
+ +

TVideoInfoV01Buf

+

videodriver.h

+
+ +

TDisplayHalFunction

+

u32hal.h

+
+ + +
+
+LCD +Extension Architecture +Implementing +Dynamic DSA Allocation +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-834781AF-D202-5752-B81A-A51D12A4D1EC.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-834781AF-D202-5752-B81A-A51D12A4D1EC.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,28 @@ + + + + + + Code OrganisationThis topic describes the USB Client Driver code. +

This topic describes the USB Client Driver code that Symbian platform +provides.

+

USB client driver LDD:

+
    +
  • is implemented +in USBC.LDD

  • +
  • has its source +code located in ...\e32\drivers\usbc\d_usbc.cpp

  • +
  • has its project +file located in ...\e32\drivers\usbc\usbc.mmp.

  • +
+

USB client controller PDD:

+
    +
  • The interface DUsbClientController is defined in ...\e32\include\drivers\usbc.h.

  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-84D56A30-1E97-40AE-BFB0-E33495E95AAC.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-84D56A30-1E97-40AE-BFB0-E33495E95AAC.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,17 @@ + + + + + +Base Porting DetailsDescribes the base port implementation. +

This is a section that contains the detail for specific porting +activities. You will normally access this material via links from +the section on the Porting Overview. However, this is a good place +to look if you need to review specific activities.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-85332468-292D-589B-891B-0E7ACBADC7BA-master.png Binary file Adaptation/GUID-85332468-292D-589B-891B-0E7ACBADC7BA-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-85332468-292D-589B-891B-0E7ACBADC7BA_d0e11000_href.png Binary file Adaptation/GUID-85332468-292D-589B-891B-0E7ACBADC7BA_d0e11000_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-8552E66E-73D6-51DA-8F53-DDF437186CD6.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-8552E66E-73D6-51DA-8F53-DDF437186CD6.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,63 @@ + + + + + +ValidationDescribes the DMA test code to validate the port of DMA framework. +

The same set of source code is used to build two different DMA test harnesses:

+
    +
  1. It builds: T_DMASIM.EXE, D_DMASIM.LDD, +and DMASIM.DLL. This is a software-simulated implementation +of DMA. This harness is used mainly for debugging and validating the PIL (platform-independent +layer) as it simulates every kind of DMA controller. The DMA simulator and +associated PSL (platform-specific layer) is in ...\e32test\dma\dmasim.cpp.

  2. +
  3. It builds: T_DMA.EXE, D_DMA.LDD. +The source code for building these executables is in ...\e32test\dma\t_dma.cpp and ...\e32test\dma\d_dma.cpp respectively

  4. +
+

T_DMA.EXE is a user-side harness, and is an automatic +test included in the E32TEST suite. It assumes that the underlying DMA controller +supports memory to memory transfers. This executable delegates most of the +work to D_DMA.LDD (built from base\e32test\dma\d_dma.cpp), a logical device +driver that acts as a client for the DMA Framework. D_DMA.LDD links statically +against DMA.DLL, the DMA Framework kernel extension and as such must be built +from the variant.

+

T_DMA.EXE delegates most of the work to D_DMA.LDD, +which is a logical device driver that acts as a client for the DMA Framework. D_DMA.LDD links +statically against DMA.DLL, the DMA Framework kernel +extension, and as such must be built from the variant. In practice, this means +that D_DMA.LDD must be specified in the test bld.inf for +the variant being ported. See ...\template_variant\test\bld.inf for +an example.

+

D_DMA.LDD calls the DmaTestInfo() function +in the PSL to discover the capacities of the PSL: number of channels, maximum +transfer size, etc. This is the template implementation:

+TDmaTestInfo TestInfo = + { + 0, + 0, + 0, + 0, + NULL, + 0, + NULL, + 0, + NULL + }; + + +EXPORT_C const TDmaTestInfo& DmaTestInfo() +// +// +// + { + return TestInfo; + } + + +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-857F981E-711B-5CA8-AB37-5C700A6140FA.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-857F981E-711B-5CA8-AB37-5C700A6140FA.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,93 @@ + + + + + +HAL Groups +and Handlers List of HAL groups and the location of their associated handlers. +

Some of the handlers are part of Symbian platform generic code and do not +require porting.

+ + + + +

HAL group

+

Location

+

Customizable?

+

Explicit registration required?

+
+ +

EHalGroupVariant

+

Variant

+

Yes. It needs to be implemented as the Asic::VariantHal() function +defined by the Asic class.

See the template port: ...\template\template_variant\specific\variant.cpp

+

No. It is done automatically as part of the kernel initialization.

+
+ +

EHalGroupPower

+

Power model

+

Yes. It needs to be implemented when implementing the power model.

See +the template port: ...\template\template_variant\specific\power.cpp

+

No. It is done automatically as part of the kernel initialization.

+
+ +

EHalGroupDisplay

+

LCD driver

+

Yes, when porting the LCD driver.

See the template port: ...\template\template_variant\specific\lcd.cpp.

+

Yes, during initialization of the driver.

+
+ +

EHalGroupDigitiser

+

Digitiser

+

Yes, when porting the digitiser.

See the template port: ...\template\template_variant\specific\xyin.cpp.

+

Yes, during initialization of the driver.

+
+ +

EHalGroupKeyboard

+

Keyboard driver

+

Yes, when porting the keyboard driver.

See the template +port: ...\template\template_variant\specific\keyboard.cpp.

+

Yes, during initialization of the driver.

+
+ +

EHalGroupKernel

+

Kernel

+

No. It is part of Symbian platform generic code.

+

No. It is done automatically as part of the kernel initialization.

+
+ +

EHalGroupMedia

+

Media Driver

+

No. This is in the media driver LDD; this is a kernel extension +and is implemented by Symbian platform.

+

Yes, during initialization of the driver/extension.

+
+ +

EHalGroupEmulator

+

Emulator

+

No. The emulator is a port of Symbian platform maintained by Symbian.

+

Yes, during 3rd phase initialization of the emulator variant.

+
+ +

EHalGroupSound

+

Sound driver

+

Unlikely—the only example is in the sound driver maintained for +backwards compatibility with pre-Symbian hardware.

+

Yes

+
+ +

EHalGroupMouse

+

Emulator

+

Unlikely—the only example is in the emulator, which is a port of +Symbian platform maintained by Symbian.

+

Yes

+
+ + +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-85C18DAF-DB76-51C6-B38D-A802E314F4D1.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-85C18DAF-DB76-51C6-B38D-A802E314F4D1.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,159 @@ + + + + + +Performance +Guarantee Tutorial Describes how to maintain performance guarantees when writing a +software package on a data paged platform. +

Data paging can +affect performance guarantees. When writing software for a data paged platform, +you need to perform an impact assessment on the components of your application. +To do so, you perform the following analyses and implement the appropriate +mitigation for the impacts you discover:

    +
  • Static analysis,

  • +
  • Use case analysis, and

  • +
  • IPC analysis.

  • +
+ +Perform a static +analysis of the impact of data paging on your code. + + +List all the executables in your package, indicating their size and +pageability. + + +For each item in the list identify its static dependencies, indicating +their size and pageability. + + +For each item in the list identify its dynamic dependencies, indicating +their size and pageability. +For instance, note whether the component is a plug-in to a framework +or is itself a framework. + + +The purpose of collecting this information is to identify which +executables are most likely to be impacted by data paging. + +Perform a use case +analysis of the impact of data paging on your code. It is good practice to +distinguish between use cases involving real time and performance critical +performance guarantees. You do not need to cover use cases which do not involve +guarantees of this kind. + +List all the +use cases for the component which involve real time performance guarantees. +Real time use cases are those having very strict response time guarantees +and also those involving an acceptable user perception of behaviour. +
    +
  • Video playback,

  • +
  • VoIP phone calls, and

  • +
  • File download over USB.

  • +
+Examples of use cases involving acceptable user perception are: +
+List all the +use cases for the component which involve performance critical guarantees. +This means the bench-marked use cases by which the performance of the operating +system is measure. +Examples of use cases having a strict response time are: +
    +
  • Standard boot time,

  • +
  • Application start-up +time, and

  • +
  • Camera image capture +time.

  • +
+
+Identify compound +cases involving both real time and performance critical guarantees. +An example of a compound case is receiving a text message while playing +MP3 audio. + +
+
+Perform an IPC analysis +of the impact of data paging on your code. + +Identify all +performance critical or real time servers which the component interacts with. + +List each case +where these servers read paged data from a client's address space. In this +case, paged data includes: +
    +
  • Paged heaps and stacks,

  • +
  • RAM-loaded code, and

  • +
  • Read only XIP data structures +including

      +
    • bitmaps,

    • +
    • constant descriptors,

    • +
    • constant data arrays +in code,

    • +
    • data files accessed +through a pointer, and

    • +
    • exported DLL data.

    • +
  • +
+
+Identify all +cases of custom architectures where one thread reads from another thread's +address space. + +
+
+Take steps to mitigate +the impacts of data paging which you have identified, as appropriate to each +case. + + +Protect the real +time and performance critical code paths. These paths will have been identified +in the static analysis of the component. There are two ways of protecting +them. +
    +
  • For all use cases, ensure +that the minimum paging cache size is large enough to accommodate both the +protected code path and any other paged data required at the same time.

    This +method of protection may not always be practical, because compound use cases +may involve unpredictable amounts of data which exceed the size of the paging +cache.

  • +
  • Make the protected code +path unpaged. Mark the code itself as unpaged, and either mark whole regions +of memory as unpaged or pin memory to ensure that it is unpaged.

  • +
+
+Redesign the +component architecture to isolate areas where data paging impacts on performance. +Examples of this are: +
    +
  • Separating the data +plane and the control plane, and

  • +
  • Splitting a monolithic +library into paged and unpaged parts.

  • +
+
+Use code paging +or XIP ROM paging to mitigate the impact of paging. + +For instance, a monolithic library with static dependences may only +need to be partially loaded, and some dependencies may not need to be loaded +at all. + + +Mitigate the impact of data paging on IPC using the techniques set out +in the document Device +Driver Writing Technology Tutorial + +
+
+
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-86082C0C-B0EE-5E7C-85B4-4A509066012F.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-86082C0C-B0EE-5E7C-85B4-4A509066012F.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,16 @@ + + + + + +MMC Porting +Implementation TutorialDescribes the steps to implement a port of the MMC Controller. +Concepts + + \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-862CA4C4-C6E8-4D60-8DD0-F3590C92E15D.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-862CA4C4-C6E8-4D60-8DD0-F3590C92E15D.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,13 @@ + + + + + +Interrupt Client InterfaceDescribes the client interface of the Interrupt platform +service. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-86737CAB-2A4A-4424-8856-67E0804BCD60.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-86737CAB-2A4A-4424-8856-67E0804BCD60.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,28 @@ + + + + + +Time OverviewProvides a basic idea about the Time platform service. +
What +is Time platform service

Time platform service +starts during device start up. It is responsible for maintaining a +queue of all system-wide alarms. It allows clients to query the status +of alarms, set alarms, remove alarms and perform other utility functions.

+
Need +for Time platform service

Time platform service +is required to manage the alarm in the system and system +state manager utility plug-in specifically RTC adaptation plug-in.

+
For +whom does Time platform service matter to?

Time platform service matters to all the Real time clock and alarm +implementations to fulfill the requirements set by the RTC adaptation +plug-in interface that is introduced beside of a System State Manager. +The SSM Adaptation Server contains a RTC Adaptation plug-in.

+
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-86C21C9B-9F08-579F-84E9-CBE46F756373-master.png Binary file Adaptation/GUID-86C21C9B-9F08-579F-84E9-CBE46F756373-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-86C21C9B-9F08-579F-84E9-CBE46F756373_d0e10964_href.png Binary file Adaptation/GUID-86C21C9B-9F08-579F-84E9-CBE46F756373_d0e10964_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-877EEB52-40C8-4880-87A0-9736A625F85F.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-877EEB52-40C8-4880-87A0-9736A625F85F.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,76 @@ + + + + + +TDmaChannel Derived Class ImplementationDescribes how to write a class describing a DMA channel. +

The TDmaChannel class is part of the PSL implementation. +It is an abstract class with pure virtual functions which you must +derive in order to implement it. The implementation of a DMA channel +involves hardware-specific decisions such as the choice of DMA mode

+

The purpose of DMA is to transfer data such as streaming audio +produced by a client application. A typical transfer involves passing +the data from user side to kernel side via a shared chunk and then +a transfer from one memory location to another by DMA over a buffer. +If the amount of data to be transferred exceeds the maximum transfer +size supported by the controller or involves non-contiguous physical +memory, the data is fragmented and transmitted in a sequence of transfers +in one of three modes.

+
    +
  • In single buffer mode the hardware controller provides a single +set of transfer registers used alternately to perform an active transfer +and to set up a pending one: however this mode incurs overhead in +the form of significant periods of time when the driver is idle during +the pending phase.

  • +
  • In double buffer mode the hardware controller provides two +sets of transfer registers, one set for the active transfer and one +for the pending transfer..

  • +
  • In scatter-gather mode, a single procedure call sequentially +writes data from multiple buffers to a single data stream or from +a data stream to multiple buffers.

  • +
+

The PIL supplies three derived classes corresponding to the DMA +modes:

+
    +
  • TDmaSbChannel

    for a single-buffer channel,
  • +
  • TDmaDbChannel

    for a double-buffer channel, +and
  • +
  • TDmaSgChannel

    for a scatter-gather channel.
  • +
+

These three classes are defined in dma_v1.h.

+

You may simply use one of these classes or derive further classes +from them and implement those. For example, the template scatter-gather +implementation defines a TTemplateSgChannel class +derived from TDmaSgChannel for storing data when +appending new descriptors to a running channel:

+class TTemplateSgChannel : public TDmaSgChannel + { +public: + TDmaDesc* iTmpDes; + TPhysAddr iTmpDesPhysAddr; + }; + +

In general, design decisions are made at the level of implementation +in hardware and are subsequently reflected in the structure of the +derived classes.

+

There are two ways of extending the DMA Framework:

+
    +
  • to provide platform-specific functionality on a per-channel +basis, and

  • +
  • to provide platform-specific functionality on a channel independent +basis

  • +
+

In the first case, TDmaChannel::Extension() calls TDmac::Extension() and the PSL provides an implementation +of the virtual function TDmac::Extension(). The +default implementation just returns KErrNotSupported. In the second case, TDmaChannel::StaticExtension() calls DmaChannelMgr::StaticExtension() and the +PSL provides an implementation of the static function DmaChannelMgr::StaticExtension(). The template PSL implementation just returns KErrNotSupported.

+
+DMA +Channels +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-8798F896-E0CB-4B9B-8F88-3C8B58574213.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-8798F896-E0CB-4B9B-8F88-3C8B58574213.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,26 @@ + + + + + +The +Physical ChannelThis document describes how a logical device communicates with +a physical device over a physical channel. +

The +physical channel defines the interface between the logical device and the +physical device. Typically, this interface is different for each device family +and, therefore, the device driver framework does not require a particular +type of interface. The only requirement is that the physical channel class +is derived from DBase. It is up to the driver writer to +define the physical channel class.

+ Device driver physical channel classes + + +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-892931C3-E560-54AA-A9CB-2820BF025E52.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-892931C3-E560-54AA-A9CB-2820BF025E52.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,70 @@ + + + + + +Fault +Information CommandsDescribes how to use the f command to get information +about the fault type. +

There are two possibilities:

+
    +
  • an unhandled exception has occurred

  • +
  • a panic has occurred

  • +
+

To start, use the f command. +You will see something like this:

+Fault Category: Exception Fault Reason: 10000000 +ExcId 00000001 CodeAddr f800415c DataAddr 00000000 Extra 00000005 +Exc 1 Cpsr=60000013 FAR=00000000 FSR=00000005 + R0=64007328 R1=00000000 R2=00000000 R3=00000001 + R4=64007328 R5=640074c0 R6=00000000 R7=f8047ba4 + R8=64006f80 R9=64006fec R10=00000013 R11=64006ec4 +R12=00000001 R13=000029b4 R14=0000016c R15=f800415c +R13Svc=64006ea8 R14Svc=f8002b2c SpsrSvc=600000ff + +

The Fault Category field shows the type of fault, in this case an +exception.

+
Unhandled +exceptions

If the Fault Category is Exception, then +the fault is caused by an unhandled processor exception. You can get further +information on the type of exception by looking at the first three lines of +the generated output:

Fault Category: Exception Fault Reason: 10000000 +ExcId 00000001 CodeAddr f800415c DataAddr 00000000 Extra 00000005 +Exc 1 Cpsr=60000013 FAR=00000000 FSR=00000005

The CodeAddr and DataAddr fields +show the address of the instruction that caused the exception and, depending +on the type of exception and instruction, the address of the data the instruction +was trying to access. You can use the CodeAddr value to find +the function which was being executed by using +the MAKSYM tool.

The number after ExcId is +the type of exception, in hexadecimal, and is one of the ARM exception types. The meaning of the numbers depends on the type +of processor.

    +
  • If the exception is +a prefetch abort, then the code address is invalid.

  • +
  • A data abort means that +the code address is invalid.

  • +

The number after FAR is the fault address register; +this is the address that caused the fault.

The number after FSR is +the fault +status register value and shows why the MMU raised an exception.

The +number after CPSR is the value of the CPU's CPSR register when the exception +occurred. The 5 least-significant bits of the CPSR register indicate the ARM +processor modes (CPSR register).

+
Panics

If +the Fault Category is not Exception, then the fault is due to +a panic. In this case the only other valid field is the Fault reason; +the values of all other fields are meaningless.

The panic number is +the low 16-bits of the fault reason, shown in hexadecimal.

For example, +a KERN 27 panic would generate:

Fault Category: KERN Fault Reason: 0000001b +ExcId ffffee5e CodeAddr ffff99a9 DataAddr bfff3e54 Extra fffec4cd +

If the panic is KERN 4, then a thread or process marked as +protected has panicked. For other panics, kernel side code has panicked; this +code is either in the kernel itself or in a device driver.

See Kernel State Information +Commands to find out which process and thread were running at the time +of the panic.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-898704CF-26A1-50F5-BEFE-1E29D85064AA.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-898704CF-26A1-50F5-BEFE-1E29D85064AA.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,13 @@ + + + + + +ReferenceThis section describes the command and syntax for ROM building +tools and input files. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-89BCF9A5-ABBD-5523-BA76-FDB00B806A30.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-89BCF9A5-ABBD-5523-BA76-FDB00B806A30.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,237 @@ + + + + + +Fair Scheduling and File CachingDescribes how to implement and configure the fair scheduling +and file caching features for file systems implementations. +
Enabling +fair scheduling

The MExtendedFileInterface API enables fair scheduling. The FAT, FAT32 and LFFS file systems +support MExtendedFileInterface, this API allows requests +to be split into one or more segments with the aOffset parameter. Support has been built in for large files by changing +the file’s position parameter (aPos) from a TInt to a TInt64.

To enable +fair scheduling, the file system mounted on a particular drive must +support CFileCB::MExtendedFileInterface. The object +returned by CFileSystem::NewFileL() must be derived +from CFileCB and CFileCB::MExtendedFileInterface. The file server determines whether this is the case by calling CFileCB::GetInterface.

The CFileCB::MExtendedFileInterface interface is as follows:

class MExtendedFileInterface +{ +public: + virtual void ReadL(TInt64 aPos, TInt& aLength, TDes8* aDes, const RMessagePtr2& aMessage, TInt aOffset) = 0; + virtual void WriteL(TInt64 aPos, TInt& aLength, const TDesC8* aDes, const RMessagePtr2& aMessage, TInt aOffset) = 0; + virtual void SetSizeL(TInt64 aSize) = 0; +};

The file system indicates its support for MExtendedFileInterface by intercepting the CFileCB::EExtendedFileInterface enumeration in the CFileCB::GetInterface() method +as in the following example:

TInt CFatFileCB::GetInterface(TInt aInterfaceId, TAny*& aInterface, TAny* aInput) + { + switch(aInterfaceId) + { + case EExtendedFileInterface: + ((CFileCB::MExtendedFileInterface*&) aInterface) = this; + return KErrNone; + + //etc. + + default: + return CFileCB::GetInterface(aInterfaceId, aInterface, aInput); + } + }
+
Enabling +read and write caching

To enable caching, the file system +must support reads and writes to local buffers, which are buffers +created and owned by the file server itself rather by a client of +the file server.

The local media subsystem already supports +local messages, but the file system and any file system extensions +need to be examined carefully to ensure that they do not call any RMessagePtr2 methods, otherwise a panic results.

The file server calls CMountCB::LocalBufferSupport() to find out whether the file system and all file system extensions +mounted on a particular drive fully support local buffers before it +enables caching. The file system handles the CMountCB::ELocalBufferSupport enumeration in its CMountCB::GetInterface() method +and passes the request on to the first proxy drive, as in the following +example:

TInt CFatMountCB::GetInterface(TInt aInterfaceId, TAny*& aInterface, TAny* /*aInput*/) + { + TInt r= KErrNone; + switch(aInterfaceId) + { + // file caching supported, so pass query on to first proxy drive + case CMountCB::ELocalBufferSupport: + r = LocalDrive()->LocalBufferSupport(); + break; + default: + r=KErrNotSupported; + } + return r; + }

If no file system extensions are loaded, then +the query is eventually handled by CLocalProxyDrive::GetInterface(), which returns KErrNone to indicate that TBusLocalDrive and the local media sub-system support local +buffers.

If there are any file system extensions, they must +handle the CProxyDrive::ELocalBufferSupport enumeration, +as in the following example:

TInt CBitExtProxyDrive::GetInterface(TInt aInterfaceId, TAny*& aInterface, TAny* aInput) + { + switch(aInterfaceId) + { + // file caching supported, so pass query on to next proxy drive + case ELocalBufferSupport: + return CBaseExtProxyDrive::LocalBufferSupport(); + + default: + return CBaseExtProxyDrive::GetInterface(aInterfaceId, aInterface, aInput); + } + }
+
Configuring +caching

The global and drive-specific cache property defaults +are defined in f32\sfile\sf_file_cache_defs.h. They may be overridden for a particular drive by appropriate entries +in the Base Starter component's ESTART.TXT configuration +file. The format of this file has been enhanced to support the .ini file style syntax:

C: 0 ELOCAL FAT 0 FS_FORMAT_COLD,FS_SYNC_DRIVE # IRAM +D: 1 ELOCAL FAT 0 FS_SCANDRIVE # MMC (textshell) +I: 2 ELOCAL FAT 0 FS_FORMAT_CORRUPT # NAND - USER DATA +K: 8 ELFFS LFFS 0 FS_FORMAT_CORRUPT # LFFS + +[DriveD] +FileCacheSize 256 +FairSchedulingLen 128 +FileCacheRead ON +FileCacheReadAhead ON +FileCacheWrite ON +ClosedFileKeepAliveTime 3000 +DirtyDataFlushTime 3000 +FileCacheReadAsync ON + +[DriveI] +FileCacheWrite ENABLED + +[DriveK] +FileCacheWrite ENABLED + +[FileCache] +GlobalCacheEnabled ON +GlobalCacheSize 32768 +GlobalCacheMaxLockedSize 1024 +LowMemoryThreshold 10

In this example, write caching +is enabled on drives I and K and has been turned on by default on +drive D.

Most of the properties in the example are set to +their default values: the definitions are redundant but are shown +for illustrative purposes.

For details, see Base Starter Technology.

Global +cache settings

The following table holds the global caching +properties:

+ + + + +

Property

+

Type

+

Comments

+

Default value

+
+ +

GlobalCacheEnabled

+

boolean

+

on or off

+

on

+
+ +

GlobalCacheSize

+

integer

+

Size of disconnected chunk shared by all files in kilobytes.

+

32768K (32MB)

+
+ +

GlobalCacheMaxLockedSize

+

integer

+

Maximum amount of locked RAM for all files in kilobytes.

+

1024K (1 MB)

+
+ +

LowMemoryThreshold

+

integer

+

Low memory threshold expressed as a percentage of total +RAM. If the amount of RAM drops below this value, attempts to allocate +memory for file caching fails.

+

10%

+
+ + +

File +cache settings

The properties FileCacheRead, FileCacheReadAhead and FileCacheWrite may each be in one of 3 states:

    +
  • OFF - file caching is permanently off and cannot be turned on.

  • +
  • ENABLED - file caching is off by default but may be turned on using an appropriate +file open mode, such as EFileReadBuffered

  • +
  • ON - file caching is on by default but may be turned off using an appropriate +file open mode, such as EFileReadDirectIO.

  • +

See Run time cache settings.

If FileCacheReadAsync is set, media driver reads on this drive are asynchronous. This +results in read ahead requests being issued before completing a client +read request. However, if FileCacheReadAsync is OFF, +then media driver reads on this drive are synchronous. So, issuing +a read ahead is likely to block any client thread that is normally +running at lower priority than the media driver's thread. In this +case read ahead requests only happen during periods of inactivity +to improve latency.

+ + + + +

Property

+

Type

+

Comments

+

Default value

+
+ +

FileCacheSize

+

integer

+

Maximum amount of locked or unlocked RAM per file.

+

128K

+
+ +

FairSchedulingLen

+

integer

+

Read & write requests greater than this length are split +up into 2 or more requests.

+

128K

+
+ +

FileCacheRead

+

string

+

OFF, ENABLED or ON.

+

ENABLED

+
+ +

FileCacheReadAhead

+

string

+

OFF, ENABLED or ON.

+

ON

+
+ +

FileCacheWrite

+

string

+

OFF, ENABLED or ON.

+

ENABLED

+
+ +

FileCacheReadAsync

+

boolean

+

ON or OFF. If set, media driver reads on this drive are +asynchronous.

+

OFF

+
+ +

ClosedFileKeepAliveTime

+

integer

+

Time after which a file is removed from the closed file +queue, in milliseconds.

+

3000ms (3 secs)

+
+ +

DirtyDataFlushTime

+

integer

+

Time after which a file containing dirty data is flushed, +in milliseconds.

+

3000ms (3 secs)

+
+ + +
+
+Fair +Scheduling and File Caching Background +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-8A1B6104-4B13-5200-AF3D-64B3929707BB-master.png Binary file Adaptation/GUID-8A1B6104-4B13-5200-AF3D-64B3929707BB-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-8A1B6104-4B13-5200-AF3D-64B3929707BB_d0e14531_href.png Binary file Adaptation/GUID-8A1B6104-4B13-5200-AF3D-64B3929707BB_d0e14531_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-8A5EC98B-E9AD-5496-9909-7C3B35610785.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-8A5EC98B-E9AD-5496-9909-7C3B35610785.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,64 @@ + + + + + +Demand +Paging Deadlock GuideDescribes deadlocks in the context of demand paging and how to +prevent them from occurring. +
Introduction

A +deadlock is when two or more processes have some resources, but not all of +the resources required to execute. The resources that are required are held +by the other processes, which in turn want the resources that are held by +the initial processes. In this state, no process can execute.

The +classic sign that a deadlock has occurred is that a collection of processes +just appear to never do anything i.e. 'just hang'.

In the context +of demand paging, the resource is a page of RAM that can be paged in or out. +If one process wants data in a page of RAM that is paged-in or out by another +process, then a potential deadlock condition can occur.

Deadlocks +are only likely to occur if you are altering or interacting with one of the +components used in paging in and out, such as media drivers or the paging +sub-system. The majority of user-side code does not need to worry about deadlocks +from paging.

This guide is most applicable to device side writers +and other engineers writing kernel-side code.

+
Deadlock features

For a deadlock to occur, +four necessary conditions must occur:

Mutual exclusion condition +

A resource cannot be used by more than one process at a time.

Hold +and wait condition

One process is holding one resource, but needs +another before it can finish.

No preemption condition

The +resources can only be relinquished by the process holding it.

Circular +wait condition

One process is holding a resource and wants another +resource that is held by another process, which in turn wants access to the +resource held by the initial process.

+
Deadlock Prevention

Since the cause of deadlocks +(as far as demand paging is concerned) is due to the paging in and out of +RAM, the following points have to be considered:

    +
  • Make sure all kernel-side components are always unpaged.

  • +
  • Pinning; new APIs have been added that allows a process to over-ride + the demand paging rules as regards to how RAM pages are paged in and out +the phone's memory. The name comes from that fact that the RAM page is fixed +in the phone's RAM (as if a pin had been stuck into it) until a detached command +is executed (unpinned). This is implemented by using the new DLogicalChannel::SendMsg() method.

  • +
  • Mutex use in device drivers - if the nesting order is violated then +deadlock can occur. To overcome this, make sure that all device driver operations +that could cause a page fault don't use mutexes. In other words, any access +to paged memory while holding a mutex has the potential to cause a deadlock.

  • +
  • Code running in DFC Thread 1 must not access user memory. This DFC +thread is used by the implementation of the system timer functionality, hence +paging RAM in or out of the system by this thread could cause serious performance +problems or a deadlock.

  • +
  • For media drivers, make sure that when the media driver services page-in +requests, that the thread that the driver runs in does not also make requests +to page-in RAM pages. Because, if this was to occur, then the media driver +will not be able to service the page in request and a dead lock would occur.

  • +
+
+Thrashing +Guide +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-8A78D678-D1C8-4A4E-9BF1-81C7019815C3-master.png Binary file Adaptation/GUID-8A78D678-D1C8-4A4E-9BF1-81C7019815C3-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-8A78D678-D1C8-4A4E-9BF1-81C7019815C3_d0e94711_href.png Binary file Adaptation/GUID-8A78D678-D1C8-4A4E-9BF1-81C7019815C3_d0e94711_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-8B7E2A72-B793-5E70-87F0-92AA0A482F23.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-8B7E2A72-B793-5E70-87F0-92AA0A482F23.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,165 @@ + + + + + +Interrupt::Bind() +and Interrupt::Unbind() Describes two types of configuration used in the implementation +of bind and unbind functions. +

The functions Interrupt::Bind() and Interrupt::Unbind() provide +device drivers with a way of binding ISRs to interrupt sources, and unbinding +ISRs from interrupt sources. The implementation of these functions follows +a standard pattern that can be re-used in most cases.

+

The implementation can be different if there is a single Variant DLL, or +if there is also an ASSP extension.

+
Variant DLL only configuration

The following example +implementation of Interrupt::Bind() assumes that all ISRs +in the ISR table have been bound, by default, to the spurious interrupts handler function as done in initialising +the table. To bind an interrupt source, the spurious interrupts handler +is replaced with the provided ISR. The implementation prevents an ISR from +being bound to an interrupt source that is already bound, by assuming that +an unbound interrupt source is bound to the spurious interrupts handler.

The +implementation shows the basic idea but may need to be extended, especially +where chained +interrupts and/or multiple +interrupt sources and pseudo interrupt sources are involved.

EXPORT_C TInt Interrupt::Bind(TInt aId, TIsr aIsr, TAny* aPtr) + { + TInt r = KErrNone; + If(TUint(aId)>=TUint(KInterruptSourceCount)) + { + r = KErrArgument; // Illegal interrupt number + } + else + { + SInterruptHandler& h = IsrHandlers[aId]; + TInt irq = NKern::DisableAllInterrupts(); + if (h.iIsr != &SpuriousHandler) + { + r = KErrInUse; // Already bound to an ISR + } + else + { + h.iPtr = aPtr; // The ISR parameter + h.iIsr = aIsr; // Pointer to the ISR + } + NKern::RestoreInterrupts(irq); + } + return r; + } +

Interrupt::Unbind() is the logical opposite +of Bind(), replacing the ISR with the spurious handler function. +The following code is the matching example implementation.

EXPORT_C TInt Interrupt::Unbind(TInt aId) + { + TInt r = KErrNone; + if (TUint(aId) >= TUint(KInterruptSourceCount)) + { + r = KErrArgument; // Illegal interrupt number + } + else + { + SInterruptHandler& h = IsrHandlers[aId]; + TInt irq = NKern::DisableAllInterrupts(); + if (h.iIsr == &SpuriousHandler) + { + r = KErrGeneral; // Already unbound + } + else + { + h.iPtr =(TAny*)aId; + h.iIsr = SpuriousHandler; // Replace with spurious handler + // NOTE: at this point it may be wise to + // force the hardware interrupt source to disabled. + } + NKern::RestoreInterrupts(irq); + } + return r; + } +

Note that functions in the Interrupt class +can be called from anywhere in kernel-side code, including ISRs, DFCs and +IDFCs, and kernel threads. You need to ensure that if you are manipulating +the ISR table, or any other structure that is shared, you need to disable interrupts +to prevent corruption of the data. Interrupts are disabled and re-enabled +using NKern::DisableAllInterrupts() and NKern::RestoreInterrupts().

+
ASSP Extension and Variant DLL configuration

When +a common ASSP extension is used, the Variant DLL may have to implement extra +interrupt binding and dispatch functions for the device-specific interrupts.

The +following code is an example of an implementation of Interrupt::Bind() in +the ASSP layer, where negative Interrupt IDs represent device specific interrupts.

EXPORT_C TInt Interrupt::Bind(TInt aId, TIsr aIsr, TAny* aPtr) + { + TInt r = KErrNone; + if(aId < 0 ) + { + return MyAsic->VariantBind( aId, aIsr, aPtr ); // Device specific ID, call variant + } + else if (aId >= KInterruptSourceCount) + { + r = KErrArgument; // Illegal interrupt number + } + else + { + SInterruptHandler& h = IsrHandlers[aId]; + TInt irq = NKern::DisableAllInterrupts(); + if (h.iIsr != SpuriousHandler) + { + r = KErrInUse; // Already bound to an ISR + } + else + { + h.iPtr = aPtr; + h.iIsr = anIsr; + } + NKern::RestoreInterrupts(irq); + } + return r; + }

The default device specific implementation of the VariantBind() function +might be as follows:

TInt TMyAsic::VariantBind( TInt aId, TIsr aIsr, TAny* aPtr ) + // Default implementation when device specific layer does not override + // and this is therefore an illegal aId. + { + return KErrArgument; + } +

The device specific implementation of VariantBind() would +follow the same general pattern as for the Interrupt::Bind() function +in the ASSP layer. The main difference is that the code refers to the device +specific ISR table, VariantHandlers[], defined within the +device specific layer, and the interrupt ID is converted to a positive number +so that it can be used as an index into this table:

SInterruptHandler VariantHandlers[KNumVariantInts]; EXPORT_C TInt TMyVariant::VariantBind(TInt aId, TIsr aIsr, TAny* aPtr) + { + TInt r = KErrNone; + aId = (-aId)-1; // convert to positive number >=0 + If (aId >= KInterruptSourceCount || aId < 0) + { + r = KErrArgument; // Illegal interrupt number + } + else + { + SInterruptHandler& h = VariantHandlers[aId]; + TInt irq = NKern::DisableAllInterrupts(); + if (h.iIsr != VariantSpuriousHandler) + { + r = KErrInUse; // Already bound to an ISR + } + else + { + h.iPtr = aPtr; + h.iIsr = anIsr; + } + NKern::RestoreInterrupts(irq); + } + return r; + }

Now you need a way of dispatching the interrupts and +since this is really a chained interrupt, the dispatch function can be packaged +as an ISR and bound to the core interrupt source it chains from. See IRQ and FIQ Dispatchers in +general and Dealing +with chained interrupts in particular.

+
+ +Interrupts in the split ASSP/Variant Configuration + +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-8B8CAEED-A89D-53B3-A311-51CF45B334B1.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-8B8CAEED-A89D-53B3-A311-51CF45B334B1.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,178 @@ + + + + + +IRQ +and FIQ DispatchersThe ASSP must supply two dispatcher functions, one for IRQ interrupts, +and one for FIQ interrupts. +

The following example code is a simple dispatcher for IRQ interrupts. +It assumes a simplistic interrupt controller that provides 32 interrupt sources, +and has a 32-bit pending-interrupt register where a 'one' bit indicates a +pending interrupt and all ones are cleared when the register is read.

+void IrqDispatch() + { + TUint32 pendingIrqs = TheAssp::IrqPendingRegister(); + // for the purposes of this example we assume that reading + // this register also clears the pending flags + + TInt index = 0; + while( pendingIrqs ) + { + // while there is at least one pending IRQ + if( pendingIrqs & 1 ) + { + // the next interrupt is pending - dispatch it + (IsrHandlers[index].iIsr)(IsrHandlers[index].iPtr); + } + ++index; + pendingIrqs >>= 1; + } + } + +

The code assumes that the interrupt source represented by the low order +bit in the pending-interrupt register is represented by interrupt ID number +0 etc.

+

When implementing the dispatcher it is usual to write it in C++ initially, +but once you have it working you would probably want to rewrite it in assembler +to gain maximum efficiency for what is a time-critical section of code.

+
Dealing with +chained interrupts

There are two considerations when dealing with chained +interrupts:

    +
  1. how to identify interrupts +on the lower priority chained controllers

  2. +
  3. how to handle the dispatch +of a chained interrupt.

  4. +

The first point is a question of allocating locations in your ISR +table for the secondary controllers so that the interrupt ID identifies which hardware controller the interrupt is +on. For example, if each interrupt controller handles 32 interrupt sources, +you could make the first 32 IDs refer to the highest-level controller, the +next 32 refer to one of the second-level controllers etc.

There is +no need to change the Interrupt::Bind() and Interrupt::Unbind() functions, +although you may need to consider extending the Interrupt::Enable() and Interrupt::Disable() functions +to enable and disable the chain interrupt in a higher-level interrupt controller, +if necessary.

There are at least two ways of dispatching a chained +interrupt:

Dispatching a chained interrupt (1)

One +way of dispatching a chained interrupt is simply to make it a special case +in the main interrupt dispatcher. For example:

void IrqDispatch() + { + TUint32 pendingIrqs = TheAssp::IrqPendingRegister(); + + TInt index = 0; + while( pendingIrqs ) + { + if( pendingIrqs & 1 ) + { + if( index == EMainIntChainIrq ) + { + // second-level controller is signalling + SecondLevelIrqDispatch(); + } + else + { + // call ISR + (IsrHandlers[index].iIsr)(IsrHandlers[index].iPtr); + } + } + ++index; + pendingIrqs >>= 1; + } + } +

This approach works for a simple case, for example, where +there is only a main and secondary interrupt controller. It is does not scale +well because the special cases in the dispatcher become an overhead on the +dispatch of normal, unchained interrupts as the number and depth of the chaining +increases.

Dispatching a chained interrupt (2)

A better +way of handling chained interrupts is to bind an ISR to the interrupt source +in the main interrupt controller and use it to dispatch the chained interrupt. +This is far more scalable because you can bind any number of ISRs without +having to add special cases to any of the interrupt dispatchers.

The +dispatcher code could then be re-implemented as:

void IrqDispatch() + // MAIN IRQ DISPATCHER, FIRST-LEVEL INTERRUPT + { + TUint32 pendingIrqs = TheAssp::IrqPendingRegister(); + + TInt index = 0; + while( pendingIrqs ) + { + if( pendingIrqs & 1 ) + { + (IsrHandlers[index].iIsr)(IsrHandlers[index].iPtr); + } + ++index; + pendingIrqs >>= 1; + } + } + void SecondLevelIrqDispatch( TAny* /* aParam */ ) + { + TUint32 pendingIrqs = TheAssp::SecondLevelIrqPendingRegister(); + + TInt index = EStartOfSecondLevelIntId; + while( pendingIrqs ) + { + if( pendingIrqs & 1 ) + { + (IsrHandlers[index].iIsr)(IsrHandlers[index].iPtr); + } + ++index; + pendingIrqs >>= 1; + } + } + void InitialiseSecondLevelDispatch() + // Bind and enable the second-level dispatcher + { + Interrupt::Bind(EMainIntChainIrq,SecondLevelIrqDispatch,NULL); + Interrupt::Enable( EMainIntChainIrq ); + } + +Interrupt sources + +
    +
  • The second level dispatcher, SecondLevelIrqDispatch(), +is itself an ISR, and takes a TAny * parameter, but is +not needed in this specific example. It reads the interrupt pending register +of the second-level interrupt controller. Note, however, that the TAny * +parameter may be useful when the second level dispatcher is in the variant +as opposed to the ASSP. In that case you have separate interrupt IDs for variant +level interrupts and separate ISR tables. The TAny * parameter +can point to the appropriate ISR table. Alternatively the TAny * +can point to a data block containing IO addresses - especially useful if you +have many I/O devices mapped as hardware chunks. See the code in ...\assabet\specific\variant.cpp.

  • +
  • The index count starts +at offset EStartOfSecondLevelIntId into the ISR table, where +the second-level interrupt ISRs are located. In this example, this symbol +would equate to 32.

  • +
  • EMainIntChainIrq is +the interrupt ID of the chained interrupt source to the main interrupt controller.

  • +
+
Dealing with multiple interrupt sources

The case +where multiple peripherals are connected to the same interrupt source can +be handled through the technique of pseudo interrupt sources. This involves +assigning pseudo-interrupt IDs in the ISR table to correspond to each of the +peripherals that is attached to the interrupt line, i.e. ISRs are bound to +these pseudo-interrupt sources.

Dealing with pseudo interrupt sources +is, in essence, a special case of Chained +interrupts.

The dispatcher can do one of two things:

    +
  • examine the peripheral +hardware to determine which of the interrupts are pending, and then call the +appropriate ISR

  • +
  • call all the ISRs and +leave them to determine whether their peripheral is actually signalling an +interrupt.

  • +

As usual, it is entirely up to you to choose the ID numbers for these +pseudo-interrupts.

There should be no need to alter the implementations +of Interrupt::Bind() or Interrupt::Unbind() but +you will need some special handling in Interrupt::Enable() to +enable the true interrupt source, and Interrupt::Disable() to +disable this interrupt source.

Dispatching the interrupt can be done +in either of the two ways described in dealing with chained interrupts. Making use of a special case in the main interrupt +dispatcher is acceptable for simple cases, but for more complicated cases +with large numbers of pseudo-interrupts or a combination of chained and pseudo-interrupts, +it is better to use an ISR dispatcher bound to the true interrupt source.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-8BA1EEC2-78A3-54CC-95D9-81BF2659963D.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-8BA1EEC2-78A3-54CC-95D9-81BF2659963D.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,454 @@ + + + + + +Base +Starter TechnologyThis topic describes the purpose of the Base Starter, and which +parts of it can be customised by phone developers. +

The purpose of the Base Starter is to:

+
    +
  • Define a handset's local +drives

  • +
  • Define what file systems +(.FSY) and file extensions (.FXT) +are to be mounted on those drives

  • +
  • Associate drive letters +with drives

  • +
  • Modify drive start-up +behaviour

  • +
  • Enable fair +scheduling and file caching on a drive by drive basis.

  • +
+

Handset manufacturers need to customise the Base Starter as part of the +process of porting Symbian platform to a new device. Mapping local drives is the most important part of this process, but customisation +using TFSStartup is also possible.

+

Note that there are some activities +that the Base Starter does not do

+
Mapping local +drives

There are two ways to do this:

    +
  • Create local drive mapping files

  • +
  • Use automatic local drive mapping.

  • +

Create local drive mapping +files

A local drive mapping file is an ASCII text file that explicitly +defines the drive letter, file system, and file extension to be associated +with a drive. The file contains a set of records, one for each drive, that +specifies this information. Records are also referred to as drive mappings.

The +file is created as part of your hardware variant's source tree, but is copied +into a standard location in your ROM filing system when you build the ROM.

A +drive mapping file has a formal structure; the main rules are:

    +
  • the file can contain +a maximum of 16 different drive mappings

  • +
  • each drive mapping is +represented by a separate record; each record occupies one line; each line +is separated by the new line character \n

  • +
  • information is represented +by items separated by at least one blank character

  • +
  • comments can occupy +a whole line or can be added onto the end of a record (i.e. at the end of +line). They are marked by a # character that must precede +the start of the comment text.

  • +

A record, or drive mapping, has the following items, each separated +by at least one blank character. Each item must appear in the order described:

<drive_letter> <drive_number> <file_system_filename> <file_system> <file_extension_filename> <flags> + + + +

<drive_letter>

+

A single character between A and Z followed +by a colon.

+
+ +

<drive_number>

+

The local drive number associated with the drive letter .

+
+ +

<file_system_filename>

+

The filename of the file system that is to be mounted on the drive. +This should be the filename without the .FSY extension. +If it is necessary to omit a file system file name for any reason, then this +item should contain the null character: 0.

+
+ +

<file_system>

+

The name of the file system as implemented by <file_system_filename>.

If +the file system name is the same as the file name, as represented by the <file_system_filename> item, +then supply the null character 0. [Internally, the file system +name is sometimes referred to as the object name.]

Symbian platform +supplies the following file systems:

    +
  • FAT

  • +
  • ROFS - +read/only file system

  • +
  • LFFS - +logging flash file system

  • +
  • COMP - +composite file system (but see the description of the FS_COMPOSITE flag +below)

  • +

Handset manufacturers may supply other file systems.

+
+ +

<file_extension_filename>

+

The filename of the file extension that is to be mounted on the +drive. This should be the filename without the .FXT extension. +If it is necessary to omit a file extension file name for any reason, then +this item should contain the null character: 0.

+
+ +

<flags>

+

A set of mount flags that modify the start-up behaviour of +the local drive. More than one flag can be specified, each separated by a +comma, with no intervening blank characters. If no flags apply, then the null +character: 0 must be coded.

+ + + +

FS_FORMAT_ALWAYS

+

Formats the drive as soon as it has been mounted.

+
+ +

FS_FORMAT_COLD

+

Formats the drive as soon as it has been mounted if the device is +performing a cold boot. This is generally required for internal RAM drives.

+
+ +

FS_FORMAT_CORRUPT

+

Formats the drive, if it is found to be corrupt when mounted.

+
+ +

FS_DISMNT_CORRUPT

+

Dismounts the drive, if it is found to be corrupt when mounted. +The local drive mapping remains unaltered and the associated file system file +is not unloaded.

+
+ +

FS_SWAP_CORRUPT-<drv>

+

Dismounts the drive, if it is found to be corrupt when mounted, +and swaps the mappings for this drive with the alternative drive <drv>, +and remounts both.

The alternative drive <drv> must +be specified, and must follow a '-' character, which follows +the FS_SWAP_CORRUPT symbol.

For example, to swap +with drive Y:, specify:

FS_SWAP_CORRUPT-Y

This +option is commonly used when handling corrupt flash user-data drives on C:. +The corrupt drive is mapped to another drive letter – allowing data to be +extracted from it. The C: drive is replaced by a RAM +disk – providing a temporary work disk for the OS, while the main one is restored. +Note that a mapping file must not specify more than one drive for swapping, +i.e. there can only be one occurrence of FS_SWAP_CORRUPT flag +per mapping file.

Both drives involved in the swap must be internal +drives.

+
+ +

FS_SYNC_DRIVE

+

Mounts this drive as a synchronous drive. This means that requests +are handled in the main file server thread rather than in a dedicated drive +thread. This option is normally only specified for internal RAM drives.

+
+ +

FS_SCANDRIVE

+

Runs Scandrive, once mounted, but only if the +rugged file system is enabled.

+
+ +

FS_COMPOSITE

+

Marks the drive as contributing to the composite file system. The +composite file system allows multiple local drives to be overlaid with each +other, and with the core OS ROM image, and to make them appear as one drive.

Files +in one drive can add to, replace, or hide (i.e. logically remove) files in +another drive

There are number of rules:

    +
  • the drive letter must +always be Z:

  • +
  • if the file system is +omitted, i.e. both <file_system_filename> and <file_system> are +set to '0', then the the ROFS file system is assumed, and this can be the only drive +marked with FS_COMPOSITE in a mapping file.

  • +
  • if the file system is +explicitly specified, i.e. <file_system_filename> and <file_system> are +set, then more than one drive can be marked with FS_COMPOSITE. +However, adding a drive that uses a file system other than ROFS is strongly +discouraged for performance reasons.

  • +
  • the order of the records +is important, as this defines the search order when Symbian platform is working +out which files will contribute to the final ROM. The core OS ROM file system +(containing the kernel, kernel extensions, media drivers, the file server, +file systems and the Base Starter executable) is searched first, followed +by the last drive in the mapping file marked with FS_COMPOSITE, +followed by the next last drive marked with FS_COMPOSITE etc.

  • +

Note: the use of COMP as a <file_system> seems +to contradict the use of this flag. COMP was used to specify +a composite file system that allowed a single drive to be combined +with the ROM file system. For compatibility purposes, and to ensure consistency +of syntax, you can still specify COMP with FS_COMPOSITE on +a drive mapping, but you cannot have any other drive mappings marked as FS_COMPOSITE. +If you specify COMP, then the underlying file system associated +with that drive is assumed to be ROFS.

See Mounting multiple ROM images +as a single ROM drive for more detail.

+
+ +

FS_NO_MOUNT

+

Loads the file specified file system and the specified file extension, +and maps the drive as specified, but does not mount the drive. This is often +used in conjunction with FS_SWAP_CORRUPT. It allows the configuration +for the alternative drive involved in a swap to be specified – but for the +drive not to be mounted and accessible in normal operation. If the drive is +involved in a swap with another, then the FS_NO_MOUNT state +is ignored and the drive is mounted normally.

+
+ +

FS_ALLOW_REM_ACC

+

This is reserved for future use.

+
+ +

FS_NOT_RUGGED

+

Marks the mount as not rugged. Mounting the drive without the rugged +file system means that FS_SCANDRIVE is not supported. If FS_SCANDRIVE is +also defined, it is ignored.

+
+ +

FS_SYSTEM_DRIVE

+

Assigns this drive as the system drive. Applications store user +data on the system drive, and call RFs::GetSystemDriveChar() to +discover the drive letter.

A mapping file can only specify one drive +as the system drive.

See the +system drive.

+
+ + +

+ + + +

Use automatic local drive +mapping

If no drive mapping file exists or is unavailable, the +Base Starter decides which file system to mount on each local drive by interrogating +the capabilities of those drives. This is known as auto-detection.

Internally, +the Base Starter holds a table containing entries for every known supported +local drive configuration. This table is known as the auto-configuration table. +The information supplied by each entry in the table resembles that supplied +by a local +drive mapping file, and contains the following information:

    +
  • The filename of the +file system for this configuration (the .FSY). The filename +corresponds to the <file_system_filename> item in a drive +mapping file entry.

  • +
  • The object name of the +file system for this configuration. The object name corresponds to the <file_system> item +in a drive mapping file entry.

  • +
  • The filename of the +file server extension for this configuration, if applicable. The filename +corresponds to the <file_system> item +in a drive mapping file entry.

  • +
  • The set of mount flags; +these correspond to the <flags> items in a drive mapping +file entry. There is one exception - FS_SWAP_CORRUPT is not +supported, because it is impossible to auto-detect which drive is to be swapped.

  • +
  • A file system identification +function that is used to decide whether the designated file system is really +suitable for this drive. Each function is an internal part of the generic +Base Starter code.

  • +

The Base Starter uses the following default mapping of drive letters +to drive numbers:

+ + + +

Local drive number

+

Drive letter

+
+ +

0

+

C

+
+ +

1

+

D

+
+ +

2

+

E

+
+ +

3

+

F

+
+ +

4

+

G

+
+ +

5

+

H

+
+ +

6

+

I

+
+ +

7

+

J

+
+ +

8

+

K

+
+ +

9

+

L

+
+ +

10

+

M

+
+ +

11

+

N

+
+ +

12

+

O

+
+ +

13

+

P

+
+ +

14

+

Q

+
+ +

15

+

R

+
+ + +
+
Customisation +using TFSStartup

Most of the functionality provided by the Base +Starter is provided by the class TFSStartup. +This contains a number of virtual functions with default Symbian implementations. +A handset manufacturer can create a customised version of the Base Starter, +which overrides these functions.

    +
  • Disabling drive auto-detection

  • +
  • Customising for multiple hardware states

  • +
  • Overriding the default drive mapping

  • +
  • Customising mount flags

  • +
  • Customising the drive initialisation sequence

  • +
  • Customising Loadlocale

  • +
  • Customising the restart mode

  • +
  • Customising other behaviour

  • +

Disabling drive auto-detection

The +most common customisation is to use the supplied version of the Base Starter +and to create one or more local drive mapping files . In this case, savings +in code space can be made by removing the code that deals with auto-detection. +This is achieved by adding the following line to the MMP file +describing the Base Starter, and then rebuilding it.

MACRO AUTODETECT_DISABLE

Customising for multiple +hardware states

If the state of your hardware varies, and it requires +different mapping files for different states, then it is still possible to +use the local drive mapping scheme. Examples of hardware state variations +might be differences in the state of a switch or jumper setting, or the presence +or absence of a hardware feature. In this situation, the ROM can be built +with more than one mapping file. A custom version of the Base Starter provides +its own version of the virtual function TFSStartUp::LocalDriveMappingFileName(); +this checks the appropriate settings, and returns the name of the appropriate +local drive mapping file. The returned name is the full path name.

Overriding the default drive +mapping

To override the default mapping of drive letters to drive +numbers on a drive by drive basis, a custom version of the Base Starter provides +its own version of the virtual function TFSStartUp::DefaultLocalDrive().

To +override the auto-configuration table used by the automatic local drive mapping +scheme, for example to add support for a new .FSY, a +custom version of the Base Starter provides its own version of the virtual +function TFSStartUp::GetNextStandardFSInfoEntry().

Customising mount flags

Whether +you use the automatic local drive mapping scheme or an explicit local drive +mapping file, you can provide support for additional mount flags. A custom +version of the Base Starter provides its own version of the virtual functions:

    +
  • TFSStartUp::ParseCustomMountFlags()

  • +
  • TFSStartUp::HandleCustomMountFlags()

  • +

Customising the drive initialisation +sequence

To override the entire local drive initialisation sequence +provided by the generic version of the Base Starter, a custom version of the +Base Starter provides its own version of the virtual function TFSStartUp::LocalDriveInit().

Customising Loadlocale

User::UTCOffset() is called within the LoadLocale() function. Customise TFSStartup::LoadLocale() so +that the offset behaviour is correct for your time zone.

Setting the User::UTCOffset() is required within EStart +to provide backward compatibility and because it provides the system time +to components before the timezone/locale services are initialised.

See setting the universal time +offset.

Customising the restart +mode

TFSStartup::GetStartupMode() and TFSStartup::GetStartupModeFromFile() must be +implemented to get the restart mode at start-up.

Symbian platform +does not define any meaning to restart mode values. It is for the use of the +device manufacturer.

The restart mode is defined by the HAL attribute EPersistStartupM. This is a TAttribute enum +value defined in class HALData in ..\hal\inc\hal_data.h.

To +use this attribute, define it in your variant’s config.hcf file +and set an initial value in your variant’s values.hda file. +The template port defines the attribute as settable using the following definition +in the config.hcf file.

EPersistStartupModeKernel : set = ProcessPersistStartupMode

The value can be changed using HAL::Set(). ProcessPersistStartupMode is +the name of a function internal to Symbian platform. If you choose to make +the attribute settable, you must use this definition.

Calls to HAL::Get() are routed to the function Template::VariantHal() in +your variant's variant.cpp file, and handled by the EVariantHalGetPersistedStartupMode case.

Calls +to HAL::Set() are routed to the function Template::VariantHal() in +your variant's variant.cpp file, and handled by the EVariantHalPersistStartupMode case.

You +need to do the following:

    +
  • If you choose to make +the custom startup mode settable (in Symbian platform terminology, the attribute +is said to be derived), you need to implement TFSStartup::GetStartupMode(). +Derived attributes are saved when the system is closed down. The function GetStartupMode() is +called before the file server starts.

  • +
  • If you choose to make +the custom startup mode non-settable (in Symbian platform terminology, the +attribute is said to be non-derived), you need to implement TFSStartup::GetStartupModeFromFile(). +Non-derived attributes are read from file, and this function is called after +the file server has started.

  • +
  • You need to provide +an implementation for your Template::VariantHal() function +in your variant.cpp file.

  • +

The example below is the OMAP H4 variant implementation of GetStartupModeFromFile() and GetStartupMode() found +in ...\dev1\omap_hrp\h4estart\estartmain.cpp.

TInt TH4FSStartup::GetStartupModeFromFile() + { + if (iStartupMode != EStartupModeUndefined) + { + TInt r = ReadAndReset(); + return r; + } + return KErrNone; + } + +TInt TH4FSStartup::GetStartupMode() + { + TInt r = ReadAndReset(); + return r; + } + +TInt TH4FSStartup::ReadAndReset() + { + TInt value; + TInt r = HAL::Get(HALData::EPersistStartupModeKernel, value); + if (r == KErrNone) + { + iStartupMode = value; + } + r = HAL::Set(HALData::EPersistStartupModeKernel, EStartupModeUndefined); + return r; + }

See User-Side +Hardware Abstraction.

Customising other behaviour

You +can change other default behaviour. For example, to add additional functionality +related to File Server initialisation, or the initialisation of other base +related components, then the following virtual functions can also be customised. +Follow the links to the individual functions for more detail:

    +
  • TFSStartup::Init()

  • +
  • TFSStartup::Run()

  • +
  • TFSStartup::InitialiseHAL()

  • +
  • TFSStartup::StartSystem()

  • +
  • TFSStartup::Close()

  • +
+
Activities +that the Base Starter does not do

The Base Starter is responsible +for mapping local drives to drive letters and for loading the appropriate +file systems on local drives. It does not install media drivers, and +is not responsible for deciding which local drive a media driver will register +with. This is done by the individual media drivers and peripheral controllers +when they are initialised.

See Registering +the media driver for information about how to register a media driver.

See +also Local +Media Subsystem.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-8C22AF20-EE0E-5AD2-BEFD-FED5A7DBB09B.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-8C22AF20-EE0E-5AD2-BEFD-FED5A7DBB09B.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,25 @@ + + + + + +LCD +ExtensionThe LCD Extension is a kernel extension that manages the +screen hardware. This section describes how to create a port of it +for your phone hardware. +

The user-side interface to the LCD Extension is defined +by the EHalGroupDisplay group of HAL functions defined +by the User-Side Hardware Abstraction (HAL). The LCD Extension implements +a handler for this group of functions.

+
+ +User-Side Hardware Abstraction +Implementing +Dynamic DSA Allocation +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-8C9F26BC-2579-545C-9A86-9C45E06679F0-master.png Binary file Adaptation/GUID-8C9F26BC-2579-545C-9A86-9C45E06679F0-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-8C9F26BC-2579-545C-9A86-9C45E06679F0_d0e32265_href.png Binary file Adaptation/GUID-8C9F26BC-2579-545C-9A86-9C45E06679F0_d0e32265_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-8D237BD6-9759-4180-B190-F1624594017F.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-8D237BD6-9759-4180-B190-F1624594017F.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,76 @@ + + + + + +Time Client Interface Tutorial — Using the InterfaceProvides examples of how the Time client interface is used. +

The Time client interface methods can be executed independently. +The following examples show the Time client interface functions being +used along with an explanation.

+
Using +the <xref href="GUID-CC79A63E-15DF-3437-983B-9A90966B3004.dita#GUID-CC79A63E-15DF-3437-983B-9A90966B3004/GUID-AC7C2EFB-BE71-301A-9C03-A15BDC0EF310"><apiname>MRtcAdaptation::ValidateRtc()</apiname></xref> function

An example of the use of this function is:

MRtcAdaptation* rtcAdaptation = NewRtcAdaptationL(); +TPckgBuf<TBool> boolPckg; +TRequestStatus status; + +rtcAdaptation->ValidateRtc(boolPckg, status); +

The first three lines define the instance of the MRtcAdaptation class and the variables that are to be used.

The fifth line invokes the MRtcAdaptation::ValidateRtc() method. The first parameter will return the validity of the Real +Time Clock (RTC) as a boolean value. The second parameter returns +the completion status of the request. If the RTC clock is valid, then +this would be KErrNone.

+
Using +the <xref href="GUID-69C70CA3-1121-3C5B-AEA4-B2E0245539B9.dita#GUID-69C70CA3-1121-3C5B-AEA4-B2E0245539B9/GUID-2D7976BE-F6D5-3FC4-8253-C34A592A63D3"><apiname>ASIC::SetSystemTimeCalibration()</apiname></xref> function

An example of the use of this function is:

Asic Asic_class; +TInt r; +r = Asic_class::SetSystemTimeCalibration(30);

In the +above example, the RTC is being set with a time calibration value +of 30ppm (parts per million). This means that the RTC can lose up +to one second every 30 million seconds.

The value returned by +this function is either KErrNone or a system wide +error code if something went wrong.

+
Using +the <xref href="GUID-C82E90BC-451B-3BB4-83E0-243061BCFA14.dita#GUID-C82E90BC-451B-3BB4-83E0-243061BCFA14/GUID-611E6535-9CCA-39E3-8236-654FF280B7CD"><apiname>MRtcAdaption::SetWakeUpAlarm()</apiname></xref> function

An example of the use of this function is:

TPckgC <TTime> timePckg(testTime); + rtcAdaptation->SetWakeupAlarm(timePckg, status);

In +the above example, the first line declares the variable to be used +and initializes it. The second line is used to set the wake-up alarm +time.

+
Using +the <xref href="GUID-CC79A63E-15DF-3437-983B-9A90966B3004.dita#GUID-CC79A63E-15DF-3437-983B-9A90966B3004/GUID-C2A7DE1F-6354-31D6-A397-5CE690C4C67E"><apiname>MRtcAdaptation::UnsetWakeUpAlarm()</apiname></xref> function

An example of the use of this function is:

TRequestStatus status; +rtcAdaptation->UnsetWakeupAlarm(status); +

The first line declares the variable that is to be +used. The second line deletes the current device wake-up alarm time.

+
Using +the <xref href="GUID-CC79A63E-15DF-3437-983B-9A90966B3004.dita#GUID-CC79A63E-15DF-3437-983B-9A90966B3004/GUID-ADC7041A-23F0-319F-A163-29E8BB261D0B"><apiname>MRtcAdaptation::Cancel()</apiname></xref> function

An example of the use of this function is:

rtcAdaptation->Cancel(); +

In the above example, the last request made to the +instance of the MRtcAdaptation class, defined as rtcAdaptation in the above example, will be deleted.

+
Using +the <xref href="GUID-CC79A63E-15DF-3437-983B-9A90966B3004.dita#GUID-CC79A63E-15DF-3437-983B-9A90966B3004/GUID-C44E98E9-6568-3628-9A7E-85379C4298FD"><apiname>MRtcAdaptation::Release()</apiname></xref> function

An example of the use of this function is:

rtcAdaptation->Release(); +

In the above example, a call to the destructor in the +instance of the MRtcAdaptation class, defined as rtcAdaptation in the above example, is made.

+
Using +the <xref href="GUID-69C70CA3-1121-3C5B-AEA4-B2E0245539B9.dita#GUID-69C70CA3-1121-3C5B-AEA4-B2E0245539B9/GUID-EE99A729-F30E-3B3A-BCA2-0F10B383AB6C"><apiname>ASIC::SystemTimeInSecondsFrom2000()</apiname></xref> function

An example of the use of this function is:

Asic Asic_class; +TInt hwrtc = 0; +Asic_class::SystemTimeInSecondsFrom2000(hwrtc); +

The first and second lines declare and initialize the +variables and classes that are to be used. The third line calls the ASIC::SystemTimeInSecondsFrom2000() function. The number +of seconds since the start of the year 2000 is placed in the variable +that has been passed as a parameter.

The value returned by this +function is either KErrNone or a system wide error +code (if something went wrong).

+
Using +the <xref href="GUID-69C70CA3-1121-3C5B-AEA4-B2E0245539B9.dita#GUID-69C70CA3-1121-3C5B-AEA4-B2E0245539B9/GUID-C6983BB7-6496-3863-8109-6845F5DA62CF"><apiname>ASIC::SetSystemTimeInSecondsFrom2000()</apiname></xref> function

An example of the use of this function is:

Asic Asic_class; +TInt r=0; +r = Asic_class::SetSystemTimeInSecondsFrom2000(0);

The +first and second lines declare and initialize the variables and classes +that are to be used. The third line sets the RTC to be zero seconds +from the start of the year 2000.

The value returned by this +function is either KErrNone or a system wide error +code (if something went wrong).

+
+Time +Implementation Guide +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-8D7ED882-C61E-4B4F-8483-A323C60BFC57.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-8D7ED882-C61E-4B4F-8483-A323C60BFC57.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,112 @@ + + + + + +Register Access Interface OverviewProvides a summary of the Register Access platform service +interface. +

The Register Access platform service is provided by functions of +the AsspRegister class. The AsspRegister class is defined in the os/kernelhwsrv/kernel/eka/include/kernel/arm/assp.h file. The functions defined in the AsspRegister class must be implemented +in the baseport variant to allow device drivers and other kernel side +code to access registers.

+
+ Register read functions + + + +API +Description + + + + +AsspRegister::Read8(TLinAddr aAddr) +Read the contents of an 8 bit register + + +AsspRegister::Read16(TLinAddr aAddr) +Read the contents of a 16bit register + + +AsspRegister::Read32(TLinAddr aAddr) +Read the contents of a 32 bit register + + +AsspRegister::Read64(TLinAddr aAddr) +Read the contents of a 64 bit register + + + +
+
Register +write functions + + + +API +Description + + + + +AsspRegister::Write8(TLinAddr aAddr, TUint8 aValue) +Store a new value in an 8 bit register. + + +AsspRegister::Write16(TLinAddr aAddr, TUint16 aValue) +Store a new value in a 16 bit register. + + +AsspRegister::Write32(TLinAddr aAddr, TUint32 aValue) +Store a new value in a 32 bit register. + + +AsspRegister::Write64(TLinAddr aAddr, TUint64 aValue) +Store a new value in a 64 bit register. + + + +
+
Register +modify functions

The difference between write and modify +functions is that the modify function allows the client to change +partial contents of a register using masks.

+ + + +API +Description + + + + +AsspRegister::Modify8(TLinAddr aAddr, TUint8 aClearMask, +TUint8 aSetMask) +Modify the contents of an 8 bit register. + + +AsspRegister::Modify16(TLinAddr aAddr, TUint16 aClearMask, +TUint16 aSetMask) +Modify the contents of a 16 bit register. + + +AsspRegister::Modify32(TLinAddr aAddr, TUint32 aClearMask, +TUint32 aSetMask) +Modify the contents of a 32 bit register. + + +AsspRegister::Modify64(TLinAddr aAddr, TUint64 aClearMask, +TUint64 aSetMask) +Modify the contents of a 64 bit register + + + +

The header file for the Registry Access platform service +can be found here.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-8D9A9283-6E55-4AC8-89CE-DD2B55D05067.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-8D9A9283-6E55-4AC8-89CE-DD2B55D05067.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,20 @@ + + + + + +Time Technology GuideDescribes the technology involved in the Time platform +service. +
Real-time +clock

A real-time clock is a chip that keeps +track of elapsed time. It is more accurate and consumes less power +than computing time from elapsed execution cycles.

+
Alarms

The real-time clock can generate interrupts at specific times. +This provides a reliable alarm mechanism.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-8DC12024-7599-52E8-BCF1-D9D765EC7B9B.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-8DC12024-7599-52E8-BCF1-D9D765EC7B9B.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,12 @@ + + + + + +Dynamic BehaviourDescribes the behaviour of the Sound Driver for and record operations. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-8EB25927-D49E-578F-BD93-294C4EECB7E7.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-8EB25927-D49E-578F-BD93-294C4EECB7E7.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,809 @@ + + + + + +Basic +APIsAccessing APIs and basic functions in kernel-side programs. +

Device drivers, like user-side programs, need to use APIs for basic tasks +such as managing buffers and arrays. However, the EKA2 architecture does not +allow kernel-side programs such as drivers to link and use the User Library +(euser.dll) that provides these APIs to user-side programs. +This means kernel side code cannot use the majority of classes and +functions that are available to user side code.

+

However, some classes are available for use on both the user side and the +kernel side. The first section of this document, Available EUSER functionality, explains what these are. In other cases, +there are alternative Kernel-specific APIs or techniques that you can use. +The second section, Coding +techniques to replace EUSER functionality, describes these.

+

The detailed contents are given below:

+

Contents

+
    +
  • Available EUSER functionality

      +
    • 8-bit descriptors

    • +
    • Arrays

    • +
    • Character representation

    • +
    • Basic utility functions and classes

    • +
    • The Package Buffers API

    • +
    • The UID manipulation APIs

    • +
    • Version handling API

    • +
    • TRequestStatus

    • +
    • TIpcArgs

    • +
    • Basic graphic classes

    • +
  • +
  • Coding techniques to replace EUSER functionality

      +
    • Buffers: replacing HBufC8 with HBuf

    • +
    • Buffers: replacing HBufC8 with C style pointers

    • +
    • Handling 16-bit data items

    • +
    • Replacing CBase with DBase

    • +
    • Replacing User::QueryVersionSupported() with Kern::QueryVersionSupported()

    • +
  • +
+
Available EUSER +functionality

This is a list of USER side classes, types and APIs +that can still be used on the kernel side. However, a subset of the class +member functions may not be available.

    +
  • 8-bit descriptors

  • +
  • Arrays

  • +
  • Character representation (TChar)

  • +
  • Basic utility functions and classes

  • +
  • The Package Buffers API

  • +
  • The UID manipulation APIs

  • +
  • Version handling API

  • +
  • TRequestStatus

  • +
  • TIpcArgs

  • +
  • Basic graphic classes

  • +

8-bit descriptors

The +following classes, defined in e32des8.h, can be +used on the kernel side.

For some classes, the kernel side can use +the same member functions that are available to the user side. However, for +other classes, the kernel side is restricted to using a subset of functions; +where this is the case, the functions are listed

+ + + +

Classes available

+

Public member functions that are available to kernel side code

+
+ +

TDesC8

+

TInt operator<(const TDesC8 &aDes) const;

TInt +operator<=(const TDesC8 &aDes) const;

TInt +operator>(const TDesC8 &aDes) const;

TInt operator>=(const +TDesC8 &aDes) const;

TInt operator==(const +TDesC8 &aDes) const;

TInt operator!=(const +TDesC8 &aDes) const;

const TUint8 &operator[](TInt +anIndex) const;

TInt Length() const;

TInt +Size() const;

const TUint8 *Ptr() const;

TInt +Compare(const TDesC8 &aDes) const;

TInt Match(const +TDesC8 &aDes) const;

TInt MatchF(const TDesC8 +&aDes) const;

TInt MatchC(const TDesC8 &aDes) +const;

TInt Locate(TChar aChar) const;

TInt +LocateReverse(TChar aChar) const;

TInt Find(const +TDesC8 &aDes) const;

TInt Find(const TUint8 +*pS,TInt aLenS) const;

TPtrC8 Left(TInt aLength) +const;

TPtrC8 Right(TInt aLength) const;

TPtrC8 +Mid(TInt aPos) const;

TPtrC8 Mid(TInt aPos,TInt +aLength) const;

TInt CompareF(const TDesC8 &aDes) +const;

+
+ +

TDes8

+

TDes8& operator=(const TUint8 *aString);

TDes8& +operator=(const TDesC8 &aDes);

TDes8& operator=(const +TDes8 &aDes);

TInt MaxLength() const;

TInt +MaxSize() const;

const TUint8 &operator[](TInt +anIndex) const;

TUint8 &operator[](TInt anIndex);

TDes8 +&operator+=(const TDesC8 &aDes);

void Zero();

void +SetLength(TInt aLength);

void SetMax();

void +Copy(const TDesC8 &aDes);

void Copy(const TUint8 +*aBuf,TInt aLength);

void Copy(const TUint8 *aString);

void +Copy(const TDesC16 &aDes);

void Append(TChar +aChar);

void Append(const TDesC8 &aDes);

void +Append(const TDesC16 &aDes);

void Append(const +TUint8 *aBuf,TInt aLength);

void Fill(TChar aChar);

void +Fill(TChar aChar,TInt aLength);

void FillZ();

void +FillZ(TInt aLength);

void Num(TInt64 aVal);

void +Num(TUint64 aVal, TRadix aRadix);

void NumFixedWidth(TUint +aVal,TRadix aRadix,TInt aWidth);

void +AppendNum(TInt64 aVal);

void AppendNum(TUint64 +aVal, TRadix aRadix);

void AppendNumFixedWidth(TUint +aVal,TRadix aRadix,TInt aWidth);

+
+ +

TPtrC8

+

Same as for user side code.

+
+ +

TPtr8

+

Same as for user side code.

+
+ +

TBufC8

+

Same as for user side code.

+
+ +

TBuf8

+

Same as for user side code.

+
+ +

TDes8Overflow

+

Same as for user side code.

+
+ +

TLitC8

+

Same as for user side code.

+
+ + +

Arrays

The +following classes, defined in e32cmn.h, can be +used on the kernel side.

For some classes, the kernel side can use +the same member functions that are available to the user side. However, for +other classes, the kernel side is restricted to using a subset of functions; +where this is the case, the functions are listed

+ + + +

Classes available

+

Public member functions that are available to kernel side code

+
+ +

RArray <class T>

+

RArray();

RArray(TInt aGranularity);

RArray(TInt +aGranularity, TInt aKeyOffset);

RArray(TInt aMinGrowBy, +TInt aKeyOffset, TInt aFactor);

void +Close(); inline TInt Count() const;

const T& +operator[](TInt anIndex) const;

T& operator[](TInt +anIndex);

TInt Append(const T& anEntry);

TInt +Insert(const T& anEntry, TInt aPos);

void Remove(TInt +anIndex);

void Compress();

void +Reset();

TInt Find(const T& anEntry) const;

TInt +Find(const T& anEntry, TIdentityRelation<T> anIdentity) +const;

TInt FindInSignedKeyOrder(const T& anEntry) + const;

TInt FindInUnsignedKeyOrder(const +T& anEntry) const;

TInt +FindInOrder(const T& anEntry, TLinearOrder<T> +anOrder) const;

TInt FindInSignedKeyOrder(const +T& anEntry, TInt& anIndex) const;

TInt +FindInUnsignedKeyOrder(const T& anEntry, TInt& +anIndex) const;

TInt FindInOrder(const T& anEntry, +TInt& anIndex, TLinearOrder<T> anOrder) const;

TInt +SpecificFindInSignedKeyOrder(const T& anEntry, TInt +aMode) const;

TInt SpecificFindInUnsignedKeyOrder(const +T& anEntry, TInt aMode) const;

TInt +SpecificFindInOrder(const T& anEntry, TLinearOrder<T> +anOrder, TInt aMode) const;

TInt SpecificFindInSignedKeyOrder(const +T& anEntry, TInt& anIndex, TInt aMode) const;

TInt +SpecificFindInUnsignedKeyOrder(const T& anEntry, +TInt& anIndex, TInt aMode) const;

TInt SpecificFindInOrder(const +T& anEntry, TInt& anIndex, TLinearOrder<T> +anOrder, TInt aMode) const;

TInt InsertInSignedKeyOrder(const +T& anEntry);

TInt InsertInUnsignedKeyOrder(const +T& anEntry);

TInt InsertInOrder(const +T& anEntry, TLinearOrder<T> anOrder);

TInt +InsertInSignedKeyOrderAllowRepeats(const T& anEntry);

TInt +InsertInUnsignedKeyOrderAllowRepeats(const T& anEntry);

TInt +InsertInOrderAllowRepeats(const T& anEntry, TLinearOrder<T> +anOrder);

+
+ +

RArray <TInt>

+

RArray();

RArray(TInt aGranularity);

RArray(TInt +aMinGrowBy, TInt aFactor);

void Close();

TInt +Count() const;

const TInt& operator[](TInt +anIndex) const;

TInt& operator[](TInt anIndex);

TInt +Append(TInt anEntry);

TInt Insert(TInt anEntry, +TInt aPos);

void Remove(TInt anIndex);

void +Compress();

void Reset();

TInt +Find(TInt anEntry) const;

TInt FindInOrder(TInt +anEntry) const;

TInt FindInOrder(TInt anEntry, +TInt& anIndex) const;

TInt +SpecificFindInOrder(TInt anEntry, TInt aMode) const;

TInt +SpecificFindInOrder(TInt anEntry, TInt& anIndex, +TInt aMode) const;

TInt InsertInOrder(TInt anEntry);

TInt +InsertInOrderAllowRepeats(TInt anEntry);

+
+ +

RArray <TUint>

+

RArray();

RArray(TInt aGranularity);

RArray(TInt +aMinGrowBy, TInt aFactor);

void Close();

TInt +Count() const;

const TUint& operator[](TInt +anIndex) const;

TUint& operator[](TInt anIndex);

TInt +Append(TUint anEntry);

TInt Insert(TUint anEntry, +TInt aPos);

void Remove(TInt anIndex);

void +Compress();

void Reset();

TInt +Find(TUint anEntry) const;

TInt FindInOrder(TUint +anEntry) const;

TInt FindInOrder(TUint anEntry, +TInt& anIndex) const;

TInt +SpecificFindInOrder(TUint anEntry, TInt aMode) const;

TInt +SpecificFindInOrder(TUint anEntry, TInt& anIndex, +TInt aMode) const;

TInt InsertInOrder(TUint anEntry);

TInt +InsertInOrderAllowRepeats(TUint anEntry);

+
+ +

RPointerArray <class T>

+

RPointerArray();

RPointerArray(TInt +aGranularity);

RPointerArray(TInt aMinGrowBy, TInt +aFactor);

void Close();

TInt +Count() const;

T* const& operator[](TInt anIndex) +const;

T*& operator[](TInt anIndex);

TInt +Append(const T* anEntry);

TInt Insert(const T* +anEntry, TInt aPos);

void Remove(TInt anIndex);

void +Compress();

void Reset();

void +ResetAndDestroy();

TInt Find(const T* anEntry) +const;

TInt Find(const T* anEntry, TIdentityRelation<T> + anIdentity) const;

TInt FindInAddressOrder(const +T* anEntry) const;

TInt FindInOrder(const T* anEntry, +TLinearOrder<T> anOrder) const;

TInt +FindInAddressOrder(const T* anEntry, TInt& anIndex) +const;

TInt FindInOrder(const T* anEntry, TInt& +anIndex, TLinearOrder<T> anOrder) const;

TInt +SpecificFindInAddressOrder(const T* anEntry, TInt aMode) +const;);

TInt SpecificFindInOrder(const T* anEntry, + TLinearOrder<T> anOrder, TInt aMode) const;

TInt +SpecificFindInAddressOrder(const T* anEntry, TInt& +anIndex, TInt aMode) const;

TInt SpecificFindInOrder(const +T* anEntry, TInt& anIndex, TLinearOrder<T> anOrder, +TInt aMode) const;

TInt InsertInAddressOrder(const +T* anEntry);

TInt InsertInOrder(const T* anEntry, + TLinearOrder<T> anOrder);

TInt +InsertInAddressOrderAllowRepeats(const T* anEntry);

TInt +InsertInOrderAllowRepeats(const T* anEntry, TLinearOrder<T> +anOrder);

+
+ +

TIdentityRelation <class T>

+

Same as for user side code.

+
+ +

TLinearOrder <class T>

+

Same as for user side code.

+
+ + +

Character representation

The +following class, defined in e32cmn.h, can be used +on the kernel side.

For some classes, the kernel side can use the +same member functions that are available to the user side. However, for other +classes, the kernel side is restricted to using a subset of functions; where +this is the case, the functions are listed

+ + + +

Classes available

+

Public member functions that are available to kernel side code

+
+ +

TChar

+

TChar();

TChar(TUint aChar);

TChar& +operator-=(TUint aChar);

TChar& operator+=(TUint +aChar);

TChar operator-(TUint aChar);

TChar +operator+(TUint aChar);

operator TUint() const;

+
+ + +

Basic utility +functions and classes

The following global utility functions and +classes, defined in e32cmn.h, can be used on the +kernel side.

+ + + +

TRefByValue

+
+ +

TInt Lim(TInt aVal,TUint aLimit);

+
+ +

TInt LimX(TInt aVal,TUint aLimit);

+
+ +

template <class T> T Min(T aLeft,T aRight);

+
+ +

template <class T> T Min(T aLeft,TUint + aRight);

+
+ +

template <class T> T Max(T aLeft,T aRight);

+
+ +

template <class T> T Max(T aLeft,TUint + aRight);

+
+ +

template <class T> T Abs(T aVal);

+
+ +

template <class T> TBool Rng(T aMin,T aVal,T + aMax);

+
+ +

template <class T,class S> T* PtrAdd(T* aPtr,S + aVal);

+
+ +

template <class T,class S> T* PtrSub(T* aPtr,S + aVal);

+
+ +

template <class T> T Align2(T aValue);

+
+ +

template <class T> T Align4(T aValue);

+
+ + +

The Package +Buffers API

The package buffers API, represented by classes defined +in e32cmn.h, can be used on the kernel side.

+ + + +

TPckgBuf

+
+ +

TPckgC

+
+ +

TPckg

+
+ + +

The UID manipulation +APIs

The UID manipulation APIs, represented by classes defined +in e32cmn.h can be used on the kernel side. However, +only a subset of functions are available. See the detailed notes in +the following table.

+ + + +

TUid

+

Only the two inline functions can be used:

    +
  • TUid::Uid

  • +
  • TUid::Null()

  • +
+
+ +

TUidType

+

None of the member functions can be used; however, the iUid data +member is declared as public on the kernel side.

+
+ +

TUidName

+

This will only ever be an 8-bit type descriptor.

+
+ + +

Version handling +API

The version handling API, represented by the TVersion class +defined in e32cmn.h can be used on the kernel side.

TRequestStatus

The TRequestStatus class +representing the completion status of an asynchronous request, and defined +in e32cmn.h can be used on the kernel side.

TIpcArgs

The TIpcArgs class, which is part of the Version2 client/server APIs, +and defined in e32cmn.h, can be used on the kernel side. +However, the Set() and Type() member functions +that take 16-bit descriptors are not available.

Basic +graphic classes

The basic graphic classes TPoint and TSize are +defined on the kernel side. However, only the public data members are defined +- the member functions are not defined, and are not available for use.

+
Coding techniques +to replace EUSER functionality
    +
  • Buffers: replacing HBufC8 with HBuf

  • +
  • Buffers: replacing HBufC8 with C style pointers

  • +
  • Handling 16-bit data items

  • +
  • Replacing CBase with DBase

  • +
  • Replacing User::QueryVersionSupported() with Kern::QueryVersionSupported()

  • +

Buffers: replacing +HBufC8 with HBuf

In EKA2, the heap descriptor buffer, HBufC8 is +not available. However, the kernel side defines and implements an equivalent +(kernel) heap descriptor buffer: HBuf8. HBuf8 is +behaves in a similar way to HBufC8, so nearly all of your +code can be reused, but note the following points:

    +
  • If your code uses the +typedef HBufC, then you need to change it to HBuf.

  • +
  • On the kernel side, +there is no explicit support for 16-bit buffers, which means that there is +no class called HBuf16. In practice, this means that, HBuf is +always the same as HBuf8.

  • +
  • Unlike HBufC8, HBuf8 is +a modifiable type descriptor. It has TDes8 in its derivation +hierarchy, and this means that you can manipulate the descriptor's data (using +the TDes8 member functions).

  • +
  • The number of functions +available to create an HBuf8 object is more limited than +for HBufC8 - there are only three variants - although in +practice this is not a problem:

      +
    • HBuf8::New(TInt +aMaxLength) to allocate a heap descriptor buffer (on the kernel heap) +and set its length to zero; this behaves the same as the user side HBufC8::New(TInt +aMaxLength)

    • +
    • HBuf8::New(const +TDesC8& aDes) to allocate a heap descriptor buffer (on the kernel +heap) and initialise it by copying an existing descriptor's data into it.

    • +
    • HBuf8::ReAlloc(TInt +aNewMax) to re-allocate (i.e. to resize) a heap descriptor buffer +(on the kernel heap); this behaves the same as the user side HBufC8::New(TInt +aMaxLength)

    • +
  • +
  • There are no "leaving" +variants of these functions - if you have NewL(), NewLC(), and other "leaving" +variants, then you will need to change your code to explicitly check the return +code to make sure that the creation, or the reallocation of the heap descriptor +buffer has worked.

  • +
  • As the descriptor is +modifiable, there is no need for, and there is no equivalent of the function HBufC8::Des(); +you just use the base class TDes8 functions.

  • +
  • If your code uses the +assignment operators (i.e. the = operator), you don't need +to change your code; the compiler will use the operators implemented in the TDes8 base +class, which will do the right thing.

  • +
  • The descriptor function TDesC8::Alloc() is +no longer available on the kernel side, so you cannot create a heap descriptor +buffer from a general descriptor.

  • +

The following code fragments show code that is approximately equivalent +between EKA1 and EKA2. The fragments are a little artificial, and make assumptions +that would not necessarily be made in real code, but nevertheless still show +the essential differences.

+ + + +

EKA1

+

EKA2

+
+ +

This is a function that allocates a heap descriptor buffer (HBufC8), +puts data into it, changes its size, replaces the data, deletes a part of +the data, and then deletes it.

_LIT8(KTxSmall,"abcdef"); +_LIT8(KTxBig,"ghijklmnopqrstuvwxyz"); + +void X::FunctionL() + { + // Create a buffer big enough to contain + // the text "abcdef". + // This uses the "leaving" variant, and leaves + // if there is insufficient memory. + HBufC8* pBuf = HBufC8::NewL(KTxSmall().Length()); + + // Copy the text "abcdedf" into it + *pBUf = KTxSmall; + + // Make the buffer bigger... + // ... and check that it worked OK + // Note that we are using the non-leaving version. + // We could use the leaving version, but we would + // need to handle the cleanup of pBuf + HBuf8* pNewBuf = pBuf->ReAlloc(KTxBig().Length());; + + if (pNewBuf) + { + pBuf = pNewBuf; + } + else + { + delete pBuf; + User::Leave(KErrNoMemory); + } + + // Replace content of the descriptor with + // the text "ghijkl......" + *pBuf = KTxBig; + + // Need to use the Des() function to create + // a modifiable descriptor before we can make + // changes to the text in the descriptor. + TPtr8 pDesPtr; + pDesPtr = pBuf->Des(); + + // Delete the 1st two characters. + PDesPtr.Delete(0,2) + + delete pBUf; + + return; + }
+

A similar function, but it uses HBuf8 instead.

_LIT8(KTxSmall,"abcdef"); +_LIT8(KTxBig,"ghijklmnopqrstuvwxyz"); + +TInt X::Function() + { + // Create a buffer big enough to contain + // the text "abcdef", and copy the text + // from its source into the buffer. + // + // You need to check explicitly that this + // has worked. + HBuf8* pBuf = HBuf8::New(KTxSmall); + if (!pBuf) + { + return KErrNoMemory; + } + + // Make the buffer bigger... + // .. and check that it worked OK + HBuf8* pNewBuf = pBuf->ReAlloc(KTxBig().Length()); + + if (pNewBuf) + { + pBuf = pNewBuf; + } + else + { + delete pBuf; + return KErrNoMemory; + } + + // You can still use the =operator to replace + // the content of the heap descriptor ! + // Replace content with + // the text "ghijkl......" + *pBuf = KTxBig; + + + // Can now use use the TDes8 functions + // directly. + // This deletes the 1st two characters. + pBuf->Delete(0,2); + + // delete the heap descriptor + delete pBUf; + + return KErrNone; + }
+
+ +

A small code fragment that uses TDesC8::Alloc() to +create an HBufC8 heap descriptor buffer from an existing +descriptor.

HBufC8* X::Function(const TDesC8& aDes) + { + // Returns NULL if creation + // of the heap descriptor buffer fails. + + return aDes.Alloc(); + }

or possibly:

HBufC8* X::FunctionL(const TDesC8& aDes) + { + // Leaves if creation of the heap + // descriptor buffer fails, otherwise it + // returns a valid pointer. + + return(aDes.AllocL()); + }
+

An equivalent code fragment that creates an HBuf8 heap +descriptor buffer.

HBuf8* X::Function(const TDesC8& aDes) + { + // Returns NULL if creation + // of the heap descriptor buffer fails. + + return (HBuf8::New(aDes)); + }
+
+ + +

Buffers: replacing +HBufC8 with C style pointers

Instead of replacing HBufC8 with HBuf, +it may be more suitable to replace your heap descriptor buffers with C style +pointers - effectively managing your buffers in open code or as part of the +implementation of your own purpose written classes.

You allocate memory +from the kernel heap using Kern::Alloc() or Kern::AllocZ() and +track the pointers to that memory. The following code fragments show how the +use of HBufC8 translates to the direct use of these functions.

Although +the EKA2 code here uses memcpy(), and memmove(), +you will also find the functions memclr(), memset(), wordmove() and memcompare() useful in your code.

+ + + +

EKA1

+

EKA2

+
+ +

This is a function that allocates a heap descriptor buffer (HBufC8), +puts data into it, changes its size, replaces the data, deletes a part of +the data, and then deletes the whole buffer.

_LIT8(KTxSmall,"abcdef"); +_LIT8(KTxBig,"ghijklmnopqrstuvwxyz"); + +void X::FunctionL() + { + // Create a buffer big enough to contain + // the text "abcdef". + // This uses the "leaving" variant, and leaves + // if there is insufficient memory. + HBufC8* pBuf = HBufC8::NewL(KTxSmall().Length()); + + // Copy the text "abcdedf" into it + *pBUf = KTxSmall; + + // Make the buffer bigger... + // ... and check that it worked OK + // Note that we are using the non-leaving version. + // We could use the leaving version, but we would + // need to handle the cleanup of pBuf + HBuf8* pNewBuf = pBuf->ReAlloc(KTxBig().Length());; + + if (pNewBuf) + { + pBuf = pNewBuf; + } + else + { + delete pBuf; + User::Leave(KErrNoMemory); + } + + // Replace content of the descriptor with + // the text "ghijkl......" + *pBuf = KTxBig; + + // Need to use the Des() function to create + // a modifiable descriptor before we can make + // changes to the text in the descriptor. + TPtr8 pDesPtr; + pDesPtr = pBuf->Des(); + + // Delete the 1st two characters. + PDesPtr.Delete(0,2) + + delete pBUf; + + return; + }
+

A similar function, but allocates memory on the kernel heap explicitly, +and manages its own pointers instead. Note the use of the nanokernel utility +function: memcpy(), and memmove()

_LIT8(KTxSmall,"abcdef"); +_LIT8(KTxBig,"ghijklmnopqrstuvwxyz"); + +TInt X::Function() + { + // Create a buffer big enough to contain + // the text "abcdef", and copy the text + // from its source into the buffer. + // + // Steps. + // 1. work out the size of buffer needed + // 2. Get the buffer. + // 3. Copy the source. + + TInt lengthInBuffer = 0; + + // 1. + TInt Smallsize; + SmallSize = KTxSmall().Length(); + lengthInBuffer = SmallSize; + + // 2. + TUint8* pBuf; + pBuf = Kern::Alloc(SmallSize); + if (!pBuf) + { + return KErrNoMemory; + } + + // 3. + memcpy(pBuf,KTxSmall().Ptr(),SmallSize)); + + + // Make the buffer bigger. + // If it works ok, then copy the data + // to the new buffer, delete the old buffer + TInt BiggerSize; + TUint8* pNewBuf; + + BiggerSize = KTxBig().Length(); + pNewBuf = Kern::Alloc(BiggerSize); + if (pNewBuf) + { + memcpy(pNewBuf, pBuf, SmallSize); + Kern::Free(pBuf); + pBuf = pNewBuf; + } + else + { + Kern::Free(pBuf); + return KErrNoMemory; + } + lengthInBuffer = BiggerSize; + + // Replace content with + // the text "ghijkl......" + memcpy(pNewBuf, KTxBig().Ptr(), BiggerSize); + + + // Delete 1st two characters + memmove(pNewBuf, pNewBuf+2, lengthInBuffer; + lengthInBuffer -= 2; + + Kern::Free(pBuf); + + return KErrNone; + }
+
+ + +

Handling 16-bit +data items

If you need to handle 16-bit items on the kernel side, +then you can still use 8-bit heap descriptor buffers. You just need to be +aware that the data is 16 bit and cast accordingly. The following code fragments +are simplistic, but show you the basic idea.

+ + + +

EKA1

+

EKA2

+
+ +

This is a function which is passed a 16-bit descriptor containing +16-bit wide characters.

void X::FunctionL(const TDes16& aDes) + { + HBuf16* pBuf = aDes.AllocL(); + + TInt noOfCharacters; + TUint16* pointerToData; + + noOfCharacters = pBuf->Length(); + pointerToData = pBuf->Ptr(); + + ... + }
+

This is a similar function which is also passed 16-bit wide characters. +The function needs slight changes as it can only receive data through an 8-bit +descriptor.

TInt X::Function(const TDes8& aDes) + { + HBuf8* pBuf = HBuf8::New(aDes); + if (!pBuf) + { + return KErrNoMemory; + } + + TInt noOfCharacters; + TUint16* pointerToData; + + noOfCharacters = ((pBuf->Length()) >> 1); + pointerToData = (TUint16*)(pBuf->Ptr()); + + ... + + return KErrNone; + }
+
+ + +

Replacing CBase +with DBase

The DBase class is the kernel-side +equivalent of the user-side CBase class. It provides zero-filling +of memory prior to object construction and a virtual destructor in a similar +way to CBase.

If you have a class derived from CBase, +then all you need to do is:

    +
  • change your class definition +so that it is derived from DBase.

  • +
  • Remember to include +the klib.h header file.

  • +

you should not need to do anything else.

One additional feature +provided by DBase that is not available in CBase is +the function DBase::AsyncDelete(). This allows you to delete +an instance of a DBase derived class asynchronously, and +is useful if you need to delete a DBase derived object +in time-critical code.

Internally, asynchronous deletion works by +placing the object to be deleted onto a queue, and then triggering a DFC, +which runs in the context of the supervisor thread. This means that only a +small amount of code is executed by your (the calling) thread, and the actual +deletion is done by the supervisor thread.

Its use is straightforward.

class DMyObject : public DBase + { + ... + } DMyObject pPtr; + ... + pPtr = new DMyObject; + ... + pPtr->AsyncDelete(); + ...

Replacing +User::QueryVersionSupported() with Kern::QueryVersionSupported()

User::QueryVersionSupported() is +replaced by Kern::QueryVersionSupported() on the kernel +side.

The parameters passed to these functions are the same, both +in type and meaning. The behaviour of both functions is also the same. This +means that all you need to do is replace User:: with Kern:: in +your code.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-8F78705E-CD82-5039-A7CB-7C963F7FBA83-master.png Binary file Adaptation/GUID-8F78705E-CD82-5039-A7CB-7C963F7FBA83-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-8F78705E-CD82-5039-A7CB-7C963F7FBA83_d0e69457_href.png Binary file Adaptation/GUID-8F78705E-CD82-5039-A7CB-7C963F7FBA83_d0e69457_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-8FA1B2B0-5842-4D5D-BD61-C2D79B56ADC6.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-8FA1B2B0-5842-4D5D-BD61-C2D79B56ADC6.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,25 @@ + + + + + +Interrupt Service Routine (ISR)This document describes interrupt service routines as used by device +drivers. +

An ISR is a static function that will be executed when an interrupt occurs +on the interrupt source bound to the ISR.

+// Interrupt service routines +static void UartIsr(TAny* aParam); + +

An ISR performs the actions necessary to service the event of the peripheral +that generated the interrupt and to remove the condition that caused it to +interrupt. It queues a DFC to do the required processing. It disables the +interrupts and FIQs on ARM, if required, to handle the interrupt, and enables +them before leaving. It can also disable the source of the interrupt that +it is servicing.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-904C9C5A-5FDB-5978-88CF-E30D6C0DBB61-master.png Binary file Adaptation/GUID-904C9C5A-5FDB-5978-88CF-E30D6C0DBB61-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-904C9C5A-5FDB-5978-88CF-E30D6C0DBB61_d0e8869_href.png Binary file Adaptation/GUID-904C9C5A-5FDB-5978-88CF-E30D6C0DBB61_d0e8869_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-90B5FDD9-7D59-5035-BF53-2B177655DCD6.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-90B5FDD9-7D59-5035-BF53-2B177655DCD6.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,119 @@ + + + + + +Migration +Tutorial: Demand Paging and Internal MMC CardsExplains how to change the MMC media driver for when demand paging +is used. +

Demand paging is a change made from Symbian platform v9.3 to how the Kernel +uses RAM and storage media. This topic

+

For general information on migrating media drivers, see Migration +Tutorial: Demand Paging and Media Drivers.

+
PSL changes

ROM and code paging can be enabled +for a Multi Media Card (MMC) provided the card is non-removable. Removing +a card would result in a kernel fault whenever the next page-in request is +issued.

As the MMC media driver is entirely generic, a way of returning +the paging related information contained in variantmedia.def to the +generic part of the MMC stack is required. This is achieved by modifying the +Platform Specific Layer (PSL) of the MMC stack to implement the DMMCStack::MDemandPagingInfo interface +method:

class DMMCStack : public Dbase + { +public: + // etc… + }; + +/** +Demand paging support +@see KInterfaceDemandPagingInfo +*/ + +class TDemandPagingInfo + { +public: + const TInt* iPagingDriveList; + TInt iDriveCount; + TUint iPagingType; + TInt iReadShift; + TUint iNumPages; + TBool iWriteProtected; + TUint iSpare[3]; + }; + +class MDemandPagingInfo + { +public: + virtual TInt DemandPagingInfo(TDemandPagingInfo& aInfo) = 0; + // etc… + };

This example is taken from the H4 HRP VariantMedia.def changes:

// Variant parameters for the MMC Controller (EPBUSMMC.DLL) +#define MMC_DRIVECOUNT 1 +#define MMC_DRIVELIST 1 +#define MMC_NUMMEDIA 1 +#define MMC_DRIVENAME "MultiMediaCard0" + +#define MMC_PAGING_TYPE DPagingDevice::ERom | DPagingDevice::ECode +#define MMC_PAGEDRIVELIST 1 // code paging from User Data +#define MMC_PAGEDRIVECOUNT 1 +#define MMC_NUM_PAGES 8

This example is from H4 MMC +stack class definition:

class DDemandPagingInfo : public DMMCStack::MDemandPagingInfo + { +public: + virtual TInt DemandPagingInfo(DMMCStack::TDemandPagingInfo& aInfo); + }; + + +class DOmapMMCStack : public DCardStack + { +public: + virtual void GetInterface(TInterfaceId aInterfaceId, MInterface*& aInterfacePtr); + // etc… +private: + DDemandPagingInfo* iDemandPagingInfo; + // etc… + };

This example is from H4 MMC stack class implementation:

TInt DOmapMMCStack::Init() + { + if((iDemandPagingInfo = new DDemandPagingInfo()) == NULL) + return KErrNoMemory; + // etc… + } + +void DOmapMMCStack::GetInterface(TInterfaceId aInterfaceId, MInterface*& aInterfacePtr) + { + if (aInterfaceId == KInterfaceDemandPagingInfo) + aInterfacePtr = (DMMCStack::MInterface*) iDemandPagingInfo; + // etc… + } + +TInt DDemandPagingInfo::DemandPagingInfo(DMMCStack::TDemandPagingInfo& aDemandPagingInfo) + { + static const TInt pagingDriveNumbers[MMC_PAGEDRIVECOUNT] = {MMC_PAGEDRIVELIST}; + + aDemandPagingInfo.iPagingDriveList = pagingDriveNumbers; + aDemandPagingInfo.iDriveCount = MMC_PAGEDRIVECOUNT; + aDemandPagingInfo.iPagingType = MMC_PAGING_TYPE; + aDemandPagingInfo.iReadShift = 9; + aDemandPagingInfo.iNumPages = MMC_NUM_PAGES; + return KErrNone; + }
+
Preparing an internal MMC card for ROM paging - MMCLoader

To +support ROM paging from an internal card, the MMCLoader utility is used to +write the ROM image to the card. MMCLoader can be found in e32utils/mmcloader.

The +paged image is written as a normal file under the FAT file system. For paging +to work however, the images file’s clusters must all be contiguous so, before +doing anything else, MMCLoader formats the card. It then writes the paged +part of the ROM to a file and checks that the file’s clusters are contiguous, +which is normally the case as the card has just been formatted. A pointer +to the image file is stored in the boot sector. When the board is rebooted +the MMC/SD media driver reads the boot sector and uses this pointer to determine +where the image file starts so that it can begin to satisfy paging requests.

MMCLoader +takes the filename of the original ROM image file as an input. It then splits +the given file into unpaged and paged files. The following code fragment shows +the syntax:

Syntax: mmcloader <RomSrcFileName> <UnPagedRomDstFileName> <PagedRomDstFileName> +Eg: mmcloader z:\\core.img d:\\sys$rom.bin d:\\sys$rom.pag
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-9173EEBA-CC84-51D9-9C8D-A75F7F494D62-master.png Binary file Adaptation/GUID-9173EEBA-CC84-51D9-9C8D-A75F7F494D62-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-9173EEBA-CC84-51D9-9C8D-A75F7F494D62_d0e9004_href.png Binary file Adaptation/GUID-9173EEBA-CC84-51D9-9C8D-A75F7F494D62_d0e9004_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-91958EA5-9444-5895-B4B8-F2C670B81CD7-master.png Binary file Adaptation/GUID-91958EA5-9444-5895-B4B8-F2C670B81CD7-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-91958EA5-9444-5895-B4B8-F2C670B81CD7_d0e11017_href.png Binary file Adaptation/GUID-91958EA5-9444-5895-B4B8-F2C670B81CD7_d0e11017_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-919E48BE-6AA1-54CC-8B70-3A4B3A9C6CF1.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-919E48BE-6AA1-54CC-8B70-3A4B3A9C6CF1.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,65 @@ + + + + + +Writing +a Class Driver TutorialThis document set provides step-by-step instructions that will +enable a user to use the USB LDD interface to create a simple class driver. +

Before you start, +you must:

    +
  • Understand USB,

  • +
  • Understand Shared +Chunks.

  • +
+

It is recommended +that shared chunks are used for speed of transfer when transmitting a large +amount of data. This approach is not recommended when transmitting smaller +amounts of data infrequently.

Complete the tasks listed below to create +a class driver that + interfaces with the USB LDD using shared chunks. +

+ + + Load and Open +a USB Channel, + + + Set the Configuration +Descriptors, + + + Set the Interface +Descriptors, + + + Allocate Resources +for Endpoints - this task is optional, + + + Re-Enumerate, + + + Using the BIL +Interface - this task is optional, but recommended, + + + Read Data from +USB using Shared Chunks, + + + Write Data to +USB using Shared Chunks, + + + Close and Unload +the Driver. + + +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-921AF7A3-C711-5979-877B-4B6D977888E8-master.png Binary file Adaptation/GUID-921AF7A3-C711-5979-877B-4B6D977888E8-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-921AF7A3-C711-5979-877B-4B6D977888E8_d0e5006_href.png Binary file Adaptation/GUID-921AF7A3-C711-5979-877B-4B6D977888E8_d0e5006_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-922E4771-C1FD-5C88-9C11-57499684DB97.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-922E4771-C1FD-5C88-9C11-57499684DB97.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,80 @@ + + + + + +SPITOOL +

SPITOOL is a utility for creating static plug-in information (SPI) +files, which contain registration data for ROM-based plug-ins.

+

The tool is normally invoked by BUILDROM, +though it can be used independently (for example, for test purposes).

+
+
SPITOOL +command syntax spitool [options] files directories

The tool creates an SPI file by concatenating the specified input +files, using the options specified.

You can specify the input +files by specifying the full path to each file, or by specifying a +directory name, in which case all files from that directory are included.

options can be one or more of the following:

+ + + +

-t<SPIFileName>

+

<SPIFileName> is the name for the produced +SPI file (e.g. ecom.spi)

+
+ +

-d<TargetDir>

+

<TargetDir> is the directory where +the SPI file should be created. The directory name should end with +a \.

+
+ +

-i<Existing>

+

<Existing> is the path of an existing +SPI file to which to concatenate the specified input files.

If this option is used, then the specified file is used as a base +for the new output file. The output file will contain the contents +of the existing file with new input files appended. The location of +the output file is still specified using the -d and -t options.

+
+ +

-uid[1 | 2 | 3]=<UIDValue>

+

Specifies that input files should be filtered by their UID +values.

This option can be used multiple times, so a list +of valid UID1 values can be specified, and similarly for UID2 and +UID3 values. The UIDs of each input file are compared with this list, +and if a UID value matches a relevant value in the UID lists, then +that file is included in the SPI file. If the file does not match +any values, it is excluded.

Use 1, 2, or 3 in the option keyword +to specify to which of the three UIDs the filter should apply. <UIDValue> should be a UID value in decimal or hexadecimal +(0x....).

+
+ +

-existinguid[1 | 2 | 3]=<UIDValue>

+

Test that files concatenated in an existing SPI file use +the specified UID value. This allows the possibility of checking that +the correct type of files are being concatenated together.

Use 1, 2, or 3 in the option to specify to which of the three UIDs +the test should apply. <UIDValue> should be a +UID value in decimal or hexadecimal (0x....).

+
+ +

-existinguidcrc=<CRCValue>

+

Test that files concatenated in an existing SPI file use +the specified CRC checksum value. A file's CRC is generated from all +three of its UIDs.

<CRCValue> should +be a value in decimal or hexadecimal (0x....).

+
+ +

-hide <ResourceFileNames>

+

Marks a resource file as hidden in the SPI file.

<ResourceFileNames> is a list of resource file names separated +by a space or comma, which need to be marked as hidden in the SPI +file.

+
+ + +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-93DA75DE-096F-5E40-A47E-5A1A94C3145A.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-93DA75DE-096F-5E40-A47E-5A1A94C3145A.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,34 @@ + + + + + +Source Code OrganisationThis topic describes the Base Starter source code that +Symbian platform provides. + + + +

sf/os/kernelhwsrv/userlibandfileserver/fileserver/estart/estart.h

+

Header file containing the definition for the class TFSStartup, and other required structs, typedefs etc.

You do not make changes to the contents of this file.

+
+ +

sf/os/kernelhwsrv/userlibandfileserver/fileserver/estart/estart.cpp

+

Contains generic code and default versions of the TFSStartup virtual functions. This file also contains the +code involved in auto-detection.

You do not make changes +to the contents of this file.

See Use automatic local drive mapping.

+
+ +

sf/os/kernelhwsrv/userlibandfileserver/fileserver/estart/estartmain.cpp

+

Contains the entry point to the Base Starter. If you need +to customize the Base Starter, then you do it to a copy of +this file.

+
+ + +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-9573F7B9-76E9-5DCB-A498-C0DE59606911.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-9573F7B9-76E9-5DCB-A498-C0DE59606911.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,16 @@ + + + + + +ConceptsDescribes the technology, architecture, and behaviour of the MMC +Controller. +MMC Tutorials + + \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-9595FD6F-1EDE-51A8-B00D-029CFDFE0F38.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-9595FD6F-1EDE-51A8-B00D-029CFDFE0F38.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,40 @@ + + + + + +Boot TableDescribes the boot table. +

The boot table consists of a linear array of 4-byte entries whose index +positions are defined by the TBootTableEntry enumeration +in os/kernelhwsrv/kernel/eka/include/arm/bootdefs.h.

+

The entries in the array are divided into two groups, one whose index positions +are defined by the enumerator names BTF_* and the other group +defined by the enumerator names BTP_*.

+

Entries in the first group specify addresses of Boot +Table Functions.

+

Entries in the second group specify Boot +Table MMU Permission and Cache Attribute Definitions to be used for +certain standard memory and I/O areas.

+

A boot table entry is the offset of the function from the beginning of +the bootstrap code but, since the bootstrap is linked for a base address of +zero and is position independent, bare function addresses can be used.

+

Use DCD to place a function in the boot table, for example:

+DCD function-name +

In the Template port, available in os/kernelhwsrv/bsptemplate/asspandvariant/template_variant/bootstrap/template.s, +the boot table is defined by the label BootTable, followed +by DCD entries for every boot table function, like in the +following example:

+BootTable + DCD DoWriteC ; output a debug character + DCD GetRamBanks ; get list of RAM banks + DCD SetupRamBank ; set up a RAM bank + DCD GetRomBanks ; get list of ROM banks + DCD SetupRomBank ; set up a ROM bank + ... +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-9597DB22-D932-5A58-9C3C-4E5FCA244253.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-9597DB22-D932-5A58-9C3C-4E5FCA244253.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,14 @@ + + + + + +Re-Enumerate A short description of how to perform a Re-Enumeration.
Introduction

If any interface settings have been changed then a re-enumeration must be forced by calling RDevUsbcScClient::ReEnumerate(). A re-enumeration involves the device initiating a bus disconnection and re-connection.

Re-enumerate

ReEnumerate() is an asynchronous operation that completes when the controller is successfully configured by the host. Because it is not known if the operation has failed, set up a timer to complete after approximately 5 seconds. It can be assumed that if the operation has not completed in this time then it will not complete. When the request is completed status contains the result of the re-enumeration. See TRequestStatus.

TRequestStatus status; +gPort.ReEnumerate(status); +User::WaitForRequest(status);

If the re-enumeration has not completed within the expected time period then use RDevUsbcClient::ReEnumerateCancel() to cancel the request. Note: this function does not undo the re-enumeration.

If alternate interface settings have been set up enquire which interface has been selected following a re-enumeration by using RDevUsbcScClient::GetAlternateSetting().

After you have forced a re-enumeration you can use your USB class driver to Read Data from USB using Shared Chunks or Write Data to USB using Shared Chunks or if you wish to use the Buffer Interface Layer (recommended) then go to Using the BIL Interface.

\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-95A33491-17AC-4F12-948E-A1352ADDA483.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-95A33491-17AC-4F12-948E-A1352ADDA483.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,85 @@ + + + + + +DMA Implementation GuideExplains how to implement the DMA Platform Specific Layer +(PSL) for your platform. +

The DMA Framework is made of a PIL and a PSL. You have to write +a new Platform specific implementation code whenever your hardware +changes, but the PIL and the platform service API do not change.

+
Prerequisites

You should be familiar with the DMA Technology Guide and with the specifications of your hardware DMA controller.

+
Architecture

In the diagram below, the classes in green provide the platform +service API and the classes in blue implement the Platform-specific +functions (PSL).

+PSL class diagram + +
+
Implementation +files

The following table lists the important files of the +DMA Framework and what you should do with each of them. + + + +File +Usage + + + + +/os/kernelhwsrv/kernel/eka/include/drivers/dma.h +

This file is the main header file for DMA.

Include +it in the PSL implementation.

+
+ +/os/kernelhwsrv/kernel/eka/include/drivers/dma_v1.h +

This file contains the definitions of the PSL classes.

Refer to this file for the signature of the PSL functions.

+
+ +/os/kernelhwsrv/kernel/eka/drivers/dma/dmapil.cpp +This file is for information only: it contains the source code +for the generic implementation. + + +/os/kernelhwsrv/kernel/eka/drivers/dma/dma_lib.mmp +

This file is the MMP for the PIL.

Use it to build +the .LIB file for the PIL.

+
+ +/os/kernelhwsrv/bsptemplate/asspandvariant/template_assp/dmapsl.cpp +

This file contains the template code for the PSL implementation.

Copy it to your variant directory and modify it.

+
+ +/os/kernelhwsrv/bsptemplate/asspandvariant/template_assp/dma.mmp +

This file is the template MMP for the PSL implementation.

Copy it to your variant directory and modify it.

Use the +new file to build the DMA Framework (PIL and PSL).

+
+ + +

+
Implementation +process

To write the PSL for the DMA Framework, do the following:

    +
  1. Copy the template +listed in the above section to your own variant directory (at chip +level or at board level depending on where the DMA hardware is located).

  2. +
  3. Implement the DmaChannelMgr functions.

  4. +
  5. Derive the TDmac class and implement its controller-specific functions.

  6. +
  7. If necessary, +derive the TDmaChannel class or one of its sub-classes +to store channel-specific data.

  8. +
  9. Test the PSL +implementation.

  10. + +

+
+DMA +Client Interface Guide +DMA +Testing Guide +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-95BD3650-08CB-407D-969E-DFDB39B2FEFC.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-95BD3650-08CB-407D-969E-DFDB39B2FEFC.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,155 @@ + + + + + +What is a Platform Service?A platform service is an interface designed to make it +quick, easy and inexpensive to integrate hardware into a mobile device. +
Platform +Service

A platform service is a set of defined functionality, +usually providing an abstraction or encapsulation for functionality +provided by hardware.

For example, a platform service may provide +a standard interface for using a serial bus to send commands and data +between integrated circuits on the base board. Another example would +be providing a standard interface for Direct Memory Access (DMA) hardware +for moving blocks of data from one block of memory locations to another +or from a block of memory to a hardware device.

The platform +service separates the functionality required by kernel, device driver +and application processes from the specific hardware implementation. +This means, for example, that a device driver can be written for a +platform service that uses the published APIs, without needing to +know the specifics of the actual hardware device/chipset.

+Platform service + +

The platform service is a consistent hardware interface at +the bottom of the operating system platform software stack. In the +past much of the logic and configuration required to enable a new +piece of hardware was higher up in the operating system stack and +that made it difficult to support new or variant hardware. The platform +service architecture separates out the hardware specific interfaces +and encapsulates them behind a standard set of platform service (client +interface) APIs.

The platform service consists of :

    +
  • Client Interface/Platform service APIs

  • +
  • Implementation of the APIs:

      +
    • Platform Independent Layer (PIL)/Framework/Generic implementation

    • +
    • SHAI interface

    • +
    • Platform Specific Layer (PSL)/SHAI Implementation/Hardware +implementation

    • +
  • +

The PIL contains all the common functionality code such as +maintaining a list of available channels for communication or holding +the pending list of memory transfers to be processed by DMA when the +hardware becomes available. Usually the PIL provides the implementation +of the Client Interface APIs. This is sometimes referred to as the +Framework.

The interface between the framework code and the +PSL code is known as the Symbian Hardware Adaptation Interface (SHAI). +The SHAI interface specifies how the PIL and PSL talk to each other +(APIs, shared memory areas etc.)

The PSL consists of the specific +code required to work with a particular piece of hardware. This means +that supporting a new or variant chipset only requires the PSL to +be amended or to have detection code to handle a particular piece +of hardware.

Some Platform Services, such as GPIO, provide +APIs that directly address the hardware, and so the PSL provides the +client interface API implementation directly. For example, there is +no GPIO PIL/framework.

+
Variations +on platform service

Not all platform services are as simple +as the diagram above suggests. Some platform services do not talk +to hardware directly or at all, but provide a higher-level abstraction, +often with further low-level platform services below them in the OS +stack. For example, the Power Manager Policy platform service, provides +APIs to control power management policy, but does not interface with +any hardware directly. In these cases there is either no PSL, or the +PSL provides configuration specific responses to a generic PIL. For +example, if a handset can be built in two variants, one with a hardware +graphics accelerator and one without but with a software emulated +graphics accelerator, then the PSL would be responsible for directing +graphics requests either to the hardware, or to the software and returning +the results back through the PIL to the client.

Some plaftorm +services, for example TV-Out, may use additional platform services +to output sound as well as providing hardware support for the TV-Out +chipset.

Some platform services may share a piece of hardware, +such as a radio chip. The chip may provide cellular telephony, WiFi, +FM radio transmission and other features all on one chip, but there +may be several separate platform services, each exposing an API for +one particular technology.

Both the PIL and PSL may make calls +to other OS components, including other platform services, for information +such as Hardware Configuration, power status, and the availability +of other services.

+
Why +have a platform service

Platform services +benefit both device creators and third party hardware/chipset developers +since they specify a standard software interface between the operating +system and standard functionality provided by hardware.

This +means that it is possible for a device creator to easily integrate +the best hardware for their device, and allows hardware creators to +work to a standard interface that can be used across multiple devices +and multiple customers.

As the platform service interface provides +a consistent interface to functionality, it allows the device creator +to concentrate on the core functionality and not worry about how the +hardware will provide it. And since the interface is standard for +each type of hardware component, each manufacturer can provide the +information or code for the PSL comparatively easily for each additional +variant they produce. So this means less code required from hardware +manufacturers per hardware component, and a larger market as each +new mobile device, from any device creator, can use that compliant +hardware.

The platform services abstraction for hardware adaptation +also means more common code that can be shared across the Symbian +Foundation member community. This includes sharing PSL code with other +hardware providers, and sharing code for device drivers and other +higher-level components that need to use the platform services APIs. +For example, if a device driver for a particular piece of hardware +also needs to use a serial inter-IC bus (IIC) to send commands to +that hardware, then it can use the IIC platform service APIs and re-use +code that other components have already tested for using the IIC client +interface APIs.

Platform services also allow the use of standardized +test tools and test suites. Each new piece of hardware in a particular +category (for example, camera, Bluetooth radio) has to comply with +the SHAI interface (PIL/PSL interface). This means that an existing +test suite that works with another camera module can be used to test +that this new piece of hardware works. This reduces the time taken +for testing and increases speed to market.

+
Who +uses the Platform Service?
    +
  • Application developers, who need to use the functionality of +a hardware device, but do not need to know the specific details of +the hardware/hardware implementation. They use the client interface +and need to know what the APIs are, and what order they must be called +in and so on.

  • +
  • Framework developers, who need to know how to implement each +of the client interface APIs , and a description of the functionality +required within the framework.

  • +
  • Hardware Developers, who need to understand the hardware interface, +and have to write or update the hardware implementation (PSL) to support +their particular chipset/hardware.

  • +
+
Platform +service client interface APIs

In general these are function +calls, and associated enumerations. There are two main types of function +call:

    +
  • Synchronous

  • +
  • Asynchronous

  • +

A synchronous function call from the client/device-driver +waits for the platform service to process it and make any return value. +The client thread waits for the synchronous call to complete.

An asynchronous function call asks the platform service to do something, +but then execution of the client continues immediately. For example, +this would be the case of any function that starts a long data transmission +or receive process, such as streaming video. One of the standard components +of an asynchronous function call is a way for the result to be communicated +back to the client. Often this is done by a “callback function” where +the client specifies a pointer to a function (and parameters) during +the original call, and the platform service puts the callback on the +Delayed Function Call (DFC) queue for the client when the platform +service has completed the request. This may indicate “transfer completed” +or “transfer failed, error code 123”, it may release a lock or other +functionality defined by the author of the client.

+
+ +Symbian Foundation SHAI page +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-95CE7187-66B2-581A-A5B8-6359AD431E87.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-95CE7187-66B2-581A-A5B8-6359AD431E87.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,16 @@ + + + + + +ReferenceSummary of file formats, tools command line syntax, and related +documentation for the User-Side Hardware Abstraction (HAL) component. +API Reference: +User-Side Hardware Abstraction + \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-970EC5A9-8ED3-53C5-93A3-2EC1A7B6F25F-master.png Binary file Adaptation/GUID-970EC5A9-8ED3-53C5-93A3-2EC1A7B6F25F-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-970EC5A9-8ED3-53C5-93A3-2EC1A7B6F25F_d0e13980_href.png Binary file Adaptation/GUID-970EC5A9-8ED3-53C5-93A3-2EC1A7B6F25F_d0e13980_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-97F97D7B-D5A3-5471-A359-77B805ED198C.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-97F97D7B-D5A3-5471-A359-77B805ED198C.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,44 @@ + + + + + +DesignDescribes different modes of operations of the DMA Framework . +

Some DMA controllers provide several modes of operation. For example, one +ASSP provides both single-buffer mode and scatter-gather mode transfers.

+

There are two options:

+
    +
  • Select a single mode +of operation.

  • +
  • Select a multiple mode +of operation, and split the physical DMA controller into several logical controllers, +one for each mode to be supported. If this option is chosen, the PSL must +include one concrete controller class per logical controller; a controller +class is derived from TDmac.

    If the DMA controller +supports more than one mode of operation, implement the simplest one first. +Implementing single-buffer mode first allows most of the the PSL (platform-specific +layer) to be debugged before you start to implement the more complex scatter-gather +functionality.

  • +
+

One reference implementation adopts a mixed strategy; the mode of operation +is selectable at build-time by defining the macro __DESFETCHMODE__ to +exercise and demonstrate two different modes of operation.

+

Scatter-gather support is essentially a superset of single-buffer support +because a scatter-gather list is an ordered set of variable sized buffers, +and means that code shown here demonstrates the implementation of a scatter-gather +DMA controller.

+

Almost all modern MCUs use scatter-gather capable DMA controllers. Note +that we refer to descriptor fetch mode synonymously with scatter-gather mode, +as scatter-gather is implemented by passing the DMA controller a linked list +of descriptors describing the buffers to be transferred. Non–descriptor mode +requires that the DMA controller registers are programmed by software to describe +the buffer transfer required. Since each transfer must be handled by an interrupt +service routine triggered when the DMA controller has completed the transfer, +non-descriptor mode is not capable of performing transfers past buffer boundaries.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-98210124-0B65-4679-BB3A-E94B9999365C.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-98210124-0B65-4679-BB3A-E94B9999365C.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,143 @@ + + + + + +IIC Client Interface GuideThis document explains how to use the IIC client interface +API. +
Introduction

This guide describes how to use the IIC client interface API.

+
Channels

In this document, a channel is a multi-wire bus with a two or +more devices connected to it. At least one of the devices can act +as the master.

+
Modes +of operation

There are three possible modes that a device +can be in as regards to the IIC client interface API (regardless of +the underlying two-wire bus that is being used ):

+ + + +

Mode

+

Description

+
+ + + +

Master

+

The device is responsible for initializing and terminating +the data transfer.

+
+ +

Slave

+

The device carries out the transfer initialized by a another +device acting as a master.

+
+ +

MasterSlave

+

The device can perform both master and slave roles.

+
+ + +
+
Transactions

A single exchange of data in one direction is known as a transfer.

A list of transfers is known as a transaction.

Transactions +can be performed in half-duplex, or , full-duplex (if the underlying +bus supports it).

+
Transaction +preamble

In certain instances, some pre-processing might +be required by the devices before a transaction can occur.

This +can be done by the transaction preamble functionality, which executes +immediately before the transaction is performed. This takes the form +of a function.

the following restrictions apply to this +function:

    +
  • No spin locks are to be used.

  • +
  • There are no block or waiting on a fast mutex operations.

  • +
  • There are no calls to code that either uses spin locks, waits +or blocks a fast mutex.

  • +

This is for a device that is in master mode.

+
Extended +transactions

This is where a number of separate transactions +are linked together. It is used, for example, in situations where +it is not known in advance how big the transaction will be.

This is for a device that is in master mode.

+
Controller +and controller-less operation

Added to the above functionality, +the IIC platform service API has two modes of operation:

    +
  • With-controller and

  • +
  • Controller-less

  • +

Controller operation is used in a situation where multiple +device drivers can communicate with multiple channels. In controller-less +operation, the link between a device driver and a channel is fixed.

In controller-less operation, the mode of the channel is set at +build time, buy using the following macros in the relevant mmp files:

+ + + +

Macro

+

Description

+
+ + + +

MASTER_MODE

+

Specifies that the device is to act as a master.

+
+ +

SLAVE_MODE

+

Specifies that the device is to act as a slave.

+
+ + +
+IIC with-controller operation + + +IIC controller-less operation + +
+
Interface +classes

The class that is used for the client interface +depends on whether the IIC controller is to be used or not.

If the IIC Controller is to be used, then the client interface API +class is:

+ + + +

Name

+

Description

+
+ + + +

IicBus

+

Client interface API for the IIC component.

+
+ + +

If the IIC controller is not to be used, then the client +interface API classes are:

+ + + +

Name

+

Description

+
+ + + +

DIicBusChannelMaster

+

Client interface API for the master channel operation.

+
+ +

DIicBusChannelSlave

+

Client interface API for the slave channel operation.

+
+ +

DIicBusChannelMasterSlave

+

Client interface API for the master slave channel operation.

+
+ + +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-984C2A0D-36BE-5A99-9D65-3F8791C669FF.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-984C2A0D-36BE-5A99-9D65-3F8791C669FF.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,65 @@ + + + + + +ASSP/Variant ArchitectureA base port must provide a software layer called the ASSP/Variant. +

The ASSP/Variant layer provides two main functions. First, it implements +a small number of hardware-specific functions that are used by the +Kernel. Second, it implements common peripheral control functions +that other extensions and device drivers can use.

+

The most important +of these functions is interrupt dispatching. During initialisation +the ASSP/Variant must specify a dispatch function to be called for +all hardware interrupts.

+

In general, the ASSP/Variant provides control functions for hardware +which is shared between multiple devices. For example it is often +not possible to do a read-modify-write on a GPIO port in order to +change the state of an individual output line. This may be either +because an output port register is write-only or because reading the +port register reads the actual logic levels on the pins, not the last +value written to the register, and the pin level typically lags the +written value due to capacitive loading. In this case, the ASSP/Variant +could provide a function to set and clear individual port bits, keeping +a RAM copy of the last value written to the port register.

+

The simplest implementation is put all the code in a single DLL, +called the Variant DLL (ecust.dll). For hardware +architectures based on an ASSP, you can allow multiple types of phones +that use the same ASSP to share the common code. To do this, the common +ASSP code is implemented in a kernel extension, and the Variant DLL +implements the code that is specific to the phone type.

+ + + +

In the Base Porting Guide, we refer to the ASSP layer and the Variant +Layer, where the ASSP layer contains the source code tailored to a +range of different microprocessors (e.g. ARM720/920/SA1/Xscale), and +the Variant layer contains the source code associated with off-chip +hardware (same CPU, different peripherals).

+

For example, the standard Symbian port for the template reference +board is split into a core layer (in directory ...\template_assp\...) and code specific to the template board (in directory ...\template_variant\...). The .mmp file for the ASSP layer is ...\template_assp\katemplate.mmp, and the .mmp file for the Variant layer is ...\template_variant\vtemplate.mmp.

+
The +Asic class

The heart of the ASSP/Variant is the Asic class, defined in ..\e32\include\kernel\arm\assp.h. This is a class that contains a number of pure virtual functions +that must be implemented.

Where there is an ASSP/Variant split, +the ASSP layer should derive a concrete implementation from the Asic class. The most convenient way of implementing the +Variant layer is to further derive from this ASSP class. Only the +Variant DLL is declared as ‘variant’ in the ROM – the ASSP is declared +as an extension. If there is no ASSP/Variant split, then the Variant +is simply a concrete implementation of the Asic class.

The ASSP layer can, itself, define additional functions +to be implemented in the Variant layer. For example, the ASSP layer +defines the pure virtual function VideoRamSize() which +the Variant layer provides to map the video frame buffer.

The template reference board port has the ASSP/Variant split. The +ASSP layer is implemented by the TemplateAssp class, +and the Variant layer is implemented by the Template class.

For reference: the template port ASSP layer implementation's .mmp file is at ...\template_assp\katemplate.mmp, and the Variant layer implementation's .mmp file is at ...\template_variant\vtemplate.mmp.

Note that one of the source files that forms the ASSP layer +must have the DECLARE_STANDARD_ASSP() declaration. +See ...\template_assp\assp.cpp.

+
+Asic +Class Tutorial +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-99637158-DE86-4BB4-98D4-3A3E64AB768F-master.png Binary file Adaptation/GUID-99637158-DE86-4BB4-98D4-3A3E64AB768F-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-99637158-DE86-4BB4-98D4-3A3E64AB768F_d0e87314_href.png Binary file Adaptation/GUID-99637158-DE86-4BB4-98D4-3A3E64AB768F_d0e87314_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-9986DCC6-EE73-59FB-BDAC-9B09DC64FBCE.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-9986DCC6-EE73-59FB-BDAC-9B09DC64FBCE.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,84 @@ + + + + + +Client of Master Channel TutorialDescribes a simple implementation of a client using the +master channel functionality. +

This document describes a simple implementation of an IIC client +using the master channel functionality.

+
Purpose

This tutorial explains how to use the IIC platform service API +as a master and to communicate with a peripheral using half-duplex.

Intended Audience

Device driver writers.

Required Background

Before you start, you must:

    +
  • Have installed +the platform specific implementation of IIC channels that is required +to support the IIC platform service API.

  • +
  • Include the IIC.dll in the kernel.iby file.

  • +
  • Include the iic.h and iic_channel.h header files.

  • +

The code example fragments are for synchronous operation. +For asynchronous operation, the buffers must be allocated on the heap.

+
Implementing +the IIC platform service

The Following tasks will be covered +in this tutorial:

    +
  • Performing read/write +operations.

  • +

Basic Procedure

The implementation +on which the following code examples are based is implemented IIC +via a SPI bus. On hardware with dedicated IIC ports, the IIC port +would be specified and the header data type would be TConfigIICV01.

The high level steps to performing read/write operations are +shown here:

    +
  1. First set the +bus type, the channel number and the slave address.

    An example +of this is :

    // Configure the port. + busId.SetBusType(DIicBusChannel::ESpi); // Specify which multi-wire bus is to be used. in this example, SPI. + busId.SetChanNum(0); // Set the channel number. + busId.SetSlaveAddr(13); // Set the slave address.
  2. +
  3. Configure the +channel.

    An example of which, is :

    // create header - this configures a SPI port. + const TConfigSpiV01 TestHeader = + { + ESpiWordWidth_8, // Set the word width. In this example, 8 bits. + 260000, // Set the clock speed of the port. In this example, 260KHz. + ESpiPolarityLowRisingEdge, // Set the clock mode value. In this example, Active high, odd edges. + 500, // Set the timeout period. In this example, 500msec. + EBigEndian, // Set which endian is to be used. In this example, BigEndian is used. + EMsbFirst, // Set which bit order is to be used. In this example, the Msb is first. + 0, // Set the number of transaction wait cycles. In this example, 0. + ESpiCSPinActiveLow // Set the Chip select active mode. In this example, chip select is active low. + };
  4. +
  5. Make linked +lists of the transfers that are to be carried out.

    An example +of this is :

    // Set the transaction header. + TPckgBuf<TConfigSpiV01> header(TestHeader); + + // Set up a transmit transaction. + // This txTransfer buffer acts as the start of the transaction linked list. + TIicBusTransfer txTransfer(TIicBusTransfer::EMasterWrite, 8, &txTransferBuf); + + // Set up a receive transaction. + TIicBusTransfer rxTransfer(TIicBusTransfer::EMasterRead, 8, &rxTransferBuf); + + // Add to the receive transaction to the transaction linked list. + txTransfer.LinkAfter(&rxTransfer); + + // Create a transaction using header and the transaction linked list. + TIicBusTransaction transaction(&header, &txTransfer);
  6. +
  7. Use the IicBus::QueueTransaction() method, specifying the configuration +of the port and the start location of the transaction linked lists. +This queues the transactions on to the selected IIC channel.

    An example of this is :

    // Queue the transaction. + // Once this command has been executed, the value of r should be KErrNone. + r = IicBus::QueueTransaction(busId.GetConfig(), &transaction);
  8. +
+
+Client + of Slave Channel Tutorial +IIC +Concepts +I2C +Technology Guide +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-99C4FCCC-9E8B-51CC-85F8-F03BE18DF19E-master.png Binary file Adaptation/GUID-99C4FCCC-9E8B-51CC-85F8-F03BE18DF19E-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-99C4FCCC-9E8B-51CC-85F8-F03BE18DF19E_d0e82580_href.png Binary file Adaptation/GUID-99C4FCCC-9E8B-51CC-85F8-F03BE18DF19E_d0e82580_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-99F7E70F-2733-57B2-94F5-A0C0FF9219FE-master.png Binary file Adaptation/GUID-99F7E70F-2733-57B2-94F5-A0C0FF9219FE-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-99F7E70F-2733-57B2-94F5-A0C0FF9219FE_d0e10765_href.png Binary file Adaptation/GUID-99F7E70F-2733-57B2-94F5-A0C0FF9219FE_d0e10765_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-99FC067C-0AED-5373-AF63-8DB7FF5C1F7E.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-99FC067C-0AED-5373-AF63-8DB7FF5C1F7E.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,69 @@ + + + + + +SPI Technology GuideThis document describes the Serial Peripheral Interface +(SPI) technology. The SPI devices are used for fast data exchange +between two or more peripherals. + +
Introduction

The SPI is a synchronous serial interface. The SPI supports full +duplex communication channel for the devices that use SPI interface. +The devices and peripherals that use the SPI interface are described +as SPI devices in this document.

+
Architecture

In the SPI bus one of the node must be a master device and one +or more slave devices. There can be only one slave active at a time. +The master device initiates and terminates communication between the +SPI devices. The SPI is a full duplex serial data communication. In +full duplex communication the data can be transferred between the +master and the slave devices simultaneously.

The SPI devices +can be configured as master or slave. The SPI bus contain four wires. +The first one is the serial clock signal sent by the master device +to the slave device. The clock signal is used for synchronisation. +The Master Output / Slave Input (MOSI) is used to +send data from the master to the slave. The Slave Output / Master +Input (SOMI) is used by the master device to read +data from the slave device. The fourth line is the Slave Select (SS) that is used by the master to select a slave to initiate +the communication.

+ SPI Bus + +
+
Communication

The master device is the node on the SPI bus that initiates and +terminates the communication. The master must provide the configuration +to the slave devices. The configuration includes the details like +the channel number and the data length. The SPI devices uses 4 and +8 bit words to communicate. If a slave device or a channel is not +available the appropriate error is returned to the master.

+
Advantages

The following are the advantages of the SPI interface:

    +
  • Full duplex +synchronous communication

  • +
  • Low power requirements +compared to the I2C devices

  • +
  • Less space compared +to the parallel bus

  • +
  • Slave devices +do not require unique address assigned

  • +
+
SPI +devices

Typically the SPI devices are used for data transfers +where a delay in the time taken to send the data is acceptable. The +clients of the SPI interface are device drivers running on the application +specific integrated circuits (ASIC). Some of the peripherals that +use SPI interface are:

    +
  • Touch screens

  • +
  • Codecs

  • +
  • Real Time Clocks

  • +
  • Built-in cameras

  • +
  • Flash memory +like MMC and SD cards

  • +
+
+IIC +Concepts +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-9AE254D4-AA60-579E-8D9D-F2797106A413.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-9AE254D4-AA60-579E-8D9D-F2797106A413.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,228 @@ + + + + + +User-Side +Hardware Abstraction TechnologyDescription of HAL types and interfaces. +

The User-Side Hardware Abstraction (HAL) component provides a platform-independent +way to access and control many device specific features, and to hide hardware-specific +functionality. For example, HAL can be used to find out if a screen backlight +is present or not, or to set the display contrast. This topic

+
Attributes

Specific +items of hardware related information are referred to as attributes. +Symbian platform defines two types of attribute:

    +
  • Non-derived attribute. +This is an attribute where the information it represent is simply a value +that is stored in, and retrieved from, the HAL.

  • +
  • Derived attribute. This +is an attribute that requires a software call to obtain and set its value. +The software component is, ultimately provided by a driver, kernel extension +or by the kernel itself. The drivers or kernel extensions normally need porting.

  • +

Attributes are identified by the enumeration values of the enumerator HALData::TAttribute defined +in ...\hal\inc\hal_data.h and is exported to ...\epoc32\include\.

To +maintain backwards compatibility, the numbers identifying HAL attributes are +allocated strictly increasing consecutive values, and that a given HAL attribute +always has the same enumeration number on all implementations of Symbian platform. +This means that new HAL attributes can only be added by Symbian. This also +means that the addition of custom HAL attributes is not possible.

+
User-side interface

Symbian +platform provides the following static functions to get and set information +about specific hardware features:

    +
  • HAL::Get()

  • +
  • HAL::Set()

  • +
  • HAL::GetAll()

  • +

The HAL class is defined in the source tree header +file ...\hal\inc\hal.h, and is exported to ...\epoc32\include\. +The functions are exported from the HAL DLL, which is built as part of the +Variant.

Get() and Set() take an attribute to +identify specific hardware functionality.

GetAll(), +as its name implies gets all available hardware information, but is rarely +used. See Dealing +with the HAL::GetAll() function for more information.

Get() and Set() each +have a variation that allows a device number to be specified. The device number +allows more than one set of attributes to be used. Each set is associated +with a different device number. This is motivated by the need to support multiple +display screens where each screen is identified as a separate device of the +same 'type'. The idea of a device can be extended other hardware, and indeed +the underlying implementation assumes a device number. If a device number +is not specified and has no meaning, then a default device number of 0 is +assumed for compatibility with the underlying implementation.

For +example, on return from code such as:

... +TInt xpixels; +HAL::Get(EDisplayXPixels, xpixels); +...

xpixels contains the horizontal size +of the display screen in terms of the number of pixels. If you have more than +one screen, i.e. more than one device, then you would use the API variant +that takes a device number.

+
HAL handler +interface

A request for fetching and setting information about +hardware is dealt with by an entity called a HAL handler on the kernel side. +This section describes the types and concepts used to implement a HAL handler.

+
HAL groups and function-ids

It is useful to group +together requests for information about related hardware features so that +they can be dealt with by a single HAL handler. As an example, all the HAL +screen attributes are in the display group and are handled by the screen (i.e. +video or LCD) driver. This means that a HAL group has a one-to-one association +with a HAL handler.

A HAL group has an associated set of function-ids, +which identify requests for different pieces of information to the HAL handler.

Symbian +platform identifies HAL groups by a number defined by the THalFunctionGroup enum +in u32hal.h, which is exported to ...\epoc32\include. +For example, the EHalGroupDisplay enum value identifies +the group associated with the HAL screen attributes.

The function-ids +associated with each HAL group are also defined in u32hal.h. +Each set of function-ids is defined by an enum; for example the enum TDisplayHalFunction defines +the function-ids associated with the HAL group EHalGroupDisplay.

The +idea of the HAL group is what allows HAL handling functionality to be implemented +in the Variant, rather than in the kernel.

Up to 32 groups can be +defined. Often, a HAL group is concerned with mode settings for a particular +piece of hardware; for example there are standard HAL groups for keyboard, +digitiser and display. However, some groups are concerned with some overall +aspect of the platform which extends across all devices; for example, there +is a group to handle emulation parameters on emulator platforms.

An attribute maps +to a HAL group/function-id pair, although the mapping is not necessarily a +one-to-one relationship. For example, the calls:

TInt xPixels, yPixels; +... +HAL::Get(HALData::EDisplayXPixels,xPixels); +HAL::Get(HALData::EDisplayYPixels,yPixels); +...

both result in calls to the screen (i.e. video or LCD) +HAL handler, as represented by the HAL group number THalFunctionGroup::EHalGroupDisplay, +using the same function-id TDisplayHalFunction::EDisplayHalScreenInfo.

However, +there are HAL group/function-id pairs for which there are no corresponding +generic attributes. In these cases, the hardware attributes represented by +the HAL group/function-id pair are used internally, and can only be accessed +using the kernel side function Kern::HalFunction() **.

The +following picture shows the general idea:

+ +

**Technically, the user side function UserSvr::HalFunction() will +achieve the same thing, but this is internal to Symbian and is not +intended for general use.

+
HAL handler implementation

Most HAL handlers are +implemented as part of a driver, a kernel extension, the Variant or the kernel +itself. Some will need porting. See Groups +and the location of their HAL handlers.

An extension or a device +driver must register a handler for HAL group. It does so by calling Kern::AddHalEntry(), +specifying the group number. It is important to note that it is the extension +or driver's responsibility to do this; in other words, the kernel cannot know +what entity within a final ported Symbian platform is going to be the HAL +handler until it is explicitly told by registration. One point to note is +that the HAL handlers for the groups: EHalGroupKernel, EHalGroupVariant and EHalGroupPower are not explicitly registered - they are registered internally by the kernel +itself.

Internally, pointers to the HAL handler are stored in the +array K::HalFunction[], and this is indexed by the group +number.

On the template board, for example, the HAL handler for the +display group is part of the screen driver. The screen driver source can be +found in ...\template_variant\specific\lcd.cpp. The HAL +handler itself is the function:

LOCAL_C TInt halFunction(TAny* aPtr, TInt aFunction, TAny* a1, TAny* a2) + { + DLcdPowerHandler* pH=(DLcdPowerHandler*)aPtr; + return pH->HalFunction(aFunction,a1,a2); + }

The following code, implemented in the Create() function +of the main class, does the registration.

TInt DLcdPowerHandler::Create() + { + ... + // install the HAL function + r=Kern::AddHalEntry(EHalGroupDisplay,halFunction,this); + if (r!=KErrNone) + return r; + ... + }

Security is the responsibility of the HAL handler. If +necessary, it needs to check the capability of the caller's process. Each +information item, as identified by the function-id, can have an associated +capability.

Each function-id defined in u32hal.h is +documented with the required capability. If no capability is listed, then +no specific capability is required.

See Implementing +HAL handlers for details.

+
Kernel-side +interface

Code such as device drivers that runs on the kernel side +need not use the generic interface provided by the HAL class functions. The Kern::HalFunction() API +is provided to access HAL information.

Unlike the HAL class functions, Kern::HalFunction() uses +the group number and function-ids to identify hardware related information. +This means that kernel side code does not use attributes to identify hardware +related information. The implication here is that you may have to make +changes to your kernel side code when porting to another platform. In practice, +no changes may be needed, but at the very least you need to check.

+
Config and Values files define attributes

Although +an attribute is +generic, some attributes may not have meaning on some platforms. In addition, +each platform needs to define whether an attribute is either:

    +
  • non-derived, +i.e. has a value that is simply stored in the HAL,

  • +

or:

    +
  • derived, i.e. +requires a call to a software entity to get and set the value.

  • +

This is the role of the Config file.

The Config file +contains a list of all the attributes that have meaning on a platform, and +uses the symbols defined in the enum HALData::TAttribute to +identify them. Using a simple syntax, an attribute can be defined as being +derived by associating the attribute symbol with the name of a function. This +function is known as the accessor function.

There is also a +file known as the Values file that defines the initial values for all +of the non-derived attributes, i.e. those attributes that are simply stored +in, and retrieved from, the HAL.

The Config and Values files are text +files that, for a specific implementation of the HAL, reside in the ...\variant\hal directory. +The MMP file also resides there, and the HAL is built as part of the Variant. +As part of the build process, the Config and Values files are passed to a +Perl script, halcfg.pl, which translates the contents +into C++ source files. The resulting binaries are linked in as part of the +resulting HAL DLL.

In effect, these C++ source files implement the +static data arrays defined by the HalInternal class. As its +name suggests, this class is internal to Symbian platform, and is only +discussed here to help with understanding.

class HalInternal + { + ... + static const TUint8 Properties[HAL::ENumHalAttributes]; + ... + static const TInt InitialValue[HAL::ENumHalAttributes]; + static const THalImplementation Implementation[HAL::ENumHalAttributes]; + ... + }

The data member Implementation[] is +an array of pointers to the accessor functions

See Creating +the Config & Values files for detailed syntax.

+
Derived attributes require accessor functions

Each +derived attribute has a corresponding accessor function. For example, ProcessDisplayContrast().

All +accessor functions are implemented in ...\hal\src\userhal.cpp, +and are provided by Symbian platform because of the 'connection' to attributes +which are themselves defined as part of the generic platform.

Generally +there is one accessor function per derived attribute, although there is nothing +to prevent an accessor function dealing with more than one attribute. The +attribute number is used to route calls made to HAL::Get() and HAL::Set() forward +to the correct accessor function. Internally, Symbian platform routes calls +to Get() and Set() for an attribute to the same accessor function, distinguishing +between the two by a boolean value.

A new implementation of an accessor +function should rarely, if ever, be needed as all likely accessor functions +are already defined and implemented by Symbian platform in ...\hal\src\userhal.cpp.

See Writing accessor functions +for derived attributes.

+
Accessor functions call UserSvr::HalFunction()

Typically, +an accessor function implementation calls UserSvr::HalFunction(), +specifying a group number, as defined in THalFunctionGroup, +and a function-id that is related to the attribute, but is not the +attribute number as defined in TAttribute. Function numbers +are published in u32hal.h, and exported into ...\epoc32\include; +for example, the enumerators of the enum TDigitiserHalFunction.

This +means that it is the accessor function, which is part of Symbian platform +generic code, that decides which HAL handler is to deal with a request (as +identified by the attribute).

The kernel uses the HAL group number +as an index to dispatch the call to the correct HAL handler.

Note +that there may be cases where access to a HAL attribute may be handled through +a device driver or server.

+
UserSvr::HalFunction() calls ExecHandler::HalFunction()

The +static function UserSvr::HalFunction(), which is internal to +Symbian platform, is the user side point of access. It takes a HAL group to identify a set of related hardware features. In addition, +it takes a function-id to identify specific hardware functionality within +the HAL group, for example, one of the TDisplayHalFunction enumerators.

A +call to this function results in a call to the kernel side function exechandler::HalFunction(), +passing the group number and the function-id. This, in turn, finds the appropriate HAL +handler function in the internal array K::HalFunction[], +using the group number as the index.

UserSvr::HalFunction() is +exported from euser.dll, and is therefore accessible +from the user side. However, it is not intended for general third party +use.

For information purposes, the UserSvr class +is defined in the source tree header file ...\e32\include\e32svr.h, +which is exported to ...\epoc32\include\.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-9B52E0C3-9EBB-44C6-A1BF-2F95711FFBA4.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-9B52E0C3-9EBB-44C6-A1BF-2F95711FFBA4.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,32 @@ + + + + + +Template +Source CodeThis document discusses the template code from which device drivers +are created. +
Template +source code

To help enable a base port be produced quickly, +Symbian platform provides template source code for drivers for most peripherals. +The template implements a framework and protocols for the type of peripheral; +the base port implementer then supplies additional implementation for the +particular hardware device. For example, for the UART driver, the PDD template +implements the standard hardware abstraction interfaces for serial communication, +such as the DComm class. It leaves some sections marked as +"TBD", which are specific to the device. Driver developers can start with +these templates and fill in the "TBD" functions to create a basic driver. +If required, additional functionality can then be added to this.

The +template drivers are located in the sf\os\kernelhwsrv\bsptemplate\asspandvariant\template_variant source +directory. The template directory provides a variant +base port that includes all the drivers required to do the minimal base port +for any variant.

Details of the templates for particular drivers are +discussed in the relevant sections of the Base Porting Guide. This +tutorial presents an additional example device driver.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-9B66387C-B6CF-41D9-BEFC-F79E30C70F52.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-9B66387C-B6CF-41D9-BEFC-F79E30C70F52.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,17 @@ + + + + + +Interrupt Build GuideDescribes how to build Interrupt platform service +

The Interrupt platform service is implemented as a part of the +ASSP variant layer and hence included in the baseport. For more information, +refer to ROM +Building guides.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-9BBDFF77-5E2C-4E13-BEB3-716CC80B3375.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-9BBDFF77-5E2C-4E13-BEB3-716CC80B3375.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,71 @@ + + + + + +SDIO Implementation GuideHow to port the SDIO Controller for your platform to provide +the SDIO adaptation. +

The SDIO implementation shares most of its functionality with the +Secure Digital (SD) Controller, which in turn extends the MultiMedia +Card (MMC) Controller. SDIO adds support for data transfer between +Input/Output hardware included on SDIO peripherals. The SDIO Controller +initializes SDIO peripherals and provides an API so that class drivers +can access the SDIO services.

+

Providing an SDIO adaptation for your platform means porting the +SDIO Controller. This is done by providing platform specific implementations +of the SDIO SHAI interface functions.

+
Prerequisites

SDIO depends on SD and MMC: the SDIO protocol is a super-set of +the SD protocol (and of the MMC protocol). Therefore, in addition +to the SDIO standard, you need to know about the following:

    +
  • SD (Secure Digital)

  • +
  • MMC (MultiMedia Card)

  • +

+
Architecture

The following diagram illustrates the implementation of the SDIO +extension for the MMC Controller. The classes in green provide the +hardware interface and the classes in blue implement the platform-specific +functions.

+SDIO Controller classes + +
+
ImplementationThe Platform-Independent Layer (PIL) of the SDIO Controller is made +up from three sets of files described in the following table:

+ + + +Standard +Source code location + + + + +MMC +

os/kernelhwsrv/kernel/eka/drivers/pbus/mmc

See also Code Organization in the MMC section.

+
+ +SD +os/kernelhwsrv/kernel/eka/drivers/pbus/mmc/sdcard/sdcard3c/

Also see Source Code in the SD section.

+
+ +SDIO +os/kernelhwsrv/kernel/eka/drivers/pbus/mmc/sdcard/sdcard3c/sdio/ + + + +

The Platform-Specific Layer (PSL) should be located +in a variant directory and have a similar folder hierarchy to the +PIL. It should provide the following implementations:

    +
  • Stack

  • +
  • Power Supply Unit (PSU)

  • +
These implementations are discussed in the tutorials:
    +
  • SDIO +Stack Implementation Tutorial

  • +
  • SDIO +PSU Implementation Tutorial

  • +

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-9C05C157-D58E-4C43-87E4-82B4F310AEA9.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-9C05C157-D58E-4C43-87E4-82B4F310AEA9.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,50 @@ + + + + + +DmaChannelMgr ImplementationDescribes how to write the hardware-specific functions +of the DmaChannelMgr class. +

The DmaChannelMgr class is already defined in +the DMA header file but it belongs to the PSL implementation: opening +and closing channels require hardware-specific operations.

+

When implementing the PSL, you need to provide at least one function:TDmaChannel* DmaChannelMgr::Open(TUint32 aOpenId)

+

This function opens a DMA channel and returns the object controlling +this channel.

+

How the channel is allocated is hardware-dependent. The call to +the Open() function specifies which channel to open +through the aOpenId parameter. The format of the +parameter is not part of the DMA platform service and depends on an +agreement between the PSL implementation and the driver using DMA. +The example section below shows a static method, but the allocation +could also be completely or partially dynamic.

+

If you want to perform a hardware-specific operation when closing +the channel, you also need to update DmaChannelMgr::Close(). It is usually not necessary: in the template source code, it is +implemented as doing nothing.

+

+Open() example

This example illustrates +a simple allocation scheme where aOpenId represents +the index of the requested channel in the channel array (Controller.iChannels). +TDmaChannel* DmaChannelMgr::Open(TUint32 aOpenId) + { + __DMA_ASSERTA(aOpenId < static_cast<TUint32>(KChannelCount)); + TDmaChannel* pC = Controller.iChannels + aOpenId; + if (pC->IsOpened()) + pC = NULL; + else + { + pC->iController = &Controller; + pC->iPslId = aOpenId; + } + return pC; +}

+
+DMA +Client Interface Guide +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-9CC514E9-85C2-5F4B-9F3B-F9FA1F4CB20A-master.png Binary file Adaptation/GUID-9CC514E9-85C2-5F4B-9F3B-F9FA1F4CB20A-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-9CC514E9-85C2-5F4B-9F3B-F9FA1F4CB20A_d0e14358_href.png Binary file Adaptation/GUID-9CC514E9-85C2-5F4B-9F3B-F9FA1F4CB20A_d0e14358_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-9CF985F1-C100-5999-9410-58B7865A1E18.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-9CF985F1-C100-5999-9410-58B7865A1E18.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,12 @@ + + + + + +Obey Files

OBEY files are standard text files containing statements that are used to control the operation of the ROM building tools. ROMBUILDAn obey file has a .oby extension, and any files included by the OBEY file have a .iby extension.

ROMBUILD and ROFSBUILD understand a different subset of the complete set of OBEY file statements. Many statements are only understood by one tool, and a number of statements are common to both tools. In addition, some specific keywords are understood by BUILDROM only. BUILDROM typically converts them into statements that are understood by ROMBUILD, ROFSBUILD or both.

\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-9D26E38F-5C7B-5330-A54B-8F97D0F204D0-GENID-1-2-1-8-1-1-7-1-1-5-1.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-9D26E38F-5C7B-5330-A54B-8F97D0F204D0-GENID-1-2-1-8-1-1-7-1-1-5-1.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,90 @@ + + + + + +Performance +LoggingSymbian platform provides macros that you can use in device driver +and kernel extension programs to write a trace log. +

You can use the trace log to test the performance of the programs.

+
Perfomance macros

There are three macros that you +can insert into your code. They only differ with respect to the optional data +that you can add to the trace record. All are defined in kernperfloger.h

    +
  • PERF_LOG0 (aSubCategory)

  • +
  • PERF_LOG1 (aSubCategory,aUserData)

  • +
  • PERF_LOG2 (aSubCategory,aUserData,aUserData2)

    Note: +the PERF_LOG macro is identical to PERF_LOG2.

  • +

You must specify an the 8-bit integer subcategory value in the aSubCategory argument. +You can also supply one or two (or zero) 32-bit values; you are free to decide +on the meaning of such values.

The macros wrap around the standard BTrace*** macros. +All trace records generated by these macros are given a category of BTrace::EKernPerfLog.

The +generation and capture of trace information is implemented as a kernel extension. +This means that it is loaded and activated at an early stage in the startup +process of the device.

+
Performance macro output format

The following table +shows which fields of a trace record are generated by each of the macros PERF_LOG0, PERF_LOG1, +and PERF_LOG2:

+ + + +

Field

+

PERF_LOG0

+

PERF_LOG1

+

PERF_LOG2

+
+ +

Fast Counter Timestamp

+

Yes

+

Yes

+

Yes

+
+ +

Context Id

+

Yes

+

Yes

+

Yes

+
+ +

PC value

+

Yes

+

Yes

+

Yes

+
+ +

the 32-bit integer value passed as aUserData

+

NO

+

Yes

+

Yes

+
+ +

the 32-bit integer value passed as aUserData2

+

NO

+

NO

+

Yes

+
+ +

Tick Count as returned from a call to NKern::TickCount()

+

Yes

+

Yes

+

Yes

+
+ + +
+
How to use the macros

To use the macros:

    +
  • Include the header file kernperfloger.h in +your source code.

  • +
  • Link to btrace.lib in +your project

  • +
  • Call the PERF_LOG*** macros +at appropriate points in your code.

    For examples, see the test code +for the macros in ...\e32test\group\d_perflogger_test_ldd.mmp and ...\e32test\group\t_perflogger.mmp

  • +
  • Rebuild your project

  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-9D26E38F-5C7B-5330-A54B-8F97D0F204D0-GENID-1-2-1-9-1-8-1-19-1.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-9D26E38F-5C7B-5330-A54B-8F97D0F204D0-GENID-1-2-1-9-1-8-1-19-1.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,90 @@ + + + + + +Performance +LoggingSymbian platform provides macros that you can use in device driver +and kernel extension programs to write a trace log. +

You can use the trace log to test the performance of the programs.

+
Perfomance macros

There are three macros that you +can insert into your code. They only differ with respect to the optional data +that you can add to the trace record. All are defined in kernperfloger.h

    +
  • PERF_LOG0 (aSubCategory)

  • +
  • PERF_LOG1 (aSubCategory,aUserData)

  • +
  • PERF_LOG2 (aSubCategory,aUserData,aUserData2)

    Note: +the PERF_LOG macro is identical to PERF_LOG2.

  • +

You must specify an the 8-bit integer subcategory value in the aSubCategory argument. +You can also supply one or two (or zero) 32-bit values; you are free to decide +on the meaning of such values.

The macros wrap around the standard BTrace*** macros. +All trace records generated by these macros are given a category of BTrace::EKernPerfLog.

The +generation and capture of trace information is implemented as a kernel extension. +This means that it is loaded and activated at an early stage in the startup +process of the device.

+
Performance macro output format

The following table +shows which fields of a trace record are generated by each of the macros PERF_LOG0, PERF_LOG1, +and PERF_LOG2:

+ + + +

Field

+

PERF_LOG0

+

PERF_LOG1

+

PERF_LOG2

+
+ +

Fast Counter Timestamp

+

Yes

+

Yes

+

Yes

+
+ +

Context Id

+

Yes

+

Yes

+

Yes

+
+ +

PC value

+

Yes

+

Yes

+

Yes

+
+ +

the 32-bit integer value passed as aUserData

+

NO

+

Yes

+

Yes

+
+ +

the 32-bit integer value passed as aUserData2

+

NO

+

NO

+

Yes

+
+ +

Tick Count as returned from a call to NKern::TickCount()

+

Yes

+

Yes

+

Yes

+
+ + +
+
How to use the macros

To use the macros:

    +
  • Include the header file kernperfloger.h in +your source code.

  • +
  • Link to btrace.lib in +your project

  • +
  • Call the PERF_LOG*** macros +at appropriate points in your code.

    For examples, see the test code +for the macros in ...\e32test\group\d_perflogger_test_ldd.mmp and ...\e32test\group\t_perflogger.mmp

  • +
  • Rebuild your project

  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-9D4B8CDF-60D7-5952-AAAF-94A3C1E8908F.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-9D4B8CDF-60D7-5952-AAAF-94A3C1E8908F.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,36 @@ + + + + + +ArchitectureExplains architecture of the User-Side Hardware Abstraction (HAL) +component. + + + +
    +
  • Specific items of hardware +related information are called attributes.

    The base port customises the hal.dll library to +set which attributes can be used on a device.

    Some attributes are +simple values, but some attributes must be read and set with a function. These +functions are called accessor functions. The base port sets identifiers for +the accessor functions to use.

  • +
  • User-side programs use +the user-side +interface HAL class in hal.dll to +get and set information about attributes.

  • +
  • The accessor functions +are implemented on the kernel side by functions called HAL handlers.

    The variant DLL and many device drivers in a +base port can implement HAL handlers.

  • +
  • Kernel-side programs +can use the Kernel-side +interface Kern::HalFunction() function to call HAL +handler functions.

  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-9D8C62FB-1E42-5B69-8ECC-2B68AD7C71A5-master.png Binary file Adaptation/GUID-9D8C62FB-1E42-5B69-8ECC-2B68AD7C71A5-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-9D8C62FB-1E42-5B69-8ECC-2B68AD7C71A5_d0e25863_href.png Binary file Adaptation/GUID-9D8C62FB-1E42-5B69-8ECC-2B68AD7C71A5_d0e25863_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-A04F46F8-1BA9-5A77-B455-59C67DD4AA36.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-A04F46F8-1BA9-5A77-B455-59C67DD4AA36.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,22 @@ + + + + + +Serial Port DriverThe Serial Port Driver is a device driver that handles serial port +hardware (create the physical channel). This section describes how to create +a port of it for your phone hardware. +

The Serial Port Driver +provides a logical device driver, ecomm.dll. You must +provide a physical device driver to implement the interface to the serial +port hardware on your phone.

+
+ +H4 serial connections +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-A25FFD79-0797-43EC-8975-8C23E7E539C4.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-A25FFD79-0797-43EC-8975-8C23E7E539C4.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,49 @@ + + + + + +Register Access Technology GuideProvides information about the Register Access technology. +

The Register Access platform service is implemented in the ASSP +layer. The Register Access functionality is provided to the clients +by implementing the AsspRegister class.

+
+ Purpose

The Register Access platform +service provides an interface to the kernel and device drivers to +read, write or modify the contents of only the ASSP registers.

+
Key +concepts
+ +
Register
+

A register is a memory location on the ASSP hardware to store +data that relates to the operation of that hardware. The Symbian platform +support registers that can store 8, 16, 32 and 64–bit data.

+
+ +
Bitmask
+

The Modify function of the AsspRegister class +allows the clients to set or clear certain bits stored in the register.

+
+ +
Application-Specific Standard Product (ASSP)
+

ASSP is an integrated circuit consisting of CPU, Memory Management +Unit (MMU), cache and a number of on-chip peripherals, which is intended +to be used in a class of devices. Typical examples include UARTs, +timers, LCD controller that are designed and marketed by a silicon +vendor.

+
+
+
Typical +uses

The Register Access platform service allows the clients +to:

    +
  • read data stored in 8, 16, 32 and 64–bit registers

  • +
  • store data in 8. 16, 32 and 64–bit registers

  • +
  • change certain bits of the data in 8, 16, 32 and 64–bit registers.

  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-A27BD4D8-8B0E-57C8-9C15-736109297DEA.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-A27BD4D8-8B0E-57C8-9C15-736109297DEA.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,369 @@ + + + + + +Keyword reference (D-F) +

This page lists the keywords starting from D to F.

+
data-aligndata-align = <hex-number>

rombuild +only

This keyword specifies the alignment for the executable's +data. It indicates the start address of a data segment that must be +aligned to a specified value.

Note: The +inclusion of data-align keyword in an OBY file does +not increase the size of ROM image.

+
datapagingoverride datapagingoverride [NOPAGING | ALWAYSPAGE | DEFAULTUNPAGED | DEFAULTPAGED]

rombuild and rofsbuild

If the datapagingoverride keyword is spe,cified in an OBY file, it overrides the configuration +for data paging for the executable files defined in OBY file. This +keyword takes a single argument, which can be one of the possible +values listed in codepagingoverride.

+
datapagingpolicy datapagingpolicy [NOPAGING | ALWAYSPAGE | DEFAULTUNPAGED | DEFAULTPAGED]

rombuild and rofsbuild

This overrides the default +settings for data paging and the settings from all the previous levels.

This keyword takes a single argument, +which can be one of the possible values listed in codepagingoverride.

+
data[[HWVD]] data[[HWVD]] = <source-file> <destination-file> [File-attribute-list] +

rombuild and rofsbuild

A file that +is copied from its source location into the ROM without any processing.

Note that the HWVD is optional but, if specified, must be enclosed +within square brackets.

+
dataaddress dataaddress = <hex-address>

rombuild only

Linear address of data/bss chunks +for all executables except the Kernel.

+
datadriveimagename datadriveimagename = <image name>

ROFSBUILD only

Specifies the name of the data +drive image.

+
DATA_IMAGE DATA_IMAGE <id> <name> [size=<partition size>] [FAT16 | FAT32] [compress | no-compress]

BUILDROM only

Defines a data drive image.

This is a data drive configuration feature. There is no limitation +for the number of data drive images that can be defined for an internal +media.

+ + + +

id

+

A value to identify the data drive image.

+
+ +

name

+

A name suitable as a suffix for the data drive image, IBY +and logs.

+
+ +

size = <partition size>

+

Defines the size of the data drive image that has to be +generated.

+
+ +

compress

+

Compresses files in the image. If not specified, no compression +is the default behaviour.

+
+ + +

To mark a file for inclusion in a data drive it is prefixed +with the keyword DATA_IMAGE. For example:

DATA_IMAGE[2] fatname size=16000000 fat16 -compress

The above information can also be included using '{' '}' braces, +for example:

DATA_IMAGE[2] + { + dataimagename=fatname + compress + dataimagefilesystem=fat16 + dataimagesize=16000000 + } +
+
dataimagefilesystem dataimagefilesystem = <FAT16 | FAT32>

BUILDROM and ROFSBUILD only

Specifies the file +system type of the datadrive image. If this is not specified then +by default BUILDROM sets the image file system as fat16.

+
dataimagename dataimagename = <image name>

ROFSBUILD only

Specifies the name of the datadrive +image. If this is not specified then by default BUILDROM sets +the image name as dataimagex, where x is the image index.

+
dataimagesize dataimagesize = <size in bytes>

ROFSBUILD only

Specifies the maximum size of +a data drive image. The default size is the size of the data drive +folder.

+
DEFAULT_LANGUAGE DEFAULT_LANGUAGE NN

BUILDROM only

Localisation support. Specifies +the default language as a Symbian 2-digit code. This keyword should +only be used once.

+
DEFINE DEFINE <name> <replacement>

BUILDROM only

Performs textual substitution. +All subsequent instances of <name> are replaced by <replacement>.

Notes:

    +
  • There is no +UNDEFINE facility, and substitutions are applied in an unspecified +order

  • +
  • The C++ preprocessor +cannot be used conveniently because it inserts whitespace around substituted +text.

  • +
+
device[[HWVD]] device[[HWVD]] = <source-file> <destination-image-file> [File-attribute-list] [Override-Attribute-list]

rombuild only

Defines kernel-mode logical or +physical device drivers, which can have global data. The address of +this data is generated by rombuild.

Note +that the HWVD is optional but, if specified, must +be enclosed within square brackets.

+
dll[[HWVD]] dll[[HWVD]] = <source-file> <destination-image-file> [File-attribute-list] [Override-Attribute-list]

rombuild only

Specifies an executable file whose +entry point must be called.

+
debugport debugport = <32bit-number>

rombuild only

Specifies the destination port +for Kernel and Bootstrap traces.

rombuild stores the value in the ROM header. Each ASSP is free to interpret +the debug port as it pleases, for example, as a serial port number +or as an I/O base address. The default value is -1.

+
defaultstackreserve defaultstackreserve = <default stack reserve>

rombuild only

Specifies the maximum size of +the stack.

+
demandpagingconfig demandpagingconfig <MinLivePages> <MaxLivePages> <YoungOldPageRatio> <NANDPageReadDelay> <NANDPageReadCPUOverhead>

rombuild only

Specifies settings for demand +paging enabled ROM.

This keyword takes four arguments, which +are described below:

    +
  • MinLivePages: This is the minimim number of RAM pages to reserve for the paging +system.The number must be at least equal to 2*(YoungOldPageRatio+1). +If a smaller number is specified, a number equal to this formula is +used instead.

    For example, the YoungOldPageRatio is 3 and MinLivePages is set to 5. According to +the formula 2*(YoungOldPageRatio+1), the minimum number of live pages +must be 8, but the number specified is 5. So the minimum number is +set to 8.

  • +
  • MaxLivePages: The maximum number of RAM pages the paging system may use. The +number must be greater than or equal to MinLivePages. On a production system the number is always set to maximum (32767). +However, low values may be used to test the effects of low free RAM.

  • +
  • YoungOldPageRatio: The ratio of young to old pages maintained by the system. For this +purpose, the paging system maintains a list of live pages, which is +again split into two sub-lists: a list of young pages, and a list +of old pages in the system. The paging system uses YoungOldPageRatio to maintain the relative sizes of these two lists.

    For example, +let us assume that the ratio is R, the number of young pages is Ny and the number of old pages is No. If Ny > RNo, a page is taken from the end of the young pages +list and placed at the start of the old pages list. This process is +called aging.

  • +
  • NANDPageReadDelay: The delay in microseconds, between initiating a page read operation +and completing it. During this delay, other threads in the system +may use the CPU.

  • +
  • NANDPageReadCPUOverhead: The CPU instruction execution time in microseconds, to setup and +process a page read operation. During this delay, the CPU is busy +and is not accessible by other threads.

  • +

Note: All the above listed attributes are limited +to the value range 0-32767.

+
dlldatatop dlldatatop = <address of data region>

rombuild only

Specifies the top of the DLL data +region.

+
ECHO ECHO <anything at all>

BUILDROM only

Prints the rest of the line following +the ECHO keyword to standard output.

+
__ECOM_PLUGIN __ECOM_PLUGIN(<local build directory>, <rom binary directory>, <local epoc32\data\Z directory>, <rom resources directory>, <DLL filename>, <resource filename>)

BUILDROM only

Specifies an ECom plug-in, consisting +of an implementation DLL and an ECom registration resource file, to +include in ROM.

Symbian platform code does not use this keyword +directly. Instead, it uses the macro ECOM_PLUGIN, +defined in \epoc32\rom\include\header.iby, which +allows the plug-in to be specified more briefly, in the following +form:

ECOM_PLUGIN(<DLL name>,<resource file name>)

For example:

ECOM_PLUGIN(foo.dll,12345abc.rsc)

Note that the resource file name is specified using the <DLL-uid>.rsc format.

Use of this keyword allows BUILDROM to perform special handling of ECom plug-ins. In +particular, it allows BUILDROM optionally to create +a static plug-in information (SPI) file, which contains all the resource +registration files for ROM-based plug-ins. This allows ECom to be +more efficient, as it can use the SPI file to find all ROM-based plug-ins +and not have to scan the file system for them. BUILDROM implements +this using the spidata keyword.

Note that as part of the ROM creation +process, it is possible to add support for multiple languages. This +affects how ECom resource files are specified by BUILDROM:

    +
  • If an SPI file +is being created the ECOM_PLUGIN lines are processed +at an intermediate BUILDROM stage to produce:

    spidata=MULTI_LINGUIFY( EXT sourcename destname ) <spi-id> <target-spi-dir>

    During the BUILDROM localisation stage these lines become:

    spidata = <source-file> <original-destination-file> <spi-id> <target-spi-dir>

    where <spi-id> has the extension .SPI for +the default language, and the extension .Snn for +all other language codes nn. This means that if +multiple languages are being included in the ROM image there is an +SPI file for each included language.

  • +
  • If an SPI file +is not being created ECOM_PLUGIN lines are processed +an intermediate BUILDROM stage to produce:

    data=MULTI_LINGUIFY( EXT sourcename destname )

    During the BUILDROM localisation stage these lines become:

    data=sourcename.Enn destname.EXT for the default +language code

    data=sourcename.Enn destname.Enn for all other language codes nn.

  • +
+
EPOCROOT EPOCROOT

BUILDROM only

A pre-defined substitution. This +is replaced with the value of the EPOCROOT environment variable.

Note that there is no UNDEFINE facility, and substitutions are +applied in an unspecified order.

+
epocwrapper epocwrapper

rombuild only

Indicates that a Symbian platform +ROM wrapper is required

+
ERROR ERROR <anything at all>

BUILDROM only

Prints the rest of the line following +the ERROR keyword to standard output, and reports the source file +name and the line number. In addition, it causes BUILDROM to terminate without attempting to create the ROM image(s).

+
exattrib exattrib=U

ROFSBUILD only

This keyword is used with the data keyword to specify an additional attribute for the file +being included in the ROM image. This attribute enables the file server +to append the ROFS mounting information in the format, file.ext[<mount_id>-00] when registering the file.

The following example shows how +this keyword is used to set the attribute for a text file, which is +copied to the ROM image:

data=EPOCROOT##epoc32\rom\rofstest\hello8.txt Exattrib\test1.txt exattrib=U +

Assuming that the test1.txt file +is in the ROFS image and is the first one to be mounted by the file +server, the file is included in the ROM image in the following format:

z:\Exattrib\test1.txt[01-00]
+
EXCLUDE_FEATURE EXCLUDE_FEATURE <feature name> [ SF <status flags> ] [ UD <user data> ]

Where <feature> is either the feature name +or a feature uid value.

Note: The space between the keyword FEATURE and <feature name> is +optional.

<status flags> is a 32 bit +hex number indicating the status flags of the feature. Each bit in +the status flag signifies the following:

+ + + + +Bit +Flag Name +Value + + + + +

0

+

Supported

+

If the bit is set the feature is included, else the feature +is excluded.

+
+ +

1

+

Upgradeable

+

This bit is reserved for future use. It will be used to +upgrade a feature which is already associated to the device.

+
+ +

2

+

Modifiable

+

If the bit is set the feature is modified at run-time. The +default flag values for such a feature are defined in a ROM image +obey file.

+
+ +

3

+

Blacklisted

+

If the bit is set the feature is blacklisted, and cannot +be changed at run-time. It signifies that if the feature appears in +subsequent data files or plug-in info, it would be ignored.

It also prevents a feature from being upgraded and it can never be +changed/ overridden. If a feature is blacklisted, its upgradeable +flag is not set.

+
+ +

4

+

Uninitialised

+

If the bit is set the flag supported state is not initialised +at build-time, and it is initialised at run-time by system software.

To set the supported flag of a specific feature, perform a runtime +call to RFeatureControl.

+
+ +

5

+

Persisted

+

If the bit is set the flag value is preserved across reboot +or system turn off period.

+
+ +

6-31

+

Reserved

+

These bits are reserved for future use.

+
+ + +

<user data> is a 32 bit hex number +indicating the user data value associated with the feature.

BUILDROM only

The EXCLUDE_FEATURE keyword +is used to mark a feature as excluded.

+
extension[[HWVD]] extension[[HWVD]] = <source-file> <destination-image-file> [File-attribute-list] [Override-Attribute-list]

rombuild only

Defines a kernel-mode DLL that +can have global data, the address of which is generated by rombuild. Extension files are connected together in a linked +list, which allows the Kernel to load the extensions at boot time +before the ROM file system is available.

Note that the HWVD is optional but, if specified, must be enclosed within +square brackets.

+
extensionrofs extensionrofs

rofsbuild only

Marks the start of the definition +of an optional extension ROFS.

+
extensionrofsname extensionrofsname = <filename>

rofsbuild only

Defines the name of the ROFS +extension image.

Any new files added after this keyword will +appear in the extension. The files in the core can be renamed, hidden, +and aliased by using the other keywords.

+
extensionrom extensionrom = <rom-file-name>

rombuild only

This marks the start of an extension +ROM section. A filename of "*" can be specified, which means use the +file name specified on the romname keyword in a rom-information-statement

+
externaltool externaltool=<toolname>

BUILDROM only

Used for invoking external tools +through the IBY file keyword externaltool, specifying the list of +toolnames each seperated by a comma. externaltool=toolname1, +toolname2,... toolnameN

The same invocation can +be achieved alternatively by using BUILDROM command-line option -e<toolname>.

+
fattable fattable=<number of FAT tables>

rofsbuild only

Configures the number of FAT +tables for the file system in the data-drive image.

+
FEATURE FEATURE <feature name> [ SF <status flags> ] [ UD <user data> ]

Where <feature> is either the feature name +or the feature uid value.

Note: The space between +the keyword FEATURE and <feature name> is optional.

<status flags> is a 32 +bit hex number indicating the status flags of the feature. Each bit +in the status flag signifies the following:

+ + + + +Bit +Flag Name +Value + + + + +

0

+

Supported

+

If the bit is set the feature is included, else the feature +is excluded.

+
+ +

1

+

Upgradeable

+

This bit is reserved for future use. It will be used to +upgrade a feature which is already associated to the device.

+
+ +

2

+

Modifiable

+

If the bit is set the feature is modified at run-time. The +default flag values for such a feature are defined in a ROM image +obey file.

+
+ +

3

+

Blacklisted

+

If the bit is set the feature is blacklisted, and cannot +be changed at run-time. It signifies that if the feature appears in +subsequent data files or plug-in info, it would be ignored.

It also prevents a feature from being upgraded and it can never be +changed/ overridden. If a feature is blacklisted, its upgradeable +flag is not set.

+
+ +

4

+

Uninitialised

+

If the bit is set the flag supported state is not initialised +at build-time, and it is initialised at run-time by system software.

To set the supported flag of a specific feature, perform a runtime +call to RFeatureControl.

+
+ +

5

+

Persisted

+

If the bit is set the flag value is preserved across reboot +or system turn off period.

+
+ +

6-31

+

Reserved

+

These bits are reserved for future use.

+
+ + +

<user data> is a 32 bit hex number +indicating the user data value associated with the feature.

BUILDROM only

The FEATURE keyword is used +to mark a feature as included.

+
file[[HWVD]] file[[HWVD]] = <source-file> <destination-image-file> [File-attribute-list] [Override-Attribute-list] [paged | unpaged]

rombuild and rofsbuild

A standard executable +file, for example, a .exe or a .dll, in PE format or E32 image format. Executable files are stripped +of their relocation information prior to being stored in the ROM. +The relocation information is not necessary in the ROM because all +files are executed in place with an address that is determined at +ROM build time. Use the modifiers paged and unpaged to specify whether to page the executables or not. +You can also use the MMP file keywords paged and unpaged to specify whether to +page an executable or not.

For example, the following entry +in the Obey file provides the source and destination locations of +the file MyLibrary.dll and marks the DLL as unpaged.

file=ABI_DIR\DEBUG_DIR\MyLibrary.dll \sys\bin\MyLibrary.dll unpaged

Notes:

    +
  • the HWVD is optional but, if specified, must be enclosed within +square brackets.

  • +
  • the information +required to relocate the file is not preserved; this keyword provides +a fully resolved uncompressed file.

  • +
+
filecompressnone filecompressnone=\Epoc32\release\<platform><build><target directory><source file> <destination file>

rombuild only

Doesn't compress the resulting +ROM image.

For example:

filecompressnone=\epoc32\release\ARMV\UREL\TEST\RUNTEST.EXE sys\bin\RUNTEST.EXE
+
filecompressinflate filecompressinflate=\Epoc32\release\<platform><build><target directory><source file> <destination file>

rombuild only

Compresses the resulting ROM image +using the Deflate, Huffman+LZ77 algorithm.

For example:

filecompressinflate=\epoc32\release\ARMV\UREL\TEST\RUNTEST.EXE sys\bin\RUNTEST.EXE
+
filecompressbytepair filecompressbytepair=\Epoc32\release\<platform><build><target directory><source file> <destination file>

rombuild only

Compresses the resulting ROM image +using the bytepair algorithm.

For example:

filecompressbytepair=\epoc32\release\ARMV\UREL\TEST\RUNTEST.EXE sys\bin\RUNTEST.EXE
+
filecompress[[HWVD]] filecompress[[HWVD]] = <source-file> <destination-file> [File-attribute-list] [Override-Attribute-list]

rombuild only

An XIP (execute-in-place) executable +to be loaded into the ROM in compressed format. Note that the information +required to relocate the file is preserved.

+
fileuncompress[[HWVD]] fileuncompress[[HWVD]] = <source-file> <destination-file> [File-attribute-list] [Override-Attribute-list]

rombuild only

XIP (execute-in-place) executable +to be loaded into the ROM uncompressed format. Note that the information +required to relocate the file is preserved.

+
fixed fixed

rombuild only

This executable is loaded as a +fixed address process, and has its data fixed in kernel space (high +memory). The data of normal executables is paged in and out of low +memory as the executable runs. Fixing a chosen subset of the system +servers saves context switch time, and speeds execution considerably.

+
formatversion

formatversion= <format version>

Specifies the SMR image format version. This value is checked by +the SMR consumers (such as HCR) at runtime to ensure code compatibility +with image or data format.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-A328F9E3-7D91-594A-A589-E8CE5FA9227A-master.png Binary file Adaptation/GUID-A328F9E3-7D91-594A-A589-E8CE5FA9227A-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-A328F9E3-7D91-594A-A589-E8CE5FA9227A_d0e69077_href.png Binary file Adaptation/GUID-A328F9E3-7D91-594A-A589-E8CE5FA9227A_d0e69077_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-A3A3405C-C89C-5079-85CE-8CB069C8E0C0.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-A3A3405C-C89C-5079-85CE-8CB069C8E0C0.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,53 @@ + + + + + +IIC Client Interface QuickstartThis document gives a brief overview of the IIC client +interface API. +
Purpose

The IIC client interface API creates a common interface from +device drivers to serial inter-IC buses (IIC buses).

Intended +audience

This document is intended to be used by device +driver writers.

+
Architectural +relationship

The IIC client interface API is part of a +group of APIs which provide a common, hardware-independent, interface +from kernel to different hardware. Other APIs of this type include +GPIO.

Description

Physically, a bus represented +by IIC is accessed over a node. The IIC client interface API wraps +a node in a software construct called a channel. It provides functionality +for creating and accessing channels directly. There are two possible +modes of operation:

    +
  • Controller

    Where the device drivers that use the IIC +client interface API can access different IIC channels.

  • +
  • Controller-less

    Where the channels that the device driver +can access are set at compile time.

  • +

Furthermore, there are three possible channel behaviors:

    +
  • Master

    The device driver initializes the data transfer.

  • +
  • Slave

    The device driver carries out a data transfer that +is controlled by another node attached to the bus.

  • +
  • MasterSlave

    The device driver can carry out both roles.

  • +
+
IIC +classes

If the access to the IIC bus is to be via a controller, +then the IIC platform service API class to use is:

    +
  • IicBus

  • +

If the access to the IIC bus is to be without a controller +(controller-less operation), then the IIC platform service API classes +to use are:

    +
  • DIicBusChannelMaster

  • +
  • DIicBusChannelSlave

  • +
  • DIicBusChannelMasterSlave

  • +
+
+Client +of Master Channel Tutorial +Client +of Slave Channel Tutorial +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-A4179FF3-4541-44B8-A8F3-52C1318159B3.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-A4179FF3-4541-44B8-A8F3-52C1318159B3.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,60 @@ + + + + + +Platform +SecurityThis document discusses how device drivers should implement platform +security. +

Device drivers must follow the Symbian platform security guidelines. As +a part of platform security, drivers must be given the necessary platform +security capabilities. A driver can also check the capabilities of a process +opening a channel on the device, in order to restrict access to the device.

+

Driver-side +definition

Because drivers are loaded by the Kernel, both LDDs +and PDDs must have the same level of trust and capability as the Kernel. This +means that platform security capabilities must be set to ALL in +the LDD and PDD .mmp files.

// LDD: mmp file +... +CAPABILITY ALL // PDD: mmp file +... +CAPABILITY ALL

The user program must have the necessary +capability set in its .mmp file to open and access the +driver API. The reference documentation for the API should say what capabilities +are required. Usually, they are the same as the minimum capability that is +required to load the drivers.

// Test application: mmp file +... +CAPABILITY CommDD ReadDeviceData PowerMgmt
+

User-side verification

A +device driver must check the capability of the process that is accessing it. +This is typically done during channel creation and, if required, for specific +requests to the LDD. The Kernel provides the Kern::CurrentThreadHasCapability() API +to check the capability of the calling process. It can check for more than +one capability.

The following shows how the example driver checks +during channel creation that the user has the ECapabilityCommD capability:

TInt DExDriverLogicalChannel::DoCreate(TInt /*aUnit*/, const TDesC8* +/*anInfo*/, const TVersion& aVer) + { + // Capability check - CommDD + if (!Kern::CurrentThreadHasCapability (ECapabilityCommDD, + __PLATSEC_DIAGNOSTIC_STRING("Checked by Tutorial Driver"))) + return KErrPermissionDenied; + ... + }
+

Data caging

Symbian +platform security requires that all DLLs and EXEs are placed in the folder /sys/bin. +Drivers and test application binaries must be placed in the /sys/bin folder +by their ROM .iby file.

// iby file +device[VARID]=KERNEL_DIR\DEBUG_DIR\exdriver_ldd.ldd \Sys\Bin\exdriver_ldd.ldd +device[VARID]=KERNEL_DIR\DEBUG_DIR\exdriver_pdd.pdd \Sys\Bin\exdriver_pdd.pdd +file=ABI_DIR\BUILD_DIR\exdriver_test.exe \Sys\Bin\exdriver_test.exe +
+
+Platform +security architecture +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-A4C19890-2380-5498-A5F8-3B6D95CEFEF4.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-A4C19890-2380-5498-A5F8-3B6D95CEFEF4.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,428 @@ + + + + + +PSL +ImplementationDescribes how to create the PSL implementation. +

To create a port of the DMA Framework, you must create an implementation +of the PSL for the DMA controller hardware.

+
Define and +implement PSL-specific channel classes

The choice of class to be +used for implementing DMA channels is governed by the mode of operation to +be supported:

    +
  • single-buffer channels +should use TDmaSbChannel

  • +
  • double-buffer channels +should use TDmaDbChannel

  • +
  • scatter-gather channels +should use TDmaSgChannel

  • +

These three classes are defined in dma.h.

In +addition, the PSL may need to store channel-specific data. One way of achieving +this is by deriving a PSL-specific class from one of the generic ones. For +example, the template scatter-gather implementation defines a TTemplateSgChannel class +derived from TDmaSgChannel for storing data when appending +new descriptors to a running channel:

class TTemplateSgChannel : public TDmaSgChannel + { +public: + TDmaDesc* iTmpDes; + TPhysAddr iTmpDesPhysAddr; + }; + +
+
Define and +implement the controller classes

A controller can either be a physical +controller, or a logical one depending on which DMA +mode you intend to support.

The PSL (platform-specific layer) +must define one concrete controller class per supported controller. A controller +class is derived from TDmac. The concrete class must implement +all the pure virtual functions defined in TDmac, and, optionally +the functions used to manipulate hardware descriptors.

Taking the +template port as an example, the class is defined as:

class TTemplateDmac : public TDmac + { +public: + TTemplateDmac(); + TInt Create(); +private: + // from TDmac (PIL pure virtual) + virtual void Transfer(const TDmaChannel& aChannel, const SDmaDesHdr& aHdr); + virtual void StopTransfer(const TDmaChannel& aChannel); + virtual TBool IsIdle(const TDmaChannel& aChannel); + virtual TInt MaxTransferSize(TDmaChannel& aChannel, TUint aFlags, TUint32 aPslInfo); + virtual TUint MemAlignMask(TDmaChannel& aChannel, TUint aFlags, TUint32 aPslInfo); + // from TDmac (PIL virtual) + virtual void InitHwDes(const SDmaDesHdr& aHdr, TUint32 aSrc, TUint32 aDest, TInt aCount, + TUint aFlags, TUint32 aPslInfo, TUint32 aCookie); + virtual void ChainHwDes(const SDmaDesHdr& aHdr, const SDmaDesHdr& aNextHdr); + virtual void AppendHwDes(const TDmaChannel& aChannel, const SDmaDesHdr& aLastHdr, + const SDmaDesHdr& aNewHdr); + virtual void UnlinkHwDes(const TDmaChannel& aChannel, SDmaDesHdr& aHdr); + // other + static void Isr(TAny* aThis); + inline TDmaDesc* HdrToHwDes(const SDmaDesHdr& aHdr); +private: + static const SCreateInfo KInfo; +public: + TTemplateSgChannel iChannels[KChannelCount]; + }; +

Notes:

    +
  • The array of channels +must be defined in the PSL controller class because only the PSL knows what +kind of channels are used.

  • +
  • The PSL controller class +must be allocated in the BSS section of the DMA kernel extension. The second +phase constructor must be called from the extension entry point.

  • +
  • The C++ constructor +must pass a TDmac::SCreateInfo structure to the TDmac constructor. +This structure defines what the PIL (platform-independent layer) needs to +know about the underlying DMA controller. The template TTemplateDmac constructor +just passes a TDmac::ScreateInfo structure, which defines +the layout of the (base class managed) descriptor pool to the base class constructor +through a ctor list:

    TTemplateDmac::TTemplateDmac() +// +// Constructor. +// + : TDmac(KInfo) + {} + +

    where KInfo is a TDmac::ScreateInfo type.

  • +
  • The PSL controller class +needs a second phase constructor. This is the Create() function, +which must:

      +
    1. call the second phase +constructor of the base class: TDmac::Create().

    2. +
    3. perform any hardware-specific +initialisation.

    4. +
    5. bind and enable the +DMA interrupt(s).

    6. +

    In the template port, Create() calls the base class TDmac::Create() function +and then initialises the template specific channel object members (the temporary +descriptor fields used for appending requests to live channels), and performs +platform specific initialisation for the interrupt dispatch of DMA interrupt +events:

    TInt TTemplateDmac::Create() +// +// Second phase construction. +// + { + TInt r = TDmac::Create(KInfo); // Base class Create() + if (r == KErrNone) + { + __DMA_ASSERTA(ReserveSetOfDes(KChannelCount) == KErrNone); + for (TInt i=0; i < KChannelCount; ++i) + { + TDmaDesc* pD = HdrToHwDes(*iFreeHdr); + iChannels[i].iTmpDes = pD; + iChannels[i].iTmpDesPhysAddr = DesLinToPhys(pD); + iFreeHdr = iFreeHdr->iNext; + } + r = Interrupt::Bind(EAsspIntIdDma, Isr, this); + if (r == KErrNone) + { + // TO DO: Map DMA clients (requests) to DMA channels here. + + r = Interrupt::Enable(EAsspIntIdDma); + } + } + return r; + } +
  • +
+
Implement the +channel allocator

Channel allocation is implemented in the PSL +(platform-specific layer) because this is a hardware-specific operation. There +are two basic options:

    +
  • Preallocate, at design +time, one channel per DMA-aware peripheral. This is the simplest approach, +and it should be acceptable for most Symbian platform devices because the +set of supported peripherals is closed. In this case, cookies passed by client +device drivers map uniquely to DMA channels.

  • +
  • Full dynamic allocation. +This is a simple approach too, but DMA channels are, in general, not completely +identical. For example, some channels may have greater priorities than others.

  • +

Mixed schemes are also possible, for example, client device driver +cookies could be used to select a subset of channels, and dynamic allocation +used inside this subset.

Whatever option is chosen, the PSL must provide +an implementation for the function DmaChannelMgr::Open(). +The template implementation is:

TDmaChannel* DmaChannelMgr::Open(TUint32 aOpenId) +// +// +// + { + __KTRACE_OPT(KDMA, Kern::Printf(">DmaChannelMgr::Open aOpenId=%d", aOpenId)); + + __DMA_ASSERTA(aOpenId < static_cast<TUint32>(KChannelCount)); + + TDmaChannel* pC = Controller.iChannels + aOpenId; + if (pC->IsOpened()) + pC = NULL; + else + { + pC->iController = &Controller; + pC->iPslId = aOpenId; + } + + return pC; + } +

The template DMA channel manager returns a pointer to +a DMA channel if the channel has not been previously allocated. Note that +since channels possess preset priorities, the device drivers must be aware +of which channel(s) they require DMA service from and configure the DMA controller +to route sources to allocated channels accordingly.

The platform-specific +cookies passed by client device drivers to the PSL must be defined somewhere +so that client device drivers can access them.

+
[Optionally] +implement channel cleanup

In the template PSL (platform-specific +layer), the function DmaChannelMgr::Close() is a no-operation. +This function is called by the PIL (platform-independent layer) when client +device drivers call TDmaChannel::Close(). If the PSL needs +to perform any hardware-specific operation when the channel is closed, then +the implementation of DmaChannelMgr::Close() should be updated +to reflect that.

+
Implement the +mandatory controller virtual functions

The TDmac class +contains several pure virtual functions that must be implemented by the PSL +(platform-specific layer):

    +
  • TDmac::Transfer()

  • +
  • TDmac::StopTransfer()

  • +
  • TDmac::IsIdle()

  • +

These functions start and stop transfers on a DMA channel and are +the main interface between the PIL (platform-independent layer) and the PSL. +The implementation of these functions depends on the hardware available for +performing DMA, and on the characteristics used to specify a DMA transfer:

    +
  • the source and destination +addresses

  • +
  • the burst size

  • +
  • the maximum transfer +size

  • +
  • the transfer width, +i.e. number of bits per memory access

  • +
  • the memory alignment +and endianness.

  • +

The DMA Framework manages the transfer descriptors according to the +descriptor parameter passed into the TDmac constructor +by the derived class constructor; the descriptor parameter is a TDmac::SCreateInfo structure. +The per-request transfer parameters are passed into the descriptors for each +request issued by a driver.

The +transfer function: Transfer()

This function initiates a previously +constructed request on a specific channel. This is the template implementation:

void TTemplateDmac::Transfer(const TDmaChannel& aChannel, const SDmaDesHdr& aHdr) +// +// Initiates a (previously constructed) request on a specific channel. +// + { + const TUint8 i = static_cast<TUint8>(aChannel.PslId()); + TDmaDesc* pD = HdrToHwDes(aHdr); + + __KTRACE_OPT(KDMA, Kern::Printf(">TTemplateDmac::Transfer channel=%d des=0x%08X", i, pD)); + + // TO DO (for instance): Load the first descriptor address into the DMAC and start it + // by setting the RUN bit. + (void) *pD, (void) i; + + } +

The +stop transfer function: StopTransfer()

This function requires +that the RUN mode is cleared. This is the template implementation:

void TTemplateDmac::StopTransfer(const TDmaChannel& aChannel) +// +// Stops a running channel. +// + { + const TUint8 i = static_cast<TUint8>(aChannel.PslId()); + + __KTRACE_OPT(KDMA, Kern::Printf(">TTemplateDmac::StopTransfer channel=%d", i)); + + // TO DO (for instance): Clear the RUN bit of the channel. + (void) i; + + } +

The +function: IsIdle()

IsIdle() returns the state +of a given channel. This is the template implementation:

TBool TTemplateDmac::IsIdle(const TDmaChannel& aChannel) +// +// Returns the state of a given channel. +// + { + const TUint8 i = static_cast<TUint8>(aChannel.PslId()); + + __KTRACE_OPT(KDMA, Kern::Printf(">TTemplateDmac::IsIdle channel=%d", i)); + + // TO DO (for instance): Return the state of the RUN bit of the channel. + // The return value should reflect the actual state. + (void) i; + + return ETrue; + } +
+
Implement the +non-mandatory controller virtual functions

The following auxiliary +functions are used to implement the scatter-gather transfer mode behaviour +by creating and manipulating the linked list of transfer fragment headers +that describe a given scatter-gather transaction. They are called by the TDmac base +class functions when the instance of the TDmac derived class +reports itself as being capable of scatter-gather operations.

    +
  • TDmac::InitHwDes()

  • +
  • TDmac::ChainHwDes()

  • +
  • TDmac::AppendHwDes()

  • +

First +scatter-gather support function: InitHwDes()

This is a function +for creating a scatter-gather list. From the information in the passed-in +request, the function sets up the descriptor with that fragment's:

    +
  • source and destination +address

  • +
  • size

  • +
  • driver/DMA controller +specific transfer parameters: memory/peripheral, burst size, transfer width.

  • +

This is the template implementation:

void TTemplateDmac::InitHwDes(const SDmaDesHdr& aHdr, TUint32 aSrc, TUint32 aDest, TInt aCount, + TUint aFlags, TUint32 aPslInfo, TUint32 /*aCookie*/) +// +// Sets up (from a passed in request) the descriptor with that fragment's source and destination address, +// the fragment size, and the (driver/DMA controller) specific transfer parameters (mem/peripheral, +// burst size, transfer width). +// + { + TDmaDesc* pD = HdrToHwDes(aHdr); + + __KTRACE_OPT(KDMA, Kern::Printf("TTemplateDmac::InitHwDes 0x%08X", pD)); + + // Unaligned descriptor? Error in generic layer! + __DMA_ASSERTD(IsHwDesAligned(pD)); + + pD->iSrcAddr = (aFlags & KDmaPhysAddrSrc) ? aSrc : Epoc::LinearToPhysical(aSrc); + pD->iDestAddr = (aFlags & KDmaPhysAddrDest) ? aDest : Epoc::LinearToPhysical(aDest); + pD->iCmd = DcmdReg(aCount, aFlags, aPslInfo); + pD->iDescAddr = TDmaDesc::KStopBitMask; + } + +

Second +scatter-gather support function: ChainHwDes()

If the framework +needs to fragment the client’s request, for transfer size or memory discontiguousness +reasons, then the framework calls this function. It chains hardware descriptors +together by setting the next pointer of the original descriptor to the physical +address of the descriptor to be chained. It assumes that the DMAC channel +is quiescent when called.

This is the template implementation:

void TTemplateDmac::ChainHwDes(const SDmaDesHdr& aHdr, const SDmaDesHdr& aNextHdr) +// +// Chains hardware descriptors together by setting the next pointer of the original descriptor +// to the physical address of the descriptor to be chained. +// + { + TDmaDesc* pD = HdrToHwDes(aHdr); + TDmaDesc* pN = HdrToHwDes(aNextHdr); + + __KTRACE_OPT(KDMA, Kern::Printf("TTemplateDmac::ChainHwDes des=0x%08X next des=0x%08X", pD, pN)); + + // Unaligned descriptor? Error in generic layer! + __DMA_ASSERTD(IsHwDesAligned(pD) && IsHwDesAligned(pN)); + + // TO DO: Modify pD->iCmd so that no end-of-transfer interrupt gets raised any longer. + + pD->iDescAddr = DesLinToPhys(pN); + } + +

Third +scatter-gather support function: AppendHwDes()

This function is +called by the TDmac base class when a driver request is +called for a channel that is still active, i.e. where the intent is to provide +data streaming so that the target device is constantly provided with data; +for example, an audio device playing a track. In this case, the function provided +by the derived class must:

    +
  • stop the DMAC to prevent +any corruption of the scatter-gather list while appending the new fragment +descriptor

  • +
  • append the new descriptor

  • +
  • re-enable the channel, +ideally before the target has detected the gap in service.

  • +

This is the template implementation:

void TTemplateDmac::AppendHwDes(const TDmaChannel& aChannel, const SDmaDesHdr& aLastHdr, + const SDmaDesHdr& aNewHdr) +// +// Appends a descriptor to the chain while the channel is running. +// + { + const TUint8 i = static_cast<TUint8>(aChannel.PslId()); + + TDmaDesc* pL = HdrToHwDes(aLastHdr); + TDmaDesc* pN = HdrToHwDes(aNewHdr); + + __KTRACE_OPT(KDMA, Kern::Printf(">TTemplateDmac::AppendHwDes channel=%d last des=0x%08X new des=0x%08X", + i, pL, pN)); + // Unaligned descriptor? Error in generic layer! + __DMA_ASSERTD(IsHwDesAligned(pL) && IsHwDesAligned(pN)); + + TPhysAddr newPhys = DesLinToPhys(pN); + + const TInt irq = NKern::DisableAllInterrupts(); + StopTransfer(aChannel); + + pL->iDescAddr = newPhys; + const TTemplateSgChannel& channel = static_cast<const TTemplateSgChannel&>(aChannel); + TDmaDesc* pD = channel.iTmpDes; + + // TO DO: Implement the appropriate algorithm for appending a descriptor here. + (void) *pD, (void) i; + + NKern::RestoreInterrupts(irq); + + __KTRACE_OPT(KDMA, Kern::Printf("<TTemplateDmac::AppendHwDes")); + } +
+
Implement an +interrupt service routine

The interrupt service routine needs to +do the following:

    +
  • identify the channel +that raised the interrupt

  • +
  • decide whether the interrupt +was raised because of a successful data transfer or because of an error

  • +
  • call the base class +function TDmac::HandleIsr(), which queues a DFC, or increments +the number of pending interrupts if a DFC is already queued.

  • +

This is the template implementation:

void TTemplateDmac::Isr(TAny* aThis) +// +// This ISR reads the interrupt identification and calls back into the base class +// interrupt service handler with the channel identifier and an indication whether the +// transfer completed correctly or with an error. +// + { + TTemplateDmac& me = *static_cast<TTemplateDmac*>(aThis); + + // TO DO: Implement the behaviour described above, call HandleIsr(). + + HandleIsr(me.iChannels[5], 0); // Example + + } +
+
Implement the +test support table and function

The DMA Framework comes with a +test harness that can be used to validate the port if the underlying DMA controller +supports memory to memory transfers.

The test harness needs to know +about the capabilities of the port being tested. The PSL provides the global +function DmaTestInfo() that returns a TDmaTestInfo object +that contains this information. In the template PSL, this structure is initialised +to binary zeroes. Before using the test harness, it must be initialised with +valid values.

See TDmaTestInfo, DmaTestInfo() and Validation.

+
Optimise the +performance of critical functions

You can optionally optimise critical +functions by writing them in assembler. The two candidates for an assembler +rewrite are:

    +
  • The interrupt service +routine

  • +
  • In scatter-gather mode, +the TDmac::AppendHwDes() function if it needs to suspend +a transfer when appending a new descriptor chain to an existing one.

  • +
+
Extend the +framework with platform-specific functionality

There are two ways +of extending the DMA Framework:

    +
  1. to provide platform-specific +functionality on a per-channel basis.

  2. +
  3. to provide platform-specific +functionality on a channel independent basis.

  4. +

In the first case, the PSL provides an implementation of the virtual +function TDmac::Extension(). The default implementation +just returns KErrNotSupported.

TDmaChannel::Extension() calls TDmac::Extension().

In the second case, the PSL provides an implementation of the static +function DmaChannelMgr::StaticExtension(). The template +PSL implementation just returns KErrNotSupported.

TDmaChannel::StaticExtension() calls DmaChannelMgr::StaticExtension().

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-A4CCF2B6-26B7-5E8C-B738-9EE9E68A0B35.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-A4CCF2B6-26B7-5E8C-B738-9EE9E68A0B35.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,62 @@ + + + + + +ReferenceSummary of related documentation for the DMA Framework. +
API Reference

Kernel +Architecture 2

+ + + +

Item

+

Header

+
+ +

DDmaRequest

+

dma.h

+
+ +

DmaChannelMgr

+

dma.h

+
+ +

SDmaDesHdr

+

dma.h

+
+ +

SDmaPseudoDes

+

dma.h

+
+ +

TDmac

+

dma.h

+
+ +

TDmaChannel

+

dma.h

+
+ +

TDmaSbChannel

+

dma.h

+
+ +

TDmaSgChannel

+

dma.h

+
+ +

TDmaTestInfo

+

dma.h

+
+ + +
+
Engineering +Specifications

No specifications are published.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-A51C3E48-3ED0-519B-A128-C5175D7E175B-master.png Binary file Adaptation/GUID-A51C3E48-3ED0-519B-A128-C5175D7E175B-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-A51C3E48-3ED0-519B-A128-C5175D7E175B_d0e19782_href.png Binary file Adaptation/GUID-A51C3E48-3ED0-519B-A128-C5175D7E175B_d0e19782_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-A568F9D3-58E3-58D6-8A6E-4EC6BEC41A4D-master.png Binary file Adaptation/GUID-A568F9D3-58E3-58D6-8A6E-4EC6BEC41A4D-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-A568F9D3-58E3-58D6-8A6E-4EC6BEC41A4D_d0e29723_href.png Binary file Adaptation/GUID-A568F9D3-58E3-58D6-8A6E-4EC6BEC41A4D_d0e29723_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-A6845EB0-4B4D-49C8-85A5-A933A2C351CF-master.png Binary file Adaptation/GUID-A6845EB0-4B4D-49C8-85A5-A933A2C351CF-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-A6845EB0-4B4D-49C8-85A5-A933A2C351CF_d0e89230_href.png Binary file Adaptation/GUID-A6845EB0-4B4D-49C8-85A5-A933A2C351CF_d0e89230_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-A6D14A03-ADBF-570D-8AC7-E8BC2700F930.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-A6D14A03-ADBF-570D-8AC7-E8BC2700F930.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,183 @@ + + + + + +Factory +ImplementationMedia driver must implement a PDD factory class derived from DPhysicalDevice. +

The PDD factory creates the main media driver objects.

+

The Device Driver +Guide describes the general theory for implementing a derived class, +while this section gives the specifics for the media driver.

+

In implementing your DPhysicalDevice derived class, +you must, as a minimum, provide an implementation for the following four functions, +defined as pure virtual in DPhysicalDevice:

+
    +
  • Install() - complete the initialisation of the PDD factory object

  • +
  • Create() - create the media driver object

  • +
  • Validate() - check that the PDD is suitable for use

  • +
  • GetCaps() - return the capabilities of the Media Driver

  • +
+

The following function is virtual in DPhysicalDevice but +has a default implementation that must be changed:

+
    +
  • Info() - set the priority of the media driver

  • +
+
Install() - +complete the initialisation of the PDD factory object

See also DPhysicalDevice::Install().

This +PDD factory function is called after the PDD DLL has been successfully loaded, +as a result of a call to User::LoadPhysicalDevice(), and +the factory object has been successfully created on the kernel heap.

The +function is a second stage constructor for the factory object, and allows +any further initialisation of the factory object to be done. As a minimum, +the function must set a name for the media driver's factory object. The name +is important as it is the way in which the object will subsequently be found. +The name should be of the form:

Media.<MDExt>

where <MDExt> is descriptive of the specific media. For example, Media.Ata, +and Media.Iram.

When a DMedia object, +created by the internal Symbian platform ELOCD.LDD logical +device driver, attempts to mount a media device, i.e. to open a media driver, +it does a search by name. This is a search through all loaded PDDs whose names +match Media.*.

The following simple function is typical:

TInt DMyPhysicalDeviceMedia::Install() + { + _LIT(KDrvNm, "Media.MyName"); + return SetName(&KDrvNm); + } +
+
Create() - +create the media driver object

See also DPhysicalDevice::Create().

This +PDD factory function is called by the device driver framework to create, and +return, the media driver object. This is an instance of a class derived from DMediaDriver. +Note that, occasionally, you may find this object referred to as the physical +channel.

Create() is called when initially mounting +a media device, or accessing a removable media after an insertion event. Contrast +this with Install(), +which is only called once, when the PDD factory object is loaded.

Typically, Create() does +the following:

    +
  • Compares the build version +of the media driver with the version requested, and returns KErrNotSupported if +the versions are incompatible.

  • +
  • Creates an instance +of the DMediaDriver derived class, the media driver object.

  • +
  • Initiates second-phase +construction of the media driver object. Typically, this involves initialisation +that is capable of failing. This may be done synchronously or asynchronously. +You would probably do this asynchronously for removable media that is slow +to power up, or for slow internal media, in which case, you would need to +make sure that you attached a DFC queue during media +driver initialisation. Although the device driver framework does not +mandate any specific function name in which to implement this, the example +code fragment suggests a function name of DoCreate().

  • +
  • Acknowledges creation +of the media driver object. The way you do this depends on whether creation +is done synchronously or asynchronously:

      +
    • Synchronous creation +- call DMediaDriver::OpenMediaDriverComplete() passing KErrNone, +or an error code if appropriate, and then return KErrNone from Create(). +Do not return any value other than KErrNone from Create(), +otherwise the framework may call it again.

      Note that DMediaDriver::OpenMediaDriverComplete() can +be called from within the media driver class, if that is the way the driver +is designed, but Create() must still return KErrNone.

    • +
    • Asynchronous creation +- return either KErrNone, if initiation of the operation +was successful, or an error code, if the operation failed immediately. However, +it is the responsibility of the media driver object to signal completion.

    • +
  • +

The following is a typical example:

TInt DMyPhysicalDeviceMedia::Create(DBase*& aChannel, TInt aMediaId, const TDesC8* aInfo ,const TVersion &aVer) + { + // Check the build version of the media driver + if (!Kern::QueryVersionSupported(iVersion,aVer)) + { + return KErrNotSupported; + } + + //Create my DMediaDriver derived object + DMyMediaDriver* pD=new DMyMediaDriver (aMediaId); + aChannel=pD; + + // Call my media driver’s second-stage constructor + Tint r = KErrNoMemory; + if(pD) + { + r = pD->DoCreate(aMediaId); + } + + // Synchronous Creation (don’t do this if Asynchronous)… + if(r == KErrNone) + { + pD->OpenMediaDriverComplete(KErrNone); + } + + return r; + } +
+
Validate() +- check that the PDD is suitable for use

See also DPhysicalDevice::Validate().

This +PDD factory function is called by the kernel's device driver framework to +check whether this PDD is suitable for use with the media type specified in +the function.

A typical implementation of this function would perform +the following steps:

    +
  • Compare the build version +of the media driver with the version requested

  • +
  • Confirm that this driver +is responsible for the media type

  • +

The following is a very typical implementation:

TInt DMyPhysicalDeviceMedia::Validate(TInt aUnit, const TDesC8* aInfo, const TVersion& aVer) + { + // Check the build version of the media driver + if (!Kern::QueryVersionSupported(iVersion,aVer)) + { + return KErrNotSupported; + } + + // Check that the given type of media is supported by this driver + if (aUnit!=MEDIA_DEVICE_MYMEDIA) + { + return KErrNotSupported; + } + + return KErrNone; + } + +

Note that the value passed in via the aUnit argument +is the unique media ID used when the media driver was registered. In other +contexts, the argument may be denoted by the symobol aMediaId.

+
GetCaps() - +return the capabilities of the Media Driver

See also DPhysicalDevice::GetCaps().

For +media drivers, this PDD factory function is not used. However, an implementation +is required because the function is defined as pure virtual in the DPhysicalDevice base +class. Simply implement an empty function, for example:

void DMyPhysicalDeviceMedia::GetCaps(TDes8& /*aDes*/) const +// +// Return the media drivers capabilities. +// + { + } +
+
Info() - set +the priority of the media driver

See also DPhysicalDevice::Info().

This +PDD factory function is intended to return information relating to the media +driver. The function can, potentially, return many different types of information, +depending on the value passed as the first parameter. However, the only type +of information that Symbian platform currently requires is the priority of +the media driver. The returned priority value is used by Symbian platform +to decide the order in which media drivers are to be opened.

The default +implementation just returns 0, and therefore needs to be overridden.

Under +most circumstances, you can return the value KMediaDriverPriorityNormal. +You can, however, return KMediaDriverPriorityHigh in circumstances +where it is important that the driver is initialised before a lower priority +driver.

The following code fragment is a typical implementation:

TInt DMyPhysicalDeviceMedia::Info(TInt aFunction, TAny* /*a1*/) + { + if (aFunction==EPriority) + { + return KMediaDriverPriorityNormal; + } + return KErrNotSupported; + } +

where EPriority indicates that priority +information is required (this is an enum value of enum TInfoFunction, +defined in DPhysicalDevice.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-A70A01D2-467E-5BA8-A01D-6182558F3F52.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-A70A01D2-467E-5BA8-A01D-6182558F3F52.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,67 @@ + + + + + +Boot +Time Initialisation ImplementationHow to write an initialisation function, implemented by the Media +driver and called by the kernel at boot time. +

You use the DECLARE_STANDARD_EXTENSION() macro as a +wrapper around the code that does this. There are at two important things +to do at this stage:

+
    +
  • attach a DFC queue, +if the underlying media driver supports asynchronous creation

  • +
  • register the media driver +with the local media system.

  • +
+
Asynchronous +creation of the media driver

If the underlying media driver supports +asynchronous creation, then a DFC queue must be attached at this stage. +However, media drivers that interface to the Peripheral Bus Controller should +create a new DPBusPrimaryMedia object, as shown in the +code above, but should not allocate a DFC for asynchronous creation; this +is handled by the Peripheral Bus Controller.

See also Create() - create the media driver object.

+
Register the +media driver with the local media system

The media driver must +be registered with the Local Media Subsystem; this provides information such +as the number of supported drives, partitions, names and drive numbers. This +is done by calling LocDrv::RegisterMediaDevice(), and passing +appropriate values.

The media device type can be any of the TMediaDevice enumerated +values provide that a given value is only used once. This value may sometimes +be referred to as the media ID.

The values passed to this function +are highly dependent on the target hardware platform, and it is common practice +to define them in a file contained within the Variant directory, instead of +hard-coding them into generic Symbian platform code. For example, Variant +A may provide two PC Card slots, while Variant B may provide 4.

The +port for the template reference board has the header file ...\template_variant\inc\variantmediadef.h, +which defines constants that are used when registering a media driver for +that specific hardware.

Your code may find it convenient to use the +struct SMediaDeviceInfo to capture this information.

+

The following code is used:

DECLARE_STANDARD_EXTENSION() + { + TInt r=KErrNoMemory; + DPrimaryMediaBase* pM=new DPrimaryMediaBase; + if (pM) + { + //…Required here for Asynchronous creation (if supported) + pM->iDfcQ = &MyDfcQ; + + //…Perform registration here + r = LocDrv::RegisterMediaDevice(MEDIA_DEVICE_TYPE, + MEDIA_DRIVECOUNT, + &IMediaDriveNumbers[0], + pM,MEDIA_NUMMEDIA,KMediaDriveName + ); + } + return(r); + } +

You can also do any further initialisation that is appropriate +to your driver.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-A74BC61D-85E6-5DB5-93F4-DFE4F0B93EF2.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-A74BC61D-85E6-5DB5-93F4-DFE4F0B93EF2.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,17 @@ + + + + + +ConceptsDescribes the source code organisation and format of the bootstrap. +

+
+Port +Implementation Tutorial +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-A74F0245-1A37-41C8-B0E9-63AF858EE4B6.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-A74F0245-1A37-41C8-B0E9-63AF858EE4B6.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,13 @@ + + + + + +Platform ServicesSummary of platform services available on +the Symbian platform. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-A789E0D6-74B2-517D-B73A-F9B11794F175.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-A789E0D6-74B2-517D-B73A-F9B11794F175.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,160 @@ + + + + + +Peripheral Driver Power Implementation TutorialDescribes an implementation of the DPowerHandler class. +

Peripheral driver power management is based on the DPowerHandler class. This is a class that defines the interface that the driver +must provide to the generic kernel side power manager.

+

The class also provides the necessary support functions. The class +is defined as:

+class DPowerHandler : public DBase + { +public: + IMPORT_C ~DPowerHandler(); +public: + IMPORT_C DPowerHandler(const TDesC& aName); + IMPORT_C void Add(); + IMPORT_C void Remove(); + IMPORT_C void PowerUpDone(); + IMPORT_C void PowerDownDone(); + IMPORT_C void SetCurrentConsumption(TInt aCurrent); + IMPORT_C void DeltaCurrentConsumption(TInt aCurrent); +public: + virtual void PowerDown(TPowerState aTargetState) = 0; + virtual void PowerUp() = 0; +private: + ... + }; + +

Typically, at least one power handler object is implemented by +the peripheral driver. In some cases the peripheral driver interface +class may derive from DPowerHandler, in others +it creates and owns an instance of a DPowerHandler derived class.

+

The first eight functions are exported from the kernel, EKERN.EXE, while the remaining two pure virtual functions +are implemented by the peripheral driver.

+
    +
  • PowerDown()

  • +
  • PowerUp()

  • +
+

Notes:

+
    +
  1. Current consumption +monitoring does not have a full implementation in the power manager +at present. It is unclear whether this will be ever required. However, DPowerHandler does provide two functions: DPowerHandler::SetCurrentConsumption() and DPowerHandler::DeltaCurrentConsumption() that +a power handler can use to track the peripheral's power consumption. +Note that this is not based on actual measurements.

    SetCurrentConsumption() sets a target current consumption, +usually at driver creation time.

    DeltaCurrentConsumption() changes this target current consumption value, specifying a positive +or a negative value as appropriate; this might be called in response +to an operation that is about to start.

    Although we have described +the context in which these functions would be used, we recommend that +you do not use them.

  2. +
  3. Fixed media +drivers do not have a power handler. This means there is currently +no mechanism to power down media drivers and the associated fixed +media when the system transitions to a low power state.

  4. +
  5. The __NEW_POWER_HANDLERS macro is used to maintain backwards +compatibility with the power model used in previous versions of Symbian +platform. If this macro is not defined, it is possible for +power handlers to revert back to the behavior they present in Kernel +Architecture 1 (EKA1).

    If implementing an old style power +handler, the following functions will have to have an implementation +provided by the peripheral driver:

    virtual TInt DoPowerUp() +virtual void DoPowerDown(TUint32 /* aPowerDownMask */) +virtual void DoEmergencyPowerDown() +

    If using at least an old style power handler +the power manager will not complete any powering down (transition +to Off or Standby). Thus it is recommended that they +not be used.

  6. +
+
DPowerHandler::PowerDown() virtual void PowerDown(TPowerState) = 0;

When is it called?

DPowerHandler::PowerDown() is called by the Power manager during a transition to the Standby or +the Off state. The TPowerState argument +specifies which of the two power states is the target.

Implementation issues

    +
  1. After receiving +a request to power down, as a result of a system transition to the Standby or Off states, a peripheral driver should perform +the necessary activity to power down the peripheral and ancillary +hardware, unless it is required for the detection of wake-up events. +This activity might include requesting the removal of the power supply +and any other power resources.

  2. +
  3. The power down +operation can be done in the same thread in which PowerDown() runs, i.e. synchronously, or it can run in another thread, i.e. +asynchronously. You would probably implement power down in another +thread if the operation were potentially slow. Once the peripheral +has powered down, it must inform the power manager by calling DPowerHandler::PowerDownDone(), and this function can be +called from the same thread in which PowerDown() runs, +or it can be called from another thread. Two points to note:

      +
    • PowerDownDone() can be called before or after PowerDown() returns

    • +
    • PowerDownDone() cannot be called before PowerDown() has been entered.

    • +
  4. +
  5. PowerDown() is only called on a transition to the Standby or the Off state. If the peripheral hardware is powered down when the peripheral +driver is closed, or when the hardware resources are relinquished +by the driver, then this is managed by the driver alone.

  6. +
  7. There are synchronisation +issues related to calls to the DPowerHandler::Add() and DPowerHandler::Remove() functions. DPowerHandler::Add() is called by the peripheral driver +when the driver object is created. This registers the power handler +with the power manager so that so that the driver can receive notification +of power state transitions. Conversely, DPowerHandler::Remove() is called when the peripheral driver is in the process of being +destroyed. This de-registers the power handler so that the driver +is no longer notified of power state transitions. Calls to DPowerHandler::Add(), DPowerHandler::Remove(), DPowerHandler::PowerDown() and DPowerHandler::PowerUp() can run asynchronously in relation to one another. For example, +it is entirely possible that the kernel may be asking the driver to +power down while it is being created, or indeed while it is being +destroyed.

    To avoid deadlock, DPowerHandler::Add(), DPowerHandler::Remove(), and the Power manager functions that call your DPowerHandler::PowerDown() and your DPowerHandler::PowerUp() functions, +all acquire a lock, a DMutex. While the lock itself +is internal to Symbian platform, it does impose a requirement that:

      +
    • DPowerHandler::Add()

    • +
    • DPowerHandler::Remove()

    • +
    • DPowerHandler::PowerDown()

    • +
    • DPowerHandler::PowerUp()

    • +

    all run in the same thread. A common implementation of DPowerHandler::PowerDown(), therefore, schedules a DFC +to run on the same thread (a DFC queue) as the one that calls DPowerHandler::Add() and DPowerHandler::Remove().

  8. +
+
DPowerHandler::PowerUp() virtual void PowerUp() = 0;

When is it called?

DPowerHandler::PowerUp() is called by the Power manager during a transition from the Standby state +back to the Active state. It is up to the peripheral driver +to decide whether or not to power up the peripheral.

Implementation +issues

    +
  1. After receiving +a notification to power up, as a result of a system transition from +the Standby to the Active state, it is up to the peripheral +driver to decide whether or not to power up the peripheral and ancillary +hardware. The decision usually depends on whether or not the peripheral +driver is currently in use.

  2. +
  3. The power up +operation can be done in the same thread in which PowerUp() runs, i.e. synchronously, or it can run in another thread, i.e. +asynchronously. You would probably implement power up in another thread +if the operation were potentially slow. Whether or not the peripheral +driver intends to power up immediately, it must acknowledge the power +up request by calling DPowerHandler::PowerUpDone(), and this function can be called from the same thread in which PowerUp() runs, or it can be called from another thread. +Two points to note:

      +
    • PowerUpDone() can be called before or after PowerUp() returns

    • +
    • PowerUpDone() cannot be called before PowerUp() has been entered.

    • +
  4. +
  5. PowerUp() is only called on a transition to the Active state. If the +peripheral hardware is powered up when the peripheral driver is opened, +or when the hardware resources are first used by the driver, then +this is managed by the driver alone.

  6. +
  7. There are synchronisation +issues related to calls to the DPowerHandler::Add() and DPowerHandler::Remove() functions. DPowerHandler::Add() is called by the peripheral driver +when the driver object is created. This registers the power handler +with the power manager so that so that the driver can receive notification +of power state transitions. Conversely, DPowerHandler::Remove() is called when the peripheral driver is in the process of being +destroyed. This de-registers the power handler so that the driver +is no longer notified of power state transitions. Calls to DPowerHandler::Add(), DPowerHandler::Remove(), DPowerHandler::PowerDown() and DPowerHandler::PowerUp() can run asynchronoulsy in relation to one another. For example, +it is entirely possible that the kernel may be asking the driver to +power down while it is being created, or indeed while it is being +destroyed.

    To avoid deadlock, DPowerHandler::Add(), DPowerHandler::Remove(), and the power manager functions that call your DPowerHandler::PowerDown() and your DPowerHandler::PowerUp() functions, +all acquire a lock, a DMutex. While the lock itself +is internal to Symbian platform, it does impose a requirement that:

      +
    • DPowerHandler::Add()

    • +
    • DPowerHandler::Remove()

    • +
    • DPowerHandler::PowerDown()

    • +
    • DPowerHandler::PowerUp()

    • +

    all run in the same thread. A common implementation of DPowerHandler::PowerUp(), therefore, schedules a DFC to +run on the same thread (a DFC queue) as the one that calls DPowerHandler::Add() and DPowerHandler::Remove().

  8. +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-A7ECF51F-F96A-5251-A71F-2F269C8C0664.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-A7ECF51F-F96A-5251-A71F-2F269C8C0664.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,204 @@ + + + + + +Accessor +Functions for Derived AttributesExplains how to add accessor functions for derived attributes. +

You can change HAL to add accessor functions for new derived attributes. +This step is not often done, because all normal accessor functions are already +defined in ...\hal\src\userhal.cpp.

+

Each derived attribute is declared with an associated function name in Config +file. A function with that name must be provided, and it must have +the following signature, which is also defined by the THalImplementation typedef:

+TInt Function(TInt aAttrib, TBool aSet, TAny* aInOut); +

This function is called whenever any client of the HAL references the associated +attribute.

+ + + + +

aAttrib

+

Contains the attribute number.

+
+ +

aSet

+

Defines whether the attribute is being set or being read: ETrue means +that the attribute value is being set; EFalse means that +the attribute value is being read.

Note that if the attribute, as +defined in the config.hcf file, does not have the settable +property, then aSet is ignored .

+
+ +

aInOut

+

A pointer to a TInt type, that contains:

    +
  • the attribute value +to be set, if aSet is ETrue

  • +
  • the attribute value +to be read, if aSet is EFalse.

  • +
+
+ + +
+

Once the config file has been written, the Perl script ...\hal\group\halcfg.pl can +be used to generate a skeleton implementation file. For example, calling

+

perl \hal\group\halcfg.pl -s \hal\inc\hal_data.h config.hcf +imp.cpp

+

produces the file imp.cpp containing the following +skeleton code for each derived attribute:

+// EAttributeName +TInt Function(TInt /*aAttrib*/, TBool /*aSet*/, TAny* aInOut) + { + return KErrNone; + } + +

The full implementation for the function can now be written.

+

Notes:

+
    +
  • The aAttrib parameter +is always marked as a comment because it is not usually needed; it is only +needed if the same function is used to implement more than one attribute.

  • +
  • The aSet parameter +is marked as a comment if the attribute does not have the settable property.

  • +
  • On some platforms it +may be necessary to access some HAL attributes via a device driver or server, +rather than using UserSvr::HalFunction() . In this case, +a handle to the device driver or server must be opened on the first access. +Use the HalInternal::Tls() function to do this.

  • +
  • Access to any HAL attribute +requiring the use of a server or device driver can fail due to lack of memory.

  • +
+

Thee code fragments in the example +accessor functions show the cases where the HAL has an attribute that +requires a device driver and another attribute that requires a server.

+

See also halcfg.pl +Syntax.

+
Example accessor +functions for derived attributes using a device driver and a server

This +code fragment shows the implementation of accessor functions for two HAL derived +attributes. One uses a device driver, and the other uses a server to provide +the necessary functionality.

The examples assume that the attributes +are defined in the config.hcf file with function names Attrib1 and Attrib2.

Using a device driver

TInt Attrib1(TInt /*aAttrib*/, TBool aSet, TAny* aInOut) + { + // Do something with the device driver + RHwDevice d; + TInt r=GetDeviceDriverHandle(d); + if (r==KErrNone) + { + if (aSet) + { + r=d.Write((TInt)aInOut); + } + else + { + r=d.Read(*(TInt*)aInOut); + } + } + return r; + } TInt GetDeviceDriverHandle(RHwDevice& aDevice) + { + // Return the device driver handle for this thread + // If it doesn't exist, attempt to open a handle + // Careful with OOM errors + + SHandles* pH=GetHandles(); + if (!pH) + { + return KErrNoMemory; // couldn't allocate TLS memory + } + if (pH->iDevHandle) + { + // device driver handle already open + aDevice.SetHandle(pH->iDevHandle); + return KErrNone; + } + + // note: Someone should have previously loaded the required + // device driver. Eg. + // User::LoadLogicalDevice(_L("HARDWARE.LDD")); + // This can be done here, but it is inefficient since it will + // happen once per thread. It's much better to do it once + // at Hal start-up. + + TInt r=aDevice.Open(); // open handle to driver + if (r==KErrNone) + { + pH->iDevHandle=aDevice.Handle(); // store handle + } + return r; + } struct SHandles + { + TInt iDevHandle; + TInt iSvrHandle; + }; + SHandles* GetHandles() + { + // Return a pointer to the SHandles structure for this thread + // If it doesn't exist, attempt to create it + + // This function zeros a newly allocated memory block + return (SHandles*)HalInternal::Tls(sizeof(SHandles)); + } +

Using +a server

TInt Attrib2(TInt /*aAttrib*/, TBool aSet, TAny* aInOut) + { + // Do something with the server + RHwServer s; + TInt r=GetServerHandle(s); + if (r==KErrNone) + { + if (aSet) + { + r=s.Write((TInt)aInOut); + } + else + { + r=s.Read(*(TInt*)aInOut); + } + } + return r; + } TInt GetServerHandle(RHwServer& aServer) + { + // Return the server handle for this thread + // If it doesn't exist, attempt to open a handle + // Careful with OOM errors + + SHandles* pH=GetHandles(); + if (!pH) + { + return KErrNoMemory; // couldn't allocate TLS memory + } + if (pH->iSvrHandle) + { + // server handle already open + aServer.SetHandle(pH->iSvrHandle); + return KErrNone; + } + TInt r=aServer.Connect(); // create session with server + if (r==KErrNone) + { + pH->iSvrHandle=aServer.Handle(); // store handle + } + return r; + } struct SHandles + { + TInt iDevHandle; + TInt iSvrHandle; + }; + SHandles* GetHandles() + { + // Return a pointer to the SHandles structure for this thread + // If it doesn't exist, attempt to create it + + // This function zeros a newly allocated memory block + return (SHandles*)HalInternal::Tls(sizeof(SHandles)); + } +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-A819DE06-7B00-4643-9D3E-EFE14132981C-master.png Binary file Adaptation/GUID-A819DE06-7B00-4643-9D3E-EFE14132981C-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-A819DE06-7B00-4643-9D3E-EFE14132981C_d0e99133_href.png Binary file Adaptation/GUID-A819DE06-7B00-4643-9D3E-EFE14132981C_d0e99133_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-A819DE06-7B00-4643-9D3E-EFE14132981C_d0e99345_href.png Binary file Adaptation/GUID-A819DE06-7B00-4643-9D3E-EFE14132981C_d0e99345_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-A87D9280-B61A-49BA-A9AF-178DB9BAECBC.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-A87D9280-B61A-49BA-A9AF-178DB9BAECBC.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,101 @@ + + + + + +Reading and WritingThis document describes how device drivers should open, read from +and write to shared chunks. +

Both user-side code and drivers can read and write to shared chunks. Once +the chunk is created, opened, and memory committed to it, data can be written +and read to the shared chunk using the base address.

+
Opening

If a shared chunk has already been created +by a driver, then another driver can access that shared chunk through its +handle by using one of the following functions:

DChunk* Kern::OpenSharedChunk(DThread* aThread, TInt aChunkHandle, + TBool aWrite); + +DChunk* Kern::OpenSharedChunk(DThread *aThread, + const TAny *aAddress, TBool aWrite, + TInt &aOffset); +
+
User-side access

RChunk is +the user side representation of a shared chunk. The user gets a shared chunk +handle from a driver, and initialises the RChunk object with +it using RChunk::SetHandle(TInt aHandle).

The user +can now obtain the base address of the chunk by calling RChunk::Base(). +Data can be read or written to this memory location, in same way as any other +memory.

// User side chunk object. + RChunk chunkTx; + +// Get the handle to the chunk. A driver creates the chunk and +// returns the handle to the user to access it. The handle is +// assigned to the user side chunk object using RChunk::SetHandle(). +// (here done in the GetTxChunkHandle function). The handle has to be a positive +// value. It can be obtained using RChunk::Handle(), if required. +// +r=ldd.GetTxChunkHandle(chunkTx); +test(r==KErrNone); + +// Create a constant descriptor with test data +_LIT8(KTestSendData,"<< TEST DATA FOR TUTORIAL DRIVER EXAMPLE >>"); + +TUint8* chunkbase; +// Retrieve the base address of the chunk. Using this address, the user +// can access the shared chunk just like any memory pointer. +// RChunk::Base() returns the linear address of the shared chunk. +// +chunkbase=chunkTx.Base(); + +// Write the data to the shared chunk, using the chunk base address. +// Note here we do not need to send data to the driver. We just write to +// the buffer and the driver directly accesses the chunk from the kernel side. +// +TPtr8 inbuf(chunkbase,KTestSendData().Size()); +inbuf = KTestSendData; +… + +// Call the LDD interface TransmitData(). There is no need to send the +// data, instead we send only a TRequestStatus object (as it's an +// asynchronous function), and buffer size. If required, an offset in the shared chunk +// can be passed to the driver. +r = ldd.TransmitData(txStatus,inbuf.Size()); + test(r==KErrNone);
+
Kernel-side access

On the kernel side, a chunk +is represented by a DChunk object. A chunk is created, +mapped, or opened as shown in earlier sections. The linear and physical addresses +of the chunk are returned when this is done. At a later stage in the driver, +use Kern::ChunkAddress() and Kern::ChunkPhysicalAddress() to +get the linear and physical addresses respectively. A chunk is read or written +to using this address pointer and an offset.

// Note: Following lines of code are located in different +// functions and different files. Here they are shown together for +// easy comprehension. + +// Linear address of the Rx Shared chunk +TLinAddr iRxChunkKernAddr; +... + +// iRxChunkKernAddr returns the linear address of the Rx chunk +TInt r=Kern::ChunkCreate(info,chunk,iRxChunkKernAddr, mapAttr); +... + +// iRxBufPhysAddr returns the physical address of the Rx chunk +r=Kern::ChunkCommitContiguous(chunk, bufoffset, size, iRxBufPhysAddr); +... + +// Here we are directly using the linear address of the shared +// chunk, and so can get rid of any buffer copies. If the DMA +// port supports physical address, then the physical address can be +// used instead of a linear address. +// +TInt retval = iRxDmaRequest->Fragment( + TUint32)iUartComm->iPortAddr+KHoUART_RHR, + TUint32)(iUartComm->iRxChunkKernAddr), aCount, + KDmaMemDest|KDmaIncDest, 0 /* no HW Flags*/);

Synchronization +between user access and kernel access to a shared chunk is handled by the +shared chunk API.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-A90D9D85-53DC-5368-89F2-137BE5D50745-GENID-1-2-1-8-1-1-7-1-1-4-1.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-A90D9D85-53DC-5368-89F2-137BE5D50745-GENID-1-2-1-8-1-1-7-1-1-4-1.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,83 @@ + + + + + +Kernel +API Validity ChecksDescribes the pre-condition checks that Kernel APIs can do when +they are called. +
    +
  • What does checking the validity of calls mean?

  • +
  • What happens if a validity check fails?

  • +
  • Which conditions are checked?

  • +
+
What does checking +the validity of calls mean?

A kernel-side function or service almost +always requires that various preconditions apply before that function or service +can be called. There are also times when a call to a kernel-side function +or service from device drivers may not be appropriate, for example, calls +to some specific functions from within Interrupt Service Routines (ISRs) or +from within Deferred Function Calls (DFCs).

For example, before you +call Kern::CloseHandle(), the following conditions apply:

    +
  • the calling thread must +be in a critical section

  • +
  • interrupts must be enabled

  • +
  • the kernel must be unlocked

  • +
  • no fast mutex can be +held

  • +

If conditions such as these are not met before you call the kernel-side +function or service, then you risk damaging the integrity of the kernel and +the whole system, with a very high risk of causing the kernel to fault followed +by a re-boot of the device.

The pre-conditions that apply vary with +the function called; they are listed as part of the reference documentation +for that function.

To help device driver test suites check that device +driver code is valid, stringent checks can be switched on in debug (non-production) +builds of Symbian platform (and in the resulting test ROM images). These checks +help to catch non-compliant device driver code during the testing phase of +a new device. This minimizes the risk of production devices failing because +of faulty device driver code.

+
What happens +if a validity check fails?

Validity checking is done by code that +is conditionally compiled into a build of Symbian platform. Such code has +an impact on the performance of the device on which it runs, but is always +restricted to test devices. On production builds of Symbian platform, validity +checking is switched off, which means that the code is not compiled in and +has no effect on performance.

Validity checking is switched ON for +a build of Symbian platform if one or both of the following macros +is defined in ...\e32\kernel\kern_int.mmh :

    +
  • __KERNEL_APIS_CONTEXT_CHECKS_WARNING__

  • +
  • __KERNEL_APIS_CONTEXT_CHECKS_FAULT__

  • +

Validity checking is switched OFF for a build of Symbian platform +if both macros are undefined (in practice they will be marked +as a comment rather than being completely deleted from the .mmh file).

__KERNEL_APIS_CONTEXT_CHECKS_WARNING__

If +this macro is defined, then calling a kernel-side function when the necessary +pre-conditions have not been satisfied causes a text message to be written +to a trace port. The message has the format:

Description of pre-condition that has not been met +The name of the function checking the pre-condition

For example, +when you call DLogicalChannel::Close(), you must be in +a critical section. If you are not, then you will see the following text in +your trace:

Assertion failed: Calling thread must be in a critical section +DLogicalChannel::Close

__KERNEL_APIS_CONTEXT_CHECKS_FAULT__

If +this macro is defined, then calling a kernel-side function when the necessary +pre-conditions have not been satisfied:

    +
  1. causes a text message +to be written to a trace port, as happens if __KERNEL_APIS_CONTEXT_CHECKS_WARNING__ is defined.

  2. +
  3. causes the kernel to +fault, specifying the function name as the fault category, and zero as the +fault number. The crash debugger is also started if this is present on the +device.

  4. +

__KERNEL_APIS_CONTEXT_CHECKS_WARNING__ +and __KERNEL_APIS_CONTEXT_CHECKS_FAULT__

If both macros are defined, +then validity checking behaves as if __KERNEL_APIS_CONTEXT_CHECKS_FAULT__ is defined.

+
Which conditions +are checked?

The section pre-conditions within the larger section Pre-Conditions +and Post-Conditions for Kernel APIs gives you some context for the +most common pre-conditions that apply when calling kernel-side functions. +This list is not exhaustive.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-A90D9D85-53DC-5368-89F2-137BE5D50745-GENID-1-2-1-9-1-8-1-17-1.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-A90D9D85-53DC-5368-89F2-137BE5D50745-GENID-1-2-1-9-1-8-1-17-1.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,83 @@ + + + + + +Kernel +API Validity ChecksDescribes the pre-condition checks that Kernel APIs can do when +they are called. +
    +
  • What does checking the validity of calls mean?

  • +
  • What happens if a validity check fails?

  • +
  • Which conditions are checked?

  • +
+
What does checking +the validity of calls mean?

A kernel-side function or service almost +always requires that various preconditions apply before that function or service +can be called. There are also times when a call to a kernel-side function +or service from device drivers may not be appropriate, for example, calls +to some specific functions from within Interrupt Service Routines (ISRs) or +from within Deferred Function Calls (DFCs).

For example, before you +call Kern::CloseHandle(), the following conditions apply:

    +
  • the calling thread must +be in a critical section

  • +
  • interrupts must be enabled

  • +
  • the kernel must be unlocked

  • +
  • no fast mutex can be +held

  • +

If conditions such as these are not met before you call the kernel-side +function or service, then you risk damaging the integrity of the kernel and +the whole system, with a very high risk of causing the kernel to fault followed +by a re-boot of the device.

The pre-conditions that apply vary with +the function called; they are listed as part of the reference documentation +for that function.

To help device driver test suites check that device +driver code is valid, stringent checks can be switched on in debug (non-production) +builds of Symbian platform (and in the resulting test ROM images). These checks +help to catch non-compliant device driver code during the testing phase of +a new device. This minimizes the risk of production devices failing because +of faulty device driver code.

+
What happens +if a validity check fails?

Validity checking is done by code that +is conditionally compiled into a build of Symbian platform. Such code has +an impact on the performance of the device on which it runs, but is always +restricted to test devices. On production builds of Symbian platform, validity +checking is switched off, which means that the code is not compiled in and +has no effect on performance.

Validity checking is switched ON for +a build of Symbian platform if one or both of the following macros +is defined in ...\e32\kernel\kern_int.mmh :

    +
  • __KERNEL_APIS_CONTEXT_CHECKS_WARNING__

  • +
  • __KERNEL_APIS_CONTEXT_CHECKS_FAULT__

  • +

Validity checking is switched OFF for a build of Symbian platform +if both macros are undefined (in practice they will be marked +as a comment rather than being completely deleted from the .mmh file).

__KERNEL_APIS_CONTEXT_CHECKS_WARNING__

If +this macro is defined, then calling a kernel-side function when the necessary +pre-conditions have not been satisfied causes a text message to be written +to a trace port. The message has the format:

Description of pre-condition that has not been met +The name of the function checking the pre-condition

For example, +when you call DLogicalChannel::Close(), you must be in +a critical section. If you are not, then you will see the following text in +your trace:

Assertion failed: Calling thread must be in a critical section +DLogicalChannel::Close

__KERNEL_APIS_CONTEXT_CHECKS_FAULT__

If +this macro is defined, then calling a kernel-side function when the necessary +pre-conditions have not been satisfied:

    +
  1. causes a text message +to be written to a trace port, as happens if __KERNEL_APIS_CONTEXT_CHECKS_WARNING__ is defined.

  2. +
  3. causes the kernel to +fault, specifying the function name as the fault category, and zero as the +fault number. The crash debugger is also started if this is present on the +device.

  4. +

__KERNEL_APIS_CONTEXT_CHECKS_WARNING__ +and __KERNEL_APIS_CONTEXT_CHECKS_FAULT__

If both macros are defined, +then validity checking behaves as if __KERNEL_APIS_CONTEXT_CHECKS_FAULT__ is defined.

+
Which conditions +are checked?

The section pre-conditions within the larger section Pre-Conditions +and Post-Conditions for Kernel APIs gives you some context for the +most common pre-conditions that apply when calling kernel-side functions. +This list is not exhaustive.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-AA53650C-664C-53F0-8BE9-445677FC1FE2-master.png Binary file Adaptation/GUID-AA53650C-664C-53F0-8BE9-445677FC1FE2-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-AA53650C-664C-53F0-8BE9-445677FC1FE2_d0e19130_href.png Binary file Adaptation/GUID-AA53650C-664C-53F0-8BE9-445677FC1FE2_d0e19130_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-AABC7605-9EE9-41E4-BFDF-77A589A9887B.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-AABC7605-9EE9-41E4-BFDF-77A589A9887B.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,44 @@ + + + + + +Building +a DMA AdaptationThis document describes what is needed to include the DMA adaptation +in a ROM image. +

When building a ROM image, all the processes and data needed to execute +a build are included in a single file. This file is executed by the platform +when the hardware is powered up.

+
Requirements
    +
  • DMA framework.

  • +
  • You must be familiar with building a ROM for the Symbian platform.

  • +
+
Use the template +port to start your port

There is a template DMA Framework consisting +of the source file dmapsl.cpp, and the .mmp file dma.mmp located +in the directory ...\template\dma that can be used as +the starting point for your DMA PSL port. You need to:

    +
  • Decide which directory your DMA PSL and associated.mmp file +are to be stored in. You would normally choose the Variant or the ASSP directory.

  • +
  • Copy the template framework into your chosen location. Be aware that +the template dma.mmp file contains relative paths that +must be updated.

  • +
  • Change the Variant's bld.inf file to include a +reference to your mmp file.

  • +
+
Building the +ROM with DMA included

Include the DMA PIL libraries +in the final ROM image, in the list of buildrom parameters.

For more +information, refer to BUILDROM .

+
+ROM Tools +Overview +BUILDROM + +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-AB5370D9-9F0B-4583-A825-11CBF7C6365C.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-AB5370D9-9F0B-4583-A825-11CBF7C6365C.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,12 @@ + + + + + +DMA Tutorials Overview How to use the DMA for different types of data transfers. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-AB9175EB-1B61-5341-B6B9-5613A7862D74.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-AB9175EB-1B61-5341-B6B9-5613A7862D74.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,278 @@ + + + + + +Channel +ImplementationDescribes how to implement DComm to drive a serial +port hardware. +

A physical channel defines the interface between the logical device and +the physical device. The Serial Port Driver physical channel interface is +defined by the DComm class.

+

The DComm class is defined in: ...\e32\include\drivers\comm.h, +which is exported to epoc32\include\drivers:

+class DComm : public DBase + { +public: + virtual TInt Start() =0; + virtual void Stop(TStopMode aMode) =0; + virtual void Break(TBool aState) =0; + virtual void EnableTransmit() =0; + virtual TUint Signals() const =0; + virtual void SetSignals(TUint aSetMask,TUint aClearMask) =0; + virtual TInt ValidateConfig(const TCommConfigV01 &aConfig) const =0; + virtual void Configure(TCommConfigV01 &aConfig) =0; + virtual void Caps(TDes8 &aCaps) const =0; + virtual void CheckConfig(TCommConfigV01& aConfig)=0; + virtual TInt DisableIrqs()=0; + virtual void RestoreIrqs(TInt aIrq)=0; + virtual TDfcQue* DfcQ(TInt aUnit)=0; + inline TBool PowerGood(); + inline void SetCurrent(TInt aCurrent); + inline void ReceiveIsr(TUint* aChar, TInt aCount, TInt aXonXoff); + inline TInt TransmitIsr();inline void CheckTxBuffer(); + inline void StateIsr(TUint aSignals); + inline TBool Transmitting(); +public: + DChannelComm *iLdd; + TBool iTransmitting; + }; + +

Note that DComm defines the minimum set of functions to +be used by the LDD. A real physical channel object, typically, requires the +addition of an interrupt handler, some DFC callback routines (if these are +not handled in the LDD itself) and various other state variables.

+
DCommVariant constructor

Implement the constructor +for the channel object. Since there is no unit number argument, the constructor +is limited to initialising only those members that are common across all possible +channels, with no access to any specific hardware.

+
DCommVariant destructor

Implement the destructor +for the channel object. It should release any hardware and Symbian platform +resources that have been allocated to the driver, typically unbinding the +UART interrupt ISR, and any private DFCs that are still in use. The destructor +merely unbinds the interrupt as no channel specific DFCs are active at destructor +invocation.

+
DoCreate()

Implement the DoCreate() channel +initialisation function for the UART driver. In general, defining a DoCreate() function +is not mandated by the device driver framework but is useful for drivers that +make use of unit numbers. This is called by the factory object’s Create() function after the device object’s allocation has succeeded.

Typical +operations performed by this function are to setup any channel specific hardware +states and bind the driver’s ISR to the (possibly channel specific) interrupt +channel, as well as enabling the UART hardware itself. However, since the Start() function +has not yet been called, it should not enable the UART interrupts/poll routines +which would actively buffer incoming data; any data I/O requests should be +discarded until the driver’s Start() routine +has been called.

+
Start()

Implement +the Start() function. This should enable the driver’s receive +path.

Received characters are placed in the LDD upstream buffer, either +by the interrupt handler routine, or by a polling routine that tests for the +existence of received characters (and their associated error state). This +is done by calling the LDD’s ReceiveIsr() routine, with a +pointer to the buffered characters, a count and a flag indicating whether +the XON or XOFF flow control characters have been received.

The function +is called by the LDD when the owning thread opens the device channel. It should +complete any UART data I/O enabling that has not already been performed in +the DoCreate() function, i.e. the enabling of UART receive +interrupt processing as a minimum. After this function returns, it is expected +that incoming data will be placed in a (local) buffer and passed upstream +to the LDD, until Stop() is +invoked. Note that since there may have been line activity prior to this call, +it may be necessary to reset the UART state, as we do not want to report errors/states +that may have occurred before the UART was (logically) enabled.

+
Stop()

Implement +the Stop() function. This should disable the driver’s transmit +and receive paths.

Depending on the type of stop requested, i.e. emergency +power down, or otherwise, Stop() may not wait for the UART +to finish transmitting any characters stored in the transmit FIFO queue. All +receive paths are stopped instantly and any characters that may be in the +receive FIFO queue are ignored.

The function is called by the LDD when +the owning thread closes the device channel. At this point, the UART device +should revert to the state in which all data I/O requests are ignored or failed. +To save OS resources the natural method to accomplish this is to disable the +UART interrupt processing or disable the UART itself. It may also be necessary +to cancel any DFCs queued, so that event notifications are not sent to the +LDD after it has requested an end to I/O.

+
DfcQ()

Implement the DfcQ() function. +This should return the DFC queue on which the LDD will install its DFCs. Usually +the standard low priority kernel DFC queue 0 is returned.

+
Break()

Implement the Break() function. +This starts or ends a BREAK condition on the wire.

This operation is +explicitly requested by the owning thread through the LDD. A break state requires +the forcing of the line into an abnormal state, which violates standard data +format timings (a form of out of band signalling), and is detected by the +remote device and is usually used to force it to cycle through its baud rate +detection modes. Forcing a break state requires that the PDD explicitly set +some state in the UART hardware.

+
Signals()

Implement +the Signals() function. This returns the state of the flow +and MODEM control inputs, ie. DCD, DSR, CTS and RI (if implemented on the +device itself). This function is called by the LDD to return the state of +all the handshaking lines so that it can decide whether further data I/O operations +are allowed.

+
SetSignals()

Implement the SetSignals() function. +This controls the state of the flow and MODEM control outputs. It is used +by the LDD to control MODEM handshaking and line failure detection, and can +be invoked in response to a specific user request to change the handshake +signal’s state, or when the LDD itself decides that the output lines states +should be changed in response to some transfer state (e.g. requesting no further +transmissions if buffer availability runs low).

+
Caps()

Implement +the Caps() function. This returns the driver supported configurations: +speed, format, and handshaking.

It is called by the LDD in response +to a user request for the device's capabilities. The PDD must fill a TCommCapsV02 object, +with the capabilities for that port.

The object is defined in d32comm.h:

class TCommCapsV01 + { +public: + TUint iRate; + TUint iDataBits; + TUint iStopBits; + TUint iParity; + TUint iHandshake; + TUint iSignals; + TUint iFifo; + TUint iSIR; + }; + +class TCommCapsV02 : public TCommCapsV01 + { +public: + TUint iNotificationCaps; + TUint iRoleCaps; + TUint iFlowControlCaps; + };

The base object, TCommCapsV01, defines +capabilities in terms of:

    +
  • data rate

  • +
  • word format (i.e. parity, +data bits, stop bits)

  • +
  • flow control lines

  • +
  • MODEM control lines

  • +
  • IrDA support.

  • +

Each attribute range is passed as a bitfield of possible settings, +all assumed to be orthogonal, i.e. each attribute can assume all the values +independently of the other attributes.

The attribute bitfields are +defined in d32comm.h.

The iSIR attribute +in TCommCapsV01 indicates whether the port can support +slow infrared protocol.

The iNotificationCaps attribute +in TCommCapsV02 allows the driver to describe its ability +to report asynchronous events, if requested to do so by the client thread. +The only useful applications seem to be to report data arrival and handshake +line status change, although fields exist for other capabilities.

The iRoleCaps attribute +in TCommCapsV02 is intended to indicate that the device +is capable of acting as a DCE as well as a DTE, i.e. that the port can be +configured to act like a MODEM port. This essentially reverses the normal +I/O of the status lines, and could add functionality such as ring indication. +Normal UART devices will never need to change this field from the default, +i.e. DTE device personality.

The iFlowControlCaps field +in TCommCapsV02 is unused and should be set to 0.

The iHandshake field +in TCommCapsV01 describes the flow control signal support +on the device. Input signals have attributes “Obey” and “Fail” e.g. ObeyCts, +FailCts. Output signals have only the “Free” attribute, which indicates they +can be driven (via a call to Signals()) +to any state, independent of the internal state of the UART, i.e. they are +entirely under LDD control. The Fail attribute implies that the LDD will deem +operations to have failed if an input line thus labelled becomes disasserted. +This means that the PDD can report these signal states asynchronously. If, +for example, a change in CTS state can generate an interrupt, then the PDD +should report it as possessing both Obey and Fail attributes, whereas if the +DCD line cannot generate an asynchronous event, it should merely present itself +as “Obey”. If the line is unimplemented then neither attribute should be reported.

+
Configure()

Implement the Configure() function. +This configures the UART device according to the configuration data passed +into the function.

Configuration data is encapsulated by a TCommConfigV02 object:

class TCommConfigV01 + { +public: + TBps iRate; + TDataBits iDataBits; + TStopBits iStopBits; + TParity iParity; + TUint iHandshake; + TUint iParityError; + TUint iFifo; + TInt iSpecialRate; + TInt iTerminatorCount; + TText8 iTerminator[KConfigMaxTerminators]; + TText8 iXonChar; + TText8 iXoffChar; + TText8 iParityErrorChar; + TSir iSIREnable; + TUint iSIRSettings; + }; + +class TCommConfigV02: public TCommConfigV01 + { +public: + TInt iTxShutdownTimeout; + }; +

This function is called by the LDD when the physical channel +is opened. The default configuration is set by the LDD when the Dcomm object +is constructed, but the user can override the configuration with a SetConfig request +on the opened channel. The configuration is described by specifying a set +of individual capability attributes from the supported ranges returned in +the Caps() call.

Note +that the iTerminatorCount, the iTerminatorArray and iSpecialRate are +currently unused. The iParityErrorChar replaces the character +that the UART determined had a parity violation. This can be used to send +a prearranged escape character to the upstream LDD.

+
CheckConfig()

Implement the CheckConfig() function. +This is used by autosensing UARTs to pass detected configuration upstream +to the LDD. This is called by the LDD when it creates the initial channel +to allow the autosensed state to override any default it has set. If the UART +device cannot perform autosensing, and most cannot, then the CheckConfig() function +should leave the parameter buffer unchanged.

+
ValidateConfig()

Implement the ValidateConfig() function. +This returns true if the specified configuration is supported by the driver. +This should never return false if the correct capabilities have been setup, +but may be used to check for cases where, for example, a specific set of attributes +cannot be applied together. As an example, a data format word size may not +be generated for some specific baud rate.

+
DisableIrqs()

Implement the DisableIrqs() function. +This is called by the LDD to disable (all) interrupts during critical sections, +for example, during LDD buffer manipulation. It calls the kernel utility to +perform the task.

+
RestoreIrqs()

Implement the RestoreIrqs() function, +called by the LDD to enable (all) interrupts after critical sections have +completed. Calls the kernel utility to perform the task.

+
EnableTransmit()

Implement the EnableTransmit() function. +This initialises the UART transmit hardware, and the transmit ISR code path. +This function can be called from the ISR (on receipt of an unblocking XON +character), or to start a transmission of a LDD originated data buffer. It +causes the UART to generate Tx service interrupts as it finishes transmitting +a FIFOs worth of data, so that the entire buffer (passed by the LDD) can be +sent under interrupt control.

+
Data handling routines

Implement the main data +handling routines. These are entirely dependent on the UART hardware interface +and cannot therefore be described generally. They are typically driven by +the interrupt service routine as asynchronous events from the UART (eg. data +received, finished transmission of data, change in handshaking/flow control +inputs) occur.

The main ISR is typically driven by an interrupt multiplexed +from all the sources in the UART. The ISR, therefore, needs to determine which +of the interrupt sources requires attention. Since the most critical source +is the data received state, as this requires that the data is processed before +following data overwrites earlier data, then this is usually the signal to +be checked first. To avoid wasting time, the error state of the data is also +checked – data that has bad parity or framing must be noted as such. Typically +the receive path will save the currently available data into a temporary buffer, +and queue a DFC to process the data further at a later time, when more client +thread context is available (though this is a function of the LDD). The receive +ISRr just passes the location of the ISR buffer into an LDD function which +queues a DFC to process it.

The transmit path, called when the transmit +FIFO contents drop below a programmable number, merely requests more data +from the LDD. If there is none available it disables the transmit interrupt +so as to prevent further requests when there is no data to be sent. Further +data to transmit will cause the transmit FIFO empty interrupt to be re-enabled. +Hence the start of any transmission is always performed on an explicit start +request from the LDD and then continues under PDD interrupt control until +the source data is exhausted.

The status notification path is present +to inform the upstream LDD of changes in the input status signals (MODEM and +flow control status). The UART can generate interrupts when any input handshake +line changes state – the ISR merely reads the current state and queues a handler +DFC so that the LDD can be informed. The LDD is responsible for determining +what status change has occurred and dealing with it.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-ABE7BC1A-C51B-5ADD-8568-87A81423B648-master.png Binary file Adaptation/GUID-ABE7BC1A-C51B-5ADD-8568-87A81423B648-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-ABE7BC1A-C51B-5ADD-8568-87A81423B648_d0e77808_href.png Binary file Adaptation/GUID-ABE7BC1A-C51B-5ADD-8568-87A81423B648_d0e77808_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-AC2E5824-4E69-4964-968F-839EB5D2EF4F.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-AC2E5824-4E69-4964-968F-839EB5D2EF4F.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,16 @@ + + + + + +Board Support Package (BSP)A BSP provides hardware-specific support code for a given +hardware reference board. A package may be delivered as a single component +or in multiple components. +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-AC560324-798C-5D0A-B23D-2419A7688A5B.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-AC560324-798C-5D0A-B23D-2419A7688A5B.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,583 @@ + + + + + +Channel +ImplementationDescribes how to implement the physical channels with the template +port. +

A Sound Driver PDD must implement physical channels to use the audio hardware +of the phone. The main Sound Driver PDD class is derived from DSoundScPdd. +A Sound Driver PDD that provides record and playback functions must implement +a record driver channel and a playback driver channel.

+

The template defines two classes: DTemplateSoundScRxPdd and DTemplateSoundScTxPdd, +corresponding to record and playback respectively. The classes provide default +implementations for the virtual functions defined by DSoundScPdd, +together with a constructor and destructor, and typically need little or no +modification.

+
PDD class constructor

Implement +the PDD class constructor for both the playback and record driver channels. +This is normally limited to

    +
  • initialising any data +members that need values other than zero

  • +
  • initialising any DFC +call-backs added.

  • +

Access to hardware has the potential to fail and so should be deferred +to the second stage constructor DoCreate().

+
PDD class destructor

Implement +the PDD class destructor for both the playback and record driver channels. +The destructor must release any hardware and Symbian platform resources that +have been allocated to the driver. For example, this might include:

    +
  • unbinding ISRs

  • +
  • cancelling private DFCs

  • +
  • closing DMA channels

  • +
  • deleting any mono-to-stereo +conversion buffers

  • +

The template versions of this function delete each DMA request object +created in the PDD second stage constructor DSoundScPdd::DoCreate() and +close the DMA channel.

+
DoCreate()

Implement +a PDD class second stage constructor for both the playback and record driver +channels. In the template version, the function DSoundScPdd::DoCreate() is +called from the PDD factory when a channel is opened on the device. Generally, +any hardware or Symbian platform resources required by the driver +channel should be acquired here. However, powering up the sound device should +be deferred to the PowerUp() function. +Operations performed by this function include:

    +
  • binding an ISR to an +audio related interrupt

  • +
  • open a DMA channel

  • +
  • allocate a mono-to-stereo +conversion buffer

  • +

The template versions of this function include code to set up a DMA +channel. This involves opening a DMA channel in the appropriate direction +for the driver channel and then allocating a set of DMA request objects. However, +to use this implementation you must supply the missing platform specific information:

    +
  • Provide values for the +maximum number of DMA requests outstanding on the DMA channel. These values +determine the number of separate DMA request objects allocated for the DMA +channel, and so the number of transfer fragments that the PDD can accept from +the LDD at any time. See playback and record.

  • +
  • Set the appropriate +DMA values for your device within the file soundsc_plat.h. +These values, renamed in section copying +the template port implementation to reflect your device name, are KTemplateMaxTxDmaRequests or KTemplateMaxRxDmaRequests for playback and record respectively.

  • +
  • Setup the DMA channel +information for the device. This includes the following members of TDmaChannel::SCreateInfo.

      +
    • iCookie: +The platform specific ID used by the DMA controller to select the DMA channel +to open.

    • +
    • iDesCount: +The number of DMA descriptors the DMA controller should create. This is typically +set with the same value as KTemplateMaxTxDmaRequests or KTemplateMaxRxDmaRequests.

    • +
    • iDfcQ: +The DFC queue to use to service DMA interrupts. This should point to the same +DFC queue that is returned to the LDD for client request handling. See the DfcQ() section.

    • +
    • iDfcPriority: +The DFC priority. This should be set to a higher value than that used by the +LDD for handling client requests. For example, higher than one.

    • +
  • +
+
DfcQ()

Make +sure that the template version of the DSoundScPdd::DfcQ() function +is appropriate for your configuration. This function has the following signature:

TDfcQue* DfcQ()

The +supplied implementation is as follows

TDfcQue* DTemplateSoundScTxPdd::DfcQ() + { + return(iPhysicalDevice->iDfcQPtr); + }

Many requests are executed in the context of a kernel-side +thread. Rather than assign a kernel thread for the driver in the LDD, the +Sound Driver allows the PDD to specify the DFC thread returned via the DfcQ() function, +which it calls when the driver channel is opened.

The default implementation +for the record and playback driver channels, returns a pointer to the DFC +queue created by the PDD factory class.

See also Implementing +the PDD factory

+
GetChunkCreateInfo()

Implement +the DSoundScPdd::GetChunkCreateInfo() function for both +the playback and record driver channels. This function has the following signature:

void DSoundScPdd::GetChunkCreateInfo(TChunkCreateInfo& aChunkCreateInfo)

The +supplied implementation is as follows:

void DTemplateSoundScTxPdd::GetChunkCreateInfo(TChunkCreateInfo& aChunkCreateInfo) + { + __KTRACE_SND(Kern::Printf(">DTemplateSoundScTxPdd::GetChunkCreateInfo")); + + // TO DO: (mandatory) + // Setup the shared chunk create information in aChunkCreateInfo for this play device. + aChunkCreateInfo.iType=TChunkCreateInfo::ESharedKernelMultiple; + // aChunkCreateInfo.iMapAttr=??? + aChunkCreateInfo.iOwnsMemory=ETrue; // Using RAM pages. + aChunkCreateInfo.iDestroyedDfc=NULL; // No chunk destroy DFC. + }

The PDD must initialise the TChunkCreateInfo object +with the information that defines the characteristics of the shared chunk +required for the audio device. This function is called by the LDD just before +it creates a shared chunk for the channel, in response to an RSoundSc::SetBufferChunkCreate() request +from the client.

Values for the following data members must be supplied +by the PDD:

    +
  • TChunkCreateInfo::iType

  • +
  • TChunkCreateInfo::iMapAttr

  • +
  • TChunkCreateInfo::iOwnsMemory

  • +
  • TChunkCreateInfo::iDestroyedDfc

  • +

The data member TChunkCreateInfo::iMaxSize is +calculated by the LDD so there is no need to define it.

See How to share chunks.

+
Caps()

Implement +the DSoundScPdd::Caps() function for both the playback +and record driver channels. The function has the following signature:

void DSoundScPdd::Caps(TDes8& aCapsBuf) const

The +supplied implementation is as follows:

void DTemplateSoundScTxPdd::Caps(TDes8& aCapsBuf) const + { + __KTRACE_SND(Kern::Printf(">DTemplateSoundScTxPdd::Caps")); + + // Copy iCaps back. + TPtrC8 ptr((const TUint8*)&iCaps,sizeof(iCaps)); + aCapsBuf.FillZ(aCapsBuf.MaxLength()); + aCapsBuf=ptr.Left(Min(ptr.Length(),aCapsBuf.MaxLength())); + }

TSoundFormatsSupportedV02 is the +main audio capabilities class. The PDD must fill this object with the capabilities +for the particular audio device. the LDD uses this to get the play or record +capabilities of a particular sound device once a driver channel to the device +has been opened.

Values for the following variables must be supplied +by the PDD:

    +
  • TSoundFormatsSupportedV02::iDirection

      +
    • ESoundDirRecord

    • +
    • ESoundDirPlayback

    • +
  • +
  • TSoundFormatsSupportedV02::iChannels

      +
    • KSoundMonoChannel

    • +
    • KSoundStereoChannel

    • +
    • KSoundThreeChannel

    • +
    • KSoundFourChannel

    • +
    • KSoundFiveChannel

    • +
    • KSoundSixChannel

    • +
  • +
  • TSoundFormatsSupportedV02::iRates

      +
    • KSoundRate7350Hz

    • +
    • KSoundRate8000Hz

    • +
    • KSoundRate8820Hz

    • +
    • KSoundRate9600Hz

    • +
    • KSoundRate11025Hz

    • +
    • KSoundRate12000Hz

    • +
    • KSoundRate14700Hz

    • +
    • KSoundRate16000Hz

    • +
    • KSoundRate22050Hz

    • +
    • KSoundRate24000Hz

    • +
    • KSoundRate29400Hz

    • +
    • KSoundRate32000Hz

    • +
    • KSoundRate44100Hz

    • +
    • KSoundRate48000Hz

    • +
  • +
  • TSoundFormatsSupportedV02::iEncodings

      +
    • KSoundEncodings8BitPCM

    • +
    • KSoundEncodings16BitPCM

    • +
    • KSoundEncodings24BitPCM

    • +
  • +
  • TSoundFormatsSupportedV02::iDataFormats

      +
    • KSoundDataFormatInterleaved

    • +
    • KSoundDataFormatNonInterleaved

    • +
  • +
  • TSoundFormatsSupportedV02::iRequestMinSize

  • +
  • TSoundFormatsSupportedV02::iRequestAlignment

  • +
  • TSoundFormatsSupportedV02::iHwConfigNotificationSupport

  • +

Many of the attribute ranges are passed as bit settings, and can +assume all the values independently of one another.

The following +is a portion of the Caps() function for the template port +for the playback path of the AC97 Controller Unit (UCB140) codec device.

The +PDD maintains a TSoundFormatsSupportedV02 object as one +of its data members named iCaps. The contents of iCaps is +copied into the descriptor and passed as an argument to the Caps() function:

void DTemplateSoundScTxPdd::Caps(TDes8& aCapsBuf) const + { + __KTRACE_SND(Kern::Printf(">DTemplateSoundScTxPdd::Caps")); + + // Copy iCaps back. + TPtrC8 ptr((const TUint8*)&iCaps,sizeof(iCaps)); + aCapsBuf.FillZ(aCapsBuf.MaxLength()); + aCapsBuf=ptr.Left(Min(ptr.Length(),aCapsBuf.MaxLength())); + } +

The data member iCaps is initialised by the +function SetCaps() called from the second stage constructor +of the PDD object:

void DTemplateSoundScTxPdd::SetCaps() + { + __KTRACE_SND(Kern::Printf(">DTemplateSoundScTxPdd::SetCaps")); + + // The data transfer direction for this unit is play. + iCaps.iDirection=ESoundDirPlayback; + + // TO DO: (mandatory) + // Setup the rest of the capabilities structure DTemplateSoundScTxPdd::iCaps with the capabilities of this + // audio playback device. + }
+
MaxTransferLen()

Implement +the DSoundScPdd::MaxTransferLen() function for both playback +and record driver channels. The function has the following signature:

TInt DSoundScPdd::MaxTransferLen() const

The +supplied implementation is as follows:

TInt DTemplateSoundScTxPdd::MaxTransferLen() const + { + return(KTemplateMaxTxDmaTransferLen); + }

This function is called each time the LDD alters the +audio configuration of the channel. For example, after calling DSoundScPdd::SetConfig(). +The LDD uses the value returned to fragment record and playback data transfers +so that they are manageable by the PDD. See playback and record.

The +value returned by MaxTransferLen() is not as important +for PDDs that use the Symbian DMA framework because the DMA framework handles +fragmentation.

If the PDD has to employ mono-to-stereo data conversion +using a conversion buffer when configured in mono mode, then it needs to return +the value that corresponds with the size of the conversion buffer each time +it is configured in mono mode. See mono +to stereo conversion.

+
PowerUp()

Implement +the DSoundScPdd::PowerUp function for both the playback +and record driver channels. The function has the following signature:

TInt DSoundScPdd::PowerUp()

The +supplied implementation is as follows:

TInt DTemplateSoundScTxPdd::PowerUp() + { + // TO DO: (mandatory) + // Power up the audio device. + + return(KErrNone); + }

This function initialises the codec device and any associated +controller hardware that allows the CPU to communicate with it. However, at +this stage only basic initialisation of these hardware components is required, +as the specific audio configuration has not yet been specified, and data transfer +has not yet started.

If the PDD supports both record and playback +driver channels then most, if not all, of this hardware initialisation is +common to both channels. It may be necessary to ensure that such initialisation +on one channel cannot interfere with the other. For example, when calling DSoundScPdd::PowerUp() on +the record driver channel while the playback driver channel is active, make +sure that it does not interfere with audio playback. This typically requires +hardware status information to be held in the PDD factory object that is common +to both channels.

+
SetConfig()

Implement +the DSoundScPdd::SetConfig() function for both playback +and record driver channels. The function has the following signature:

TInt DSoundScPdd::SetConfig(const TDesC8& aConfigBuf) TInt DTemplateSoundScTxPdd::SetConfig(const TDesC8& aConfigBuf) + { + __KTRACE_SND(Kern::Printf(">DTemplateSoundScTxPdd::SetConfig")); + + // Read the new configuration from the LDD. + TCurrentSoundFormatV02 config; + TPtr8 ptr((TUint8*)&config,sizeof(config)); + Kern::InfoCopy(ptr,aConfigBuf); + + // TO DO: (mandatory) + // Apply the specified audio configuration to the audio device. + TInt r=KErrNone; + + __KTRACE_SND(Kern::Printf("<DTemplateSoundScTxPdd::SetConfig - %d",r)); + return(r); + }

A configuration buffer in a packaged TCurrentSoundFormatV02 object +containing the new configuration settings.

    +
  • TCurrentSoundFormatV02::iChannels

  • +
  • TCurrentSoundFormatV02::iRate

      +
    • ESoundRate7350Hz

    • +
    • ESoundRate8000Hz

    • +
    • ESoundRate8820Hz

    • +
    • ESoundRate9600Hz

    • +
    • ESoundRate11025Hz

    • +
    • ESoundRate12000Hz

    • +
    • ESoundRate14700Hz

    • +
    • ESoundRate16000Hz

    • +
    • ESoundRate22050Hz

    • +
    • ESoundRate24000Hz

    • +
    • ESoundRate29400Hz

    • +
    • ESoundRate32000Hz

    • +
    • ESoundRate44100Hz

    • +
    • ESoundRate48000Hz

    • +
  • +
  • TCurrentSoundFormatV02::iEncoding

      +
    • ESoundEncoding8BitPCM

    • +
    • ESoundEncoding16BitPCM

    • +
    • ESoundEncoding24BitPCM

    • +
  • +
  • TCurrentSoundFormatV02::iDataformat

      +
    • ESoundDateFormatInterleaved

    • +
    • ESoundDateFormatNonInterleaved

    • +
  • +

The PDD must read and locally save the contents of the TCurrentSoundFormatV02 configuration +object that has been passed as a descriptor from the LDD. The template version +contains the following code to achieve this:

// Read the new configuration from the LDD. +TCurrentSoundFormatV02 config; +TPtr8 ptr((TUint8*)&config, sizeof(config)); +Kern::InfoCopy(ptr, aConfigBuf);

It is not necessary to check +for configurations requested by the LDD that are not supported by the audio +hardware device if the Caps() function has been implemented +correctly by the PDD. This is because the LDD rejects such audio configuration +requests from the client. However, if the PDD supports both playback and record +driver channels then it needs to check that the specified configuration does +not conflict with one already in use by the other channel.

The PDD +sets up the audio hardware device according to the audio configuration specified +if it is required. Some, if not all of this hardware configuration may be +put off until data transfer is started, this is when DSoundScPdd::StartTransfer() is +called, so for now the PDD needs to save the configuration.

If the +PDD has to employ mono-to-stereo conversion of data using a conversion buffer +while the audio configuration is set to mono, then the memory for the conversion +buffer should be allocated at this time.

+
SetVolume()

Implement +the DSoundScPdd::SetVolume function for both the playback +and record driver channels. This has the following signature:

TInt DSoundScPdd::SetVolume(TInt aVolume)

The +supplied implementation is as follows:

TInt DTemplateSoundScTxPdd::SetVolume(TInt aVolume) + { + __KTRACE_SND(Kern::Printf(">DTemplateSoundScTxPdd::SetVolume")); + + // TO DO: (mandatory) + // Set the specified play volume on the audio device. + TInt r=KErrNone; + + return(r); + }

The PDD must first convert the volume/record level information +specified into a form which can be used to program the hardware. This may +require converting the value from a gain factor to an attenuation factor and/or +applying a scaling factor. The LDD detects situations where the client specifies +a record level /volume that is already in effect, and in this case does not +unnecessarily call the PDD.

The PDD may opt to setup the audio hardware +device within this function or it may defer this until data transfer is started +with the function DSOundScPdd::StartTransfer(). For PDDs +which support both record and playback driver channels, it is normal for audio +devices to allow the record and playback gains to be programmed independently, +this means that checking for conflicts between the channels is rarely required +for this function.

+
StartTransfer()

Implement +the DSoundScPdd::StartTransfer function for both the playback +and record driver channels. This has the following signature:

TInt DSoundScPdd::StartTransfer()

The +supplied implementation is as follows:

TInt DTemplateSoundScTxPdd::StartTransfer() + { + __KTRACE_SND(Kern::Printf(">DTemplateSoundScTxPdd::StartTransfer")); + + // TO DO: (mandatory) + // Prepare the audio device for playback. + TInt r=KErrNone; + + __KTRACE_SND(Kern::Printf("<DTemplateSoundScTxPdd::StartTransfer - %d",r)); + return(r); + }

This function performs any configurations of the audio +hardware device that were deferred from the DSoundScPdd::SetConfig() function. +These configurations may include start-up of the DMA engine, enabling any +interrupts related to audio transfer and interrupts that detect error conditions, +for example. At this stage, no data has yet been supplied to the device for +transfer as the function DSoundScPdd::TransferData() has +not yet been called.

If the PDD supports both record and playback +driver channels then it may be necessary to ensure that such hardware configuration +on one channel cannot interfere with the other.

+
TransferData()

Implement +the DSoundScPdd::TransferData function for both playback +and record driver channels. This has the following signature:

TInt DSoundScPdd::TransferData(TUint aTransferID,TLinAddr aLinAddr, + TPhysAddr aPhysAddr,TInt aNumBytes)

Once +transfer has been started by calling DSoundScPdd::StartTransfer(), +the function TransferData is called repeatedly by the LDD +for the transfer of each fragment. See the playback and record sections for +details.

The template version for the record driver channel contains +the following code:

TInt DTemplateSoundScRxPdd::TransferData(TUint aTransferID, TLinAddr aLinAddr, + TPhysAddr /*aPhysAddr*/, TInt aNumBytes) + { + TInt r=KErrNone; + + // Check that we can accept the request + if (iPendingRecord>=KTemplateMaxRxDmaRequests) + r=KErrNotReady; + else + { + // Start a DMA transfer. + iDmaRequest[iFlag]->iTransferID=aTransferID; + iDmaRequest[iFlag]->iTransferSize=aNumBytes; + // TO DO: (mandatory) + // Supply the DMA source information. + TUint32 src=0; // ??? + r=iDmaRequest[iFlag]->Fragment(src,aLinAddr,aNumBytes,KDmaMemDest|KDmaIncDest,0); + if (r==KErrNone) + { + iDmaRequest[iFlag]->Queue(); + iPendingRecord++; + if ((++iFlag)>=KTemplateMaxRxDmaRequests) + iFlag=0; + + // TO DO: (mandatory) + // Start the audio device transferring data. + } + } + + return(r); + }

The template version used by the playback function +is very similar.

The first step is for the PDD to check that +it has the capacity to accept a further transfer. For example, check that +the PDD has a DMA request object that is free and that the DMA controller +has the capacity for another transfer to be queued. If the PDD does not have +the capacity to accept another transfer then it should immediately return KErrNotReady to +signal this.

Otherwise, the PDD can start a DMA transfer. To do this +it must acquire a DMA request object. The class DTemplateSoundScRxDmaRequest is +the abstraction for a DMA record request and is defined as follows:

/** Wrapper function for a shared chunk sound driver record DMA request. */ +class DTemplateSoundScRxDmaRequest : public DDmaRequest + { +public: + DTemplateSoundScRxDmaRequest(TDmaChannel& aChannel, DTemplateSoundScRxPdd* aPdd, + TInt aMaxTransferSize=0); + static void DmaService(TResult aResult, TAny* aArg); +public: + /** Pointer back to the PDD. */ + DTemplateSoundScRxPdd* iPdd; + /** The transfer ID for this DMA request - supplied by the LDD. */ + TUint iTransferID; + /** The transfer sizes in progress. */ + TUint iTransferSize; + }; + This is derived from DDmaRequest the base class + for a DMA request.

The data member iPdd is +a pointer to the owning PDD object. This is used within the member function DmaService() which +is the DMA callback function, and is called when the DMA request has been +completed by the DMA framework. The data member iTransferID is +a value supplied by the LDD which it uses to identify the transfer fragment. +The PDD must save this value and pass it back to the LDD when the transfer +is completed. Similarly, the member iTransferSize is used +to hold the length of the transfer fragment in bytes. If the transfer is successful +then this value is also passed back to the LDD to allow it to maintain its +count of bytes recorded.

The record PDD class owns an array of DMA +request objects:

/** The DMA request structures used for transfers. */ +DTemplateSoundScRxDmaRequest* iDmaRequest[KTemplateMaxRxDmaRequests];

It +also owns the data member iFlag, which always holds the number +for the next DMA request that should be used for transfer. Before starting +the DMA transfer, setup the appropriate DMA request object with the transfer +ID and the transfer length.

/** A flag selecting the next DMA request for transfer. */ +TInt iFlag;

Next the function DDmaRequest::Fragment() is +called to specify the details of the transfer to the DMA framework and to +allow it to analyse this. Here the appropriate platform specific 32-bit DMA +source identifier, src, needs to be supplied. The template +driver shown previously specifies the destination memory address as a linear +address but the physical address may be used instead. Both forms of this address +are passed as arguments to the TransferData() function.

If +fragmentation is successful then the request object is queued on the DMA channel DDmaRequest::Queue() and +the value of iFlag is updated ready for the next transfer. +The PDD class also keeps a count of the number of transfer fragments outstanding +by incrementing the variable iPendingRecord:

/** The number of outstanding DMA record requests on the DMA channel. */ +TInt iPendingRecord;

The final part of this function requires +platform specific code to start the audio hardware device transferring data. +This needs to be executed for each fragment transferred or just for the first +fragment queued following the StartTransfer() function.

Once +the transfer is complete, either successfully or with an error, the DMA framework +executes the static DMA callback function, DTemplateSoundScRxDmaRequest::DmaService(), +as follows:

/** +DMA rx service routine. Called in the sound thread's DFC context by the s/w DMA controller. +@param aResult Status of DMA transfer. +@param aArg Argument passed to DMA controller. +*/ +void DTemplateSoundScRxDmaRequest::DmaService(TResult aResult, TAny* aArg) + { + DTemplateSoundScRxDmaRequest& req=*(DTemplateSoundScRxDmaRequest*)aArg; + + TInt res=KErrNone; + TInt bytesTransferred=req.iTransferSize; + if (aResult!=DDmaRequest::EOk) + { + res=KErrCorrupt; + bytesTransferred=0; + } + + // Inform the LDD of the result of the transfer. + req.iPdd->RecordCallback(req.iTransferID,res,bytesTransferred); + return; + }

This function receives two arguments:

    +
  • the result of the transfer +from the DMA framework

  • +
  • an argument supplied +to the DMA framework when the request object was created

  • +

In this specific case, the argument type is a pointer to the DMA +request object, and allows the retrieval of the transfer ID and the transfer +size. In the template driver version an unsuccessful transfer returns an error +value of KErrCorrupt with a transfer byte count of zero.

From +the callback function we call the record PDD function to decrement the count +of transfer fragments outstanding and to inform the LDD of the completion +of transfer.

void DTemplateSoundScRxPdd::RecordCallback(TUint aTransferID, TInt aTransferResult,TInt aBytesTransferred) + { + iPendingRecord--; + Ldd()->RecordCallback(aTransferID,aTransferResult,aBytesTransferred); + } +
+
StopTransfer()

Implement +the DSoundScPdd::StopTransfer function for both the play +and record driver channels. This has the following signature:

void DSoundScPdd::StopTransfer()

The +PDD must reverse any operation performed on the audio hardware device done +as part of StartTransfer() or TransferData(). +This includes stopping the audio hardware device from transferring data and +stopping the DMA channel.

The template version for the record driver +channel contains the following code:

void DTemplateSoundScRxPdd::StopTransfer() + { + // Stop the DMA channel. + iDmaChannel->CancelAll(); + iFlag=0; + iPendingRecord=0; + + // TO DO: (mandatory) + // Stop the audio device transferring data. + }

The version used by the playback function is +very similar.

+
PauseTransfer()

Implement +the DSoundScPdd::PauseTransfer() function for both the +playback and record driver channels. This has the following signature:

TInt DSoundScPdd::PauseTransfer()

When +pausing playback, there is normally some way to temporarily stop the codec +and pause the DMA channel so that it can be resumed later starting from the +next play sample.

Pausing record requires a different implementation. +All active transfers must be aborted. When this has been achieved, the PDD +must report back to the LDD how much data has been received for the fragment +that was actively being transferred when the abort took place by calling DSoundScLdd::RecordCallBack(). +If it is not possible to determine the byte count for the last fragment from +the DMA controller, then you must find some other way to discover its value. +One solution is to re-start a timer at the start of each record fragment, +and use this to calculate how much data will have been written into the record +buffer at the point the transfer is aborted.

In this case the +returned transfer ID is not important.

The supplied template +implementation is as follows:

TInt DTemplateSoundScRxPdd::PauseTransfer() + { + // Stop the DMA channel. + iDmaChannel->CancelAll(); + + if (iPendingRecord) + { + // TO DO: (mandatory) + // Determine how much data was successfully transferred to the + // record buffer before transfer was aborted. + TInt byteCount=0; // ??? + Ldd()->RecordCallback(0,KErrNone,byteCount); + iPendingRecord=0; + } + iFlag=0; + + // TO DO: (mandatory) + // Halt recording on the audio device. + TInt r=KErrNone; + + return(r); + } +

There is no need for the PDD to perform any state +checking as this is already performed by the LDD. For example, checking that +the device is not already paused or transferring data.

+
ResumeTransfer()

Implement +the DSoundScPdd::ResumeTransfer function for both the playback +and record driver channels. This has the following signature:

TInt DSoundScPdd::ResumeTransfer()

The +template version for the record driver channel contains the following code:

TInt DTemplateSoundScTxPdd::ResumeTransfer() + { + __KTRACE_SND(Kern::Printf(">DTemplateSoundScTxPdd::ResumeTransfer")); + + // TO DO: (mandatory) + // Resume playback on the audio device. + TInt r=KErrNone; + + return(r); + }

To resume playback, it is normally necessary to re-start +the codec and resume the DMA channel in order to restart playback from the +next play sample.

To resume record, all active transfers should have +been aborted when the device was paused with the function PauseTransfer(). +However, the LDD issues a new TransferData() request subsequent +to this function to resume record data transfer so the only action required +here is to recreate the same audio hardware setup that was achieved in response +to the StartTransfer() function.

There is no need +for the PDD to perform any state checking as this is already performed by +the LDD. For example, checking that the device is not already paused.

+
PowerDown()

Implement +the DSoundScPdd::PowerDown() function for both the playback +and record driver channels. This has the following signature:

void DSoundScPdd::PowerDown()

The +PDD must reverse any operation performed on the audio hardware as part of PowerUp().

+
CustomConfig()

Implement +the DSoundScPdd::CustomConfig() function for both the playback +and record driver channels. This has the following signature:

TInt DSoundScPdd::CustomConfig(TInt aFunction,TAny* aParam)

RSoundSc::CustomConfig() is called by the LDD in response to a custom configuration request by the +client. Custom configurations allow clients to issue requests to setup platform +specific audio configuration settings. Any such requests from the client with +a function identifier equal to or above 0x10000000 are passed straight through +to the PDD for function identification and implementation. These are handled +in the context of the sound driver DFC thread.

If custom configuration +is not supported, then the PDD should simply return KErrNotSupported.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-AC7830F9-C3FB-5117-B851-1D106AE400D4-master.png Binary file Adaptation/GUID-AC7830F9-C3FB-5117-B851-1D106AE400D4-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-AC7830F9-C3FB-5117-B851-1D106AE400D4_d0e10568_href.png Binary file Adaptation/GUID-AC7830F9-C3FB-5117-B851-1D106AE400D4_d0e10568_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-ACA48BEE-FE73-5C47-B022-E50728CEDBEE.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-ACA48BEE-FE73-5C47-B022-E50728CEDBEE.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,55 @@ + + + + + +ArchitectureDescribes the architecture of the Sound Driver. +

There are three main parts:

+
    +
  • the user side interface +to the Driver +channel. This is an instance of a class derived from RSoundSc.

    The +class RSoundSc provides the user side interface to the +driver. This class is defined in \e32\include\d32soundsc.h. +An instance of RSoundSc is required for each driver channel opened by the client. When opening a driver channel, the client specifies a channel number for the audio +channel. Channel numbers 0 to 3 are allocated for output/playback channels +and channels 4 to 7 are allocated for input/record channels.

  • +
  • the driver channel, also known as the logical channel or LDD.

    The +class DSoundScLdd is the logical +channel object for either audio playback or record. This class is defined +in \e32\include\drivers\soundsc.h. An instance of DSoundScLdd is +created for each driver +channel opened. The driver implements play and record operation over +a single audio hardware device as two separate units. Therefore, a client that needs to issue both record and playback requests +has to open two separate driver +channels.

    DSOundScLdd is derived from DLogicalChannel. DLogicalChannel is +the base class for a logical channel and provides the framework in which user +side client requests are normally executed in the context of a kernel side +thread. However, for this particular driver, not every request is executed +in the context of a kernel thread. Requests that do not require access to +hardware are handled in the context of the calling thread.

  • +
  • the physical +channel, also known as the PDD, manages access to the audio hardware +device for all instances of the driver +channel.

    The class DSoundScPdd is the base +class for the Sound Driver PDD object. This class is used for either playback +or record, it implements the platform specific layer of the driver and an +instance of this class is created for each driver +channel opened. This is created by the Sound Driver physical device +class DSoundScPddFactory when a channel is opened. The +class DSoundScPdd is defined in \e32\include\drivers\soundsc.h.

    The +following diagram illustrates the Sound Driver architecture. The interactions +between the user side and kernel side classes are shown.

  • +
+ + The main classes involved in Sound Driver implementation. + + + +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-ACB79CEF-CA4D-5C96-AFCD-6AD7C7C26C53.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-ACB79CEF-CA4D-5C96-AFCD-6AD7C7C26C53.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,48 @@ + + + + + +Thrashing +GuideDescribes thrashing in terms of demand paging and how to prevent +it. +
Introduction

Thrashing +is an undesirable state where most of the processes in the system are in the +process of paging-in memory and none of the threads are doing useful work. +This results in unacceptable system performance.

+
Background information

These topics are useful background +information on thrashing:

    +
  • Paging

  • +
  • Virtual memory

  • +
+
Thrashing features

The signs of thrashing in demand +paging are:

    +
  • The system performance rapidly becomes unacceptable, since no threads +are doing useful work. The device will become unresponsive or appear to 'hang'.

  • +
  • When observing paging activity logs it's seen that the same set of +pages are paged in and out many times over the course of a use case.

  • +
  • When observing paging activity logs there are long periods where many +threads are waiting for pages to be paged in.

  • +
  • There are large periods of null thread activity.

  • +
+
Thrashing prevention

The following is a means of +preventing thrashing from occurring:

    +
  • Increase the size of the paging cache. This reduces page faults and +hence the need to page-in memory.

  • +
  • Mark the code or data involved as unpaged, for example if a 20MB buffer +is actively used through a use-case and discarded afterwards there is little +use in making it paged as it will need to always be in the page cache.

  • +
  • Reduce the working set size so that it fits into the paging cache, +for example instead of having four activities running concurrently, serialize +them.

  • +
+
+Preventing +And Recovering From Thrashing Guide +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-ACC010D4-B419-4CDD-8091-C85579575D46-master.png Binary file Adaptation/GUID-ACC010D4-B419-4CDD-8091-C85579575D46-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-ACC010D4-B419-4CDD-8091-C85579575D46_d0e94724_href.png Binary file Adaptation/GUID-ACC010D4-B419-4CDD-8091-C85579575D46_d0e94724_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-AD195629-81CE-5E57-A59E-C67AACF7A2C2.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-AD195629-81CE-5E57-A59E-C67AACF7A2C2.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,206 @@ + + + + + +USB +Client Driver TechnologyThis topic describes the technology that the USB Client Driver +provides. +
USB

The Universal Serial Bus (USB) is a high speed +data transport mechanism that uses a 4 wire cable attached to a USB Host to +transfer signals and bus power to low cost peripherals (clients). Theoretically, +up to 127 devices (such as keyboards, video cameras etc.) can share the bus, +although less than four devices is more typical.

There are two versions +of the USB standard in use: V1.1 and V2.0. The following table shows the speeds +supported by the different versions:

USB Speeds

+ + + +

Name

+

Rate

+

USB Version

+
+ +

High Speed

+

480Mbit/s

+

2.0 only

+
+ +

Low Speed

+

12Mbits/s

+

1.1 and 2.0

+
+ +

Full Speed

+

1.5Mbits/s

+

1.1 and 2.0

+
+ + +

As the table shows USB V2.0 adds support for the higher speed +of 480Mbit/s.

The USB system consists of single USB host controller +(the USB Host) connected to a number of USB peripheral devices. The host is +the bus master, initiating all transactions over the bus.

A client +device is a USB peripheral device. It is connected to a USB Controller and +responds to transactions addressed to it from the Controller. The Universal +Serial Bus Specification 1.1 describes how a USB Host sends commands to a +peripheral and how data can be transferred from and to a Client. The main +points are:

    +
  • USB is a Host polled +bus. This means that a peripheral cannot send a data packet unless the Host +has requested it. The request must either be accepted, and the data packet +sent within a given time period, or refused.

  • +
  • Every peripheral attached +to the USB is allocated a unique device address. The Host uses the device +address to direct its communication to a particular device. In fact, the Host +sees the peripheral as a collection of endpoints. Each endpoint is an address +within the peripheral to which the Host sends packets or from which the Host +receives packets.

  • +
  • Endpoints are grouped +together by the peripheral into Interfaces. The Host regards each peripheral +as a set of functions and communicates with each function via its Interface. +Simple devices, such as mice, contain only one function, other devices may +contain more than one function, e.g. a monitor may contain speakers and a +microphone.

  • +
  • Each function requires +its own driver at the Host end which communicates with the function within +the peripheral using a USB class driver or vendor defined protocol. The function +informs the Host what protocol it understands via its Interface.

  • +

The USB Client Driver supports:

    +
  • multiple USB interfaces, +i.e. it supports licensee products that implement multiple USB interfaces +simultaneously

  • +
  • alternate USB interfaces

  • +
  • a single USB Configuration +only; the API does not provide a mechanism for specifying more than one USB +configuration.

  • +
  • extended standard endpoint +descriptors.

  • +
  • reading and modifying +standard descriptors.

  • +
  • setting class specific +interface and endpoint descriptors.

  • +
  • remote wakeup signalling.

  • +
  • reading device directed +Ep0 (Endpoint Zero) traffic.

  • +
+
Endpoint types

There +are four endpoint types corresponding to the four transfer types:

    +
  • Control endpoints

  • +
  • Bulk endpoints

  • +
  • Interrupt endpoints

  • +
  • Isochronous endpoints.

  • +

Control +endpoints

These are serially bi-directional. This means that they +can send and receive data, but not simultaneously.

Every peripheral +has at least one control endpoint. Although other control endpoints are possible, +Symbian platform only allows Endpoint zero (Ep0) as the control endpoint. +Ep0 is a shared resource, which must always be available.

Ep0 is vital +for the operation of the device. Its primary function is the control endpoint +for the Host. When the device is first connected to the Host, a process known +as enumeration must occur, and this takes place through Ep0. During enumeration, +the client tells the Host what kind of device it is and what classes it supports. +Enumeration is complete, for the purpose of writing client drivers, when the +Host moves the client into its configured state. The Host moves the client +into its configured state when a Host driver is available to communicate with +the client.

Ep0 needs handling with some sensitivity. Every request +arriving on Ep0 must be handled either by the Controller or by a client class +driver. Each request must be moved through the data phase, even if there is +no associated request data, so that the status phase may begin. It is imperative +that this happens otherwise endpoint zero will be unable to accept any further +requests. This could result in the Host stopping communication with the device.

Bulk endpoints

These are unidirectional. They can have the +IN or the OUT direction.

The IN direction means sending packets to +the Host. The OUT direction means receiving packets from the Host.

Bulk +endpoints can supply a maximum of 64 bytes of data per packet, but such transfers +have no guaranteed bus bandwidth.

Interrupt +endpoints

Interrupt endpoints are similar to Bulk endpoints but, +in addition, the endpoint descriptor specifies how often the Host should poll +the endpoint for data. The polling frequency may be anything from 1ms to 255ms.

Isochronous endpoints

Isochronous endpoints can deliver up +to 1023 bytes of data per packet, but there is no retry capability if an error +is detected. Like Interrupt endpoints, they have an associated polling frequency, +which is fixed at 1ms.

+
Endpoint numbering

Two +numbering schemes are used within the USB implementation. There is also the +external USB address numbering scheme.

Virtual endpoint numbers

Applications +or class drivers use virtual endpoints when communicating with the USB client +driver. These numbers are used when exchanging data over the USB.

Virtual +endpoints range in value from 1 to KMaxEndpointsPerClient, +and applications refer to these endpoints by number when using the user side +handle to the USB client driver.

For applications that implement a +specific USB device class, and which need access to endpoint-0, virtual endpoint-0 +is available. This endpoint is special because it does not belong to any specific +interface. It is always available and, at the interface to the USB client +driver, is the only bi-directional endpoint.

Implementation note

Within the platform independent layer, +virtual endpoint numbers are represented by instances of the internal class TUsbcLogicalEndpoint. +Note that there is no representation for virtual endpoint-0.

Physical endpoints

Physical (or 'real') endpoints are used +at the interface between the platform independent layer and the platform specific +layer within the USB client controller. They represent endpoints physically +present on a given device.

Implementation note

Within the platform independent layer, +physical endpoint numbers are represented by instances of the internal class TUsbcPhysicalEndpoint, +in the array represented by the internal data member DUsbClientController::iRealEndPoints.

To +simplify array indexing, the numbering scheme uses "transformed" USB endpoint +addresses. We represent each channel as a separate endpoint, RX (OUT) channel +as iRealEndpoints[n] and TX (IN) channel as iRealEndpoints[n ++ 1].

Canonical endpoint numbers

The +two layers of the USB client controller, i.e. the Platform Independent layer +and the Platform Specific layer, use a numbering system known as canonical +endpoint numbers when communicating between each other. The physical endpoint +numbers are never used explicitly.

This system is based upon the physical +endpoint number, but takes the direction of the endpoint into account. If r is +the physical endpoint number, then the corresponding canonical endpoint number +is a value defined as:

    +
  • 2r + 1

    if +the endpoint direction is IN

  • +
  • 2r

    if +the endpoint direction is OUT

  • +

This means that canonical endpoint numbers fall into a range from +0 to 31.

For example, Endpoint 0 (Ep0) is represented by 2 canonical +endpoint numbers:

    +
  • 0, representing Ep0(OUT)

  • +
  • 1, representing Ep0(IN).

  • +

Converting between Endpoint +number representations

It is possible to convert between the Endpoint +Address representation and the Canonical Endpoint. The following text explains +how these values are stored in memory and shows the conversion process:

Endpoint Address

+

where the numbers 0-7 represent bits 0-7 of the byte containing the +endpoint address.

D = Direction: 0 = Receive/IN, 1 = Transmit/OUT

P3 +P2 P1 P0 represents the physical endpoint number (0-15)

+ +

Canonical Endpoint Number

The canonical endpoint number is +just the endpoint address rotated left by 1 bit as shown below:

+ +

Summary +of Endpoint Number Representations

The APIs use the following +conventions for representing endpoint numbers types:

+ + + +

Name

+

Endpoint number

+
+ +

aRealEndpoint

+

Canonical Endpoint Number

+
+ +

aEndpointNum

+

Virtual Endpoint Number

+
+ +

aAddress

+

Endpoint Address

+
+ +

n/a

+

Physical Endpoint Number

+
+ + +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-AD2BD987-E097-5E1F-A914-B91CFB706D51.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-AD2BD987-E097-5E1F-A914-B91CFB706D51.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,243 @@ + + + + + +Environment +SlotsUp to 16 separate pieces of information can be passed to a process +on creation using Environment Slots. These include handles and binary data. +

Handles and binary data can be passed to a process at process creation +time using environment slots. This topic describes this concept, and explains +how to use the process APIs for environment slots.

+
    +
  • Overview

  • +
  • The APIs

  • +
  • Passing a file handle and a subsession

  • +
  • Passing a general handle, derived from RHandleBase

  • +
  • Passing descriptor data

  • +
  • Passing an integer

  • +
  • Error handling issues

  • +
+
Overview

Handles +and binary data, in the form of descriptors or integer values, can be passed +to a process at process creation time, using what are called environment slots.

Up +to 16 separate pieces of information can be passed to a process on creation. +For this purpose, a process has 16 environment slots that can contain the +information passed to it by the launching process.

Slot 0 is reserved +and is never available for general purpose information passing.

The +parent (launching) process can only pass information to the child (created) +process after the child process has been created. However, it should be done +before the child process is resumed; it is an error to try and set environment +data in a child process that has been resumed.

A child process can +only extract the information from its environment slots once. Extracting information +from a slot causes that information to be deleted from the slot.

It +is a matter of convention between the parent and child process as to the meaning +to be applied to a slot, and the type of data that it is to contain.

+
The APIs

To +pass, a handle, a client server subsession, or binary data to a child process, +the parent process calls RProcess::SetParameter(), where +the RProcess object represents the newly created child +process. There are five overloaded variants of SetParameter() used +for passing:

+ + + +

handle:

+TInt RProcess::SetParameter(TInt aSlot, RHandleBase aHandle); +
+ +

client server subsession:

+TInt RProcess::SetParameter(TInt aSlot, const RSubSessionBase& aSession); +
+ +

8-bit descriptor:

+TInt RProcess::SetParameter(TInt aSlot, const TDesC8& aDes); +
+ +

16-bit descriptor:

+TInt RProcess::SetParameter(TInt aSlot, const TDesC16& aDes); +
+ +

integer:

+TInt RProcess::SetParameter(TInt aSlot, TInt aData); +
+ + +

To extract, a handle, or a client server subsession, a child process +can use the Open() function called on the relevant RHandleBase derived +type:

TInt RSemaphore ::Open(TInt aArgumentIndex, TOwnerType aType=EOwnerProcess); +TInt RBusLogicalChannel::Open(TInt aArgumentIndex, TOwnerType aType=EOwnerProcess); +TInt RMsgQueueBase::Open(TInt aArgumentIndex, TOwnerType aType=EOwnerProcess); +TInt RMutex::Open(TInt aArgumentIndex, TOwnerType aType=EOwnerProcess); +TInt RChunk::Open(TInt aArgumentIndex, TOwnerType aType=EOwnerProcess); +TInt RSessionBase::Open(TInt aArgumentIndex, TOwnerType aType=EOwnerProcess); +

To extract descriptor data, or integer data, a child process +can use the User class functions:

static TInt User::ParameterLength(TInt aSlot); +static TInt User::GetTIntParameter(TInt aSlot, TInt& aData); +static TInt User::GetDesParameter(TInt aSlot, TDes8& aDes); +static TInt User::GetDesParameter(TInt aSlot, TDes16& aDes); + +Environment slots + +
+
Passing a +file handle and a subsession

File server session handles and file +handles can both be passed to a child process.

The child process adopts +the file handle, and must not be closed by the parent. To use a file handle, +the session handle must also be passed.

For security reasons, +when sharing a file handle, the parent process should create a separate file +server session for the specific purpose of sharing the file handle. If the +parent process has other files open with this file server session, the child +process can gain access to those files by iterating through all the possible +values for the file handle and attempting to Adopt() each +one. For the same reason, the child process should only use this session for +sharing the file; it should not access other files through this session.

The +following two code fragments show code in the parent process and corresponding +code in the child process.

//Code in the parent (launching) process + + RProcess p; + p.Create(KProcName, KNullDesC); //create “child” process + + RFile file; + RFs session; + session.Connect(); //connect to file server + session.ShareProtected(); + file.Create(iSession, KFileName, EFileStreamText|EFileWrite|EFileShareAny); + file.Write(0, KTestData); + + p.SetParameter(5, session); //session handle passed in slot 5 + p.SetParameter(6, file); //file handle passed in slot 6 + Session.Close(); + p.Resume(); +

KProcName is the full path name of the +executable associated with the child process, and KFilename is +the file name.

//Code in the child (launched) process + + RFs session; + session.Open(5); //obtain session handle from slot 5 + + RFile file; + TInt handle; + ret = User::GetTIntParameter(8, handle);//get file handle from slot 8 + file.Adopt(session, handle); //adopt the handle + TBuf8<100> rbuf; //use the file + ret = file.Read(0, rbuf); + file.Close(); + session.Close(); +
+
Passing a +general handle, derived from RHandleBase

General handles derived +from RHandleBase can be passed to a child process.

The +handle is duplicated when it is stored in the child process’s environment. +The parent can close the handle immediately after calling SetParameter(), +or continue to use the handle and close it later.

The following two +code fragments show code in the parent process and corresponding code in the +child process.

//Code in the parent (launching) process, +//passing handles to a mutex and a semaphore. + + RMutex mutex; + RSemaphore sem; + + RProcess p; + p.Create(KProcName, KNullDesC); + mutex.CreateGlobal(KMutexName); //create the mutex + sem.CreateGlobal(KSemName,0); //create the semaphore + p.SetParameter(3, mutex); //put mutex handle into child process env' slot 3 + p.SetParameter(4, sem); //put semaphore handle into child process env' slot 4 + mutex.Close(); + Sem.Close(); + p.Resume(); //resume the child process + //Code in the child (launched) process retrieving the handles. + + RMutex mutex; + mutex.Open(3, EOwnerThread); //get mutex handle + RSemaphore sem; + sem.Open(4, EOwnerThread); //get semaphore handle + + //use the semaphore and mutex + mutex.Close(); + sem.Close(); +
+
Passing descriptor +data

Both 8-bit and 16-bit descriptor data can be passed from a +parent to a child process.

Internally, an HBuf descriptor +is created containing the passed descriptor data, and a pointer to this descriptor +is passed in the relevant slot.

The child process retrieves the descriptor +data by calling User::GetDesParameter(). It can get the +length of the data by calling User::ParameterLength().

The +following two code fragments show code in the parent process and corresponding +code in the child process.

//Code in the parent (launching) process, passing 8 and sixteen bit data + + RProcess p; + p.Create(KProcName, KNullDesC); + p.SetParameter(2, KSixteenBitDes); + p.SetParameter(3, KEightBitDes); + p.Resume(); +

where KSixteenBitDes is a 16-descriptor, +and KEightBitDes is an 8-bit descriptor.

//Code in the child (launched) process retrieving 8 and sixteen bit data + + TInt len; + TInt ret; + + TBuf16<40> buf; + len = User::ParameterLength(2); //parameter length is the size in bytes + ret = User::GetDesParameter(2, buf); + + //buf.Length() should have the value of len/2; + + + TBuf8<40> buf8; + len = User::ParameterLength(3); + ret = User::GetDesParameter(3, buf8); + //buf.Length() should be the same as len +

Note that the descriptors, buf, and buf8 used +in the child process must have sufficiently large maximum lengths to accomodate +the data.

+
Passing an +integer

An integer can be passed from a parent to a child process.

The +following two code fragments show code in the parent process and corresponding +code in the child process.

//Code in the parent (launching) process + + RProcess p; + TInt ret; + + ret = p.Create(KProcName, KNullDesC); + p.SetParameter(12, 1234); // Using slot 12 + p.Resume(); + //Code in the child (launched) process, retrieving the integer. + + TInt val; + TInt ret; + + ret = User::GetTIntParameter(12, val); + +
+
Error handling +issues

The parent process is panicked when calling SetParameter() with +a handle if:

    +
  • the parent process is +not the creator of the child process

  • +
  • the slot number is out +of range, i.e. is not in the range 0 to 15

  • +
  • the slot is in use

  • +
  • the handle is local.

  • +

The parent process is panicked when calling SetParameter() with +a descriptor or integer if:

    +
  • the parent process is +not the creator of the child process

  • +
  • the slot number is out +of range, i.e. is not in the range 0 to 15

  • +
  • the slot is in use

  • +
  • the length of the data +is negative.

  • +

The child process is panicked if the slot number is out of range.

The +API functions that extract data from the process environment return KErrArgument if +a slot contains the incorrect data type, or the length is incorrect. They +return KErrNotFound if a slot is empty.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-ADB848FD-317A-521C-9684-BBCF20358207.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-ADB848FD-317A-521C-9684-BBCF20358207.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,86 @@ + + + + + +ArchitectureDescribes the USB client architecture. +

Symbian platform provides access to USB client hardware through its USB +client driver.

+

The following diagram shows the USB client architecture. Devices can provide +more than one USB function. To better show the typical use, the diagram shows +the components in use with a phone that is configured as a combined +WHCM and OBEX peripheral.

+ + + +

There are three main elements:

+
    +
  • The user side interface +to the USB client driver.

  • +
  • The USB client driver +LDD that provides the driver's logical channel. This is hardware independent.

  • +
  • The PDD, or client controller, +that manages access to the USB client hardware.

  • +
+
User API

The user side interface to the USB client +driver is provided by RDevUsbcClient. The user side interface +is implemented as a set of inline functions and means that there is no separate +user side library component. This is typically the case for device drivers.

+
USB client +driver (LDD)

The USB client driver provides an interface to the +USB client device. The USB client driver is also referred to as a channel to +the USB client device; it may also be referred to as the USB logical device +driver.

Each user component that requires a connection to the USB +client device opens a channel using the user side RDevUsbcClient class.

A +channel supports only one USB interface. A channel (i.e. the USB LDD) can +be loaded as many times as needed; the decision is based on the number of +interfaces required. This can be done either in the same process or in a different +process depending on the relationship between the interfaces.

If there +is more than one channel open on the USB client device, then they can all +share Control Endpoint 0 (Ep0). Each channel can make a request on this endpoint. +The other endpoints cannot be shared between channels; instead each endpoint +is used exclusively by one, and only one, channel.

Each channel can +claim up to a maximum of five endpoints in addition to Ep0. Each endpoint +claimed on a channel is locally numbered from one and five. This number need +not correspond to the actual endpoint number of the hardware interface; this +number is called the logical endpoint number, and all transfer requests use +the logical number for the endpoint. A driver can, however, discover the physical +endpoint address of a logical endpoint by requesting the endpoint descriptor.

A +channel can have asynchronous requests outstanding on one or more of its endpoints +simultaneously; this includes Ep0. As Ep0 can be shared between channels, +then the underlying USB Controller must manage multiple requests on this endpoint

+
USB client +controller (PDD)

The USB client controller manages access to the +USB client hardware on behalf of all USB client drivers. It has a two layer +implementation:

    +
  • a licensee product independent +layer that provides an API for the USB client driver. This is often referred +to as the Platform Independent Layer, and forms the 'upper' part of the USB +physical device driver (PDD).

  • +
  • a layer that interfaces +with the hardware. This is often referred to as the Platform Specific Layer, +and forms the 'lower' part of the USB physical device driver (PDD). It +is this part that needs porting effort.

  • +

The Platform Independent Layer contains, as far as possible, the +functionality that is defined in the USB specification. This includes the +‘Chapter 9’ device state handling and request processing. The Platform Specific +Layer contains only that functionality which cannot be abstracted and made +generic, because different USB Device Controller designs are programmed differently +and operate differently.

The complete USB client controller (PDD) +is an instance of a DUsbClientController derived class +and is implemented as a kernel extension named usbcc.dll.

The +functionality of the Platform Independent Layer is provided by the base class DUsbClientController. +This class also defines a large number of pure virtual functions that are +intended to provide the functionality that is not part of the USB specification, +but is specific to the USB Device Controller. Such functions typically implement +direct USB Device Controller hardware manipulation, register access, endpoint +FIFO loading/unloading etc. The platform specific layer provides the implementation +for these pure virtual functions by defining and implementing a device specific +class derived from DUsbClientController.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-ADC42B89-B061-50C3-B532-6065A0C418C3.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-ADC42B89-B061-50C3-B532-6065A0C418C3.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,12 @@ + + + + + +USB Shared ChunksThe USB client Logical Device Driver (LDD) API has been extended to share chunks between the kernel side USB LDD and the user side USB applications such as Mass Storage.

Shared chunks improve performance by eliminating the need to copy data between different processes. USB client application efficiency will be improved by sharing chunks from the kernel side drivers to the application.

\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-AE486C82-8854-463F-8CB9-B7353D6B2804.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-AE486C82-8854-463F-8CB9-B7353D6B2804.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,30 @@ + + + + + +Baseport Template Build GuideDescribes how to build a Baseport Template. +

The Baseport Template contains dummy functions. The Baseport Template +is designed to boot without supporting any peripherals. The developers +should port the individual drivers depending on the hardware used. +This guide describes a generic build procedure for ARMv5 based devices.

+
Template +port

The baseport code is available at os/kernelhwrrv/bsptemplate/asspandvariant/template_variant/. The comments in the Baseport Template provide enough information +to start porting.

+
Procedure

The following steps describe how to build the Baseport Template +for an ARMv5 processor.

    +
  1. Create a file, +for example, commands.txt that contains the list +of files to be built. Each line of commands.txt would be in the following example format:

    -b \os\buildtools\toolsandutils\e32tools\group\bld.inf
  2. +
  3. Call commands.txt file using the following command:

    sbs –command=commands.txt –c armv5_urel The above +would produce a armv5 urel version.
  4. +
+
+Symbian Build System v2 +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-AE53C15E-0C0F-5726-BBA4-E7DCDA7F48B4-master.png Binary file Adaptation/GUID-AE53C15E-0C0F-5726-BBA4-E7DCDA7F48B4-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-AE53C15E-0C0F-5726-BBA4-E7DCDA7F48B4_d0e9145_href.png Binary file Adaptation/GUID-AE53C15E-0C0F-5726-BBA4-E7DCDA7F48B4_d0e9145_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-AEDBF425-6077-4C84-A698-508291671F2B-master.png Binary file Adaptation/GUID-AEDBF425-6077-4C84-A698-508291671F2B-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-AEDBF425-6077-4C84-A698-508291671F2B_d0e27993_href.png Binary file Adaptation/GUID-AEDBF425-6077-4C84-A698-508291671F2B_d0e27993_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-AF245763-EB25-49BC-90DC-0BD5F2D22AA5.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-AF245763-EB25-49BC-90DC-0BD5F2D22AA5.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,74 @@ + + + + + +Specific +Build InformationThis document discusses the details of the build procedure which +are specific to device drivers. +
Building +device drivers

Building a device driver is similar to building +any other component in Symbian platform. This section discusses the details +that are specific to drivers, and assumes that you are familiar with the Symbian +platform build tools.

Device drivers can be built either by using +console commands (bldmake and abld) +or by using an IDE. Any project can be built for multiple platforms. Generally, +it is either ARM for the hardware target or WINSCW for the emulator target. +For hardware target builds, the build can be for ARMV5, ARMV6, and Thumb, +while for emulator builds, the platform is WINSCW. The compilers used for +ARM are the ARM RVCT compiler or, in earlier versions of the platform, +a version of the GNU GCC compiler. For the emulator, the compiler is the Carbide.c++ +or Metrowerks CodeWarrior compiler.

The .mmp file +(project file) specifies the source files to build and the platform for which +the target binary will be built.

+
Variant specific target

When a target is specified +using the keyword VariantTarget(), the build tools generate +a unique name for the binary by adding the variant name. This allows separate +binaries to be created for each variant, and prevents the current binary being +overwritten.

For example, if the target to be built is d_expio_ldd.ldd, +then VariantTarget(d_expio_ldd,ldd) would be specified +in the .mmp file. If the project is then built for the h4hrp variant, +the final target binary built is called _h4hrp_d_expio_ldd.ldd.

+
ROM image build

To include a driver in a ROM image, +the driver's files must be included in the corresponding obey files (.oby). +In the base subsystem, the binaries are specified in .iby files, +and the .iby files are then included in .oby files.

For +example, to include a driver in the H4 text shell ROM image, it should be +included in kernel.iby. This file is located in base\omap_hrp\h4\rom\, +and exported to epoc32\rom\h4hrp. Similarly for the TechView +ROM build, the relevant file is base_h4hrp.iby file, +which is located in base\omap_hrp_h4\rom\, and exported +to epoc32\rom\include. An example from an .iby file +is shown below:

// .iby file + +/** +##KMAIN## gets the path for e32 +##BUILD## gets the build – udeb/urel according to build +##VARIANT gets the target from corresponding variant +*/ + +device[VARID]=\EPOC32\RELEASE\##KMAIN##\##BUILD##\d_expio_ldd.ldd sys\bin\d_expio_ldd.ldd + +device[VARID]=\EPOC32\RELEASE\##KMAIN##\##BUILD##\_##VARIANT##_d_expio_pdd.pdd sys\bin\d_expio_pdd.pdd

On +building the test .inf files, test .iby files will be +generated. This includes the newly added binaries in the .iby file.

After +building the drivers, a ROM can be built. Device driver and base developers +generally build text shell ROM images for development and testing. These can +be built using the rom tool (from base\e32\rombuild). +By default, the ROM image is generated in that directory. An alternate path +can also be specified.

For example, for the H4HRP variant, a text +shell ROM image is built using:

rom –v=h4hrp –I=armv5 udeb

This +builds a ROM called H4HRPARMV5D.IMG, which can then be +downloaded to target hardware and tested.

To include base test programs +in a ROM image, the option –type can be used. For example:

rom +–v=h4hrp –I=armv5 udeb –type=e32tests

This includes the +tests from base\e32test. The tool uses as input a generated +or precompiled oby file, which includes all the generated +test .iby files.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-AF2E227B-C5BD-5F05-98D4-7D15530161C8.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-AF2E227B-C5BD-5F05-98D4-7D15530161C8.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,42 @@ + + + + + +Interrupt::Clear()Describes the implementation of the clear function. +

The function Interrupt::Clear() is used by device drivers +to acknowledge that they have serviced the interrupt and cleared the pending +flag in the interrupt controller hardware.

+

This is useful in situations where an interrupt must be cleared explicitly +rather than as a side effect of an I/O register access, especially where the +clearing is done from generic code such as in the PC card and MMC controllers.

+

The implementation of this function is completely dependent on the interrupt +hardware.

+

In the template port, Interrupt::Clear() is implemented +in ...\template_assp\interrupts.cpp.

+EXPORT_C TInt Interrupt::Clear(TInt anId) + { + __KTRACE_OPT(KEXTENSION,Kern::Printf("Interrupt::Clear id=%d",anId)); + TInt r=KErrNone; + // if ID indicates a chained interrupt, call variant... + if (anId<0 && ((((TUint)anId)>>16)&0x7fff)<(TUint)KNumTemplateInts) + r=TemplateAssp::Variant->InterruptClear(anId); + else if ((TUint)anId>=(TUint)KNumTemplateInts) + r=KErrArgument; + else + { + // + // TO DO: (mandatory) + // + // Clear the corresponding Hardware Interrupt source + // + } + return r; + } +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-AF71FDC2-A8CC-5035-91FE-36212844BC07.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-AF71FDC2-A8CC-5035-91FE-36212844BC07.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,216 @@ + + + + + +Channel +ImplementationDescribes how to use the template port to implement the physical +channel for the Digitizer Driver. +
Define the +size of the digitizer

The following four constants defined at the +top of the template implementation in xyin.cpp define +the origin and size of the digitizer device in pixels. Modify the values to +define your own origin and size.

const TUint KConfigXyOffsetX = 0; +const TUint KConfigXyOffsetY = 0; +const TUint KConfigXyWidth = 640; // pixels per line +const TUint KConfigXyHeight = 480; // lines per panel +

This is information that is returned when calls are made:

    +
  • user side to HAL::Get() passing +the attribute(s) EPenX and EPenY

  • +
  • kernel side to Kern::HalFunction(), +passing group EHalGroupdigitizer and function-id EdigitizerHalXYInfo

  • +

See User-Side +Hardware Abstraction.

The following four constants define the +digitizer origin and size in digitizer ADC coordinates. Modify the values +for your own digitizer:

const Tint KConfigXySpreadX = 4096; // maximum valid X spread +const Tint KConfigXySpreadY = 4096; // maximum valid Y spread +const Tint KConfigXyMinX = 0; // minimum valid X value +const Tint KConfigXyMinY = 0; // minimum valid Y value +
+
Implement power +on behaviour

In the template port, this is implemented by DTemplatedigitizer::digitizerPowerUp(). +Note that this function is not derived from any base class function.

    +
  • Add code to this function +to do these things:

      +
    1. Clear all digitizer +interrupts.

    2. +
    3. Request power resources +from the power controller. This will power the device up from sleep mode. +Note that power up, and power down, can be implemented later.

    4. +
    5. Configure the hardware +so that it generates an interrupt when the digitizer is touched.

    6. +
  • +
  • Make sure that the digitizer +interrupt is defined. In the template port, the interrupt id is defined as +the constant:

    const TInt KIntIddigitizer=EAsspIntIdC

    in +the file ...\template\template_assp\template_assp.h.

  • +
  • Make sure that the interrupt +controller is configured for the digitizer interrupt. See Interrupt +Dispatcher.

  • +
+
Implement Ddigitizer::WaitForPenDown()

This +code is executed at startup or whenever the pen is lifted up. It implements +a request for an interrupt to be generated when the pen next touches the digitizer. +It is called by the platform independent layer:

    +
  • at startup

  • +
  • when the pen is removed +from the digitizer after a pen-up event has been issued.

  • +

There are two main cases to deal with: the digitizer is powering +down; the digitizer is not powering down

The +digitizer is powering down

The implementation for this case can +be left until later. It is discussed in Implement +power up and power down handling.

The +digitizer is not powering down

To deal with this case, +your implementation needs to:

    +
  • clear the digitizer +interrupt

  • +
  • set up the hardware +so that it can detect when the digitizer is touched.

  • +

The pen interrupt is now enabled; if the digitizer is now touched, +the pen interrupt ISR (interrupt service routine) DTemplatedigitizer::PenInterrupt() is +called.

In the template port, the ISR includes the statement:

__KTRACE_OPT(KHARDWARE,Kern::Printf("I"));

and +means that if the KHARDWARE tracing flag has been set, and +tracing is on, then a single “I” is printed whenever the digitizer is touched.

Tracing +note

If the KEXTENSION, KPOWER and KHARDWARE tracing +flags have been set, and tracing is on, then by the time WaitForPenDown() is +called, you should be able to see the following sequence of calls in the trace:

    +
  • DoCreate()

  • +
  • digitizerPowerUp()

  • +
  • WaitForPenDown()

  • +

+
Implement the +pen interrupt ISR

In the template port, the interrupt service routine +(ISR) that handles a pen interrupt is implemented by DTemplatedigitizer::PenInterrupt(). +Note that this function is not derived from any base class function.

There +are two main things to consider here:

    +
  1. You need to add code +to the start of the function to decide whether the pen is now up (i.e. removed +from the screen panel), or whether the pen is now down (i.e. touching the +digitizer panel). To make the decision, you may need to read the appropriate +hardware register. The detail depends on the hardware.

  2. +
  3. If the pen is down, +you need to check the value of the configurable constant KPenDownDelayTime. What you do next depends on the value of this constant:

      +
    • If the value is greater +than zero, then you do not need to change the code at this time. The existing +code just starts a timer to delay the beginning of the collection of samples. +Note, however, that you will need to modify the debounce timer callback function timerIntExpired() to +clear the digitizer interrupt - see Add +code to the debounce timer callback function.

    • +
    • If the value is zero, +then you must clear the digitizer interrupt here in this function, PenInterrupt().

    • +
  4. +
  5. To contribute the timing +of pen interrupts as a source of random data for the Random Number Generator +(see CSPRNG Implementation +in Kernel), ensure that a call to Interrupt::AddTimingEntropy() is +made in the ISR.

  6. +
+
Initialise +sampling

In the template port, the initialisation of sampling is +implemented in the first half of the function DTemplatedigitizer::TakeSample() function. +Note that this function is not derived from any base class function.

There +are two main things to consider here:

    +
  1. You need to decide whether +the pen is up or down. Set the variable penDown to ETrue if +the pen is down or EFalse if the pen is up.

    To +do this you may need to read the appropriate hardware register - the detail +depends on the hardware.

  2. +
  3. Change the section of +code that is executed when the pen is found to be up after a power on, i.e. +the block of code:

    if (iState==E_HW_PowerUp) + { + if (!penDown) + { + ... + }

    The block of code needs to do the following:

      +
    • reset the sample buffer

    • +
    • clear the digitizer +interrupt

    • +
    • set up the hardware +so that it can detect when the digitizer is touched

    • +
    • enable the digitizer +interrupt.

    • +
  4. +
+
Take sample +readings

In the template port, the initialisation of sampling is +implemented in the second half of the function DTemplatedigitizer::TakeSample() function. +Note that this function is not derived from any base class function.

This +code is executed while the pen is down, and needs to do the following:

    +
  • read the hardware for +the digitizer samples and put the results into the sample buffer. The sample +buffer resides in the platform independent layer.

  • +
  • set up the hardware +so that it can detect when the digitizer is touched

  • +
  • schedule the reading +of the next sample using a one shot timer; the time interval is defined by +the value of the configurable constant KInterSampleTime

  • +
  • when a complete group +of samples has been taken, tell the platform independent layer by calling RawSampleValid(); +the function is a member of the base class Ddigitizer.

  • +

Tracing note

If the KHARDWARE tracing +flag has been set, and tracing is on, then it should be possible to move the +pen over the screen and see the raw sample values on the debug output. Check +they are correct.

+
Add code to +the debounce timer callback function

In the template port, the +debounce timer callback function is implemented by the local function timerIntExpired().

If +not already done in Implement +the pen interrupt ISR, add code to this callback function to clear +the digitizer interrupt.

+
Deal with a +pen up interrupt

If the digitizer generates an interrupt when the +pen is lifted, then you need to add code to the pen interrupt ISR to handle +this. This is the same function, DTemplatedigitizer::PenInterrupt(), +referred to in Implement +the pen interrupt ISR.

The code should:

    +
  • clear the digitizer +interrupt.

  • +
  • set up the hardware +so that it can detect when the digitizer panel is touched.

  • +

If there is no pen up interrupt by design, then you need to add code +into the DTemplatedigitizer::TakeSample() function at the point where +the pen is up and the digitizer is in the pen up debounce state (i.e. E_HW_PenUpDebounce):

if (!penDown) + { + if (iState==E_HW_PenUpDebounce) + { + . . .

At this point, you should have almost all digitizer +capability – pen up handling, pen down handling, and the taking of digitizer +readings.

+
Implement Ddigitizer::digitizerOff()

This +function is called when the digitizer is being powered down.

If the +device is powered on, then the function needs to do disable the digitizer +interrupt.

If the digitizer is in the collect sample state +(i.e. E_HW_CollectSample), then it also needs to do the following:

    +
  • set up the hardware +so that the device wakes up from standby if the digitizer panel is touched.

  • +
  • relinquish the request +for power resources; this will place the peripheral hardware into a low power +"sleep" mode, which is capable of detecting an interrupt.

  • +
+
Implement power +up and power down handling

At this point, the device should be +working successfully.

You now need to put the device into a low power +"sleep" mode when it is switched off, and to bring it out of "sleep" mode +when the digitizer is touched.

    +
  • Add code to the template +port function DTemplatedigitizer::digitizerPowerUp() to request power +resources from the power controller. This will power the device up from sleep +mode.

  • +
  • Add code to the powering +down part of your implementation of Ddigitizer::WaitForPenDown() that +does the following:

      +
    • sets up the hardware +to wake the device from standby if the digitizer is touched.

    • +
    • relinquishes the request +for power resources - this will place the peripheral hardware into a low power +"sleep" mode, which is capable of detecting an interrupt.

    • +
  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-AFA1604D-FF0C-56BE-A71E-AF3C662F8943.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-AFA1604D-FF0C-56BE-A71E-AF3C662F8943.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,102 @@ + + + + + +Platform-Specific +MakefileDescribes how to write the platform-specific makefile to build +the bootstrap. +

The platform-specific makefile sets some variables for file and path names +and then includes the generic makefile.

+

The makefile consists of a collection of variables divided into a mandatory +set, which must have values assigned, and an optional set.

+

The values are used by the Symbian platform generic makefile.

+
Mandatory variables + + + +

NAME

+

This the name of the bootstrap binary file. The filename is NAME.bin and +it appears in EPOCROOT/epoc32/release/PLATFORM where +PLATFORM is e.g. ARM4, ARMV5 etc.

+
+ +

MEMMODEL

+

This specifies which memory model is to be used on the target platform. +Valid values are:

    +
  • direct

  • +
  • moving

  • +
  • multiple

  • +

Platforms that use an ARM architecture 4, 4T or 5 will use moving for +the main bootstrap.

Platforms that use ARM architecture 6 will use multiple.

Usually, direct will +only be used when building a bootloader.

+
+ +

SOURCES

+

Specifies a list of platform-dependent assembler source files, each +separated by at least one space, needed to build the bootstrap. Only file +names are required, not paths.

In the example of the template, there +is a single source file, template.s.

+
+ +

INCLUDES

+

Specifies a list of platform-dependent assembler include files, +each separated by at least one space, needed to build the bootstrap. Only +file names are required, not paths.

In the example of the template, +there is a single include file, config.inc.

+
+ +

E32PATH

+

Specifies the relative path from the directory containing the platform-specific +makefile to the directory containing the e32 source tree. +This is used to find the generic source and the generic include files required +to build the bootstrap.

In the example of the template, the path is ../...

+
+ + +
+
Optional variables + + + +

EXTRA_INC_PATH

+

Specifies a list of directories, each separated by at least one +space, which should be searched for assembler include files (.inc), +and possibly C/C++ header files (.h) to be translated +into assembler syntax.

Each entry in this list is relative to the +directory in which the platform-specific makefile resides.

+
+ +

EXTRA_SRC_PATH

+

Specifies a list of directories, each separated by at least one +space, which should be searched for assembler source files (.s).

Each +entry in this list is relative to the directory in which the platform-specific +makefile resides.

+
+ +

GENINCLUDES

+

Specifies a list of additional C/C++ header files (.h), +each separated by at least one space, which should be translated into assembler +syntax include files (.inc) for inclusion in assembler +source.

For example, if a file x.h is specified +in this list, it will be translated to x.inc in the build +directory, and it should be included as x.inc in any +source file which requires it.

+
+ +

ASM_MACROS

+

Specifies a list of additional symbols, each separated by at least +one space, which should be defined when assembling each source file. Values +may not be assigned to the symbols; all that can be tested is whether a symbol +is defined.

+
+ + +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-B0FA9741-CB42-560F-A13E-78FAA57F7871-master.png Binary file Adaptation/GUID-B0FA9741-CB42-560F-A13E-78FAA57F7871-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-B0FA9741-CB42-560F-A13E-78FAA57F7871_d0e93088_href.png Binary file Adaptation/GUID-B0FA9741-CB42-560F-A13E-78FAA57F7871_d0e93088_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-B0FA9741-CB42-560F-A13E-78FAA57F7871_d0e93496_href.png Binary file Adaptation/GUID-B0FA9741-CB42-560F-A13E-78FAA57F7871_d0e93496_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-B1CE51BC-B452-5FC9-9C00-35447AF40671.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-B1CE51BC-B452-5FC9-9C00-35447AF40671.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,357 @@ + + + + + + Implement +the controllable power resourcesThis document describes how to write and use power resources. +
Purpose

Implement your power resource according +to the type of resource you wish to support.

Introduction

Power +resources controlled by the PRM can be turned on, off and varied with software.

See +the Power +resources section for detailed information about resources. There are +five main types of resource that can be implemented:

    +
  • static resources - derived +from the DStaticPowerResource base class,

  • +
  • static resource that +support dependancy - derived from the DStaticpowerResourceD base +class,

  • +
  • dynamic resources - +derived from the DDynamicPowerResource base class. Create +dynamic resources in the kernel data section or in the heap,

  • +
  • dynamic resource that +support dependancy - derived from the DDynamicPowerResourceD.

  • +
  • custom sense resources +- when shared the power level of this resource may be increased or decreased +freely by some privileged clients but not by others, which are bound by the +requirement of the privileged clients.

  • +

Note: dynamic resources and resource dependancies are only +supported in the extended version of the PRM. See setup and configuration requirements.

+
Implementing power resources

The following tasks +are covered in this tutorial:

    +
  • Create your resource by

    Override +the pure virtual functions,

  • +
  • Create resource dependencies,

  • +
  • Create custom resources.

  • +

Override the pure +virtual functions

The pure virtual functions of DStaticPowerResource or DDynamicPowerResource must +be implemented.

Constructor

Information about the resource +based on the resources category must be set in the iFlags bit +mask. Static variables that define a resources classification can be found +within 32\include\drivers\resource.h.

Each resource +is classified based on:

    +
  • usage,

  • +
  • operating levels,

  • +
  • latency,

  • +
  • resource sense.

  • +

Below is the example implementation of derived class constructor

// multilevel, shared, long latency, read and write, positive resource. +DMLSHLGLSPResource::DMLSHLGLSPResource() : DStaticPowerResource(KDBSHLGLSPResource, E_ON), + iMinLevel(E_OFF), iMaxLevel(E_ON), iCurrentLevel(E_ON), iPolled(ETrue) + { + iFlags = EMultilevel | KShared | KLongLatencySet | KLongLatencyGet; + . . . + }

GetInfo()

The PIL uses GetInfo() to +get resource information. The default implementation of this function provides +generic information about the resource by updating the passed descriptor that +contains an information structure TPowerResourceInfoV01. +Derived implementations must fill in all the PSL specific fields and call +the base class implementation. Below is an example implementation.

TInt DH4SndFclkResource::GetInfo(TDes8* info) const + { + __KTRACE_OPT(KRESMANAGER, Kern::Printf(">DH4SndFclkResource::GetInfo\n")); + + /** Call base class implementation to fill generic details */ + DStaticPowerResource::GetInfo((TDes8*) info); + TPowerResourceInfoV01 *buf1 = (TPowerResourceInfoV01*) info; + buf1->iMinLevel = iMinLevel; + buf1->iMaxLevel = iMaxLevel; + __KTRACE_OPT(KRESMANAGER, Kern::Printf("<DH4SndFclkResource::GetInfo\n")); + return KErrNone; + }

The member variables of the TPowerResourceInfoV01 structure +are reserved for PSL information. These can be used to return resource specific +information to clients.

DoRequest()

DoRequest() is +used by the PIL to control resources. For example, to change and read the +state of resources. DoRequest() takes a TPowerRequest object +that contains all the request information. Note: This function needs +to be implemented for all resources.

Below is an example DoRequest() function +implementation for a binary, instantaneous resource.

TInt DH4MmcCtrllerPwrResource::DoRequest(TPowerRequest& aRequest) + { + TInt retVal = KErrNone; + TUint16 config; + /** Enable/disable the MMC controller by programming the MMC controller 'CON' register- 'POW' bit */ + if (aRequest.ReqType()==TPowerRequest::EGet) + { + PRM_PSL_RESOURCE_GET_STATE_START_TRACE + config = OMAPMMC_GET_REG(KHoMMC_Con_Reg); + if(config & KHtMMC_PowerUp) + { + aRequest.Level() = 1; + iCurLevel = 1; + } + else + { + aRequest.Level() = 0; + iCurLevel = 0; + } + PRM_PSL_RESOURCE_GET_STATE_END_TRACE + } + else if(aRequest.ReqType()==TPowerRequest::ESetDefaultLevel) + { + PRM_PSL_RESOURCE_CHANGE_STATE_START_TRACE + OMAPMMC_MOD_REG(KHoMMC_Con_Reg, KHtMMC_PowerUp, KClear32); + iCurLevel = iDefaultLevel; + aRequest.Level() = iDefaultLevel; + PRM_PSL_RESOURCE_CHANGE_STATE_END_TRACE + } + else + { + PRM_PSL_RESOURCE_CHANGE_STATE_START_TRACE + if(aRequest.Level() == 1) + { + OMAPMMC_MOD_REG(KHoMMC_Con_Reg, KClear32, KHtMMC_PowerUp); + } + else + { + OMAPMMC_MOD_REG(KHoMMC_Con_Reg, KHtMMC_PowerUp, KClear32); + } + iCurLevel = aRequest.Level(); + PRM_PSL_RESOURCE_CHANGE_STATE_END_TRACE + } + return retVal; + }

The DoRequest function implementation should take care +of blocking the Resource Controller thread as operations on a long latency +resource take a significant amount of time to complete (in hardware). Usually +the request completion is notified either through an ISR (interrupt driven) +or through register setting (polling wait) by hardware.

Below is an +example DoRequest() implementation for a long latency resource.

TInt DH4MmcPowerResource::DoRequest(TPowerRequest& aRequest) + { + TUint8 iMenelausConf; + TInt retVal = KErrNone; + + /** Access to Menelaus registers is over I2C bus. This is a long latency synchronous operation. + Create a Menelaus Request structure and send it to Menelaus chip, Wait until a response is received */ + + if (aRequest.ReqType()==TPowerRequest::EGet) + { + // Frame the request + ... + } + // Default level is off. + else if (aRequest.ReqType() == TPowerRequest::ESetDefaultLevel) + { + // Frame request to move the resource to default state + ... + } + // EChange + else + { + // Frame request to set the requested resource state + ... + } + + // Request the operation on the hardware + retVal = Menelaus::AccessRegister(iMenelausReq); + + // Wait for the request to complete + __KTRACE_OPT(KPBUS1, Kern::Printf("Waiting for menelaus req to signal sem\n")); + NKern::FSSetOwner(&iSemaphore,NULL); + iSemaphore.iCount = 0; + + // This will be signalled in Menelaus access functions callback below + NKern::FSWait(&(iSemaphore)); + + // Menelaus chip has responded + if(iMenelausAccessErr == KErrNone) + { + switch(iMenelausState) + { + case EMenelausRead: + // Return 0/1 depending on the value set + iMenelausConf = (*(iRdBuffer.Ptr())) & KHoMenelausVmmcModeMask; + if(iMenelausConf == 3) + { + iCurLevel=aRequest.Level()=1; + } + else + { + iCurLevel=aRequest.Level()=0; + } + PRM_PSL_RESOURCE_GET_STATE_END_TRACE + break; + + case EMenelausSingleWrite: + iCurLevel = aRequest.Level(); + PRM_PSL_RESOURCE_CHANGE_STATE_END_TRACE + break; + } + } + return iMenelausAccessErr; + } + +/** Below is the Menelaus access functions callback where the semaphore is signalled. */ +void DH4MmcPowerResource::MenelausAccessDone(TAny* aPtr, TInt aResult) + { + DH4MmcPowerResource* ptr = reinterpret_cast<DH4MmcPowerResource*>(aPtr); + ptr->iMenelausAccessErr = aResult; + if(aResult != KErrNone) + { + __KTRACE_OPT(KRESMANAGER, + Kern::Printf("Menelaus::MenelausAccessRegister ERR(%d)\n", aResult)); + } + // Signal the waiting thread + NKern::FSSignal(&(ptr->iSemaphore)); + return; + }

Create +resource dependencies

A resource has a dependency if the state +of the resource depends on the state of one or more resources. For example, +a clock whose frequency is derived from another clock or voltage is a dependent +resource. The PSL usually handles resource dependencies transparently. However, +if the resources have public users (clients of the PRM), then these resources +should be registered with the PRM as Resource +dependencies that are linked.

Each dependency must be assigned +a priority value. The priority is used by the PIL when propagating the change +and propagating the request for notifications. Each link stemming from a resource +must have a unique priority value.

Note: Resource dependencies +are only supported in the extended version of the PRM. Only long latency resources +are allowed to have dependents and no closed loop dependencies are allowed.

Register +resource dependencies for dynamic and static resources

Static +resources that support dependencies are created and registered with the PRM +during resource controller creation time and are derived from DStaticPowerResourceD:

DXXXStaticPowerResourceD : public DStaticPowerResourceD + { +public: + DXXXStaticPowerResourceD(); + TInt DoRequest(TPowerRequest &req); + TInt GetInfo(TDes8* aInfo) const; + TChangePropagationStatus TranslateDependentState(TInt aDepId, TInt aDepState, TInt& aResState); +private: + TInt iMinLevel; + TInt iMaxLevel; + TInt iCurrentLevel; + ... + };

Dependencies between static resources should be established +by the PSL before registering these resources with the PIL. Use the DStaticPowerResourceD::AddNode() function +provided in the base class to establish a dependency link between static resources. +See Creating +dependencies between static resources.

Dynamic resources that +support dependency are derived from DDynamicPowerResourceD. +These can be registered and deregistered from the PRM at any time after the +PRM is fully initialised. Dependencies between resources are established by +the client using PowerResourceManager::RegisterResourceDependency().

DXXXDynamicPowerResourceD : public DDynamicPowerResourceD + { +public: + DXXXDynamicPowerResourceD(); + TInt DoRequest(TPowerRequest &req); + TInt GetInfo(TDes8* aInfo) const; + TChangePropagationStatus TranslateDependentState(TInt aDepId, TInt aDepState, TInt& aResState); +private: + TInt iMinLevel; + TInt iMaxLevel; + TInt iCurrentLevel; + ... + };

Dependencies can be established between a dynamic resource +and a static (dependency enabled) resource using the same API. A client can +deregister dependencies between a pair of dynamic resource (or between a dynamic +and static resource) using PowerResourceManager::DeRegisterResourceDependency(). +When a dynamic resource that supports dependency deregisters from the PRM, +dependencies are removed automatically by the PIL.

Change the state +of dependent resources

When a state change is requested by a client +on any resource in a dependency tree before proceeding with the change the +PIL must check if the change is allowed by its dependents and the ones it +depends on. The PIL does this by calling the TranslateDependentState() function +on each resource. This is a pure virtual function in the base class and must +be implemented in the derived class.

This function is called by the +PIL prior to a resource change on any of its dependents. The function returns +one of these values:

    +
  • EChange - +If the resource accepts the state change of the dependent resource and, as +a result of the dependent resources state change this resource needs to change +its own state. The new state of this resource is updated in aResState,

  • +
  • ENoChange - +if the resource accepts the dependent resources state change and this resource +does not need to change its state,

  • +
  • ENotAllowed - +if the resource does not accept the dependent resources state change.

  • +
TChangePropagationStatus DXXDependResource::TranslateDependentState(TInt /*aDepId*/, TInt aDepState, + TInt& aResState) + { + /* Switch ON if the dependent resource is ON */ + if((aDepState == 1) && (iCurrentLevel == 0) + { + aResState = iMaxLevel; + return EChange; + } + + /* Don’t allow dependent to OFF, if this is still ON */ + else if (aDepState == 0) && (iCurrentLevel == 1) + { + return ENotAllowed; + } + + return ENoChange; + }

Create +custom resources

Clients on a shared resource may have different +requirements on the state of a shared resource. The resource sense is used +by the PIL to determine whose requirement prevails:

    +
  • positive sense resources +- when shared can have their value increased without prejudice to their clients,

  • +
  • negative sense resources +- when shared can have their value decreased without prejudice to their clients,

  • +
  • custom sense resources +- when shared may be increased or decreased freely by some privileged clients +but not by others, which are bound by the requirement of the privileged clients.

  • +

A custom function must be supplied for every Power resources resource. This function is called by the PIL every +time a change request is issued to determine if the change requested by the +client is allowed as a decision to allow the resource change is determined +solely by the PSL. The resource object contains a pointer that must be set +at construction for custom sense resources by calling this function:

inline void SetCustomFunction(TCustomFunction aCustomFunction)

This +function sets the custom function for the resource. If a custom function is +not supplied for a custom sense resource the PIL panics during a resource +state change. An example of a custom sense resource is a shared domain clock +when a domain client uses it as a bit clock.

TCustomFunction is +a function pointer:

typedef TBool (*TCustomFunction) (TInt& /*aClientId*/, + TUint /*aResourceId*/, + TInt& /*aLevel*/, + TAny* /*aLevelList*/);

The +values held in TCustomFunction are:

    +
  • the Id of the client +requesting the change,

  • +
  • the Id of the resource +on which the change is requested (this allows a single function to handle +multiple resources),

  • +
  • the level the client +is requesting,

  • +
  • a pointer to the list +of the resource’s client +levels.

  • +

Custom functions can be set at any time before a resource state change +is requested on a resource. Ideally a custom function is set at resource creation +time in the resource's constructor.

DBSHLGLSCResource::DBSHLGLSCResource() : DStaticPowerResource(KDBSHLGLSCResource, E_ON), iMinLevel(E_OFF), iMaxLevel(E_ON), iCurrentLevel(E_ON), iPolled(EFalse) + { + iFlags = KMultiLevel | KShared | KLongLatencySet | KSenseCustom; + SetCustomFunction(CustomFunction); + ... + }

The decision to allow the requested resource state change +is specified in the custom function return value. This is ETrue if +the change is allowed and EFalse if the change is not allowed.

The +function can change the state of the resource to a level other than the one +requested and can choose a client other than the passed client to hold the Caching +the prevailing level of the resource.

Supporting dependencies

If +the custom sense resource supports dependencies then use the function pointer TDependencyCustomFunction. +This takes an additional parameter that specifies the resource Client level objects.

+
+Porting the +Power Resource Manager +Implement +the PSL for the target +Port the +client drivers to use the PRM +Debugging +the PRM +Testing the +PRM PSL +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-B2F86F54-EF50-56DB-ADF7-15325AC9324D.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-B2F86F54-EF50-56DB-ADF7-15325AC9324D.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,298 @@ + + + + + +IIC ConceptsThis document provides an overview of IIC concepts. +

IIC is a an abstraction of serial inter-IC buses such as I2C and +SPI. It allows serial bus device drivers to be written that do not +need to know the specifics of the underlying hardware technology.

+
Serial +inter-IC buses

Serial inter-chip buses are a class of bus +used to transmit data between components of a hardware system. Examples +are:

    +
  • I2C,

  • +
  • SPI

  • +
  • SMBus

  • +
  • Microwire

  • +
  • SCCB

  • +
  • CCI.

  • +

These buses are commonly used to transmit commands, control-signals +and non time-critical data though other, time-critical, uses are possible. +The IIC API is used by developers creating client applications, typically +device drivers.

+
Concepts

IIC

IIC provides an abstraction of serial +inter-IC buses. These buses allow for the exchange of commands and +simple non time-critical data between devices (nodes) in a bus configuration. +IIC is not designed for high-bandwidth data transfer. IIC is not a +bus, but a set of functions and concepts so that device drivers can +be written that are independent of the chip-specific implementation +of each bus type. The Platform Independent Layer (PIL) specifies and +implements the functions that are available to device drivers and +the SHAI implementation layer implements any parts of the IIC functions +that are hardware dependent.

Bus

A bus, in this +case a serial bus, is effectively one or more wires along which data +or clock signals can be sent. More than one device/node can be attached +to a bus. This means that the data on the bus must identify which +node should receive that data. One node will be designated as the +master node which is responsible for initiating and terminating the +data transfer on the bus. See below for more on nodes, master and +slave nodes, configuring the bus etc.

Clients

Clients +are applications/device drivers that use IIC to send commands and +basic data over a serial bus. Clients are typically device drivers +for devices such as digitizers, a built-in camera or the real time +clock.

Nodes

Each device on the serial bus is a +node. A particular node can send or receive commands and data, or +can both send and receive commands and data. On each bus, one of the +nodes is going to be the phone/handset device which is the one our +device driver will be using to send commands onto the bus and to receive +commands from the bus.

Master - a serial bus node that +is always responsible for initiating and terminating the exchange +of commands/data and for synchronizing the data transfer (clocking). +A master node acts on behalf of clients of this bus. For example, +if a client wants to send commands down a serial bus to a device, +the device driver will request that the master initiate the command +transfer. One node on each bus must perform the role of Master.

Slave - each slave node sends or receives commands under +the control of the master node. A number of slave nodes can be present +on a single bus. Only one slave node can be addressed by a master +at one time. A slave must be addressed by a master before it is allowed +to transmit on the bus. A slave is usually associated with one or +more functions. Slave nodes sometimes drive the bus but only in response +to instructions from the master.

The role of master may be +exchanged between nodes. For example, in I2C, one or more nodes can +perform the role of a master, but only one can be the active master +at any one time. In IIC. this is supported by a ‘MasterSlave’ type, which can alternate the two roles.

+ An example of a serial bus (I2C) SCL=Serial CLock, +SDA=Serial DAta + +Transactions and transfers

A Transfer is defined +as single exchange involving data flowing in one direction From the +master to a slave, or slave to master.

A Transaction comprises +a list of transfers, in both directions.

A basic transaction +is half duplex (transfers in both directions, but only one at a time).

Full duplex (simultaneous transfers in both directions) are enabled +for buses that support them, such as SPI.

A transaction is a +synchronous operation and takes control of the bus until the list +of transfers in that transaction is complete. However the client can +start the transaction with a synchronous call (waits for it to complete) +or with an asynchronous call (client thread continues while the transaction +is processed. At the end of the transaction a callback function is +called to inform the client that the transaction is complete.)

+
Transaction +detail

A master node initiates a transaction by addressing +a slave node, this establishes the two ends of the transaction. The +transaction continues with data being exchanged in either direction. +The transaction is explicitly terminated by the Master.

Transactions +may be executed either synchronously, or asynchronously.

Asynchronous +execution requires the client to provide a callback. The client must +wait for the callback to be executed before accessing the transaction’s +objects (buffers, transfers and the transaction itself).

For +synchronous execution, the client thread is blocked until the transaction +processing is complete. This means that the client may access the +transaction’s objects as soon as the client thread resumes.

Transaction Preamble

The transaction preamble is an +optional client-supplied function that is called just before a transaction +takes place.

For example, the transaction preamble may perform +a hardware operation required on the slave device in order for it +to handle the transaction. This could be selecting a function on a +multi-function device, or selecting a set of internal registers.

The client-supplied transaction preamble function shall not:

    +
  • Spin.

  • +
  • Block or wait on a fast mutex.

  • +
  • Use any kernel or base port service that does any of the above. +For example, alloc/free memory, signal a DMutex, complete a request, +access user side memory.

  • +
+
Extended/multiple +transactions

An extended/multiple transaction (“multitransaction”) +is formed from a chain of transactions, and appears to the client +to be a single high-level transaction. An extended transaction should +be used when the amount of data that is to be transferred (how many +transfers) is not known in advance.

The next transfer in the +chain is selected by the Extended Transaction callback. The transaction +may be dynamically composed so that additional transfers are added +to the transaction while transfers closer to the start of the transaction +are being processed.

For example, an extended transaction could +consist of a write transaction followed by a number of read transactions. +The reason for making this a single extended transaction is that it +prevents other clients performing a read transaction after the initial +write transaction and so stealing the data that the client is expecting. +Another example is where the multiple transaction consists of a read +operation followed by several write operations. If another client +can write data after the read, then the slave buffer may not have +room for the subsequent write operations.

+
Channels

An applications’ ASIC may support a number of bus modules of different +interface standards. Each bus module for a given interface standard +may support more than one physical connection. For example, a particular +ASIC might have two I2C physical connections and one SPI physical +connection. So to set the master node on one of the I2C connections, +it must be possible to identify which physical bus to use, which is +done by allocating a 'channel number' to a particular node on each +connection. That node is the one that IIC controller or device driver +talks to.

The SHAI implementation layer for each bus standard +(I2C, SPI etc.) assigns unique channel number identifiers.

+Channels + +IIC Controller

The IIC controller keeps track +of the channels. When a client wants to send a command to a particular +piece of hardware/function (a node), it asks the controller and passes +the channel ID. The controller checks that the operation is allowed +and forwards the request to the channel. Or rejects the command if +it is not allowed. For example, if a slave operation is requested +on a master channel.

For application processors that possess +IIC channels which may be used in a shared manner, the controller +provides functionality to negotiate access between simultaneous requests +from a number of clients device drivers.

+Using a controller + +
+
Controller-less +(Standalone channel) operation

If a channel is intended +to be dedicated to a single client, the controller is not necessary. +In this case, the client device driver can access the channel interface +directly. The channel is created and maintained by the client, independently +of the IIC controller.

+Controller-less operation + +
+
Transfers +and transactions - detail

Transfers

A transfer +is implemented as a buffer containing the data to be transmitted and +information used to carry out the transmission, including

    +
  • the direction +of transmission (read or write from the point of view of the master +node),

  • +
  • the granularity +of the buffer (the width of the words in bits), and

  • +
  • a pointer to +the next buffer, used when transfers are combined into transactions +as a linked list.

  • +

The buffer is implemented with an 8 bit boundary but the +data being exchanged may be differently structured. The potential +conflict is tackled by the configuration mechanism.

Transactions

A transaction is a sequence of transfers implemented as +a linked list. This is why transfers have pointers to transfers. Transactions +are of two types.

    +
  • Unidirectional +transactions are a sequence of transfers, either all of them read +or all of them write.

  • +
  • Combined transactions +are a sequence of transfers, some of them read and the others write.

  • +

Some buses support duplex transmission, which is simultaneous +transfers of data in each direction. The transfers within a transaction +take place sequentially, never simultaneously, so that a combined +transaction is only ever in half duplex mode. However, it is possible +to use the full duplex capabilities of a bus by performing two transactions +at the same time. The simplest case of this is two unidirectional +transactions in opposite directions. It is also possible to interleave +two combined transactions, matching the read and write transfers of +each transaction to create a full duplex combined transaction. The +IIC platform service API supports this functionality but implementation +is a matter for client writers.

+
Triggers +and callbacks

A callback is a function to be executed after +a transaction in response to a condition called a trigger. A callback +is supplied with the result of the information transmitted. Callbacks +are of two kinds, master and slave.

When the client is master, +a master callback runs on completion of an asynchronous transaction +request (synchronous master transaction requests do not have callbacks). +Its purpose is to notify the client of completion since the client +will have been performing other tasks during the transaction.

A second kind of master callback is a function called just before +a master transaction. The Symbian platform name for a callback of +this kind is 'preamble'.

Multitransactions may also be associated +with master callbacks and preambles.

Slave callbacks are issued +during a transaction. Since slave channels are mainly reactive, they +need to be told what to do on receipt of each individual transfer, +and this is the purpose of a slave callback. A slave callback object +contains more information than a master callback because a slave channel +requires more information in order to proceed with a transfer. The +information packaged with a slave callback includes:

    +
  • the Id of the +channel and a pointer to the channel object (which contains the actual +function to be called),

  • +
  • a pointer to +the parameters to be passed to the callback function,

  • +
  • the trigger,

  • +
  • the number of +words to be transmitted, and

  • +
  • the number of +words to be received.

  • +
+
Use +of the bus API

Client applications use the platform service +API to communicate with an IIC bus. The bus API consists of a class +representing a bus and contains two sets of functions, the master +side API used when the client is talking to a master channel, and +the slave side API used when the client is talking to a slave channel. +A MasterSlave channel provides both sets of functions but returns +an error if a master function is used while the channel is in slave +mode, and similarly returns an error if a slave function is used when +the channel is in master mode.

A client application of a master +channel may use the functions of a number of devices on the same bus. +A client may also talk to multiple buses over multiple channels. A +master channel can also be shared between multiple clients.

The master side API provides functionality to:

    +
  • queue transactions +synchronously,

  • +
  • queue transactions +asynchronously, and

  • +
  • cancel asynchronous +transactions.

  • +

Slave nodes operate at the level of the transfer, not the +transaction, and must be told what channel and buffer to use. They +act in response to slave callbacks.

The slave side API provides +functionality to:

    +
  • capture a channel,

  • +
  • release a channel,

  • +
  • register a receive +buffer,

  • +
  • register a transmit +buffer, and

  • +
  • specify a trigger +which starts the next transfer.

  • +

A channel may also be a MasterSlave channel. A MasterSlave +channel enters either master mode or slave mode when certain entry +conditions are fulfilled and continues in that mode until certain +exit conditions are fulfilled. A MasterSlave channel can never operate +in both modes simultaneously.

A MasterSlave channel enters +master mode as soon as a transaction is queued. It continues in master +mode until all transactions are completed and then exits master mode. +While in master mode it accepts no slave API calls.

A MasterSlave +channel enters slave mode when a client captures the channel. It continues +in slave mode until the channel is released and then exits slave mode. +While in slave mode it accepts no master API calls.

The master +and slave side APIs both also supply a static extension used by developers +to provide additional functionality.

+
Configuration +of bus, transaction and device

The proprietary variants +of IIC technology and the different devices which they support require +configuration at the level of the bus and the node. Bus configuration +is static and node configuration dynamic.

The static configuration +of the bus is specified at design time and executed at build time. +It involves designating nodes as master or slave and assigning addresses +to nodes. The IIC performance service API encapsulates the bus configuration +as a single structured integer called the bus ID whose +value is set using bit masks representing individual configuration +parameters.

The dynamic configuration of the nodes is performed +by the clients. Each client configures its channel at the start of +a transaction, setting parameters relating to the physical node and +to the transaction: speed, endianness, word length and so on.

+
Timers

There are two timers that must be implemented in the SHAI implementation +layer:

    +
  • Client Timeout

  • +
  • Master Timeout

  • +

Client timeout - specifies how long to wait for +the client to respond to bus events, such as data received, before +telling the SHAI implementation layer to cancel the transaction.

Master timeout - specifies how long to wait for the master +to perform the next transfer in the transaction. If this timer runs +out, then terminate the transaction by calling the PIL NotifyClient() which will inform both the client and the SHAI implementation layer +that the transaction is aborted.

+
+Client +of Master Channel Tutorial +Client +of Slave Channel Tutorial +SPI +Technology Guide +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-B30D6027-EB0F-578F-9B2F-AFC2DFD27E39-master.png Binary file Adaptation/GUID-B30D6027-EB0F-578F-9B2F-AFC2DFD27E39-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-B30D6027-EB0F-578F-9B2F-AFC2DFD27E39_d0e19057_href.png Binary file Adaptation/GUID-B30D6027-EB0F-578F-9B2F-AFC2DFD27E39_d0e19057_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-B345CDED-92DC-50ED-BC87-AC3C903E5E10.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-B345CDED-92DC-50ED-BC87-AC3C903E5E10.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,53 @@ + + + + + +Serial +Port Driver OverviewSerial ports are used for debugging. +
Purpose

The serial port driver allows Symbian platform +to communicate with the outside world via a serial port.

Serial ports +are used for debugging by various tools: for example the EKA2 Run-Mode Debugger +as well as being used on actual phones in implementing the IR port.

+
Key concepts and terms
+ +
Serial communications
+

Means of sending data whereby transmission proceeds one bit after another +over a single medium for example a wire.

+
+
+
Architecture

Serial communications on Symbian platform +is via a client/server framework. The client communicates with the serial +communications server which, in turn, communicates to the appropriate plug +in. These plug ins are known as CSY modules.

+
APIs + + + +API +Description + + + + +

CPort

+

Defines the port that is to be used.

+
+ +

CSerial

+

Serial protocol factory interface.

+
+ +

TSerialInfo

+

Serial protocol information.

+
+ + +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-B35A70D2-1BC8-51DE-95BF-F315DB394582.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-B35A70D2-1BC8-51DE-95BF-F315DB394582.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,99 @@ + + + + + +Demand +Paging OverviewDemand paging is a technique where content appears to be present +in RAM, but may in fact be stored on some external media and is transparently +loaded when needed. +
Purpose

Demand +paging trades off increased available RAM against increased data latency, +increased media wear and increased power usage. Overall performance may be +increased as there can be more RAM available to each application as it runs.

Demand +paging is used to reduce the amount of RAM that needs to be shipped with a +device and so reduces the device cost.

+
Description

Demand +paging relies on the fact that most memory access is likely to occur in a +small region of memory and not spread over the entire memory map. This means +that if only that small area of memory is available to a process (or thread) +at any one time, then the amount of RAM required can be reduced. The small +area of memory is known as a page. The working RAM is broken down into pages, +some of which are used directly by the processor and the rest are spare. Since +Symbian platform is a multi-tasking operating system, there is more than one +page in the working RAM at any one time. There is one page per thread.

There +are three types of demand paging: ROM paging, code paging and writable data +paging. All of these types of demand paging have some features in common:

    +
  • A free RAM pool

  • +
  • Working RAM

  • +
  • Paging Fault Handler

  • +
  • A source of code and/or +data that the processor needs to access.

  • +

With demand paging, the processor requires content to be present +in the working RAM. If the content is not present, then a 'paging fault' occurs +and the required information is loaded into a page of the working RAM. This +is known as "paged-in". When the contents of this page are no longer required, +then the page returns to the pool of free RAM. This is known as "paging-out".

The +difference between the types of demand paging is the source that is to be +used:

    +
  • For ROM paging, it is +code and/or data stored under the ROM +file system

  • +
  • For code paging, it +is code and/or data stored using ROFS +file system

  • +
  • For writable data paging, +it is the writable data stored in RAM, for example user stacks and heaps. +In this case, the data is moved to a backing store.

  • +
+ +

The diagram above shows the basic operations involved in demand +paging:

    +
  1. The processor wants +to access content which is not available in the working RAM, causing a 'paging +fault'.

  2. +
  3. The paging fault handler +starts the process for copying a page of the source into a page of RAM.

  4. +
  5. A page is selected.

  6. +
  7. The contents of the +source is loaded into the page and this becomes part of the working memory.

  8. +
  9. When the contents of +the page are no longer required, the page is returned to the free RAM pool.

  10. +
+
Demand Paging features

Demand Paging provides the +following features:

    +
  • Reduced amount of RAM +required

  • +
  • Improved performance +in applications that involve loading a large amount of code into RAM, since +the number of memory access operations required has been reduced

  • +
  • Improved stability in +Out Of Memory (OOM) conditions.

  • +
+
Demand Paging limitations

The following are known +limitations of Demand Paging:

    +
  • The access time cannot +be guaranteed.

    There is an orders of magnitude difference in the access +time between an access where no page fault occurs and one where a page fault +occurs. If a page fault does not occur, then the time taken for a memory access +is in the tens to hundreds of nanosecond range. If a page fault does occur, +then the time taken for a memory access could be in the millisecond range

  • +
  • Device drivers have +to be written to allow for data latency when a page fault occurs.

  • +
+
+Demand Paging +Guides +ROM paging + +Code Paging + +Writable +Data Paging +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-B3F6FC45-3BF0-5F92-8325-44C705BA47AE.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-B3F6FC45-3BF0-5F92-8325-44C705BA47AE.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,597 @@ + + + + + +Boot +Table FunctionsDescribes how to implement the functions that the bootstrap implementation +must provide. +

The boot table function +entries are summarised in the following table. Each is identified by its TBootTableEntry enumerator +that defines its position in the table. Click the enumerator symbol for more +detail on what the function must do.

+ + + + +

Enumerator symbol

+

Summary description

+
+ +

BTF_WriteC

+

Outputs a character to the debug port.

+
+ +

BTF_RamBanks

+

Gets a list of possible RAM banks.

+
+ +

BTF_SetupRamBank

+

Does any required setup for each RAM bank.

+
+ +

BTF_RomBanks

+

Gets a list of possible ROM banks.

+
+ +

BTF_SetupRomBank

+

Does any required setup for each ROM bank.

+
+ +

BTF_HwBanks

+

Gets a list of required I/O mappings.

+
+ +

BTF_Reserve

+

Reserves physical RAM if required.

+
+ +

BTF_Params

+

Gets a list of configuration parameters.

+
+ +

BTF_Final

+

Does any final setup required before booting the kernel.

+
+ +

BTF_Alloc

+

Allocates RAM during boot.

+
+ +

BTF_GetPdePerm

+

Gets MMU PDE permissions for a mapping.

+
+ +

BTF_GetPtePerm

+

Gets MMU PTE permissions for a mapping.

+
+ +

BTF_PTUpdate

+

Called when a page table entry is updated.

+
+ +

BTF_EnableMMU

+

Enables the MMU.

+
+ + +
+
BTF_WriteC

What the function should do

On non-debug bootstrap builds, +where CFG_DebugBootRom is set to FALSE, the function should +return immediately without doing anything.

On debug bootstrap builds, +where CFG_DebugBootRom is set to TRUE, the function should +output a single character to the debug port.

It may be necessary to +examine the TRomHeader::iDebugPort field to determine the +correct destination for the character. The function should not modify any +registers, but may change flags.

This function can be called with +the MMU either disabled or enabled. Different I/O port addresses will normally +be required in these two cases. To simplify handling of this the following +macro is provided:

GET_ADDRESS Rd, PHYSICAL, LINEAR

Where Rd specifies any ARM general purpose register. PHYSICAL is +the physical address of the peripheral, LINEAR is its linear +address.

On the direct memory model, the PHYSICAL address +is always loaded into Rd. On the moving or multiple memory +models the macro performs a runtime check of the CP15 control +register to determine whether the MMU is enabled. If the MMU is enabled, then +the LINEAR address is loaded into Rd, otherwise +the PHYSICAL address is loaded.

Note that CFG_DebugBootRom is +set in the platform +specific configuration header file.

Entry conditions

    +
  • R0 bottom +8 bits contain the character to be output

  • +
  • R10 points +to the super page, represented by the SSuperPageBase struct +defined in os/kernelhwsrv/kernel/eka/include/kernel/kernboot.h

  • +
  • R12 points +to the ROM header, a TRomHeader object

  • +
  • R13 points +to a valid stack.

  • +
+
BTF_RamBanks

What the function should do

This function should return a +pointer to a list of RAM banks that are present.

The list should be +a sequence of two-word entries. Each entry has the following format:

+ +

The list is terminated by an entry that has a zero MAXSIZE.

Of +the 32 flag bits, only one is currently defined; all undefined flags should +be zero. Flag 0, which is bit 0 of the first word is the RAM_VERBATIM flag +and is interpreted as follows:

    +
  • If clear, the specified +physical address range may or may not contain RAM, and may be only partially +occupied. In this case generic bootstrap code will probe the range to establish +if any RAM is present, and if so, which parts of the range are occupied. This +process is accompanied by calls to BTF_SetupRamBank. In order for the probing algorithm to work MAXSIZE must be a power of 2 +(greater than or equal to 64K), and BASE must be a multiple of MAXSIZE.

  • +
  • If set, the specified +physical range is known to be fully occupied by RAM, and furthermore, that +all memory controller setup for that range has already been completed. In +this case BTF_SetupRamBank will +not be called for this range.

  • +

Note that all banks declared in this list and subsequently found +to be occupied will be treated as standard RAM available for any purpose. +For this reason, internal RAM or TCRAM banks are not generally included in +the list.

Entry +conditions

    +
  • R10 points +to the superpage, represented by the SSuperPageBase struct +defined in os/kernelhwsrv/kernel/eka/include/kernel/kernboot.h

  • +
  • R12 points +to the ROM header, a TRomHeader object

  • +
  • R13 points +to a valid stack

  • +
  • the MMU is disabled.

  • +

Exit +conditions

    +
  • R0 should +contain the base address of the list of banks

  • +
  • R0 -R3 and +flags may be modified, but no other registers should be modified.

  • +
+
BTF_SetupRamBank

What the function should do

The function should do any required +setup for each RAM bank.

This function is called twice for +each RAM bank that does not have the RAM_VERBATIM flag +set (see the reference to the flag bits in the description of BTF_RamBanks).

The first call is prior to RAM bus width detection, +and the second call is after width detection.

This function is only +required if the system has a complex and very variable RAM setup, for example +several banks of potentially different widths. Typical systems have one or +two banks of RAM of known width and all memory controller initialisation can +be done in theInitialiseHardware() function; +in this case this function can simply return without performing any operation.

Entry conditions

    +
  • R1 holds +the physical base address of a bank

  • +
  • R3 = 0xFFFFFFFF for +the first call

    R3 = 0x0000000Y for the second call, +where the bottom 4 bits represent the validity of each of the 4 byte lanes +(bit 0=1 if D0-7 are valid, bit 1=1 if D8-15 are valid, etc.)

  • +
  • R10 points +to the super page, represented by the SSuperPageBase struct +defined in os/kernelhwsrv/kernel/eka/include/kernel/kernboot.h

  • +
  • R12 points +to the ROM header, a TRomHeader object

  • +
  • R13 points +to a valid stack

  • +
  • the MMU is disabled.

  • +

Exit +conditions

Other than flags, no registers should be modified.

+
BTF_RomBanks

What the function should do

This function should return a +pointer to a list of XIP ROM banks that are present. It is not called if the +bootstrap is found to be running in RAM; in this case it is assumed that all +XIP code is in RAM.

The list should be a sequence of four-word entries. +Each entry has the following format:

+ +

The list is terminated by a zero value four-word entry.

Only +the first, second and fourth words of each entry are actually used by the +rest of the bootstrap. The third is there mainly to support autodetection +schemes.

The ROM_BANK macro +can be used to declare ROM bank entries.

Entry conditions

    +
  • R10 points +to the super page, represented by the SSuperPageBase struct +defined in os/kernelhwsrv/kernel/eka/include/kernel/kernboot.h

  • +
  • R12 points +to the ROM header, a TRomHeader object

  • +
  • R13 points +to a valid stack

  • +
  • the MMU is disabled.

  • +

Exit +conditions

    +
  • R0 should +contain the base address of the list of ROM banks.

  • +
  • R0 -R3 and +flags may be modified, but no other registers should be modified.

  • +
+
BTF_SetupRomBank

What the function should do

The function should do any required +setup for each ROM bank.

It is called once immediately after the call +to BTF_RomBanks and +then it is subsequently called again for each ROM bank in the list +returned by BTF_RomBanks. It is not called if the bootstrap +is running in RAM.

This function is intended to support autodetection +of the system ROM configuration. For example, the first call with R11 set +to zero could be used to set the bus controller to 32 bit width to enable +width detection to be performed on ROM banks other than the boot block. Subsequent +per-bank calls could determine the width (possibly using an algorithm that +repeatedly reads from the same address and checks which bits are consistent) +and the size of the ROM bank. These would be written to the entry pointed +by R11 and the bus controller set up correctly for that ROM +bank. If the bank is absent, then the size in the structure pointed to by R11 is +set to zero to remove it from the list.

Entry conditions

    +
  • R10 points +to the super page, represented by the SSuperPageBase struct +defined in os/kernelhwsrv/kernel/eka/include/kernel/kernboot.h

  • +
  • On the first call:

      +
    • R11 contains +0

    • +
    • R0 contains +the base address of the list of ROM banks returned by BTF_RomBanks

    • +

    On subsequent calls:

      +
    • R11 points +to a RAM copy of the entry corresponding to the ROM bank currently being processed

    • +
  • +
  • R12 points +to the ROM header, a TRomHeader object

  • +
  • R13 points +to a valid stack

  • +
  • the MMU is disabled.

  • +

Exit +conditions

For calls where R11 is non-zero, the +entry pointed to by R11 may be modified by this function +call.

If the entry size for a bank is set to zero, then that bank +is assumed not to exist, and is removed from the list of ROM banks.

Registers R0 -R4 and +flags may be modified by this function; all other registers should be preserved.

+
BTF_HwBanks

What the function should do

This function should return a +pointer to a list of required I/O mappings.

The list should be a sequence +of one-word and two-word entries, terminated by a zero-filled word. The entries +in the list are defined using the macros +for declaring I/O mappings: HW_MAPPING, HW_MAPPING_EXT, HW_MAPPING_EXT2, +and HW_MAPPING_EXT3.

In the template port, this is +implemented in os/kernelhwsrv/bsptemplate/asspandvariant/template_variant/bootstrap/template.s. +Find the symbol GetHwBanks:

GetHwBanks ROUT + ADR r0, %FT1 + MOV pc, lr + ... + DCD 0 ; terminator +

The pointer in the boot table to this list of I/O mappings +is defined by the symbol GetHwBanks.

BootTable + ... + DCD GetHwBanks ; get list of HW banks + ...

To support Level 2 cache (either L210 or L220), you +need to add the base address of the Level 2 cache controller to the list of +hardware banks. For example:

GetHwBanks ROUT + ADR r0, %FT1 + MOV pc, lr + ... + HW_MAPPING L210CtrlBasePhys, 1, HW_MULT_1M + ... + DCD 0 ; terminator +

See also theInitialiseHardware() function.

Entry +conditions

    +
  • R10 points +to the super page, represented by the SSuperPageBase struct +defined in os/kernelhwsrv/kernel/eka/include/kernel/kernboot.h

  • +
  • R12 points +to the ROM header, a TRomHeader object

  • +
  • R13 points +to a valid stack

  • +
  • the MMU is disabled.

  • +

Exit +conditions

    +
  • R0 should +contain the base address of the list of banks

  • +
  • R0 -R3 and +flags may be modified, but no other registers should be modified.

  • +
+
BTF_Reserve

What the function should do

The function reserves physical +RAM if required.

It is called before the bootstrap's memory allocator +(BTF_Alloc) +is initialised to allow physical RAM to be reserved for any platform specific +purpose.

There are two methods available for reserving physical RAM:

    +
  1. Use the generic bootstrap +function ExciseRamArea(), implemented in os/kernelhwsrv/kernel/eka/kernel/arm/bootutils.s. +This removes a specified region from the list of RAM blocks present in the +system. Subsequently, the excised area will no longer be treated as RAM. If +this method is used, then the excised areas must be a multiple of 64K in size +and aligned to a 64K boundary.

    The following entry conditions apply +when calling ExciseRamArea():

      +
    • R0 = +physical base address of the area to be excised

    • +
    • R1 = +size of area to be excised

    • +
    • R9 = SSuperPageBase::iRamBootData

    • +
    • R10 points +to the super page

    • +
    • R11 = +0

    • +
    • R13 points +to a valid stack.

    • +
  2. +
  3. Write a list of reserved +RAM blocks to the address passed in R11. The list should consist of two-word +entries, the first word being the physical base address of the block and the +second word the size. The list is terminated by an entry with zero size. The +listed blocks will still be recognised as RAM by the kernel but will be marked +as allocated during kernel boot. The blocks in the list should be multiples +of 4K in size and aligned to a 4K boundary.

  4. +

If both methods are used simultaneously, then the ExciseRamArea() function +will require recalculation of the value in R11 for the second method. The +correct value can be found by loading R11 first with SSuperPageBase::iRamBootData, +stepping forward 8 bytes at a time until an entry with a zero-filled second +word is found, and then stepping on by a further 8 bytes.

Entry conditions

    +
  • R10 points +to the super page, represented by the SSuperPageBase struct +defined in os/kernelhwsrv/kernel/eka/include/kernel/kernboot.h

  • +
  • r11 points +to the place where the pre-allocated block list should be written

  • +
  • R12 points +to the ROM header, a TRomHeader object

  • +
  • R13 points +to a valid stack

  • +
  • the MMU is disabled.

  • +

Exit +conditions

The function can modify R0, R1, R2,R3, R11 and the flags, but should preserve all other registers.

+
BTF_Params

What the function should do

The function should return the +value of a run-time configurable boot parameter. The parameter is identified +by one of the values of the TBootParam enumeration, which +is passed in R0.

Typically, the function is implemented +as follows:

GetParameters ROUT + ADR r1, ParameterTable + B FindParameter +ParameterTable ; Include any parameters specified in TBootParam + ; enum here if you want to override them. + DCD BPR_x, value ; parameter number, parameter value + DCD -1 ; terminator +

This implementation calls the generic function FindParameter(), +which performs the necessary lookup of the parameter number in the table. +The parameter table should consist of a list of two-word entries, the first +word being the parameter number and the second the parameter value. The list +should be terminated by a negative parameter number. The generic function +searches this table for the parameter value, and if found, returns it in R0 as +stated in Exit +conditions.

Note that the address of this parameter table is +also passed to the InitCpu() function by the InitialiseHardware() public function.

Each entry in the boot +parameter table is identified by a TBootParam enumeration +value that defines its position within that table. The entries have the following +meaning:

+ + + +

Enumerator symbol

+

Summary description

+
+ +

BPR_InitialMMUCRClear

+

Mask of bits to clear in MMUCR in the InitCpu() generic +function. Defaults to 0xFFFFFFFF, i.e. clear all bits.

+
+ +

BPR_InitialMMUCRSet

+

Mask of bits to set in MMUCR in the InitCpu() generic +function after clearing those specified by BPR_InitialMMUCRClear. +Defaults to a CPU-dependent value.

+
+ +

BPR_FinalMMUCRClear

+

Mask of bits to clear in MMUCR when the MMU is enabled. Defaults +to 0, which means do not clear any bits.

+
+ +

BPR_FinalMMUCRSet

+

Mask of bits to set in MMUCR when the MMU is enabled after clearing +those specified in BPR_FinalMMUCRSet. Defaults to a CPU-dependent +value.

+
+ +

BPR_AuxCRClear

+

Mask of bits to clear in AUXCR in the InitCpu() Symbian +platform generic function. Defaults to a CPU dependent value.

+
+ +

BPR_AuxCRSet

+

Mask of bits to set in AUXCR in the InitCpu() Symbian +platform generic function after clearing those specified by BPR_InitialAUXCRClear. +Defaults to a CPU-dependent value.

+
+ +

BPR_CAR

+

Initial value to set for coprocessor access register if present. +Defaults to 0.

+
+ +

BPR_UncachedLin

+

Mandatory parameter on the direct memory model, not used on other +memory models. The value is copied into SSuperPageBase::iUncachedAddress for +use by any code which needs to do an uncached memory access, usually for memory +controller synchronisation purposes. On systems with an MMU, this address +will be mapped as an alias of the super page and must refer to the base address +of a 1Mb region of unused virtual address space, aligned on a 1Mb boundary. +On a system with no MMU, this address should be the physical address of some +uncached memory.

+
+ +

BPR_PageTableSpace

+

Used only on the direct memory model on systems with an MMU. Specifies +the amount of RAM to reserve for page tables. Defaults to 32K.

+
+ +

BPR_KernDataOffset

+

Used only on the direct memory model. Specifies the offset from +the base of the super page to the base of the kernel .data section. Defaults +to 8K.

+
+ +

BPR_BootLdrImgAddr

+

Mandatory parameter for bootloader configurations; not required +for other configurations. Specifies the physical base address of the RAM-loaded +image.

+
+ +

BPR_BootLdrExtraRAM

+

Only used on bootloader configurations. Specifies the amount of +'user' memory to reserve (this is in fact used to satisfy Epoc::AllocPhysicalRam requests, +usually for video RAM) in the case where the RAM-loaded image is at the bottom +of RAM and so the bootloader RAM is at the top. Defaults to 1MB.

+
+ + +

Entry +conditions

    +
  • R0 contains the number +identifying the required parameter; see the TBootParam enumerator +defined in os/kernelhwsrv/kernel/eka/include/kernel/arm/bootdefs.h.

  • +
  • R10 points +to the super page, represented by the SSuperPageBase struct +defined in os/kernelhwsrv/kernel/eka/include/kernel/kernboot.h

  • +
  • r11 points +to the place where the pre-allocated block list should be written

  • +
  • R12 points +to the ROM header, a TRomHeader object

  • +
  • R13 points +to a valid stack

  • +
  • the MMU is disabled.

  • +

Exit conditions

If +the parameter value is specified, it should be returned in R0 and +the N flag should be cleared.

If the parameter value +is not specified, the N flag should be set.

Registers R0 , R1, R2 and +the flags may be modified. All other registers should be preserved.

+
BTF_Final

What the function should do

The function should do any final +setup required before booting the kernel. It is called at the end of the bootstrap, +just before booting the kernel.

The function should:

    +
  • Map any cache flushing +areas required by the CPU.

    Processors that flush the data cache by +reading dummy addresses or by allocating dummy addresses into the cache (e.g. +StrongARM and XScale processors) will need a main cache flush area. If the +processor has an alternate data cache (e.g. StrongARM and XScale mini data +cache) a second flush area may be required for it. On the moving and multiple +memory models the linear addresses used for these flushing areas are fixed +(KDCacheFlushArea and KDCacheFlushArea +1MB +respectively). On the direct memory model any unused linear address may be +selected. The linear addresses used should be written into SSuperPageBase::iDCacheFlushArea and SSuperPageBase::iAltDCacheFlushArea. In addition, the fields SSuperPageBase::iDCacheFlushWrap and SSuperPageBase::iAltDCacheFlushWrap should +be written with a power of 2 at least twice the cache size and no bigger than +half the reserved address area. A value of 0x00080000 (512KB) is usually used.

  • +
  • Populate any super page +or CPU page fields with platform-specific information used by the variant, +for example addresses of CPU idle routines in the bootstrap. Routines can +be placed in the bootstrap if known alignment is required for the routine.

  • +

Entry +conditions

    +
  • R10 points +to the super page, represented by the SSuperPageBase struct +defined in os/kernelhwsrv/kernel/eka/include/kernel/kernboot.h

  • +
  • r11 points +to the kernel image header, a TRomImageHeader object

  • +
  • R12 points +to the ROM header, a TRomHeader object

  • +
  • R13 points +to a valid stack

  • +
  • the MMU is disabled.

  • +

Exit +conditions

Registers R0 to R9 and +flags may be modified; other registers should be preserved.

+
BTF_Alloc

What the function should do

Allocates RAM during boot.

This +function is called at various points to initialise the memory allocator, or +to allocate physical RAM. A generic implementation is provided for this function +and this will normally be sufficient, so a typical implementation for this +function reduces to:

DCD HandleAllocRequest

in +the boot table. For systems with no MMU, the function name should be changed +to AllocatorStub.

It is advisable not to override +this function.

Entry +conditions

    +
  • R2 contains the type +of allocation required; this is defined by one of the values of the TBootMemAlloc enumeration

  • +
  • R4 contains the size +to allocate (as a log to base 2) for allocations of type BMA_Kernel

  • +
  • R10 points +to the super page, represented by the SSuperPageBase struct +defined in os\kernelhwsrv\kernel\eka\include\kernel\kernboot.h

  • +
  • R12 points +to the ROM header, a TRomHeader object

  • +
  • R13 points +to a valid stack

  • +
  • the MMU may be enabled +or disabled.

  • +

The type of allocation required is defined by the value of the enumerator TBootMemAlloc, +defined in os/kernelhwsrv/kernel/eka/include/kernel/arm/bootdefs.h. +The allocation types are as follows:

+ + + +

Enumerator symbol

+

Summary description

+
+ +

BMA_Init

+

Called to initialise the memory allocator.

+
+ +

BMA_SuperCPU

+

Should return the physical address of the super page in R0.

+
+ +

BMA_PageDirectory

+

Should return the physical address of the page directory in R0.

+
+ +

BMA_PageTable

+

Allocate a new page table (1KB size and 1KB alignment) and return +its physical address in R0. It is not necessary to clear the page table here.

+
+ +

BMA_Kernel

+

Allocate a page of size 2R4. This must be a valid processor page +size; on ARM this means R4=12, 16 or 20. The returned physical address will +be a multiple of 2R4. If no page of the requested size can be allocated a +page of the largest possible smaller size will be allocated and R4 will be +modified accordingly.If no page of any size can be allocated this call +will fault the system.

+
+ +

BMA_Reloc

+

Called when the allocator data structures need to be relocated in +memory. On entry R0 contains the offset to apply to all pointers (that is, +the new address of data minus the old address). It is assumed that all the +allocator data is contained in the super page or CPU page and that there are +no pointers to areas which could be relocated independently.

+
+ + +

Exit +conditions

R0 and flags may be modified. For BMA_Kernel allocations, R4 may +also be modified. All other registers should be preserved.

+
BTF_GetPdePerm

What the function should do

This function is called at various +points to translate a standardised permission descriptor along with the size +of mapping required to the PDE permission/attribute bits needed for such a +mapping. A standardised permission descriptor can be either an index into +the boot table (for any of the standard permission types) or the value generated +by a BTP_ENTRY macro.

A +generic implementation is provided for this function and it should not be +necessary to override it. A typical implementation for this function then +just reduces to:

DCD GetPdeValue

in +the boot table.

Note that for systems with no MMU, this function is +not required.

+
BTF_GetPtePerm

What the function should do

This function is called at various +points to translate a standardised permission descriptor along with the size +of mapping required to the PTE permission/attribute bits needed for such a +mapping. A standardised permission descriptor can be either an index into +the boot table (for any of the standard permission types) or the value generated +by BTP_ENTRY macro.

A +generic implementation is provided for this function and it should not be +necessary to override it. In the boot table, a typical implementation for +this function then reduces to:

DCD GetPteValue

Note +that for systems with no MMU, this function is not required.

+
BTF_PTUpdate

What the function should do

This function is called whenever +a PDE or PTE is updated. It performs whatever actions are required to make +sure that the update takes effect. This usually means draining the write buffer +and flushing the TLB (both TLBs on a Harvard architecture system).

A +generic implementation is provided for this function and it should not be +necessary to override it. In the boot table, a typical implementation for +this function then reduces to:

DCD PageTableUpdate

Note +that for systems with no MMU, this function is not required.

+
BTF_EnableMMU

What the function should do

This function is called to enable +the MMU and thereby switch from operating with physical addresses to operating +with virtual addresses.

A generic implementation is provided for this +function and it should not be necessary to override it. In the boot table, +a typical implementation for this function then reduces to:

DCD EnableMmu

Note +that for systems with no MMU, this function is not required.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-B4C05C46-F2C9-57FA-AD85-EFE6479C2FF1.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-B4C05C46-F2C9-57FA-AD85-EFE6479C2FF1.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,42 @@ + + + + + +DesignWhen you start a port, you must make a decision if the driver must +provide record, playback, or both playback and record. +

If the PDD is to support audio transfer in a single direction, either record +or playback, then a conventional PDD implementation is required. The PDD opens +only a single driver channel and the PDD factory creates either a record or +playback PDD object.

+

If the PDD is to support audio transfer in both directions then it must +be implemented to open two units, one playback unit and one record unit. For +each unit the PDD factory must create the appropriate PDD object.

+

One complication in this configuration is the need to co-ordinate access +to the single audio hardware device from the two separate PDD objects. This +configuration needs coordination when accessing the hardware device from two +separate PDD objects, detecting and preventing situations where the handling +of a PDD function for the channel in one direction conflicts with the channel +setup in the other direction, specifically:

+
    +
  • preventing the setup +of conflicting audio configurations between the record and playback channels.

  • +
  • preventing the channel +in one direction from powering down the audio hardware device while it is +being used for data transfer by the other channel.

  • +
+

The solution is to move the code that controls those aspects of audio hardware +setup which are shared between the two driver channels into the PDD factory +object, as this object is shared.

+

The porting process focuses on implementing a PDD that supports both record +and playback as this is the most common situation. The template port Sound +Driver is setup for this configuration. A PDD that supports audio transfer +in a single direction only omits the implementation for the direction not +supported.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-B5657E8C-770C-4322-88B2-057AAEF62E95.ditamap --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-B5657E8C-770C-4322-88B2-057AAEF62E95.ditamap Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,1090 @@ + + + + +Adaptation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-B5657E8C-770C-4322-88B2-057AAEF62E95.ditaoriginal --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-B5657E8C-770C-4322-88B2-057AAEF62E95.ditaoriginal Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,51 @@ + + + + + + +Adaptation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-B6A21D4A-86D3-45A9-95AE-A0206D15944B.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-B6A21D4A-86D3-45A9-95AE-A0206D15944B.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,12 @@ + + + + + +Register Access Describes the Register Access platform service. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-B6F0C909-6E58-584E-9270-8066337FCE0F.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-B6F0C909-6E58-584E-9270-8066337FCE0F.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,74 @@ + + + + + +Client +TutorialExplains how to use the MMC Controller interfaces to use MMC hardware. +
Client interfaces

The +following diagram shows the relationship between the Controller and its clients, +and also shows aspects of the relationship between the constituent parts. +In this case, the client is the MultiMediaCard driver, although in general +this could be some other device driver.

+ +

The session is used to pass commands either to the entire stack, +i.e. a broadcast command, or to individual cards in the stack.

The +session provides access to the stack of cards, via a pointer to a stack object, +the iStackP private member. The session is used to pass commands +either to the entire stack, i.e. a broadcast command, or to individual cards +in the stack. An individual card can be accessed via a pointer to the card +object, the iCardP private member. The card objects, TMMCCard types, +are data members of the card array object, TMMCardArray, +which, in turn is a data member of the stack object.

+
Using the MultiMediaCard +stack

Clients of the MMC Controller such as the MMC Media Driver +uses the MMC Controller as follows:

    +
  • requests a pointer to +the stack object, through which the client can obtain pointers to the individual +card objects and interrogate the cards, finding out their media type, capacity, +and capability (via the card’s TCSD object), and whether +the card is present or ready.

  • +
  • creates a session object, +an instance of the DMMCSession class, providing a callback +function for its constructor. The callback is encapsulated as a TMMCCallBack object.

  • +
  • initiates the session +with the pointer to the stack object: DMMCSession::SetStack() .

  • +

The client interacts with the stack in the following manner:

    +
  1. it sets the session +up with the pointer to the card object, by calling DMMCSession::SetCard().

  2. +
  3. it sets the session +up to do a specific job, such as a MultiMediaCard macro command, or a lower +level card command, using the API provided by DMMCSession.

  4. +
  5. it presents the session +to the stack for execution, by calling DMMCSession::Engage().

  6. +
  7. On completion, the stack +calls the client’s callback function. The client then can repeat the cycle +from step 1 or 2.

  8. +

The client can override the default bus configuration settings, i.e. +change the bus clock, enable retries, change time-out values, restore defaults +etc., using the session's stack configuration object, TMmCStackConfig, +although in practice, there is rarely a need to do this.

+
Locking the +MultiMediaCard stack

The DMMCSession API includes +general lower level functions to issue any single command or series of commands +including those currently unknown to the controller. This allows application +specific commands to be supported. It also allows the controller to support +new commands introduced in later versions of the specification (e.g. commands +to support I/O cards).

When issuing a series of application specific +commands, the client will want to lock the stack, preventing any other client +from generating bus activity during this period. This is accomplished by calling DMMCSession::SetupCIMLockStack() and +then engaging that session. If successful, the stack will be locked until DMMCSession::UnlockStack() is +called.

As it may take time for the controller to lock the stack for +that session, the mechanism for locking the stack involves submitting a session +even though no bus activity results. If this session completes successfully +then the stack is locked. The client can then go ahead and invoke its series +of commands - configuring that same session object as necessary each time +and submitting it.

+
See also

Concepts

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-B7C56FF9-FE1B-58C3-BBD4-7479F0BEE555.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-B7C56FF9-FE1B-58C3-BBD4-7479F0BEE555.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,16 @@ + + + + + +ConceptsDescribes the technology and architecture, and behaviour of the +User-Side Hardware Abstraction component. +Port Implementation +Tutorial + \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-B7E7E6D6-7824-505C-BA0B-B7861897E78F-master.png Binary file Adaptation/GUID-B7E7E6D6-7824-505C-BA0B-B7861897E78F-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-B7E7E6D6-7824-505C-BA0B-B7861897E78F_d0e13349_href.png Binary file Adaptation/GUID-B7E7E6D6-7824-505C-BA0B-B7861897E78F_d0e13349_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-B8B36A53-CB13-41C1-9CCC-CA5AABE13BF6.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-B8B36A53-CB13-41C1-9CCC-CA5AABE13BF6.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,21 @@ + + + + + +SHAI InterfaceThe boundary between the generic implementation and the +SHAI implementation. +

The +SHAI Interface can include two types of services (also known as calls):

    +
  • SHAI abstraction services (or down calls) which are implemented +as part of the adaptation software.

  • +
  • SHAI adaptation services (or up calls) which are used within +the adaptation software.

  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-B94FFCA4-1EB3-46A7-9FF9-54C55D67FFE8.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-B94FFCA4-1EB3-46A7-9FF9-54C55D67FFE8.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,49 @@ + + + + + +Entry +PointsThis document describes the entry points for each type of device +driver. +
Driver +entry points

The Device Driver framework supports the following +device driver models:

    +
  • The LDD-PDD model: +drivers of this type must be loaded by a user application.

  • +
  • The kernel extension model: +drivers of this type are loaded by the Kernel at boot up.

  • +
  • The combined model +is a combination of the kernel extension and LDD-PDD models. This is used +when the driver must perform some initialization at the time of boot up.

  • +

For each model, the Kernel provides a standard API for the entry +points to the driver.

+
Standard LDD

For a standard LDD-PDD driver, the +driver entry points are defined by the following macros:

For LDDs, +use DECLARE_STANDARD_LDD. For example:

// LDD entry point +DECLARE_STANDARD_LDD() + { + // create LDD factory object + return new DExDriverLogicalDevice; + }
+
Standard PDD

For PDDs, use DECLARE_STANDARD_PDD. +For example:

// PDD entry point +DECLARE_STANDARD_PDD() + { + // create PDD factory object + return new DExH4PhysicalDevice; + }
+
Kernel extension

For a kernel extension, the entry +point is defined by the macro DECLARE_STANDARD_EXTENSION.

+
Combined model

For drivers with a combined model, +the entry points are defined by the following macros:

    +
  • For LDDs, use DECLARE_EXTENSION_LDD.

  • +
  • For PDDs, use DECLARE_EXTENSION_PDD.

  • +

A driver creates factory objects in the entry point routines.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-B9698943-0D4E-5B18-B7E4-448A0E21876A.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-B9698943-0D4E-5B18-B7E4-448A0E21876A.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,238 @@ + + + + + +Keyword reference (A-C) +

This page lists the keywords starting from A to C.

+
## ##

BUILDROM only

Performs textual substitution. +All subsequent instances of the two characters ## are replaced with +an empty string.

Note that there is no UNDEFINE facility and +substitutions are applied in an unspecified order.

+
ABI_DOWNGRADE ABI_DOWNGRADE from->to

BUILDROM only

Allows BUILDROM to substitute a compatible executable if a specified source file +is not available.

The use of this keyword is not appropriate +for production devices, but is useful in the development environment +as it increases the chances of producing a ROM in the presence of +build problems.

For example,

ABI_DOWNGRADE THUMB->ARMI

This substitutes \ARMI\ for \THUMB\ if a specified source file +cannot be found.

Another example is in localisation support. +Problem suppression allows BUILDROM to handle a missing source.Enn file by specifying source.EXT instead. In a final pass, if any file is still not available after +applying these downgrades, then BUILDROM will simply +comment out the line in the .oby file in the +hope that the missing file is not vital to the ROM. If this behaviour +is not appropriate, then the command line option -s can be used to enforce stricter behaviour and cause BUILDROM to terminate after the final pass if files are missing.

+
alias[[HWVD]] alias[[HWVD]] = <existing-file> <destination-file> [ directory-attribute-list ]

rombuild and rofsbuild

Creates an additional +filesystem entry, which refers to an existing file. rombuild allows directory aliases to preserve the guarantee that the ROM +filesystem should not contain cycles. The existing-file must not be +hidden, and both names are now available to resolve DLL static linkage.

+
align align = <hex-number>

rombuild only

Specifies the alignment boundary +for the file that follows immediately after the align statement.

+
area area = <name>

rombuild only

Defines the area in which the +executable will be relocated. The specified name must have been previously +defined in the area control statement.

+
area area = <name> <run-address> <maxlength>

rombuild only

Defines a new relocation area. +The area is identified by the specified name. Executable files placed +in this area will be relocated so that they run in the address range X, where X is defined as:

<run-address> <= X < <run-address> + <maxlength>.

The Bootstrap is required +to copy the relevant subset of ROM to the run address at Boot time. +The main purpose of this is to relocate time-critical executables +to internal or tightly-coupled RAM.

+
ascii ascii

rombuild only

Indicates that this is not a Unicode +build.

+
attrib attrib = [ s | S ][ h | H ][ r | R | w | W ] | hide

rombuild and rofsbuild

Files may have the System, +Hidden, read-only and writable attributes.

File attributes +are copied from the source file and are then overridden by the attributes +specified by this keyword. Specifying S, H, or R sets the corresponding attribute; +specifying s, h or r clears it.

W and w are +synonyms for R and r respectively. To mark a file +in the ROM as being writable, specify attrib=W.

As this is a ROM, the file cannot be physically modified even +if the read-only attribute is cleared, but it is useful to mark files +as writeable so that copies are made writeable, for example on a CF +card or a RAM file system.

Using the hide attribute indicates that the file should be included in the ROM +but not recorded in the ROM filesystem. If the file is a DLL it will +be available for resolving static links from other files in the same +ROM, but not available to RAM-loaded software or DLLs in an extension +ROM.

+
AUTO-BITMAP AUTO-BITMAP=<source> <dest>

BUILDROM only

Either selects a compressed MBM +file if generating an XIP ROM image, or the original source file if +generating a non-XIP ROM image

This statement translates to COMPRESSED-BITMAP for XIP ROMs and to data for non-XIP ROMs.

+
autosize autosize = <block size>

rofsbuild only

Reduces the size to a whole number +of blocks where <block size> defines the granularity.

For +example if rofsize is set to 0x30000 and the actual image size is 0x1234, +then the generated image size without the autosize option is +0x30000. If autosize is set to 0x1000, then the generated image size +is 0x2000.

+
BINARY_SELECTION_ORDER BINARY_SELECTION_ORDER=<source-build1>,<source-build2>,..

This causes the tools to check the given locations for files +in the specified order:

BINARY_SELECTION_ORDER=GCCE, ARMV5_ABIv2

causes buildrom to first check the GCCE directory +for files and then if not found there, to look in the ARMV5_ABIv2 directory.

+
BITMAP BITMAP=<source> <dest>

BUILDROM only

Generates an uncompressed Symbian platform XIP ROM format MBM file from the <source> MBM +file and copies it into the ROM at <dest>.

+
bootbinary bootbinary = <boot-file-name>

rombuild only

The file name of the ROM's bootstrap +code, which on ARM CPUs appears at physical address 0x00000000 when +the machine is booted.

+
BTrace BTrace = N1 [N2 [N3 [N4 [N5 [N6 [N7 [N8]]]]]]]

rombuild only

A keyword for configuring the +behaviour of the Symbian platform mechanism for generating and capturing +trace information (BTrace).

Each trace +has a category which is an 8-bit value. The kernel implements a filter +that enables traces in each category to be either discarded (disabled) +or passed to the trace handler (enabled). This keyword sets the initial +state of that filter, i.e. to indicate whether a trace category is +enabled or disabled.

A trace category is one of the BTrace::TCategory enum values.

The BTrace keyword +takes up to eight 32-bit integers, representing a set of 256 bits. +Each bit in the set is associated with a single category: If a bit +is set it means that the corresponding category is enabled - if a +bit is not set it means that the corresponding category is disabled.

The rule for mapping the bits in these eight integers to the BTrace::TCategory values is as follows: to turn on trace +category C, where C is one of the BTrace::TCategory enum values, set bit position C%32 to one in integer Nx where x = C/32.

+ +

For example to turn on the trace category ECodeSegs, (i.e. the trace generated when code segments are created and destroyed +mapped into out of processes, and when memory is committed and decommitted) +you would specify:

BTrace 0x00000200

which turns on bit position 9 (counting from zero and starting +at the right hand side of the integer). Note that there is no need +to specify the remaining 7 integers if they all have zero values, +as zero is assumed by default.

See also Base How To BTrace.

+
BTraceBuffer BTraceBuffer = N

rombuild only

A keyword for configuring the +behaviour of the Symbian platform trace handler.

Use this +keyword to set the initial size for any memory buffer used to store +trace data.

See also Base How To BTrace.

+
BTraceMode BTraceMode = N

rombuild only

A keyword for configuring the +behaviour of the Symbian platform trace handler.

Use this +keyword to set the initial mode of the trace handler. This BTRaceBuffer +keyword takes a single integer that specifies the mode. For the default +trace handler supplied with Symbian platform, this will be one of +the RBTrace::TMode enum values defined in the header +file d32btrace.h.

See also Base How To BTrace.

+
capabilitycapability = <capability-names>

rombuild +only

This keyword overrides platform security capabilities +of the executable specified in the OBY file. For information on the +use of capabilities and current capability set, see Platform security +architecture in the Symbian C++ Developer +Library.

+
clustersizeclustersize=<cluster-size>

This keyword +specifies the cluster size for a FAT image generated by the ROM tools. +The keyword must be specified in the DATA_IMAGE[x] section of the OBY file. If it is not specified in the DATA_IMAGE[x] section, a warning is displayed.

The value of the cluster +size must meet the following conditions:

    +
  • The cluster size must be between 512 bytes and 32KB (sector +size).

      +
    • For a FAT16 image, the cluster size must be in the range 4101– +65508 bytes.

    • +
    • For a FAT32 image, the cluster size must be greater than 65541 +bytes.

    • +
  • +
  • The cluster size must belong to the geometric progression series, +512, 1024, 2048, 4096, and so on. A geometric progression series is +a sequence of numbers where each term after the first is found by +multiplying the previous one by a fixed number called common ratio. +In this series, the first number of the series is 512 and the common +ratio is 2.

  • +

+
code-align code-align = <hex-number>

rombuild only

This keyword specifies the alignment +for the executable's code. It indicates the start address of a code +segment that must be aligned to a specified value. If the original +address of the code segment does not match the alignment, the whole +executable file is relocated to meet alignment. After the image is +loaded in RAM a block of memory is unused.

The code alignment +is an optimisation depending on the hardware the ROM is being built +for. Setting the code align can allow the ROM to be built in such +a way that it reduces the work for the CPU when loading the code that +is, it can be loaded in one pass. This improves the performance. If +it is unaligned it can take multiple passes.

For example:

    +
  • Define an .oby file:

    file=\epoc32\release\armv5\urel\helloworld.exe sys\bin\helloworld.exe code-align = 0x1000
  • +
  • Build ROM with +the above .oby file.

  • +
  • The log file +is:

    Code Align to 8161f000. Skipped 2296 bytes + + ******************************************************************** + Processing file \epoc32\release\armv5\urel\helloworld.exe + Load Address: 8161ef88 + Size: 000004a8 + Uids: 1000007a e8000047 00000000 0dcafc2f + Entry point: 8161f000 + Code start addr: 8161f000
  • +

In the log file, we can find that the code start address +of helloworld.exe matches the alignment 0x1000. To do that, a gap is generated before helloworld.exe that is,after the image is loaded in RAM +a block of memory is unused.

It is unique for ekern.exe, which is at least page aligned. If the value of code-align is less than page size, ekern.exe will be aligned +as page size. Otherwise, ekern.exe will be aligned +as the value of code-align.

Note: If an .oby file includes this keyword, the +size of ROM image is same. But the size loaded in RAM is slightly +larger than the original.

+
coffwrapper coffwrapper

rombuild only

Indicates that a COFF ROM wrapper +is required.

+
collapse collapse = <cpu> <compiler> <mode>

rombuild only

This is only supported when the +<cpu> is ARM and the <compiler> is GCC.

The <mode> +can take one of the following values:

+ + + +

1

+

collapse import thunks only

+
+ +

2

+

collapse import thunks and vtables

+
+ +

3

+

collapse branches

+
+ + +
+
compress compress

rombuild only

Compresses the resulting ROM image +using the Deflate, Huffman+LZ77 algorithm.

+
COMPRESSED-BITMAP COMPRESSED-BITMAP=<source> <dest>

BUILDROM only

Generates a compressed Symbian +platform XIP ROM format MBM file from the <source> MBM file and +copies it into the ROM at <dest>.

+
coreimage coreimage = <core image file>

rofsbuild only

This tells rofsbuild that the +generation of the core image is not required and that the specified +core image should be used to as the base for generating the extension +image.

+
codepagingoverride codepagingoverride [NOPAGING | ALWAYSPAGE | DEFAULTUNPAGED | DEFAULTPAGED]

rombuild and rofsbuild

This keyword sets the +page attributes of executables at a global level. It is applicable +to all executables in ROM or ROFS partitions. It takes a single argument, +which can be one of the following:

+ + + +Argument +Purpose + + + + +

NOPAGING

+

All executables are marked as unpaged, irrespective of whether +they are marked as paged or unpaged in the MMP file.

+
+ +

ALWAYSPAGE

+

All executables are marked as paged, irrespective of whether +they are marked as paged or unpaged in the MMP file.

+
+ +

DEFAULTUNPAGED

+

All executables that are not marked as paged or unpaged +are marked as unpaged by default.

+
+ +

DEFAULTPAGED

+

All executables that are not marked as paged or unpaged +are marked as paged by default.

+
+ + +

For example, the following entry in the Obey file marks +all the executables as unpaged:

codepagingoverride NOPAGING
+
codepagingpolicy codepagingpolicy [NOPAGING | ALWAYSPAGE | DEFAULTUNPAGED | DEFAULTPAGED]

rombuild and rofsbuild

This sets a flag in +the ROM when it is built, and the loader in the kernel decides a policy +for executables that are in default state (neither marked as paged +nor as unpaged). This keyword takes a single argument, which can be +one of the possible values listed in codepagingoverride. The default value for codepagingpolicy +is DEFAULTPAGED.

For example, the following +entry in the Obey file instructs the loader not to page the executables +in default state:

codepagingpolicy NOPAGING
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-B97BAC2E-04E3-4979-BACE-9C46BADE912E.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-B97BAC2E-04E3-4979-BACE-9C46BADE912E.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,106 @@ + + + + + +Deferred Function CallsThis document describes how Deferred Function Calls are +used to implement asynchronous requests. +
Deferred +function calls

Asynchronous request processing is normally +done in a Deferred Function Call (DFC). The second stage of interrupt +handling is deferred to run as a DFC, which runs in a non-critical +context.

Different asynchronous requests can be handled using +a single or multiple DFCs. The number of DFCs to be created must be +decided when the driver is designed. For example, a driver that handles +at the same time an asynchronous receive request and a transmit request +would create two DFCs, one each for receive and transmit.

There +are two main types of deferred function call:

    +
  • standard Deferred Function Call (DFC)

  • +
  • Immediate Deferred Function Call (IDFC).

  • +

A DFC is a kernel object that specifies a function to +be run in a thread, which is processing a DFC queue. A DFC is added +to a DFC queue that is associated with a given thread, where it is +cooperatively scheduled with other DFCs on that queue. Queued DFCs +are run in order of their priority, followed by the order they where +queued. When the DFC gets to run, the function is run kernel side, +and no other DFC in this queue will get to run until it completes. +A DFC can be queued from any context.

An IDFC is run as soon +as the scheduler is next run, which is:

+ + + +Scheduler +IDFC runs + + + + +queued from an Interrupt Service Routine (ISR) +during the IRQ postamble. + + +queued from an IDFC +when the currently-running IDFC completes. + + +queued from thread context +when the kernel is next unlocked. + + + +

Unlike a DFC, the IDFC is not run from a thread context, +and its execution time must be much smaller. For these reasons, IDFCs +are rarely used directly, but are used for implementation of the kernel +and RTOS personality layers. An important use of IDFCs is in the +implementation of queuing DFCs from an ISR context. IDFCs are run +with interrupts enabled but the kernel locked.

+
Creation

DFCs are created using TDfc objects.

The DFC is initialized with a DFC callback function, a pointer to +an object to be passed to the callback function, and a priority. It +can also provide the DFC queue to be used by this DFC at the time +of construction.

TDfc iRxDfc; +/* RxDataDfc is a function pointer to a static function, "this" is passed as a parameter */ +iRxDfc(RxDataDfc,this,1); // This implements an DFC using the standard queue and priority 1. +iRxDfc(RxDataDfc,this,iDfcQ,1); // This implements an DFC on a user-specified queue with a priority of 1. +iRxDfc(RxDataDfc,this); // This implements an IDFC.DFCs are created with a priority which is 0 to (KNumDfcPriorities—1), which is typically 0..7. Using a higher priority value is an +error. IDFCs are created by not specifying a priority.
+
Queuing

To initiate the process of DFC functionality, the DFC object +must be queued to the DFC queue associated with the Kernel thread.

Before adding the DFC to a DFC queue of the thread, it must be +associated with the queue (TDfcQue) object. This +can be either done at the time of construction, or can be set later, +by calling TDfc::SetDfcQ().

... +// Associate the Tx and Rx DFCs with the same queue set to receive +// the client messages for this driver. SetDfcQ() sets up the DFC +// queue for the DFCs constructed for Tx and Rx +// +iRxDfc.SetDfcQ(iDfcQ); +...

TDfc::Add() or TDfc::Enque() is used to add the DFC object to the DFC queue. From an ISR, TDfc::Add() is used. From a thread, TDfc::Enque() is used. If preemption is disabled, TDfc::Add() could also be used.

// TDfc::Add() will queue an IDFC or a DFC from an ISR. This function +// is the only way to queue an IDFC and is the only way to queue a +// DFC from an ISR. To queue a DFC from an IDFC or a thread either +// TDfc::Enque() or TDfc::DoEnque() should be used. This function +// does nothing if the IDFC/DFC is already queued. +// +iRxDfc.Add(); +
+
Callback +function

The DFC callback function is a static function +called when a DFC is executed. A pointer to this function is provided +at the time of DFC object creation. This function implements the deferred +functionality of an asynchronous request, such as reading or writing +data from or to an I/O peripheral. It would then either complete the +request or start another operation.

static void RxDataDfc(TAny* aPtr);
+
Cancellation

A DFC function must be cancelled while cleaning up resources, +for example, when closing the channel. The function TDfc::Cancel() cancels the DFC if it is already queued. It does nothing if a DFC +is not queued. It must be called to avoid orphaned DFCs.

... +// If it is a Transmit request, cancel the Transmit DFC. +// TDfc::Cancel() cancels the DFC if it is already queued. It +// does nothing if DFC is not queued. +// +iTxDfc.Cancel(); +...
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-B9B35999-0937-51C5-BB77-91A6C039CE2F.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-B9B35999-0937-51C5-BB77-91A6C039CE2F.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,53 @@ + + + + + +ISR Table and Interrupt IDsThe ISR Table and Interrupt IDs must be defined by the +ASSP/Variant. +
ISR +Table

Decide on the number of interrupts that exist in +the system. If the port is split into a core ASSP layer, and a device +Variant layer, the core layer should include only those interrupts +that exist on the ASSP.

In the core ASSP implementation, declare +a static ISR table, of type SInterruptHandler with +the same number of entries that you have just worked out.

In the template port, for example, this table is static member of +the TemplateInterrupt class:

const TInt KNumTemplateInts=EAsspIntIdZ+1; + +class TemplateInterrupt : public Interrupt + { + ... + public: + static SInterruptHandler Handlers[KNumTemplateInts]; + }; +

SInterruptHandler is +defined in ...\e32\include\kernel\arm\assp.h, +and TemplateInterrrupt is defined in ...\template_assp\template_assp_priv.h.

+
Interrupt +IDs

Declare an enum in an exported header file that provides +labels for each of the possible Interrupt IDs in the table.

For example, in the template +port, the interrupt IDs are defined by the TTemplateAsspInterruptId enum, defined in ...\template_assp\template_assp.h, and is part of the ASSP layer:

// Enumerate here all ASSP interrupt sources. It could be a good idea to enumerate them in a way that facilitates +// operating on the corresponding interrupt controller registers (for example, using their value as a shift count) +// +// EXAMPLE ONLY +enum TTemplateAsspInterruptId + { + // ASSP or first-level Interrupt IDs + EAsspIntIdA=0, + EAsspIntIdB=1, + EAsspIntIdC=2, + EAsspIntIdD=3, + EAsspIntIdE=4, + // ... + EAsspIntIdUsb=11, + EAsspIntIdDma=12, + // ... + EAsspIntIdZ=25 + };
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-BA0AC9AA-A8E1-5650-9512-DEC06D77668F.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-BA0AC9AA-A8E1-5650-9512-DEC06D77668F.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,15 @@ + + + + + +Writable Data +Paging Developer Tips +

Contains a collection of developer tips.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-BA3B42A2-141C-49D9-B513-1571C246C19B.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-BA3B42A2-141C-49D9-B513-1571C246C19B.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,107 @@ + + + + + +TSDIOCard +Class TutorialDescribes the TSDIOCard class. +
Description

The TSDIOCard class +provides access to the individual IO functions available on the SDIO card. +It also, provides various methods for reading the card capabilities and the +Common Card Control Registers (CCCR) on the SDIO card.

+ + + +

Header file

+

sdiocard.h

+
+ +

Source code file

+

sdiocard.cpp

+
+ +

Required libraries

+

EPBUSSDIO

+
+ +

Class declaration

+

class TSDIOCard : public TSDCard

+
+ + +
+
FunctionCount()

The +function declaration for the FunctionCount() method is:

inline TUint8 FunctionCount() const;

Description

This method returns the number of IO functions that are present on +the SDIO card.

Parameters

None

Return value

+ + + +

TUint8

+

The number of IO functions present of the SDIO card.

+
+ + +
+
IoFunction()

The +function declaration for the IoFunction() method is:

inline TSDIOFunction* IoFunction(TUint8 aFunctionNo) const;

Description

This returns a pointer to the class that carries +out the required SDIO function.

Parameters

+ + + +

TUint8 aFunctionNo

+

The ID of the SDIO function.

+
+ + +

Return value

+ + + +

TSDIOFunction*

+

The pointer to the class that performs the SDIO function.

+
+ + +
+
FindFunction()

The +function declaration for the FindFunction() method is:

IMPORT_C TSDIOFunction* FindFunction(TSDIOFunctionCaps& aCaps, TUint32 aMatchFlags, TSDIOFunction* aFunctionP = NULL) const;

Description

This method provides support for the validation +and the enumeration of the card functions.

This method finds the function +that can carry out the required capabilities and either returns a function +pointer to it (if it exists), or NULL, if it does not. See Using +the SDIO Interface in a Device Driver for example code which uses this +function.

Parameters

+ + + +

TSDIOFunctionCaps& aCaps

+

The TSDIOFunctionCaps class that contains the +desired capabilities.

+
+ +

TUint32 aMatchFlags

+

A bitmask that specifies the capabilities that are to be matched.

+
+ +

TSDIOFunction* aFunctionP

+

A pointer to the currently matched function.

+
+ + +

Return value

+ + + +

TSDIOFunction*

+

A pointer to the next matching function. This value is NULL, if +there are no more matching functions.

+
+ + +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-BA4E634D-5B03-4848-8D42-743914D0955E.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-BA4E634D-5B03-4848-8D42-743914D0955E.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,65 @@ + + + + + +SDIO Interface OverviewProvides a summary of the SDIO platform service interface. +
+ Stack implementation

The SDIO stack +is created by implementing the following functions of the DSDIOStack class.

+ + + +API +Description + + + + +DSDIOStack::IssueMMCCommandSM() +Function to handle the commands to the bus and must also extend +the support of the SDIO protocol. + + +DSDIOStack::EnableSDIOInterrupt() + Function to enable or disable SDIO interrupts. + + +DSDIOStack::MaxBlockSize() +Get the maximum block size of the data that can be transferred +on a SDIO bus. + + + +
+
PSU +implementation

The Power Supply Unit (PSU) functionality +is provided by the DSDIOPsu class.

+ + + +API +Description + + + + +DSDIOPsu::PsuInfo(TPBusPsuInfo& anInfo) +Fills the TPBusPsuInfo object with platform +specific information. + + + +

The header file for the SDIO can be found here.

+
+Power +Management Services Client Interface guide +Power +Management Services Implementation Guide +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-BB507973-77A4-4DC1-91C0-65E3CA2CF790.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-BB507973-77A4-4DC1-91C0-65E3CA2CF790.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,12 @@ + + + + + +Interrupt dispatcherProvides background information about the interrupt dispatcher. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-BBEA9F6B-2F0C-584E-BF12-256E27605499.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-BBEA9F6B-2F0C-584E-BF12-256E27605499.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,14 @@ + + + + + +Keyword +ReferenceThis section lists the keywords understood by the ROM building +tools in alphabetical order. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-BC0936D7-7064-447D-83EF-68C65CF3D1B0.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-BC0936D7-7064-447D-83EF-68C65CF3D1B0.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,38 @@ + + + + + + On-Target +DebuggingThis document describes how to build a device driver to enable +stop mode debugging. +
On-target +debugging

Device Driver debugging is similar to kernel-mode +debugging, as drivers run as part of the Kernel. Debug versions of the drivers +can be debugged using debug tools such as Lauterbach through a JTAG interface +or an IDE. Other debug tools such as Metro TRK can also be used.

Most +of the hardware platforms supported by Symbian platform are ICE-enabled. Kernel +developers and those porting the operating system to new hardware often have +access to development boards exposing the JTAG interface, which allows the +use of CPU-level debuggers. Using a host PC debugger, such as Carbide.c++ +or CodeWarrior configured for remote debugging, a debug ROM image (including +drivers) can be downloaded to the target and debugged over a JTAG interface.

For +debugging, debug versions drivers are built, and the ROM image is built to +include the kernel debug DLL, which enables kernel-side (stop mode) debugging. +This is done by using the STOP_MODE_DEBUGGING flag while +building the ROM image. For example:

rom –v=h4hrp –I=armv5 +–define=STOP_MODE_DEBUGGING

This includes the kernel extension kdebug.dll in +the ROM image, which provides a stop mode debugger API.

When the ROM +image is downloaded to the target, the system boots up and the Kernel or driver +can be debugged using the host based IDE interface. Code can be stepped through +and halted, and memory on the target can be viewed.

Symbian also provide +a debug monitor (sometimes called the crash debugger) to provide information +on Kernel crashes. See Debug +Monitor Tool for more details.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-BD0D62CD-A067-4A87-8779-CC245E2C4CEA.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-BD0D62CD-A067-4A87-8779-CC245E2C4CEA.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,15 @@ + + + + + +Time Tools GuideDescribes the tools required for the Time platform service. +

There are no specific tools required to use or implement the Time +platform service.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-BDB847A2-557A-5902-AA6D-C1AE10D8E493.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-BDB847A2-557A-5902-AA6D-C1AE10D8E493.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,126 @@ + + + + + +Code +Paging GuideCode paging is the application of demand paging to executable code. +
Purpose

This document explains the principles of +code paging in Symbian platform.

Intended +Audience:

This document is intended to be read by those interested +in the Symbian platform kernel.

+
Basics of code paging

Code paging means the use +of demand paging to executable code. Demand paging increases the apparent +size of available RAM on a device by loading data into RAM when needed. Since +the memory locations used by the code cannot be determined before it is loaded, +the code needs to be modified when it is paged into RAM.

Classes explained +here.

Executable code is paged in and out of memory in accordance +with the demand paging algorithm which is discussed in the document. The algorithm +involves four basic operations:

    +
  • paging in,

  • +
  • aging,

  • +
  • rejuvenating, and

  • +
  • freeing.

  • +

The remainder of this document discusses the kernel side implementation +of each of these operations in turn. Most of the work is done by the MemModelDemandPaging class.

+
Paging in paged code

When a program accesses an +item of paged code for the first time the code needs to be paged into RAM. +The initial call generates a data abort: this is caught by the exception handler +which calls the HandleFault() function of the MemModelDemandPaging class. +The function call performs the paging in as follows.

    +
  • Checks the MMU page +table entry for the address which caused the data abort. If the entry is not KPteNotPresentEntry then +there is no memory mapped at that address and it may need paging in.

  • +
  • Verifies that the exception +was caused by an access to the code chunk memory region.

  • +
  • Finds the code segment +which is at the current address.

  • +
  • Verifies that the code +segment is the one being demand paged.

  • +

The HandleFault() function of MemModelDemandPaging then +calls the PageIn() function of MemModelDemandPaging, +which performs the following steps.

    +
  • Obtains a DemandPaging::DPagingRequest object +by calling DemandPaging::AcquireRequestObject().

  • +
  • Obtains a physical page +of RAM by calling DemandPaging::AllocateNewPage().

  • +
  • Maps the RAM at the +temporary location DemandPaging::DPagingRequest::iLoadAddr.

  • +
  • Reads the correct contents +into the RAM page by calling DemandPaging::ReadCodePage().

  • +
  • Initialises the SPageInfo structure +for the physical page of RAM and marks it as type EPagedCode.

  • +
  • Maps the page at the +correct address in the current process.

  • +
  • Adds the SPageInfo to +the beginning of the live page list.

  • +

When these calls have completed they return control to the program +which caused the data abort.

+
Aging paged code

The demand paging algorithm defines +pages in the live list to be either young or old. When a page changes status +from young to old, the kernel changes the MMU mappings for the page to make +it inaccessible. It does so by calling the SetOld() function +of the MemModelDemandPaging class. The implementation of +this procedure is different in the Moving Memory Model and the Multiple Memory +Model.

In the Moving Memory Model, the call to SetOld() acts +as follows:

    +
  • Finds the MMU page table +entry for the page and clears the bits KPtePresentMask.

  • +

In the Multiple Memory Model, SetOld() calls the +kernel function DoSetCodeOld() which acts as follows:

    +
  • Examines the bit array DMemModelCodeSegMemory::iOsAsid s +to determine the processes into which the code segment is loaded.

  • +
  • Updates each mapping +in turn.

  • +

The status of a page may change during a call to DoSetCodeOld(), +either because it has been rejuvenated or paged out. In these cases DoSetCodeOld() simply +ends, as the aging operation is no longer appropriate.

+
Rejuvenating paged code

When a program accesses +a program held in an old page, it generates a data abort because the kernel +made the page inaccessible when it was set to old. The data abort is caught +by the exception handler which calls the HandleFault() function +of the MemModelDemandPaging class. It is this call which +performs the rejuvenation as follows.

    +
  • Gets the MMU page table +entry for the address which caused the abort. If the bits KPtePresentMask are +clear then the page needs rejuvenating. If all the bits are clear then the +page needs to be paged in, not rejuvenated.

  • +
  • Finds the SPageInfo for +the page, using the physical address stored in the page table entry.

  • +
  • If it finds that the +state of the page is EStatePagedDead then the page is dead +rather than old and needs to be paged in, not rejuvenated.

  • +
  • Updates the page table +entry to make the page accessible.

  • +
  • Moves the SPageInfo for +the page to the beginning of the live list, making it the youngest page in +the list.

  • +

These steps are performed with the system lock held.

+
Freeing paged code

When a physical page of RAM +holding demand-paged code is needed for other purposes, it must be freed up. +The kernel does this by calling the SetFree() function +of the MemModelDemandPaging class. The implementation of +this procedure is different in the Moving Memory Model and the Multiple Memory +Model.

In the Moving Memory Model, the call to SetFree() acts +as follows:

    +
  • Finds the MMU page table +entry for the page and sets it to KPteNotPresentEntry.

  • +

In the Multiple Memory Model, the call to SetFree() calls +the kernel function DoSetCodeFree() which acts as follows:

    +
  • Examines the bit array DMemModelCodeSegMemory::iOsAsids to +determine the processes into which the code segment is loaded.

  • +
  • Makes each page inaccessible +in turn.

  • +
+
+Code Paging +Overview +Demand Paging +Overview +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-BDF1F32B-796B-4D3D-9C91-43FF8E9DDAF9.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-BDF1F32B-796B-4D3D-9C91-43FF8E9DDAF9.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,63 @@ + + + + + +SDIO +Commands TutorialLists commands to the SD bus that are specific to SDIO. +

The SDIO hardware interface extends the functionality of SD devices. The +combination of SD card with I/O is usually found in devices that can be ported +easily and make heavy demands on memory.

+SDIO Hardware +Interface + + + +Supported SDIO Command +Interface functions +Description + + + + +

CMD5

+

IO_OP_COND

+

Used during initialization to determine the presence of an SDIO +card and set the voltage.

+
+ +

CMD52

+

IO_RW_DIRECT

+

Used to address and access a single register.

+
+ +

CMD53

+

IO_RW_EXTENDED

+

Used to address multiple registers with a single SDIO command. This +is called by the IssueMMCCardCommand() function.

+
+ +

R4

+

IO_SEND_OP_COND

+

The SDIO response. DSDIOStack::ExtractSendOpCondResponse(aResponse,aFunctionCount) is +used to extract the SDIO operation response.)

+
+ +

R5

+

IO_RW_DIRECT

+

The SDIO response, handled by TSDIORseponseR5. It also provides +information about the current state of the SDIO bus, error state, and the +byte order the data is read.

+
+ + +
+SDIO Implementation +Overview +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-BDFAE7E7-18B2-4B5D-8349-CC6C607B717A.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-BDFAE7E7-18B2-4B5D-8349-CC6C607B717A.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,12 @@ + + + + + +DMADescribes the Direct Memory Access (DMA) Platform Service. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-BE6AFD38-5952-537F-848C-C76C8F5FA9BF.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-BE6AFD38-5952-537F-848C-C76C8F5FA9BF.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,105 @@ + + + + + +MMC +Controller ArchitectureDescribes the class architecture of the MMC Controller. +
Introduction

The +MultiMediaCard media driver defines and implements the standard media driver +interface derived from DMediaDriver. This is the client +of the MultiMediaCard controller.

+ +

Requests to the controller can also come from other device drivers. +This means that the architectural picture can be extended as shown below:

+ +

The controller currently supports a single stack capable of holding +up to 4 cards. In a future development, it may become capable of supporting +more than 1 stack. Note however, that Symbian platform allows more than one +peripheral bus controller.

The controller can handle multiple requests +outstanding simultaneously, i.e. multiple drivers each with a session engaged +(a session is a unit of work for the MMC stack). Internally, it schedules +these requests onto the bus, automatically putting the appropriate card into +the transfer state etc.

A platform containing a card socket is expected +to provide a means of detecting when a card is inserted or removed from the +stack (e.g. a media door interrupt). The controller does not attempt to initialize +and identify newly inserted cards immediately. Instead, cards remain unidentified +until they are interrogated by a client.

For hardware interfaces that +allow multiple cards in a single stack, the MultiMediaCard system supplies +no means of identifying a particular socket position within the stack. As +cards are inserted and removed, the potential exists for those cards which +remain to be allocated different card numbers (and ultimately a different +drive letter than that allocated previously) once the stack is re-initialized. +To avoid this, the controller maintains a fixed card number for a given card +for as long as it remains in the Symbian platform device (by storing the CID +of each card present). This means that a card will have a constant drive letter +for as long it remains in the Symbian platform device. However, if a card +is removed, and then subsequently re-inserted into exactly the same slot in +the stack, then there is no guarantee that it will be allocated the same card +number, and therefore, no guarantee that it will have the same drive letter +as before.

+
Class architecture

The +following diagram gives a more detailed view of the MultiMediaCard controller +in terms of the socket, stack, session, power supply and media change objects.

+ +

The socket

The +Symbian platform implementation of MultiMediaCard uses the idea of a socket. +A socket corresponds to a physical device on a given peripheral bus.

In +general, a socket is associated with its own thread. However, although each +card in a MultiMediaCard stack has its own individual slot, the bus architecture +prevents more than one card from being accessed at any one time. Further, +all cards in a stack must be powered up at the same time. All this suggests +that having a separate thread for each card in a multi-card slot would not +offer much benefit, and indeed would probably lead to conflicting hardware +accesses between the threads. This means that a single socket object is allocated +to represent for all cards in MultiMediaCard stack.

The socket is +the highest level object in the MultiMediaCard controller, and is an instance +of a DMMCSocket class. It oversees the power supply functionality, +the media change functionality, and the object that controls access to the +card stack.

You can define and implement a derived class in the variant +DLL, epbusmv.dll, although it may rarely be necessary.

The stack

Access +to the card stack is handled by an instance of a DMMCStack class, +and is owned by the socket. The DMMCStack class is designed +to implement the set of "macros" defined by the MultiMediaCard Association. +These "macros" are a predefined set of command sequences that perform complex +bus operations.

You will normally define and implement a derived class +in the variant DLL, epbusmv.dll.

The session

A +session is an instance of a DMMCSession class, and represents +a unit of work for the MMC stack. It is, in effect, the main client interface +to the MultiMediaCard Controller. Each client (i.e. the MultiMediaCard media +driver or any other device driver) creates its own instance of this class. +The client can then make MultiMediaCard requests on the stack by putting the +appropriate information into the session object (configuring the session), +and then submitting this session object to the stack; this is also referred +to as engaging the session, and is invoked by calling DMMCSession::Engage(). +Once submitted, the session is then scheduled - see Sessions +and Request Management for more background information on this.

The DMMCSession class +contains functions for initiating macro functions as laid down by the MultiMediaCard +Association as well as lower level functions that allow a client to control +the stack in a more explicit manner.

Power supply unit

The +behavior of the power supply unit (PSU) is represented by the DMMCPsu class.

You +will normally define and implement a derived class in the variant DLL, epbusmv.dll.

Media change

The behavior that deals with media change events +is represented by the DMMCMediaChange class.

You +will normally define and implement a derived class in the variant DLL, epbusmv.dll.

The controller factory

The +controller factory, also known as the controller interface, is a TMMCardControllerInterface derived +class that creates instances of your platform specific: stack class, power +supply unit class, socket class, and media change class. It also allows you +to perform platform specific initialization.

You create an instance +of your factory class in the kernel extension entry point code in your DLL. +This normally calls TMMCardControllerInterface::Create() on +the object, a Symbian platform supplied function, which calls your implementations +of the TMMCardControllerInterface pure virtual functions, +to create the instances of your classes.

Note that these functions +are only called for sockets that are associated with MultiMediaCard devices. TMMCardControllerInterface::Create() iterates +through all possible socket numbers, from 0 to KMaxPBusSockets, +calling TMMCardControllerInterface::IsMMCSocket() for each +socket number to determine whether the socket number is a MultiMediaCard socket.

+ +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-BE73CFE6-D48D-5B92-AF49-E2D967ADF0EC.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-BE73CFE6-D48D-5B92-AF49-E2D967ADF0EC.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,14 @@ + + + + + +Close and Unload the Driver A short tutorial describing how to close and unload the shared chunk, close the USB channel and unload the USB Logical Device Driver (LDD). Close the handle to the shared chunk using RChunk::Close(). // Close chunk handle +gChunk.Close(); Close the handle to the USB channel using RDevUsbcScClient::Close(). // Close USB Channel +gPort.Close(); Unload the USB logical device driver using User::FreeLogicalDevice(). User::FreeLogicalDevice(KUsbDeviceName); \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-BF04B68E-7F77-5D99-A0F6-2842758EFD4D.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-BF04B68E-7F77-5D99-A0F6-2842758EFD4D.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,185 @@ + + + + + +ROFSBUILD +

ROFSBUILD is the Symbian platform non-XIP (execute-in-place) ROM +builder. It is normally invoked through BUILDROM, +the Symbian platform ROM configuration tool that acts as a front-end +to ROFSBUILD.

+

ROFSBUILD understands a sub-set of the BUILDROM OBEY file syntax.

+
+
ROFSBUILD +command syntax

If the OBY files are encoded in UTF-8 with +non-ASCII character support, use the following the ROFSBUILD command +syntax:

ROFSBUILD [options] [–oby-charset=utf-8 <obyfile>]

If the OBY files are encoded in local character set with non-ASCII +characters support, use the following the ROFSBUILD command syntax:

ROFSBUILD [options] <obeyfile>

options can be one or more +of the following:

+ + + +

–argfile=<parameter file>

+

Accepts a parameter file, which contains a list of command-line +parameters specific to the ROM tools, as input.

+
+ +

-v

+

Verbose mode.

+
+ +

-?

+

Displays more detailed help for the command.

+
+ +

-s[log|screen|both]

+

Displays a summary of the size to the specified destination, +i.e. to the log, to the screen or to both the log and the screen.

+
+ +

-d<bitmask>

+

Sets the trace bitmask; this only applies to debug builds.

The simplest way of specifying this is to use a string of hexadecimal +characters starting with 0x (e.g 0x01234567). However, any string +that can be interpreted and translated into a valid TUint value may +be used. See the standard C function strtoul().

+
+ +

-compress

+

Compresses executable files where possible using the inflate +(Deflate, Huffman+LZ77) algorithm unless the -compressionmethod keyword is used to override the default.

+
+ +

-compressionmethod [none | inflate | bytepair]

+

Can be used either with the -compress keyword +or alone.

+ + + +

none

+

No compression is used.

+
+ +

Inflate

+

Compresses executable files using the default (Deflate, +Huffman+LZ77) algorithm.

+
+ +

bytepair

+

Compresses executable files using the bytepair algorithm. +Bytepair compression allows faster decompression than the default +Deflate, Huffman+LZ77 algorithm and supports demand paging by performing +compression and decompression of code in independent 4 KB pages.

+
+ + +

+ + +

-coreimage <core image file>

+

Uses the specified core image file as the basis for creating +the extension.

+
+ +

-datadrive=<obeyfile_1>,[...,<obeyfile_n>]

+

Specifies the data drive description IBY or OBY file.

+
+ +

-lowmem

+

Reduces the physical memory consumption during image generation.

+
+ +

-loglevel<level>

+

Level of information to log file. The following valid log +levels are available:

+ + + +

0

+

Default level of information to log file.

+
+ +

1

+

Logs the host or the ROM filenames, the file size, and the +hidden attribute in addition to the loglevel 0 information.

+
+ +

2

+

Logs the E32 file header attributes such as UIDs, data size, +heap size, stack size, VID, SID, and priority in addition to the loglevel 1 information.

+
+ + +

+
+ +

-wstdpath

+

Displays a warning if a file is placed in a non-standard +directory when PlatSecEnforceSysBin is set to OFF.

For example, the following instruction in +OBY file leads to a warning when -wstdpath is used +and PlatSecEnforceSysBin is OFF:

File=ABI_DIR/BUILD_DIR/hello.exe myfolder/bin/hello.exe

+
+ +

-j<NUM_OF_WORKING_THREADS>

+

Specifies the number of working threads that can run concurrently +to create a ROFS image. The <NUM_OF_WORKING_THREADS> must be an integer in the range 1-128.

If the -j option is not specified or an invalid value is specified, ROFSBUILD +automatically takes the number of working threads in the following +ways:

    +
  • If the NUMBER_OF_PROCESSORS environment variable is set properly, +ROFSBUILD uses the number of processors as the number of working threads.

  • +
  • If the NUMBER_OF_PROCESSORS environment variable is not set or +is invalid, the default value 8 is used as the number +of working threads.

  • +
+
+ +

-cache

+

Enables cache mechanism. It ensures that ROFSBUILD uses +cached executable files while creating a ROFS image. This allows ROFSBUILD +to reuse or generate cached files.

Notes:

    +
  • The cache mechanism +is disabled by default.

  • +
  • The cached files +are stored on the hard disk.

  • +
  • The cache command +line options (-cache, -nocache, +and -cleancache) are mutually exclusive. This means +that you can use only one cache option at a time.

  • +
+
+ +

-nocache

+

Disallows ROFSBUILD from using cached files while creating +a ROFS image.

+
+ +

-cleancache

+

Deletes all cached files from the hard disk.

+
+ +

-symbols

+

Generates symbols for each data or executable specified +in the OBY file.

Note: The symbols file is not generated +by default.

+
+ +

-smr=<smrhcr_rofsbuild_obeyfile_1>,[…, <smrhcr_rofsbuild_obeyfile_n>]

+

Creates SMR partition images.

+
+ + +

-prependepocroot

+

Prepends EPOCROOT to the file location, if the specified +location starts from \epoc32 without EPOCROOT.

+
+ + +

<obeyfile> is a standard text file +containing statements that are used to control the operation of the +tool.

See the OBEY files reference for the full syntax.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-BF157EE2-B680-554A-AE32-69C652B61FA6-master.png Binary file Adaptation/GUID-BF157EE2-B680-554A-AE32-69C652B61FA6-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-BF157EE2-B680-554A-AE32-69C652B61FA6_d0e29926_href.png Binary file Adaptation/GUID-BF157EE2-B680-554A-AE32-69C652B61FA6_d0e29926_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-BF86E9F9-531A-51A1-90B4-23B51604F5B4.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-BF86E9F9-531A-51A1-90B4-23B51604F5B4.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,103 @@ + + + + + +Reference +

This topic provides a summary of related documentation for the USB Client +Driver to which you can refer.

+
API Reference

Kernel Architecture

+ + + +

Item

+

Header

+
+ +

RDevUsbcClient

+

d32usbc.h

+
+ +

TCapsDevUsbc

+

d32usbc.h

+
+ +

TUsbcClassInfo

+

d32usbc.h

+
+ +

TUsbcEndpointCaps

+

d32usbc.h

+
+ +

TUsbcEndpointData

+

d32usbc.h

+
+ +

TUsbcEndpointInfo

+

d32usbc.h

+
+ +

DUsbClientController

+

usbc.h

+
+ +

TUsbcRequestCallback

+

usbc.h

+
+ +

TUsbcSetup

+

usbc.h

+
+ + +

Note: DUsbClientController is mostly internal. +There are 39 pure virtual functions that need to be implemented in your platform-specific +layer:

    +
  • DUsbClientController::SignalRemoteWakeup()

  • +
  • DUsbClientController::DumpRegisters()

  • +
  • DUsbClientController::DfcQ()

  • +
  • DUsbClientController::SetDeviceAddress()

  • +
  • DUsbClientController::ConfigureEndpoint()

  • +
  • DUsbClientController::DeConfigureEndpoint()

  • +
  • DUsbClientController::AllocateEndpointResource()

  • +
  • DUsbClientController::DeAllocateEndpointResource()

  • +
  • DUsbClientController::QueryEndpointResource()

  • +
  • DUsbClientController::SetupEndpointRead()

  • +
  • DUsbClientController::SetupEndpointWrite()

  • +
  • DUsbClientController::CancelEndpointRead()

  • +
  • DUsbClientController::CancelEndpointWrite()

  • +
  • DUsbClientController::SetupEndpointZeroRead()

  • +
  • DUsbClientController::SetupEndpointZeroWrite()

  • +
  • DUsbClientController::SendEp0ZeroByteStatusPacket()

  • +
  • DUsbClientController::StallEndpoint()

  • +
  • DUsbClientController::ClearStallEndpoint()

  • +
  • DUsbClientController::EndpointStallStatus()

  • +
  • DUsbClientController::EndpointErrorStatus()

  • +
  • DUsbClientController::ResetDataToggle()

  • +
  • DUsbClientController::SynchFrameNumber()

  • +
  • DUsbClientController::SetSynchFrameNumber()

  • +
  • DUsbClientController::StartUdc()

  • +
  • DUsbClientController::StopUdc()

  • +
  • DUsbClientController::UdcConnect()

  • +
  • DUsbClientController::UdcDisconnect()

  • +
  • DUsbClientController::UsbConnectionStatus()

  • +
  • DUsbClientController::UsbPowerStatus()

  • +
  • DUsbClientController::DeviceSelfPowered()

  • +
  • DUsbClientController::DeviceEndpointCaps()

  • +
  • DUsbClientController::DeviceTotalEndpoints()

  • +
  • DUsbClientController::SoftConnectCaps()

  • +
  • DUsbClientController::DeviceStateChangeCaps()

  • +
  • DUsbClientController::Suspend()

  • +
  • DUsbClientController::Resume()

  • +
  • DUsbClientController::Reset()

  • +
  • DUsbClientController::Ep0ReadSetupPktProceed()

  • +
  • DUsbClientController::Ep0ReceiveProceed()

  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-BFE1422D-3B4A-5B25-A757-B5B68D6390F8.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-BFE1422D-3B4A-5B25-A757-B5B68D6390F8.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,84 @@ + + + + + +Port +Implementation TutorialThis topic describes how to customize the Base Starter. +
Creating local +drive mapping files
    +
  1. Create an ASCII text +file containing your local drive mapping records; see create local drive mapping files for information about the syntax +of the file.

  2. +
  3. Put this text file into +your variant source tree. The source tree is typically of the form sf/os/boardsupport/.../<your + variant>/estart/ . Depending on your port, you +might need more than one local drive mapping file.

  4. +
  5. In the kernel.iby file +for your variant, you need to add lines to make sure that your local drive +mapping files are copied into the ROM's \sys\data\ directory +when the ROM is built. For example include a lines in the form

    data=\epoc32\rom\youvariant\ESTARTCOMP.TXT \Sys\Data\ESTARTCOMP.TXT
  6. +
  7. If you need more than +one mapping file, or your single mapping file has a name other than ESTART.TXT, +then you need to customise the function TFSStartUp::LocalDriveMappingFileName() so +that you can return the appropriate file name at run time.

  8. +
+
Making use +of auto detection

To make use of auto-detection, you need to ensure +that your variant cannot find local drive mapping files in your ROM's \sys\data\ directory. +If you are using the default version of TFSStartUp::LocalDriveMappingFileName(), +then make sure that no file exists with the full path name Z:\sys\data\estart.txt.

+
Customising +code

The most common customisation is to provide your own implementation +of the TFSStartup virtual functions. To do this:

    +
  1. Take a copy of ESTARTMAIN.CPP from sf/os/kernelhwsrv/userlibandfileserver/fileserver/estart/, and insert your code into this copy. Typically this will include, but is +not limited to, your implementation of the TFSStartup virtual +functions.

  2. +
  3. Place the copy into +your variant's source tree. This is typically of the form sf/os/boardsupport/.../<your +variant>/estart/. This is the general pattern for the other ports +supplied with Symbian platform.

  4. +
  5. Create a .mmp file +to build your variant's version of the Base Starter. This is usually placed +in the \<youvariant>\ directory. The general pattern +looks like this: sf/os/boardsupport/.../<your + variant>/estart/estart.mmp. Ports to other hardware variants and +the emulator (WINS) variant follow the same general pattern.

  6. +
  7. Your .mmp file +should pick up the Symbian platform generic code from sf/os/kernelhwsrv/userlibandfileserver/fileserver/estart/estart.cpp, +but should pick up your variant's customised source code from sf/os/boardsupport/.../<your +variant>/estart/estartmain.cpp. The general pattern is to give +the resulting executable the name e32strt.exe.

  8. +
  9. In the kernel.iby file +for your variant, you need to add a line that copies your executable into +the ROM's \sys\bin\ directory when the ROM is built. +For example, include a line of the form:

    file=\Epoc32\Release\##MAIN##\##BUILD##\_##VARIANT##_e32strt.exe sys\bin\estart.exe HEAPMAX(0x2000)
  10. +
+
Removing auto +detect from the Base Starter

You do this only if you need to save +code space, and you do not need the autodetect functionality.

See +also Use +automatic local drive mapping.

    +
  1. Create a .mmp file +to build your variant's version of the Base Starter. This is usually placed +in the sf/os/boardsupport/.../<your variant>/estart/ directory. +This shows the general pattern. Ports to other hardware variants and the emulator +(WINS) variant follow the same general pattern.

  2. +
  3. In your .mmp file, +define the macro:

    MACRO AUTODETECT_DISABLE
  4. +
  5. The location of all +source files in the .mmp file will be sf/os/kernelhwsrv/userlibandfileserver/fileserver/estart/.

  6. +
  7. In the kernel.iby file +for your variant, you need to add a line to make sure that your executable +is copied into the ROM's \sys\bin\ directory when the +ROM is built. For example, include a line of the form

    file=\Epoc32\Release\##MAIN##\##BUILD##\_##VARIANT##_e32strt.exe sys\bin\estart.exe HEAPMAX(0x2000)

    This is the general pattern for the other ports supplied with Symbian +platform.

  8. +
+
See also

Concepts

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-C059F39F-BC53-5C92-B05E-863B8CF22859.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-C059F39F-BC53-5C92-B05E-863B8CF22859.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,46 @@ + + + + + +Command +ObjectsThe MultiMediaCard controller uses a TMMCCommandDesc object +to contain command and parameter information when issuing a command over the +bus. +

This object is also used to contain response information resulting from +the execution of that command.

+

As it can sometimes be necessary to temporarily save current command and +parameter information, the controller implements a small stack of TMMCCommandDesc objects. +The controller then has the concept of a current command information +object.

+

The platform independent layer provides three functions through which command +and parameter information can be set up:

+
    +
  • Two variants of DMMCStack::CurrentSessFillCmdDesc()

  • +
  • DMMCStack::CurrentSessFillCmdArgs()

  • +
+

These functions are used to fill the current TMMCCommandDesc object.

+

The controller executes a single command by calling the state machine function DMMCStack::IssueMMCCommandSM(); +this is implemented by the platform specific layer as part of the porting +activity.

+

It calls DMMCSession::Command() to access the current command +and parameter information.

+
The command +stack

Internally, the command stack is implemented as a simple +array of TMMCCommandDesc objects; this is the DMMCSession::iCommand[] private +data member. The stack is KMaxMMCCommandStackDepth deep. +Internally, the current command information object is identified and accessed +through the DMMCSession::iCmdSP data member, which indexes +into the array and acts as a pointer to the current command information object.

The +platform independent layer provides two protected functions that the platform +specific layer can use to change the command information object that is current:

    +
  • DMMCStack::CurrentSessPushCmdStack()

  • +
  • DMMCStack::CurrentSessPopCmdStack()

  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-C06CFF3E-23E9-5E0B-99A1-51B8ED95465F.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-C06CFF3E-23E9-5E0B-99A1-51B8ED95465F.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,24 @@ + + + + + +USB +Client DriverThe USB Client Driver is a device driver for USB device +(client) functionality. This section describes how to create a port +of it for your phone hardware. +

Symbian platform provides a logical device driver, and a generic +Platform Independent Layer for the physical device driver. The physical +device driver is called the USB client controller. You must provide +a Platform Specific Layer of the USB client controller to implement +the interface to the USB hardware on your phone.

+

The USB Manager component in the Short Link Services module provides +a higher-level framework that can be used to implement and control +the USB device functions on a phone.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-C0DC5D95-2EB5-45D9-A859-78329A4B3EF1.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-C0DC5D95-2EB5-45D9-A859-78329A4B3EF1.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,13 @@ + + + + + +SDIO +ImplementationLanding page for SDIO implementation documents. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-C2114C7B-705C-4527-836A-C6E72227111A.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-C2114C7B-705C-4527-836A-C6E72227111A.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,139 @@ + + + + + +DMA Testing GuideDescribes the required and optional testing for the DMA +framework. +

You can use the same set of source code to build the following +DMA test harnesses:

+
    +
  1. Simulation +PSL: T_DMASIM.EXE, D_DMASIM.LDD, and DMASIM.DLL. This is a software-simulated +implementation of DMA that is used mainly for debugging and validating +the PIL (platform-independent layer), as it simulates all types of +DMA controller.

  2. +
  3. User-side +harness: T_DMA.EXE.

  4. +
+
DMA test source files

The following test code are +available to test a DMA port.

+ + + + +File +Description +Location +Usage + + + + +t_dma.exe +User-side test harness to test the DMA framework +/e32test/dma/t_dma.cpp +Mandatory + + +d_dma.ldd +Simulation PSL to test the DMA framework +/e32test/dma/d_dma.cpp +Mandatory + + +dmasim.dll +Software simulation of DMA controller and the SHAI implemetation +e32test/dma/dmasim.cpp +Optional, only used to test software simulated DMA controller. + + +t_dmasim.exe +User-side test harness to test the simulated DMA controller +/e32test/dma/t_dma.cpp +Optional, only used to test software simulated DMA controller. + + +d_dmasim.ldd +Kernel-side test harness to test the simulated DMA controller +/e32test/dma/d_dma.cpp +Optional, only used to test software simulated DMA controller. + + + +

T_DMA.EXE is a user-side harness, +and is an automatic test included in the E32TEST suite. +It assumes that the underlying DMA controller supports memory to memory +transfers. This executable delegates most of the work to D_DMA.LDD , a logical device driver that acts as a client +for the DMA Framework. D_DMA.LDD links statically +against DMA.DLL, the DMA Framework kernel extension +must be built from the variant.

T_DMA.EXE delegates most of the work to D_DMA.LDD, which +is a logical device driver that acts as a client for the DMA Framework. +D_DMA.LDD links statically against DMA.DLL, the DMA Framework kernel +extension must be built from the variant. In practice, this means +that D_DMA.LDD must be specified in the test bld.inf for the variant being ported. For an example of this, see ...\template_variant\test\bld.inf.

D_DMA.LDD calls the DmaTestInfo() function in the PSL to +obtain the information on which channels are available to be used +by T_DMA to allow it to run multiple DMA channels simultaneously. +This is the template implementation:

struct TDmaTestInfo + { + /** Maximum transfer size in bytes for all channels (ie. the minimum of all channels' maximum size)*/ + TInt iMaxTransferSize; + /** 3->Memory buffers must be 4-byte aligned, 7->8-byte aligned, ... */ + TUint iMemAlignMask; + /** Cookie to pass to DDmaRequest::Fragment for memory-memory transfer*/ + TUint32 iMemMemPslInfo; + /** Number of test single-buffer channels */ + TInt iMaxSbChannels; + /** Pointer to array containing single-buffer test channel ids */ + TUint32* iSbChannels; + /** Number of test double-buffer channels */ + TInt iMaxDbChannels; + /** Pointer to array containing double-buffer test channel ids */ + TUint32* iDbChannels; + /** Number of test scatter-gather channels */ + TInt iMaxSgChannels; + /** Pointer to array containing scatter-gather test channel ids */ + TUint32* iSgChannels; + }; + +TDmaTestInfo TestInfo = {0, 0, 0, 0, NULL, 0, NULL, 0, NULL}; + + +EXPORT_C const TDmaTestInfo& DmaTestInfo() +//... + { + return TestInfo; + } + +
+
Test +application use cases

The DMA test application is used to +test:

    +
  • one shot single buffer transfer

  • +
  • one shot double buffer transfer

  • +
  • one shot scatter/gather transfer

  • +
  • streaming single buffer transfer

  • +
  • streaming double buffer transfer

  • +
  • streaming scatter/gather transfer

  • +

The DMA test application can be used on both reference hardware +platform and software simulated DMA.

+
Limitations

The DMA test application has the following known limitations:

    +
  • only supports one shot and streaming data transfer

  • +
  • many parameters such as the number of buffers, the transfer +size and the number of fragments are fixed

  • +
  • does not support performance measurements like CPU usage, setup +time and transfer time

  • +
  • does not support memory to peripheral data transfer

  • +
  • does not support SMP related testing like allocating DFC on +same core or different core.

  • +
+
+DMA +Implementation Guide +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-C22974D8-CFB9-4A83-BE58-CCC97EA8DF13.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-C22974D8-CFB9-4A83-BE58-CCC97EA8DF13.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,13 @@ + + + + + +Device +Driver Writing GuideThis set of documents explains how to write a device driver. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-C244D421-8BD0-4212-A5C5-47A8B1E0C1E2.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-C244D421-8BD0-4212-A5C5-47A8B1E0C1E2.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,59 @@ + + + + + +Kernel +ExtensionThis document describes how to implement a device driver as a kernel +extension. +

Device +drivers can also be kernel extensions, which means that they are loaded by +the Kernel when it boots. They are used for extending the Kernel, as the name +suggests. Generally, kernel extensions provide early initialisation of devices +that must be permanently available, such as LCD, DMA, and I2C and other peripheral +bus controllers. Because kernel extensions are loaded by the Kernel, they +are never unloaded and so their destructors are never called.

The DECLARE_STANDARD_EXTENSION macro +is used to provide an entry point for a kernel extension (see Entry +Points).

Extensions are built into the ROM image, by specifying +the extension keyword in the .iby file. +This enables the ROM build tool to build the ROM header. The extensions are +loaded in the order specified in the kernel.iby file.

extension[VARID]=\Epoc32\Release\<assp>\urel\KDEBUG.DLL \System\Bin\kdebug.dll

A +kernel extension's interface to other Kernel side components is usually exported +using a static interface. Clients can access this interface by using the global +instance of the object created and initialised in the DECLARE_STANDARD_EXTENSION entry +point. They then use this object to call the exported API.

Kernel +extensions can also be implemented that let user code open channels on them +to use the interface. This model is used for devices where initialisation +has to be done at system boot up, but which can then be used by the clients, +for example, the media driver elocd.ldd.

To do +this, drivers have to declare DECLARE_EXTENSION_LDD in +addition to the DECLARE_STANDARD_EXTENSION macro. In this +model, extensions generally call Kernel::InstallLogicalDevice() /Kernel::InstallPhysicalDevice() to +install the logical device. Later clients can open channels on this driver +and use the interface in the same way as a standard driver.

DECLARE_STANDARD_EXTENSION() + { + ... + // Create factory object + DExDriverLogicalDevice* device = new DExDriverLogicalDevice; + if (device==NULL) + r=KErrNoMemory; + else + { + // Installs the logical device by calling the second + // phase constructor + r=Kern::InstallLogicalDevice(device); + } + return r; + } + +DECLARE_EXTENSION_LDD() + { + return new DExDriverLogicalDevice; + }
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-C24A5B52-0B40-53B2-BF85-6ECC35BDCBA5.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-C24A5B52-0B40-53B2-BF85-6ECC35BDCBA5.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,116 @@ + + + + + +IIC Implementation GuideDescribes how to implement the IIC platform service. +

This document describes the overview of how to implement the IIC +platform service APIs and directs you to more specific documentation.

+
Purpose

The IIC platform service APIs provides a means of accessing devices +that are connected onto a multi-wire bus within the phone. These platform +service APIs rely on hardware-specific implementation in the SHAI +implementation layer of the IIC implementation. This hardware-specific +implementation is primarily creating concrete hardware-specific implementations +of functions defined in the Platform Independent Layer (PIL),.

Intended Audience:

This document is intended for +hardware device implementers who want to write adaptation software +to use their specific serial bus hardware with IIC.

+
Background

There are two main forms of IIC operation:

    +
  • Master operation

  • +
  • Slave mode

  • +

A master node on a bus controls transactions and is responsible +for sending commands along the bus to select the slave node which +is to send or receive the commands and data. A slave node receives +instructions from a master node and sends or receives commands and +data. The OS device drivers may act as a slave or a master node, or +in some bus technologies, the role of master and slave can be exchanged.

IIC has channels, which represent a connection between two nodes +on the bus. The channel has a queue for commands and will process +each command in turn.

A device driver can either use the IIC +Controller to access channels, or if there is a dedicated node that +is going to be used by a particular device driver, then the device +driver can talk directly to that node through IIC without using the +IIC Controller.

+
The +IIC platform service API

The IicBus class +provides the platform service API for device drivers that want to +use the IIC Controller. For Controller-less operation, the platform +service API is formed by the DIicBusChannelMaster, DIicBusChannelSlave and DIicBusChannelMasterSlave classes.

A summary of methods in the IicBus class are :

+ + + +

Method

+

Purpose

+
+ +

QueueTransaction(TInt aBusId, TIicBusTransaction* aTransaction)

+

Queues a transaction for synchronous completion.

+
+ +

QueueTransaction(TInt aBusId, TIicBusTransaction* aTransaction, +TIicBusCallback* aCallback)

+

Queues a transaction for asynchronous completion.

+
+ +

CancelTransaction(TInt aBusId, TIicBusTransaction* aTransaction)

+

Cancels a previously queued transaction (if the transaction +was queued asynchronously).

+
+ +

CaptureChannel(TInt aBusId, TDes8* aConfigHdr, TIicBusSlaveCallback* +aCallback, TInt& aChannelId, TBool aAsynch=EFalse)

+

Capture a slave channel.

The aAsynch parameter indicates +if this is to be done synchronously or asynchronously. The default +is synchronous.

+
+ +

ReleaseChannel(TInt aChannelId)

+

Release a previously captured Slave channel.

+
+ +

RegisterRxBuffer(TInt aChannelId, TPtr8 aRxBuffer, TInt8 +aBufGranularity, TInt8 aNumWords, TInt8 aOffset)

+

Register a receive buffer with this slave channel.

+
+ +

RegisterTxBuffer(TInt aChannelId, TPtr8 aTxBuffer, TInt8 +aBufGranularity, TInt8 aNumWords, TInt8 aOffset)

+

Register a transmit buffer with this slave channel.

+
+ +

SetNotificationTrigger(TInt aChannelId, TInt aTrigger)

+

For a transmit operation, this sets the notification trigger, +sets the receive path and starts a transmit operation (if the node +is being addressed). For a receive operation, this sets the notification +trigger.

+
+ +

StaticExtension(TUint aId, TUint aFunction, TAny* aParam1, +TAny* aParam2)

+

Interface to provide extended functionality.

+
+ + +

The platform service APIs for controller-less operation +are almost exactly the same, but with the addition of channel constructors +and destructors. Please refer to iic.h, iic_channel.cppand iic_channel.h for +more details on these APIs.

+
Implementation +details

You must next read:

    +
  • IIC +SHAI Implementation Layer: Generic Considerations

  • +
  • IIC +SHAI Implementation Layer: Master Channel

  • +
  • IIC +SHAI Implementation Layer: Slave Channel

  • +

+
+IIC +Overview +IIC +Concepts Overview +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-C34DFF54-87C5-47F6-B0AE-3B066DC7F5A0.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-C34DFF54-87C5-47F6-B0AE-3B066DC7F5A0.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,16 @@ + + + + + +Register Access Testing GuideDescribes the test suites required to test the Register +Access platform service implementation. +

There is no specific test suite available for Register Access platform +service.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-C38DA704-8868-479B-AF81-375E0A2F5BCC.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-C38DA704-8868-479B-AF81-375E0A2F5BCC.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,42 @@ + + + + + +NameThis document describes how names are assigned to device drivers. +

Each +Symbian platform device driver has a name. When the driver is +loaded by the user, LDDs and PDDs register themselves using a name. LDDs and +PDDs have different names, which are used to identify the logical device and +physical device objects.

The following shows how the example device +drivers set their names:

_LIT(KDriverPddName," d_expio.pdd"); + +// Called while loading PDD +TInt DExH4PhysicalDevice::Install() + { + return SetName(&KDriverPddName); + } _LIT(KDriverName, " d_expio"); + +// Called while loading LDD +TInt DExDriverLogicalDevice::Install() + { + return SetName(&KDriverName); + }

The framework uses driver names to identify the PDDs +that can be used with a given LDD. This can happen in two ways:

    +
  • The framework uses the +name of the PDD factory object passed by the user while creating the logical +channel. This requires a PDD with that name to be already loaded, and its +factory object created. The framework searches for a PDD factory object with +the specified name.

  • +
  • If the user does not +pass the PDD name explicitly, then the framework searches all PDD factory +objects that have a name in the form of x.y, where x is the name of the LDD +factory object.

  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-C3C89BD7-A56D-4597-8804-01A25BC71581.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-C3C89BD7-A56D-4597-8804-01A25BC71581.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,62 @@ + + + + + +Data +Transfer between LDD and PDDThis document describes how LDDs and PDDs exchange data. +
+

The device driver framework supplies each LDD with a pointer, DLogicalChannelBase::iPdd, +through which it can access PDD functions. The pointer is initialised by the +Kernel while creating a physical channel.

An example of this pointer +in use:

inline DExUartPhysicalChannel * DExDriverLogicalChannel::Pdd() + { return (DExUartPhysicalChannel *)iPdd; } + +// example use +Pdd()->SetDfcQ();

Similarly, a PDD can access a LDD, though +this access must be initialised by the LDD. In the following example, the +physical channel declares a pointer to a logical channel, which the LDD sets. +Callbacks to the LDD are done using this pointer.

// PDD channel class +class DExH4PhysicalChannel: public DBase + { + ... +public: + DExDriverLogicalChannel* iLdd; + } + +// Second stage constructor of Logical channel +TInt DExDriverLogicalChannel::DoCreate(TInt /*aUnit*/, const TDesC8* + /*anInfo*/, const TVersion& aVer) + { + ... + Pdd()->iLdd=this; + } + +// example use in PDD +iLdd->ReceiveDataComplete(KErrNone);

The logical channel class, DLogicalChannelBase, +also has pointers to a logical device (iDevice) and a physical +device (iPhysicalDevice). These pointers are initialised +during the driver loading and channel open operations, so they can also be +used to pass information between the LDD and PDD.

class DLogicalChannelBase: public DObject + { + ... +public: + DLogicalDevice* iDevice; + DPhysicalDevice* iPhysicalDevice; + DBase* iPdd; + } + +// example use +TDynamicDfcQue* DExUartPhysicalChannelH4::DfcQ(TInt aUnit) + { + ... + return ((DExH4PhysicalDevice*) + (iLdd->iPhysicalDevice))->iDfcQueue; + }
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-C3CE35FF-240E-5385-9088-38EF926ABB7B-master.png Binary file Adaptation/GUID-C3CE35FF-240E-5385-9088-38EF926ABB7B-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-C3CE35FF-240E-5385-9088-38EF926ABB7B_d0e29836_href.png Binary file Adaptation/GUID-C3CE35FF-240E-5385-9088-38EF926ABB7B_d0e29836_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-C57086D7-7672-4A52-8634-D28B37AC6290.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-C57086D7-7672-4A52-8634-D28B37AC6290.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,144 @@ + + + + + +TSDIOFunction +Class TutorialDescribes the TSDIOFunction API Class. +
Description

The TSDIOFunction class +provides access to functionality common to all SDIO functions. It may be used +as a base class for particular functions such as UART.

+ + + +

Header file

+

function.h

+
+ +

Source code file

+

function.cpp

+
+ +

Required libraries

+

EPBUSSDIO

+
+ +

Class declaration

+

class TSDIOFunction

+
+ + +
+
Enable()

The +function declaration for the Enable() method is:

IMPORT_C TInt Enable(TBool aPollReady = ETrue);

Description

Enables the function by writing to the appropriate +register in the CCCR.

Parameters

+ + + +

TBool aPollReady

+If aPollReady == ETrue, then the function shall attempt +to enable the function, then poll for the recommended enable period until +the function is enabled, or times out. Otherwise, flow returns control to +the calling function who should be responsible for polling the IO_READY bit +(using TSDIOFunction::IsReady) +
+ + +

Return value

KErrNone if successful, +otherwise a standard Symbian platform error code.

+
Disable()

The +function declaration for the Disable() method is:

IMPORT_C TInt Disable();

Description

Disables +the function by writing to the appropriate register in the CCCR.

Parameters

None

Return +value

KErrNone if successful, otherwise a standard +Symbian platform error code.

+
IsReady()

The +function declaration for the IsReady() method is:

IMPORT_C TInt IsReady(TBool& aIsReady);

Description

Disables the function by writing to the appropriate register in the +CCCR.

Parameters

+ + + +

TBool& aIsReady

+Returns the current state of the function. +
+ + +

Return value

KErrNone if successful, +otherwise a standard Symbian platform error code.

+
RegisterClient()

The +function declaration for the RegisterClient() method is:

IMPORT_C TInt RegisterClient(DBase* aHandle, DMutex* aMutexLockP = NULL);

Description

Registers the client with the function.

Parameters

+ + + +

DBase* aHandle

+The unique Client ID +
+ +

DMutex* aMutexLockP

+The client's data access mutex which locks access to the register interface. +Use of the mutex is optional and the parameter is initialized to NULL. +
+ + +

Return value

KErrNone if successful, +otherwise a standard Symbian platform error code.

+
DeregisterClient()

The +function declaration for the DeregisterClient() method +is:

IMPORT_C TInt DeregisterClient(DBase* aHandle);

Description

Deregisters +the client from the function.

Parameters

+ + + +

DBase* aHandle

+The unique Client ID. +
+ + +

Return value

KErrNone if successful, +otherwise a standard Symbian platform error code.

+
SetPriority()

The +function declaration for the SetPriority() method is:

IMPORT_C TInt SetPriority(TSDIOFunctionPriority aPriority);

Description

This sets the priority of accesses to the function. + It is intended to allow the suspend/resume protocol to determine whether +an access to a lower priority function should become suspended while a higher +priority function is accessed. Note that the Suspend/Resume protocol is not +currently implemented, but may be in a future release.

Parameters

+ + + +

TSDIOFunctionPriority aPriority

+The requested function priority. +
+ + +

Return value

KErrNone if successful, +otherwise a standard Symbian platform error code.

+
RegisterInterface()

The +function declaration for the RegisterInterface() method +is:

inline DSDIORegisterInterface* RegisterInterface(DBase* aHandle) const;

Description

Returns +a pointer to an instance of a DSDIORegInterface class that +may be used by a client to talk to the Function Specific Registers.

Parameters

+ + + +

DBase* aHandle

+The ID of the client as registered using RegisterClient(). +
+ + +

Return value

A pointer to the DSDIORegisterInterface associated +with this function.

+
Interrupt()

The +function declaration for the Interrupt() method is:

inline TSDIOInterrupt& Interrupt();

Description

Returns a reference to a TSDIOInterrupt class that may be used by +the client to enable the use of interrupts for the function.

Parameters

None

Return +value

A reference to the interrupt class associated with this function.

+
Capabilities()

The +function declaration for the Capabilities() method is:

inline const TSDIOFunctionCaps& Capabilities() const;

Description

Returns information about the basic capabilities +of the function (function number, function type etc.).

Parameters

None

Return +value

A pointer to the DSDIORegisterInterface associated +with this function.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-C649DB97-F138-4C90-B177-16590F2E3F19-GENID-1-2-1-10-1-5-1-5-1-1-7-1-9-1-3-1.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-C649DB97-F138-4C90-B177-16590F2E3F19-GENID-1-2-1-10-1-5-1-5-1-1-7-1-9-1-3-1.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,25 @@ + + + + + +DMA ChannelsDescribes how device drivers use DMA channels. +

The DMAC has different DMA channels that can be configured for +different DMA transfers. For some peripherals, such as the Camera +and the Display controller, there can be dedicated DMA channels that +cannot be configured for DMA transfers by other peripherals. However, +drivers generally initialize and open a multi-purpose DMA channel +and use that channel to perform the DMA transfers.

+

Initialization and opening of DMA channels is done using the interface TDmaChannel.

+This class is designed only for single-thread client access. +When used by multi-threaded clients, synchronization mechanisms should +be provided by the driver. +

DMA channels must be opened before use and closed after completion +of DMA operations.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-C649DB97-F138-4C90-B177-16590F2E3F19-GENID-1-2-1-9-1-6-1-8-1-7-1-3-1.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-C649DB97-F138-4C90-B177-16590F2E3F19-GENID-1-2-1-9-1-6-1-8-1-7-1-3-1.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,25 @@ + + + + + +DMA ChannelsDescribes how device drivers use DMA channels. +

The DMAC has different DMA channels that can be configured for +different DMA transfers. For some peripherals, such as the Camera +and the Display controller, there can be dedicated DMA channels that +cannot be configured for DMA transfers by other peripherals. However, +drivers generally initialize and open a multi-purpose DMA channel +and use that channel to perform the DMA transfers.

+

Initialization and opening of DMA channels is done using the interface TDmaChannel.

+This class is designed only for single-thread client access. +When used by multi-threaded clients, synchronization mechanisms should +be provided by the driver. +

DMA channels must be opened before use and closed after completion +of DMA operations.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-C661B40F-1439-587F-9E8E-DB2DFC79C040.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-C661B40F-1439-587F-9E8E-DB2DFC79C040.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,33 @@ + + + + + +HAL GroupsDescription of HAL groups to add new attributes. +

You can extend HAL groups to add new attributes and new types of hardware.

+
Extending +an existing hardware type

Each HAL group has an associated +set of function numbers. For example, the enumerators of TDisplayHalFunction, in u32std.h define the functions associated +with the HAL group EHalGroupDisplay.

In this +specific case, new state can be represented by a new function number, +and by changing the HAL handler implementation to deal with the new function number.

It is +important to note that any new function numbers should not follow +consecutively from those defined by Symbian. Instead, choose high +values so that they are guaranteed not to clash with any future Symbian +extensions. Symbian will always use new values that follow consecutively +from previous Symbian defined values.

+
New +hardware type

Although up to 32 HAL groups can be defined, +Symbian platform does not use all 32. This leaves some values that +can be used for new hardware.

In this case choose a HAL group +number at the high end of the range, so that it is guaranteed not +to clash with any future Symbian extensions. Symbian will always use +new values that follow consecutively from previous Symbian defined +values.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-C661BFA4-6C39-476A-8DE0-08E18AA0F548.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-C661BFA4-6C39-476A-8DE0-08E18AA0F548.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,44 @@ + + + + + +IIC OverviewProvides a basic summary of the Inter-Integrated Circuit +(IIC) platform service. +

The IIC is a technology-independent interface for serial bus technologies. +The IIC supports multi-master and multi-slave serial interfaces, used +by the low power peripherals to exchange control information between +devices attached to the bus. The IIC supports different modes of data +transfer.

+
What +is the IIC platform service

The IIC platform +service provides a set of functions for device drivers to be able +to use serial interfaces without needing to know the details of the +actual chipset implementing the particular serial interface technology, +for example I2C or SPI. The client will however need to understand +how to configure headers for the particular interface technology.

For the technical details about IIC, see the IIC Quick Start.

+
Need +for the IIC platform service

IIC is used in a number of +different areas in the OS. These may include:

    +
  • controlling flash memory devices

  • +
  • controlling the LCD

  • +
  • reading data from the Real Time Clock.

  • +

The IIC platform service gives a common set of functions to +initiate a connection and to transfer the data.

+
IIC +users

The IIC documentation covers two types of user:

    +
  • those that want to write device drivers

  • +
  • those that need to write SHAI implementation code to interface +to their particular IIC chipset.

  • +

+
Limitations

IIC is an abstraction interface for several different serial bus +communication technologies. There may be features of a particular +technology that are not available through IIC. IIC imposes no throughput +limitations.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-C6647E84-7237-44FC-BD5D-2476EC161D02.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-C6647E84-7237-44FC-BD5D-2476EC161D02.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,12 @@ + + + + + +IIC ImplementationDescribes how to implement the IIC platform service. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-C6825C8F-8020-58CF-A09E-34558B1542DE.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-C6825C8F-8020-58CF-A09E-34558B1542DE.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,14 @@ + + + + + +MMC Controller +OperationThis section describes the detailed structure and operation of +the MMC Controller. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-C6ABE2CA-901E-55F1-9837-7018A1612BCF.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-C6ABE2CA-901E-55F1-9837-7018A1612BCF.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,44 @@ + + + + + +Set UpDescribes how to use the template port to start your port. +

The code for the template port Sound Driver is split into two files:

+
    +
  • This file holds the +code for the record driver channel

    ...\template\template_variant\specific\soundsc_rx.cpp

  • +
  • This file holds code +for the playback driver channel together with code which is common to both +channels.

    ...\template\template_variant\specific\soundsc_tx.cpp

  • +
+

The header file for the above can be found in:

+

...\template\template_variant\inc\soundsc_plat.h

+

The template .mmp file can be found in:

+

...\template\template_variant\soundsctemplate.mmp

+

Following the general pattern, your implementation is contained in the +directory:

+

path to your variant\specific

+

For example, ...\omap_hrp\h4\specific

+

Now complete these steps:

+
    +
  • create a copy of the +template port implementation files soundsc_rx.cpp and soundsc_tx.cpp, +copy them into your variant specific directory

  • +
  • create a copy of the +header file soundsc_plat.h, copy it to the include directory +for your variant

  • +
  • rename the Sound Driver +PDD factory class DTemplateSoundScPddFactory, to reflect +the name of your device

  • +
  • rename the classes DTemplateSoundScRxPdd and DTemplateSoundScTxPdd to reflect the name of your device.

  • +
+

You should also be prepared to add your own private data and functions +to the Sound Driver.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-C74770A5-ADD4-4AB1-946F-77105E2B8C10-GENID-1-2-1-10-1-5-1-5-1-1-7-1-9-1-6-1.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-C74770A5-ADD4-4AB1-946F-77105E2B8C10-GENID-1-2-1-10-1-5-1-5-1-1-7-1-9-1-6-1.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,167 @@ + + + + + +DMA Request OperationsDescribes the operations which a device driver performs +on a DMA request. +

After doing the required DMA initialisation, a driver can start +a DMA operation. To do this, the driver fragments the request and +then queues the request.

+
Fragment

A DMA request must be split into different fragments that are +small enough to be transferred by the DMAC in a single transaction. +The size of each fragment is smaller than or equal to the maximum +transfer size supported by the DMAC. To fragment a DMA request, a +source and destination address, and the size of data to be transferred, +must be provided. If the source and/or destination is in memory, each +fragment points to memory which is physically contiguous.

The kind of transfer to perform is specified using a set of flags +and hardware-specific information. The flags can be:

+ + + +

KDmaMemSrc

+

Source is the address of a memory buffer

+
+ +

KDmaMmeDest

+

Destination is the address of a memory buffer

+
+ +

KDmaIncSrc

+

Source address must be post-incremented during transfer

+
+ +

KDmaIncDest

+

Destination address must be post-incremented during transfer

+
+ +

KDmaPhysAddrSrc

+

Source address is a physical address (as opposed to a linear +one)

+
+ +

KDmaPhysAddrDest

+

Destination address is a physical address (as opposed to +a linear one)

+
+ + +

The following shows an example of fragmenting a DMA request:

/** + Start the DMA transfer. This function fragments the DMA request and + queues it for processing and actually triggers the DMA transfer. + + @param aSource + Source address for DMA transfer + + @param aCount + Size of data to be transferred + + @return KErrNone on success, else standard error code on failure + */ +TInt DExDriverUartTxDma::Start(const TUint8* aSource, TInt aCount) + { + ... + // Fragment the DMA request. DDmaRequest::Fragment() creates + // the DMA descriptor with source, destination address, size + // and attributes. + // + // Flags KDmaMemSrc|KDmaIncSrc or KDmaMemDest|KDmaIncDest + // should be set if the source/destination is a memory buffer, + // or cleared if the source/destination is a peripheral. If the address + // specified is physical address instead of linear, + // then specify KDmaPhysAddrSrc or KDmaPhysAddrDest accordingly. + // + TInt retval = iTxDmaRequest->Fragment((TUint32)buf, + (TUint32)(iUartComm->iPortAddr + KHoUART_THR), aCount, + KDmaMemSrc |KDmaIncSrc, // source is a buffer + 0 ); // no HW Flags + if(retval != KErrNone) + { + return retval; + } + ... + }
+
Queue

DMA transfer is initiated by queuing the DMA request. A device +driver queues the request by calling DDmaRequest::Queue() after fragmenting the DMA request. This is an asynchronous call +and the transfer of DMA will actually start once the request is scheduled.

/** + Start the DMA transfer. This function fragments the DMA request and + queues it for processing and actually triggers the DMA transfer. + @param aSource Source address for DMA transfer + @param aCount Size of data to be transferred + @return KErrNone on success, else standard error code on failure + */ +TInt DExDriverUartTxDma::Start(const TUint8* aSource, TInt aCount) + { + ... + + // Queue the DMA request. DDmaRequest::Queue() queues the + // request on the DFCQ. DMA operation starts at this point. + // + iTxDmaRequest->Queue(); + + ... + }

If the request channel is idle when a request +is queued, the request is transferred immediately. Otherwise, it is +queued and transferred later. The client is responsible for ensuring +cache consistency before and/or after the transfer if necessary.

+
Completion +notification

This is done by the DMA service callback function. +The completion notification is as follows:

Once the DMA request +is handled by the DMAC, the DMA service callback function is called +by the DMA driver. This runs in a DFC context, that is scheduled from +a DMA interrupt service routine.

The DMA service callback +function pointer must be provided while creating the DMA request:

iTxDmaRequest = new DDmaRequest(*iTxDmaChannel, TxDmaService, this);

The DMA callback function is called for both success and failure +of the request, so it needs to check the request result. On success, +the function should either initiate another DMA request, or stop DMA +and close the request. On failure, the function should stop DMA.

/** + DMA service callback function for transmit. This static function is + called on the completion of DMA transfer request. This function + pointer is provided while creating the DMA request, i.e. in + DDmaRequest(). After the request is queued, the System DMA controller + completes the request and calls this service function. Here, we do + the processing that needs to be done post the DMA request + completion. + + This function shall be called both when the DMA request succeeds or fails, + so both must be handled appropriately. + + @param aResult + DMA result, can be DDmaRequest::EOk in case of success, else error + + @param aArg pointer passed at time of registration, typically <this> + pointer + + @return none + */ +static void TxDmaService(DDmaRequest::TResult aResult, TAny* aArg) + { + // Check the result of DMA service function call. It can be + // either of the DDmaRequest::TResult enumerated values. + // + if ( aResult != DDmaRequest::EOk) + { + // DMA request failed, so stop the DMA. + Stop (); + + // Notify request completion with an error result + ... + } + else + { + // DMA request was successful. + // The program can start another DMA request, or stop + // the DMA, if no more DMA requests are needed. + // Notify request operation complete with success. + ... + } + }
+
+DMA +Requests +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-C74770A5-ADD4-4AB1-946F-77105E2B8C10-GENID-1-2-1-9-1-6-1-8-1-7-1-6-1.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-C74770A5-ADD4-4AB1-946F-77105E2B8C10-GENID-1-2-1-9-1-6-1-8-1-7-1-6-1.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,167 @@ + + + + + +DMA Request OperationsDescribes the operations which a device driver performs +on a DMA request. +

After doing the required DMA initialisation, a driver can start +a DMA operation. To do this, the driver fragments the request and +then queues the request.

+
Fragment

A DMA request must be split into different fragments that are +small enough to be transferred by the DMAC in a single transaction. +The size of each fragment is smaller than or equal to the maximum +transfer size supported by the DMAC. To fragment a DMA request, a +source and destination address, and the size of data to be transferred, +must be provided. If the source and/or destination is in memory, each +fragment points to memory which is physically contiguous.

The kind of transfer to perform is specified using a set of flags +and hardware-specific information. The flags can be:

+ + + +

KDmaMemSrc

+

Source is the address of a memory buffer

+
+ +

KDmaMmeDest

+

Destination is the address of a memory buffer

+
+ +

KDmaIncSrc

+

Source address must be post-incremented during transfer

+
+ +

KDmaIncDest

+

Destination address must be post-incremented during transfer

+
+ +

KDmaPhysAddrSrc

+

Source address is a physical address (as opposed to a linear +one)

+
+ +

KDmaPhysAddrDest

+

Destination address is a physical address (as opposed to +a linear one)

+
+ + +

The following shows an example of fragmenting a DMA request:

/** + Start the DMA transfer. This function fragments the DMA request and + queues it for processing and actually triggers the DMA transfer. + + @param aSource + Source address for DMA transfer + + @param aCount + Size of data to be transferred + + @return KErrNone on success, else standard error code on failure + */ +TInt DExDriverUartTxDma::Start(const TUint8* aSource, TInt aCount) + { + ... + // Fragment the DMA request. DDmaRequest::Fragment() creates + // the DMA descriptor with source, destination address, size + // and attributes. + // + // Flags KDmaMemSrc|KDmaIncSrc or KDmaMemDest|KDmaIncDest + // should be set if the source/destination is a memory buffer, + // or cleared if the source/destination is a peripheral. If the address + // specified is physical address instead of linear, + // then specify KDmaPhysAddrSrc or KDmaPhysAddrDest accordingly. + // + TInt retval = iTxDmaRequest->Fragment((TUint32)buf, + (TUint32)(iUartComm->iPortAddr + KHoUART_THR), aCount, + KDmaMemSrc |KDmaIncSrc, // source is a buffer + 0 ); // no HW Flags + if(retval != KErrNone) + { + return retval; + } + ... + }
+
Queue

DMA transfer is initiated by queuing the DMA request. A device +driver queues the request by calling DDmaRequest::Queue() after fragmenting the DMA request. This is an asynchronous call +and the transfer of DMA will actually start once the request is scheduled.

/** + Start the DMA transfer. This function fragments the DMA request and + queues it for processing and actually triggers the DMA transfer. + @param aSource Source address for DMA transfer + @param aCount Size of data to be transferred + @return KErrNone on success, else standard error code on failure + */ +TInt DExDriverUartTxDma::Start(const TUint8* aSource, TInt aCount) + { + ... + + // Queue the DMA request. DDmaRequest::Queue() queues the + // request on the DFCQ. DMA operation starts at this point. + // + iTxDmaRequest->Queue(); + + ... + }

If the request channel is idle when a request +is queued, the request is transferred immediately. Otherwise, it is +queued and transferred later. The client is responsible for ensuring +cache consistency before and/or after the transfer if necessary.

+
Completion +notification

This is done by the DMA service callback function. +The completion notification is as follows:

Once the DMA request +is handled by the DMAC, the DMA service callback function is called +by the DMA driver. This runs in a DFC context, that is scheduled from +a DMA interrupt service routine.

The DMA service callback +function pointer must be provided while creating the DMA request:

iTxDmaRequest = new DDmaRequest(*iTxDmaChannel, TxDmaService, this);

The DMA callback function is called for both success and failure +of the request, so it needs to check the request result. On success, +the function should either initiate another DMA request, or stop DMA +and close the request. On failure, the function should stop DMA.

/** + DMA service callback function for transmit. This static function is + called on the completion of DMA transfer request. This function + pointer is provided while creating the DMA request, i.e. in + DDmaRequest(). After the request is queued, the System DMA controller + completes the request and calls this service function. Here, we do + the processing that needs to be done post the DMA request + completion. + + This function shall be called both when the DMA request succeeds or fails, + so both must be handled appropriately. + + @param aResult + DMA result, can be DDmaRequest::EOk in case of success, else error + + @param aArg pointer passed at time of registration, typically <this> + pointer + + @return none + */ +static void TxDmaService(DDmaRequest::TResult aResult, TAny* aArg) + { + // Check the result of DMA service function call. It can be + // either of the DDmaRequest::TResult enumerated values. + // + if ( aResult != DDmaRequest::EOk) + { + // DMA request failed, so stop the DMA. + Stop (); + + // Notify request completion with an error result + ... + } + else + { + // DMA request was successful. + // The program can start another DMA request, or stop + // the DMA, if no more DMA requests are needed. + // Notify request operation complete with success. + ... + } + }
+
+DMA +Requests +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-C8217A7B-D741-5452-B95B-57B8978AD152.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-C8217A7B-D741-5452-B95B-57B8978AD152.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,301 @@ + + + + + +ValidationSymbian platform provides test code that you can run to +validate a USB client port. This topic describes the USB client test +code. +
Requirements

For testing the port, you will need:

    +
  • A Symbian platform +text shell ROM image for the device that also contains the USB drivers +(the LDD and the PDD), and the unit test applications T_USB and T_USBAPI. On a slow CPU you may need to use release (UREL) +versions of the driver binaries to avoid exceeding the time-out limits +of the USB protocol.

  • +
  • A computer running +either MS Windows 98 or above to run the Symbian host-side +test program USBRFLCT, or MS Windows 2000 to run, in addition, the USB Command Verifier (USBCV) R1.2.1 compliance test program. +On MS Windows XP you will also be able to run the USBCV R1.3 compliance +test program.

  • +
  • A USB driver +disk (or some other location accessible to the PC) containing the .inf file that matches the device to be tested, and the +driver binary file that will be installed for the device. Note that +for USBRFLCT, both items are included in the binary program distribution.

  • +

In addition, a USB analyser, like the ones made by LeCroy formerly CATC, is invaluable for this kind of work. Without this +equipment it may be impossible to be sure that the port has been fully +successful.

+
Test +steps

These are the recommended steps for testing the port:

    +
  • Run T_USBAPI on the unconnected USB device and get it to pass.

  • +
  • Use a USB cable +to connect the device under test to a PC and start T_USB on the device (use T_USB menu options '0','1','1' and +'1'). See if the device successfully delivers all the information +(descriptors) that the host asks for. If so, a dialogue box pops up +on the PC, saying “New hardware found” and offering certain options. +Point the OS to the location of the .inf files +and the driver files (the USB driver disk) and have it pick and install +the correct driver. Afterwards you should see the new USB device in +the Windows Device Manager under the category Symbian platform +controlled USB devices as USBRFLCT - Device. If things +don’t work as expected at this early stage, the USB analyser will +prove invaluable.

  • +
  • Try and run USBRFLCT and T_USB together. First start T_USB on the device, choose the +four numbered program options (but this time the first menu option +must not be '0'), and then start USBRFLCT on the PC. The program pair +should run indefinitely, in any mode. If the program halts after a +while then this almost certainly indicates either a hardware problem +associated with the USB device controller or an incorrect handling +of the controller in the PSL. If the halt occurs after a long time, +then this could point to a resource problem, such as a memory leak. +This test will verify that at least one bulk IN endpoint and one bulk +OUT endpoint are working correctly, and that data can be transferred +over the USB link.

  • +
  • Run the USB +Implementers Forum's USBCV compliance test suite and go through the “Chapter 9 +Tests”. You will first need to start T_USB on the device end, as USBCV needs a successfully enumerated device as a target (choose +'0' as the first T_USB option). These tests should all pass. It is +important to run USBCV to verify that endpoint-0 is behaving correctly, and +that the device is compliant with the USB Specification 2.0.

  • +
+
The +USBIO driver

The host (PC) side test program: USBRFLCT uses the services of a USB client driver, USBIO.SYS. This driver is loaded by the OS as part of +the enumeration once the USB device on test is connected to the PC.

The generic USB device driver USBIO is a product developed and +marketed by the German company Thesycon [USBIO Software Development +Kit for Windows; see http://www.thesycon.de/usbio/eng/usbio.htm].

The driver +provides Win32 applications with direct access to USB devices which +are otherwise only accessible from kernel-mode. It can be used with +any kind of USB device, enabling application developers to control +devices without having to develop a kernel-mode WDM driver. Symbian +owns a licence to the driver and its development package, and is entitled +to ship renamed copies of the driver binary to licensees and partners +as part of its own development kits, usually adopting the name of +the application that uses it.

+
T_USBAPI

This is a device-side only, stand-alone test program. It is used +to verify the proper working of some basic USB API functionality. +For T_USBAPI to run, the device doesn’t need to be USB-connected to +a PC although if it is then some additional tests are performed. Tests +run by T_USBAPI include:

    +
  • loading the +USB LDD and opening a channel

  • +
  • searching for +suitable endpoints and setting up an interface

  • +
  • searching for +suitable endpoints and creating an 'alternate setting' for that interface +(if supported).

  • +
  • querying and +allocating endpoint resources (DMA and double buffering)

  • +
  • powering up +the UDC and connecting it to the bus.

  • +
  • manipulating +(modifying) USB descriptors (Device, Device_Qualifier, Configuration, +Other_Speed_Configuration, Interface, Endpoint, String)

  • +
  • testing the +USB OTG API extensions

  • +
  • requesting and +releasing Device Control

  • +
  • some static +state notification tests (alternate device status, endpoint status).

  • +
  • setting and +clearing endpoint Halt condition (where supported in unconfigured +state)

  • +
  • closing the +channel and freeing the LDD

  • +

Most of these tests verify the functioning of the platform-independent +code (i.e. platform-independent layer + LDD). However, some of this +code relies on platform-specific layer functionality, such as the +stall state and the maximum packet size of endpoints. Therefore, a +working, or a partially working platform-specific layer is required +for T_USBAPI to pass.

When called normally, T_USBAPI runs +once and then exits. It can also run endlessly in a loop, provided +it is not failing, by adding the parameter soak to the command +line. Once the program is running in endless mode, it can be stopped +at any time by pressing the Esc key, in which +case the program finishes the current set of tests and then exits. +This loop mode can be useful for the detection of memory leaks in +the USB stack, although the main functionality exercised lies in the +platform-independent layer and the LDD, not in the platform-specific +layer.

T_USBAPI is a standalone program which can be safely +run on a UDEB image. Choose to display error messages and warnings +specific to the USB components using the appropriate kernel debug +flags (KPANIC, KUSBPSL and KUSB). The following example shows the E32 shell commands +to set KPANIC, KUSBPSL and KUSB in that order:

C:\>trace 80000000

C:\>trace 3 1

"trace 3 1" +means "set (bit 1|bit 0) at index 1" (KUSBPSL=33, KUSB=32)

+
USBRFLCT +and T_USB

These are the host and device side parts, respectively, +of a reflector-like USB test program. They are normally used together, +but T_USB can also be used to create a simple USB device to allow +USBCV to execute.

Since this program suite is subject to continual development + and improvement, in order for them to work properly together, +both parts must always come from the same Symbian platform +delivery.

To ensure proper internetworking, USBRFLCT and T_USB exchange their version numbers after startup, and either +program will quit if the other does not provide a suitable minimum +version number.

USBRFLCT

This is the host-side part of a reflector-like USB test program. +This is normally used together with T_USB, the device-side part.

The directory ...\e32test\win32\usbrflct\ contains its source code.

The directory ...\e32test\win32\usbrflct_distribution\ contains a binary distribution of the program, including the USBRFLCT.SYS driver and a USBRFLCT.INF file for the installation of the driver.

The syntax for +invoking this is:

usbrflct [options]

where options can be one of the following:

+ + + +

/[r|t]

+

receive|transmit only; default is to loop with statistics +printed every 1024th iteration

+
+ +

/l

+

loop mode with statistics printed for every iteration

+
+ +

/v

+

verbose driver & program output

+
+ +

/[h|?]

+

displays this help text

+
+ + +

Three modes of operation are available:

    +
  • Loop mode.

    Data chunks are read from the USB device and then immediately +written back to it. Successive data chunks are read, each being one +byte larger than the one before, starting with size 0 until a specified +maximum size has been reached. This maximum size value is specified +on the device using T_USB. After the maximum size has been reached, the size of +the data chunk is reset back to its starting value.

    A preamble +packet is sent by the device before each data chunk, containing the +size of the chunk that is to follow. This kind of protocol is necessary, +because the host side driver has to specify the exact number of bytes +that it needs to read from the device.

    Every 1024th loop, +the program displays statistics about the test run. For example, the +total number of bytes transferred, and the current average data throughput +in bytes/sec.

  • +
  • Receive-only +mode.

    In this mode, a single preamble packet containing the +size of the data chunks that are to follow is sent from the device. +The host-side program subsequently, and continuously, reads data chunks +of that size from the device. This mode can be used to determine the +raw transfer performance of the USB connection in the device upstream +direction.

  • +
  • Transmit-only +mode.

    In this mode, no preamble packet is sent. Instead, maximum +(constant) sized data chunks are sent. This mode can be used to determine +the raw transfer performance of the USB connection in the device downstream +direction.

  • +
  • Verbose mode.

    In this mode, the driver and program output are both displayed. +Use this to track down problems that occur when trying to get USBRFLCT and T_USB to work together. This may help in the following circumstances:

      +
    • the first time +you test a port of the platform specific layer

    • +
    • after installation +changes on the PC

    • +

    The error messages are particularly helpful, a list of error +codes together with explanations for the USBRFLCT.SYS driver can be +found in the USBIO Reference Manual. These codes are also available +on Thesycon's website at http://www.thesycon.de/usbio/usbioman.pdf. Do not use this +mode during loop or throughput testing to avoid program slowdown which +could affect these tests.

  • +

T_USB

This is the device-side part of a reflector-like USB test program. +This is normally used together with USBRFLCT, the host-side part.

The source for this +program can be found in:

    +
  • ...\e32test\device\t_usb.h

  • +
  • ...\e32test\device\t_usb.cpp

  • +
  • ...\e32test\device\t_usbco2.cpp

  • +

After starting the program, you are prompted to choose a +maximum size for a single transfer.

Note: The maximum +transfer size is not the same as the maximum packet size.

The prompt appears as follows:

++++Choose max +transfer size++++

'0' - Set up USB +device for USBCV

'1' - 32 bytes

'2' - 1024 bytes

'3' - 64 kbytes

'4' - 1 Mbyte

Once you have chosen the maximum transfer size you are prompted +to choose a bandwidth priority for the interface that will be created +and used for the tests. All options except '0' are used when T_USB is run together with USBRFLCT. The program carries out dynamic version number checking +of the two programs to ensure compatibility . Option '0' sets up a +static USB device that can be used to perform other tests, including +compliance testing with USBCV. This option also circumvents dynamic version checking. +Most of the other menu options have no meaning in this mode.

Choose a bandwidth priority from the following menu for the interface +specifically created for the tests. All tests will be carried out +over this interface.

++++ Choose Bandwidth Priority +++++

'1' - Economical buffering - default

'2' - More memory than default buffering - Plus1

'3' - More memory than Plus1 buffering - Plus2

'4' - Maximum memory for buffering

Choose endpoint options from the following two configuration +menus:

++++ Choose Endpoint I/O Transfer Mode ++++

'1' - Interrupt Mode

'2' - DMA Mode (recommended)

++++ Choose Endpoint FIFO Mode ++++

'1' - Normal Buffering Mode

'2' - +Double Buffering Mode (recommended)

A message +prompts the user to start the host side test program USBRFLCT.

Once host enumeration +and USBRFLCT configuration completes, the program's main menu +is displayed as follows:

++++ Select Program Option +++++

'L'oop test

Loop test with data 'C'ompare

'R'eceive-only test (we receive, host transmits)

'T'ransmit-only test

Receive and 'P'ut (write) to File

Transmit and 'G'et (read) from File

Signal Remote - 'W'akeup to the host

'S'top current transfer

Re'E'numerate +device

'Q'uit

Choose +one of the six main test modes. The selected mode should correspond +with the mode in which the host-side program is running. For example, +device-side Receive matches host-side Transmit.

The Loop test with Compare is just like +the normal Loop, except that the received data is +compared with the data that was previously sent, allowing any transmission +errors to be detected. The purpose of the non-comparing mode is performance +(throughput) assessment of the USB link, in this mode the slow down +of the application introduced by the byte-by-byte checking of the +compare operation is not desirable. Note: The non-comparing mode does +do some checking, specifically it compares the received transfer number +(4 bytes at the start of each buffer) against the expected value.

The standard 'Receive-only' test mode R immediately discards the data received, similarly the standard 'Transmit-only' +mode T creates random data on the fly to send +to the device. These tests are useful for checking the maximum throughput +of the link, however they do not reflect normal usage. In a real world +scenario, transmitted data would be read from a file and received +data would be written to a file.

There are two further tests +which include file I/O. These are:

    +
  • 'Receive' mode P, where data received from the link is written to a +newly created file.

  • +
    +
  • 'Transmit' mode G, where data is read from a newly created file and sent +across the link.

  • +

In both cases you must first enter a source or destination +from the list of available drives.

S stops an ongoing transfer at any time

W issues a Remote Wake-up signal to the host; this is needed, for +example, when running USBCV.

E re-enumerates the +USB device by first disconnecting it from, and then reconnecting it +to the bus.

ESC or Q quits the program after tearing down the device configuration and +freeing all used resources.

+
USBIOAPP

Thesycon provide this Win32 GUI application. Like USBRFLCT it works on top of the USBRFLCT.SYS driver (otherwise known as USBIOAPP.EXE). The +source code for this program is part of the USBIO development kit. +You can find the compiled executable USBIOAPP.EXE in the same directory as USBRFLCT and the host side drivers: ...\e32test\win32\usbflct_distribution\.

Use USBIOAPP to exercise and test the low-level functionality +of an attached USB device. In this case, the Symbian platform device +running the USB device stack which includes the port of the platform-specific +layer.

The following steps describe an example test:

    +
  • Connect the +Symbian platform USB device to a PC on which the USBRFLCT driver has been installed.

  • +
  • Start T_USB on the device to create a USB device (use option '0' +for the transfer size).

  • +
  • Launch USBIOAPP on the PC.

  • +
  • Press the Scan for USBIO devices button. The device should be detected +by USBIOAPP.

  • +
  • Test and exercise +the USB device using the different options provided by the USBIOAPP program.

  • +

Further details can be found in the USBIO manual, which contains +a chapter on the USBIOAPP. See http://www.thesycon.de/usbio/usbioman.pdf

+
USB +Command Verifier (USBCV)

This test program is written and +maintained by the USB Implementers Forum, Inc, (also referred to as +the “USB Forum” or “USB IF”). It can be used to check compatibility +of the USB device with the USB specification (currently version 2.0). +It contains a collection of different test suites, but the only tests +that are of interest regarding the platform-specific layer port are +the “Chapter 9 Tests”. Even though most of the "Chapter 9" request +processing is done by the platform-independent layer, the tests can +help to uncover potential problems with endpoint-0 controlling platform-specific +layer code. The tests will also show whether or not the platform-specific +layer and the platform-independent layer work together without problems.

This program runs on Windows 2000 and Windows XP (English Version) +only. At the time of writing, the version of the package is R1.2.1, +and can be obtained from http://www.usb.org/developers/tools/USBCV121.msi.

+
USBMSAPP +(USB Mass Storage Application)

This is not a dedicated +test program, but it can be used to check that the USB driver stack +is operating correctly. Since it is not a test program USBMSAPP is +not normally included in ROMs with any of the ...\e32tests\f32tests\alltests +rom.bat options. The source can be found ...\e32ustils\usbmsapp\. If you want to include it, use the command line macro below.

Note: Add this macro to \e32\rombuild:

rom --variant=h4hrp --inst=armv5 --build=urel +--type=alltests --symbol --define=ROMOPT_USBMSAPP --name=H4HRPARMV5.IMG

Start the program from the command prompt with a drive letter +as a parameter:

C:\> usbmsapp d:

This mounts the specified drive with the Mass Storage file system +('MSFS'). Check that you can see it as a Read/Write disk drive on +the USB host computer. The drive name on the host computer will be +the first free drive letter available.

Note: You +can only mount drives marked as 'removable' as USB Mass Storage devices. +The C: drive cannot be marked as 'removable'. Internal drives made +available for USB Mass Storage must be marked as 'removable' for reasons +of platform security.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-C8450E58-A603-5CF8-993E-053C990DDA19-master.png Binary file Adaptation/GUID-C8450E58-A603-5CF8-993E-053C990DDA19-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-C8450E58-A603-5CF8-993E-053C990DDA19_d0e9181_href.png Binary file Adaptation/GUID-C8450E58-A603-5CF8-993E-053C990DDA19_d0e9181_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-C8DF0CB0-92F4-5F9E-A8F1-7DE50954C4F1.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-C8DF0CB0-92F4-5F9E-A8F1-7DE50954C4F1.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,37 @@ + + + + + +Debugging +the PRMThis document describes how to debug the PRM using internal macros. +
Purpose

Use the provided KTrace and BTrace macros +to debug your PRM implementation.

Introduction

These +kernel services allow you to generate and capture trace information in a manner +designed to minimise the impact on a running system.

+
Using KTrace

Use the KTRACE macro +with KRESMANAGER for debug print messages in the code.

__KTRACE_OPT(KRESMANAGER,Kern::Printf(">DH4PowerResourceController::DoInitController\n”))
+
Using the kernel +trace tool

The BTRACE category, TCategory::EResourceManager, +and a number of sub categories are defined and used to trace the progress +of all operations on the PRM. All tracing sub categories are wrapped with +a macro definition. Implement macro definitions in e32\include\drivers\rescontrol_trace.h to +replace BTrace with other tracing methods.

+
+Porting the +Power Resource Manager +Implement +the controllable power resources +Implement +the PSL for the target +Port client +drivers to use the PRM +Testing the +PRM PSL +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-C92CC81A-35A1-5860-AA08-C8C08B39804C.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-C92CC81A-35A1-5860-AA08-C8C08B39804C.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,96 @@ + + + + + +Boot +Table MMU Permission and Cache Attribute DefinitionsLists MMU attributes that the bootstrap implementation must provide. +

The definitions are summarised in the following table. Each entry type +is identified by its TBootTableEntry enumerator value that +defines its position within the table. This group of entries always follows +the function entries.

+ + + + +

Enumerator symbol

+

Summary description

+
+ +

BTP_Rom

+

Defines permissions for XIP ROM areas, including RAM used as ROM.

+
+ +

BTP_Kernel

+

Defines permissions for kernel data, initial kernel stack and initial +kernel heap.

+
+ +

BTP_SuperCPU

+

Defines permissions for super page and CPU page.

+
+ +

BTP_PageTable

+

Defines permissions for page directory and page tables.

+
+ +

BTP_Vector

+

Defines permissions for ARM exception vector mapping.

+
+ +

BTP_Hw

+

Defines permissions for I/O mappings.

+
+ +

BTP_MiniCache

+

Defines permissions for mini cache flush area, if required.

+
+ +

BTP_MainCache

+

Defines permissions for main cache flush area, if required.

+
+ +

BTP_PtInfo

+

Defines permissions for page table info and, for the multiple memory +model, ASID info.

+
+ +

BTP_User

+

Defines permissions for user memory area in direct memory model.

+
+ +

BTP_Temp

+

Defines permissions for temporary identity mapping of code while +enabling MMU.

+
+ +

BTP_Uncached

+

Defines permissions for dummy uncached area mapping on moving or +multiple model and for identity RAM mapping on direct memory model.

+
+ + +
+

Each entry is defined using the BTP_ENTRY macro. See this macro for a detailed description of the syntax and meanings.

+

Take the template port, in os/kernelhwsrv/bsptemplate/asspandvariant/template_variant/bootstrap/template.s as +an example. The first two entries, at position BTP_Rom and +position BTP_Kernel in the boot table, follow the last function +entry at position BTF_EnableMMU within +the table. This gives the following code:

+BootTable + DCD DoWriteC ; output a debug character + ... + +IF CFG_MMUPresent + + BTP_ENTRY CLIENT_DOMAIN, PERM_RORO, CACHE_WTRA, 0 ; ROM + BTP_ENTRY CLIENT_DOMAIN, PERM_RWNO, CACHE_WBRA, 0 ; kernel data/stack/heap + ... + +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-C9644081-004E-5DA0-8133-A32EEA91EF5E.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-C9644081-004E-5DA0-8133-A32EEA91EF5E.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,180 @@ + + + + + +IIC SHAI Implementation Layer: Slave ChannelThis document explains how to implement a slave channel +in the SHAI implementation layer of IIC. +
Purpose

This document explains how to implement a slave channel in the +SHAI implementation layer of IIC.

Intended Audience

Base porting engineers.

Introduction

IIC buses (a term used in this document to represent serial inter-chip +buses that IIC can operate on) are a class of bus used to transmit +non time-critical data between components of a hardware system

+
Implementing +a slave channel

To implement the SHAI implementation layer +of an IIC channel as slave you must write a class extending DIicBusChannelSlave. You must implement certain pure virtual +functions of the parent class in the subclass. Those functions and +any other functions which you write in the subclass are called the +SHAI implementation layer. The functions inherited from the parent +class are called the Platform Independent Layer (PIL).

The +four functions you must implement are:

    +
  • DoCreate()

  • +
  • DoRequest()

  • +
  • ProcessData()

  • +
  • CheckHdr()

  • +

You must also provide the following functionality:

    +
  • From the constructor, +call the constructor of the base class DIicBusChannelSlave with arguments for bus type and duplex settings,

  • +
  • assign the channel +number (if you are using the IIC Controller) and channel ID, and

  • +
  • report events +signalled by the hardware by calling the NotifyClient() callback function with the appropriate trigger.

  • +

Your implementation of the SHAI implementation layer will +need to call functions of the PIL. You are restricted to using a certain +subset of these.

Implementing the Platform Specific Layer

Implementing DoCreate()

DoCreate() is the second phase constructor of your class. Implement it with +functionality including:

    +
  • If you are using +the IIC controller, set the channel number,

  • +
  • call the Init() method of the base class, and

  • +
  • set the iChannelId member to an ID to be returned to the SHAI implementation +layer, which will use it to create a channel ID which is unique with +respect to other opened slave channels.

  • +

Implementing DoRequest()

DoRequest() is the gateway function to the SHAI implementation layer. Implement +it with functionality including:

    +
  • configure the +interface,

  • +
  • set triggers +and initiate transfers, and

  • +
  • disable interrupts +in the event of an abort.

  • +

DoRequest() shall be called with an +argument representing one of various possible operations.

    +
  • The argument +is EAsyncConfigPwrUp when the client called the +client API with instructions to complete asynchronously. The SHAI +implementation layer should power up and configure the hardware and +then call ChanCaptureCallback() with the result +as argument.

  • +
  • The argument +is ESyncConfigPwrUp when the client called client +called the client API with instructions to complete synchronously. +The SHAI implementation layer should power up and configure the hardware +and return the result.

  • +
  • The argument +is EPowerDown when the client called client called +the client API. The SHAI implementation layer should disable the interrupts, +stop any ongoing or outstanding operations and stop or reset the hardware +to its initial state.

  • +
  • The argument +is ETransmit when the client called Iic::SetNotificationTrigger() with any of the transmit triggers as argument. The SHAI implementation +layer should initialize the hardware and set up transmission buffers. +In a typical implementation, if the transmission has not yet started +it should also fill up the transmit FIFO and enable interrupts to +prepare for transmission, but this is not necessary if the transmission +is ongoing and the argument ETransmit was passed +because of a transmit underrun.

  • +
  • The argument +is EReceive if the client called Iic::SetNotificationTrigger with any of the receive triggers as argument. The SHAI implementation +layer should initialize the hardware and set up receive buffers. In +a typical implementation, if the transmission has not yet started +it should also flush or fill the receive FIFO and enable interrupts, +but this is not necessary if the transmission is ongoing and the argument EReceive was passed because of a receive overrun.

  • +
  • The argument +is EAbort if the timer of the master activity has +expired. The SHAI implementation layer should stop the transfer by +disabling interrupts, stopping ongoing and outstanding operations +and resetting the hardware and return failure.

  • +

Implementing ProcessData()

The easiest way +to understand this, is to review the template port at \os\kernelhwsrv\bsptemplate\asspandvariant\template_assp\iic\iic_slave.

ProcessData() is the function called by +the platform independent layer in response to NotifyClient(). It has two arguments representing a trigger aTrigger and a callback aCb. You implement it to modify +the callback

    +
  • aTrigger, a trigger of class TInt, and

  • +
  • aCb, a callback of class TIicBusSlaveCallback.

  • +

You implement the function to update the callback according +to the value of the trigger.

    +
  • If the trigger +is a receive trigger, update the callback with the number of words +already received to the buffer by calling

    aCb->SetRxWords(numWordsReceived);
  • +
  • If the trigger +is a transmit trigger, update the callback with the number of words +already transmitted (moved to the hardware transmit FIFO) by calling

    aCb->SetTxWords(numWordsTransmitted);
  • +
  • Whether the +trigger is receive or transmit, update the trigger member of the callback +containing the accumulated event history by calling

    aCb->SetTrigger(trigger | aCb->GetTrigger());

    where trigger is one of the receive or transmit +triggers or EGeneralBusError.

  • +

Implementing CheckHdr()

Implement CheckHdr(). This is the function which is called if the +client tries to capture the channel. Implement it with the following +functionality:

    +
  • check if the +specified configuration is valid.

  • +

Using the Platform Independent Layer

You can +only use certain functions of the PIL. They provide functionality +which is generic to IIC buses. They are:

    +
  • DIicBusChannelSlave(). The constructor of the superclass DIicBusChannelSlave.

  • +
  • Init(). Initializes DIicBusChannelSlave.

  • +
  • ChanCaptureCallback(). Called with the error code when asynchronous channel capture has +completed in response to DoRequest(EAsyncConfigPwrUp).

  • +
  • NotifyClient(). Called to notify the PIL (which then notifies the client) that +a hardware event of the passed in type has occurred.

  • +
  • SetMasterWaitTime(). Sets the timeout for the master to respond after the transmission +has been started.

  • +
  • GetMasterWaitTime(). Gets the timeout for the master to respond after the transmission +has been started.

  • +
  • SetClientWaitTime(). Sets the client wait time within which it is expected to respond +with the next operation.

  • +
  • GetClientWaitTime(). Gets the client wait time within which it is expected to respond +with the next operation.

  • +

Implementing event notification

A slave channel +reports events on the hardware by calling the PIL function NotifyClient() to pass the following notifications under +the stated conditions.

    +
  • Pass ERxAllBytes if the transmission has stopped with all bytes +received.

  • +
  • Pass ETxAllBytes if the transmission has stopped with all bytes +transmitted.

  • +
  • Pass ERxUnderrun if the transmission has been stopped but the +receive buffer provided by the client is not full, indicating that +the master has sent less data than expected.

  • +
  • Pass ERxOverrun if the transmission has not been stopped but +the receive buffer provided by the client is full. The client should +respond to a receive overrun by

      +
    • providing new +receive buffer, and

    • +
    • resetting its +receive notification triggers for instance by calling SetNotificationTrigger(ERxAllBytes).

    • +

    To make this possible the SHAI implementation layer should +try to keep the receive hardware FIFO at the lowest possible level.

  • +
  • Pass ETxUnderrun if the transmission has not been stopped but +all the data in the transmit buffer provided by the client has been +transferred. The client should respond to a transmit underrun by

      +
    • providing new +transmit buffer, and

    • +
    • resetting its +transmit notification triggers for instance by calling SetNotificationTrigger(ETxAllBytes).

    • +

    To make this possible the SHAI implementation layer should +try to keep the transmit hardware FIFO at the highest possible level.

  • +
  • Pass ETxOverrun if the transmission has been stopped but not +all the data in the transmit buffer provided by the client has been +transferred. This indicates that the client specified a bigger buffer +for the transmission than the master needed to read from the slave.

  • +
  • Pass EGeneralBusError if a bus error has occurred, that is if +an interrupt signals a bus overrun or underrun indicating data corruption.

  • +
+
+IIC +SHAI Implementation Layer: Generic Considerations +IIC +SHAI Implementation Layer: Master Channel +Client +of Master Channel Tutorial +Client +of Slave Channel Tutorial +IIC +Concepts +I2C +Technology Guide +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-C98DF912-A903-4FDB-B27A-CC8E75E3E40F.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-C98DF912-A903-4FDB-B27A-CC8E75E3E40F.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,25 @@ + + + + + +The +Logical ChannelThis document describes how device driver code is accessed through +a logical channel. +
+

All interaction between user code and the driver code takes place +through a logical channel. On the user side, a channel is encapsulated by +a RBusLogicalChannel derived class; on the Kernel side, a +channel is encapsulated by a DLogicalChannelBase or a DLogicalChannel derived +class, constructed by the DLogicalDevice factory object.

+ Device driver logical channel classes + + +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-C9923DF3-8425-4EB4-8066-FB5A92A85F5B.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-C9923DF3-8425-4EB4-8066-FB5A92A85F5B.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,92 @@ + + + + + +Adaptation Process GuideAdaptation is the process of porting a platform on to a +new hardware configuration. The existing process requires developers +to write new hardware abstractions for any changes in the hardware +configuration. Platform services provide a simple standard interface +that reduces the adaptation time for a given hardware component. +
Hardware

A hardware component can be added to introduce a new feature or +create a new variant of an existing feature. Mobile phones are developed +with various form factors, a new variant is created for each form +factor.

A particular new piece of hardware may require several +platform services to be used to support all the functionality of that +hardware. A camera may provide photos and video streams and require +the use of a GPIO platform service to configure the camera resolution, +to set focal distance, or to trigger the shutter.

+Basic blocks of an adaptation + +
+
Platform +services

Platform services are intended to be platform agnostic +and aim to reduce the porting time of hardware adaptation from one +platform to other. Platform services can be broadly classified into +two categories:

    +
  1. Platform services +that provide a service to other platform services.

  2. +
  3. Platform services +that use various kernel services and other platform services to drive +a hardware component.

  4. +
+ Types of platform service + +

The adaptation developer should identify the platform services + required to implement the new hardware. Some platform services may +already be implemented for other hardware and so it may be a simple +matter of reusing another implementation with minor modifications +for your particular component.

+
Hardware +configurations

The adaptation will use certain hardware +configurations and some of the configuration parameters can be reused. +Reusable hardware configurations can be stored in a repository called +the Hardware Configuration Repository (HCR). The HCR allows the configurations +to be stored in the repository during various stages of the device +creation. The HCR platform service provides APIs to the kernel and +device drivers to read the values stored in the repository. For more +information, see the HCR Platform Service documentation.

+
Implementation

The adaptation developer needs to know the specifications to implement +a hardware on the device. The implementation process involves the +identification of other services that must be implemented to support +a hardware. The other services may be provided by other platform services, +kernel extensions or drivers of other hardware components.

+
Platform +service compliance

Once the hardware component is implemented, +the developer must ensure that the implementation conforms to the +relevant platform service compliance testing. If the test fails then +the adaptation code should be modified until the tests pass.

+
Adaptation +process

The adaptation process can be summarized as:

    +
  1. Identify the +hardware

  2. +
  3. Identify the +platform services required to implement the hardware component

  4. +
  5. Identify the +dependencies

  6. +
  7. Identify the +required interfaces to be implemented

  8. +
  9. Implement the +required interfaces

  10. +
  11. Build and test +the interfaces

  12. +
  13. Modify the implementation, +if required

  14. +
+Adaptation process flowchart + +
+
+What +is Adaptation? +What +is a Platform Service? +Platform +Services +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-CA788AFE-D425-4B72-B8A2-34D38A8C341B.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-CA788AFE-D425-4B72-B8A2-34D38A8C341B.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,43 @@ + + + + + +Device +Driver Writing Guide Quick StartConceptual information that a developer should know before creating +a device driver. +

A device driver is a program that controls a particular type of device +that is attached to a base port. Writing a device driver requires an in-depth +understanding of how the hardware and the software of a given platform function. +The Device Driver writing guide tells you what you need and how to create +a device driver.

+
    +
  • For information about the parameters needed to create a valid Symbian +platform device driver, see Minimal +Driver Requirements.

  • +
    +
  • For information about high-level implementation designs for your device +driver, see Design +Options.

  • +
    +
  • For information about how device drivers are implemented as logical +device drivers (LDDs) and physical device drivers (PDDs), see The +LDD/PDD Model.

  • +
    +
  • For information about organizing memory, managing data transfer across +memory boundaries and the data transfer between LDD and PDD, see Memory +Management.

  • +
    +
  • For information about the user-side requests to a driver and the synchronization +methods used by the driver, see User +Requests and Synchronization.

  • +
    +
  • For information about how device drivers use interrupts, see Interrupts .

  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-CAEDFD1D-ECA1-5A6F-9861-63B7BE24E9E4.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-CAEDFD1D-ECA1-5A6F-9861-63B7BE24E9E4.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,60 @@ + + + + + +ReferenceSummary of related documentation for the Local Media Subsystem. +
API Reference

Kernel +Architecture 2

+ + + +

Item

+

Header

+
+ +

DLocalDrive::TRequestId

+

locmedia.h

+
+ +

DMedia

+

locmedia.h

+
+ +

DMediaDriver

+

locmedia.h

+
+ +

DPrimaryMediaBase

+

locmedia.h

+
+ +

LocDrv

+

locmedia.h

+
+ +

SMediaDeviceInfo

+

locmedia.h

+
+ +

TLocDrvRequest

+

locmedia.h

+
+ +

TPartitionEntry

+

locmedia.h

+
+ +

TPartitionInfo

+

locmedia.h

+
+ + +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-CB0FC4F4-6DAB-4ADD-B044-0E8B9365B4D5.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-CB0FC4F4-6DAB-4ADD-B044-0E8B9365B4D5.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,12 @@ + + + + + +IIC TechnologyDescribes the technology that is used within IIC. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-CB3A8650-751C-4DAA-9408-7AEB3C7FD41A.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-CB3A8650-751C-4DAA-9408-7AEB3C7FD41A.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,13 @@ + + + + + +Minimal +Driver RequirementsThis section explains how to make a valid Symbian Platform driver. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-CC04A14B-A839-5613-820D-F1E65EB2DF7F.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-CC04A14B-A839-5613-820D-F1E65EB2DF7F.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,54 @@ + + + + + +MAKSYM/MAKSYMROFS +

MAKSYM/MAKSYMROFS tool is used to create a symbol file, which lists +the addresses of every global and exported function in the ROM. It +reads a log file to generate the symbol file. The log file contains +information about the contents of the ROM or ROFS image.

+

MAKSYM reads the log file which is created by ROMBUILD when building +a ROM image. MAKSYMROFS reads the log file which is created by ROFSBUILD +when building a ROFS image. The command syntax for MAKSYM and MAKSYMROFS +is the same.

+
MAKSYM +command syntax MAKSYM <logfile> [<outfile>] + + + +

<logfile>

+

This is the name of the log file generated by the ROMBUILD tool.

+
+ +

<outfile>

+

This is the name for the MAKSYM output file. If not specified, +it defaults to <ROMimagename>.symbol.

+
+ + +

By default, ROMBUILD produces a log file called ROMBUILD.LOG, which is passed to MAKSYM tool in the following +way:

MAKSYM rombuild.log

This +will generate an output text file (Symbolic information file) called <romimagename>.symbol.

The file contains all +the global variables along with their address and length. For example, +the start of EKERN.EXE looks like this:

From \Epoc32\Release\Misa\UREL\ekern.exe + +50003040 0094 _E32Startup +500030d4 002c ImpDma::Init1(void) +50003100 0004 ImpDma::Init3(void) +50003104 0008 ImpDma::MaxBlockSize(void) +

In this example, the function ImpDma::Init1() starts at address 0x500030d4 and is 0x2c bytes long.

Notes:

    +
  • If you are distributing +ROM images for testing, it is also useful to supply the symbolic information +file for that image.

  • +
  • If you re-build +the ROM image you must also rebuild the symbolic information file +using MAKSYM.

  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-CDB2DD00-482D-5AEA-AF89-064C8F904DD9.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-CDB2DD00-482D-5AEA-AF89-064C8F904DD9.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,29 @@ + + + + + +Set UpDescribes how to use the template port to start your port. +

There is a template DMA Framework consisting of the source file dmapsl.cpp, and the mmp file dma.mmp located in the directory ...\template\dma that +can be used as the starting point for your DMA PSL port. You need +to:

+
    +
  • Decide which +directory your DMA PSL and associated .mmp file +are to be stored in. You would normally choose the variant or the +ASSP directory.

  • +
  • Copy the template +framework into your chosen location. Be aware that the template dma.mmp file contains relative paths that must be updated.

  • +
  • Change the variant's bld.inf file to include a reference to your +mmp file.

  • +
+

The remainder of this porting guide refers to the implementation +of the DMA Framework for the template ASSP, which forms the basis +for the template reference board; the source file can be found in ..\template_assp\dmapsl.cpp and the mmp file in ...\template_assp\dma.mmp.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-CDDD8189-D532-5179-92F6-74264C2E3D81-master.png Binary file Adaptation/GUID-CDDD8189-D532-5179-92F6-74264C2E3D81-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-CDDD8189-D532-5179-92F6-74264C2E3D81_d0e35308_href.png Binary file Adaptation/GUID-CDDD8189-D532-5179-92F6-74264C2E3D81_d0e35308_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-CE9EA167-0594-5E61-9640-6B2B63A92EA7.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-CE9EA167-0594-5E61-9640-6B2B63A92EA7.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,14 @@ + + + + + +Code Paging +

Demand paging documentation related to code demand paging.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-CEA3343B-138E-4D6B-8E5F-A255C5C73376.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-CEA3343B-138E-4D6B-8E5F-A255C5C73376.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,16 @@ + + + + + +SHAI ImplementationAdaptation software providing a realization of the SHAI +Interface. The SHAI Implementation is also known as the Platform Specific +Layer (PSL). +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-CEDA0EFF-A1D4-53FE-9BF2-DB9AA857BCF5-master.png Binary file Adaptation/GUID-CEDA0EFF-A1D4-53FE-9BF2-DB9AA857BCF5-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-CEDA0EFF-A1D4-53FE-9BF2-DB9AA857BCF5_d0e3163_href.png Binary file Adaptation/GUID-CEDA0EFF-A1D4-53FE-9BF2-DB9AA857BCF5_d0e3163_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-CF252B09-335E-5831-94A6-0B16B64C5030-master.png Binary file Adaptation/GUID-CF252B09-335E-5831-94A6-0B16B64C5030-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-CF252B09-335E-5831-94A6-0B16B64C5030_d0e10851_href.png Binary file Adaptation/GUID-CF252B09-335E-5831-94A6-0B16B64C5030_d0e10851_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-CF710BE5-531D-4287-9002-39E7DE27FACA.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-CF710BE5-531D-4287-9002-39E7DE27FACA.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,14 @@ + + + + + +Device +DriverDevice Drivers provide a standard interface between Applications +and hardware. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-CFE0A4EB-845C-43B6-A732-AA155AFD99D6.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-CFE0A4EB-845C-43B6-A732-AA155AFD99D6.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,41 @@ + + + + + +User +Requests and SynchronisationThis document introduces user requests and synchronisation methods +used by device drivers. +
Types +of user request

User-side requests to a driver can be of +three types: synchronous, asynchronous, and cancellation of an asynchronous +request. User requests can be handled in two different ways, based on the +logical channel model used by the device driver. A channel implementation +is derived from either:

    +
  • DLogicalChannelBase: +the driver developer decides how a request is handled.

  • +
  • DLogicalChannel: +this is derived from DLogicalChannelBase, and implements +a basic mechanism for handling requests.

  • +

In the DLogicalChannel derived model, requests from +user threads to the driver are queued as messages and handled sequentially +by a single Kernel side DFC. This is the model described in this section. +More details on the differences between the models can be found inLogical +Channel documentation.

All requests from the user result in +a call to a single function DLogicalChannelBase::Request(). +In this function the driver determines the type of the request, i.e. synchronous, +asynchronous, or cancel, and implements handling of the requests.

+
+
Synchronisation +methods

A driver uses the following synchronisation methods.

    +
  • Deferred Function Calls
  • +
  • Timers
  • +
  • Generated Events
  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-D003030D-8506-4210-9194-7A3819205D68.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-D003030D-8506-4210-9194-7A3819205D68.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,29 @@ + + + + + +Hardware +RegistersThis document describes how device drivers use hardware registers. +

The +APIs to access hardware peripheral registers are provided by a Symbian base +port. For example, the base port for the OMAP 2420 provides the TOmap::SetRegister() and TOmap::GetRegister() functions +to access its peripheral controller registers. Peripheral drivers would generally +use these APIs. Some examples:

    +
  1. To set the UART LCR +register:

    TOmap::SetRegister8(iPortAddr+KHoUART_LCR, KHbUartLCRFifoConfig);
  2. +
  3. To get the UART MDR +register:

    TOmap::Register8(iPortAddr+KHoUART_MDR1)
  4. +
  5. To modify only the specified +bits of the register: here, the UART LCR register bit 6 is being set to 0 +(LCR[6] = 0)

    TOmap::ModifyRegister8(iPortAddr+KHoUART_LCR, + (TUint8)KHtUartLCRBreakEnable, + (TUint8)KSetNone);
  6. +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-D048E187-6B1C-5A80-9CD0-89CD10688C6F.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-D048E187-6B1C-5A80-9CD0-89CD10688C6F.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,27 @@ + + + + + +Keyboard +DriverA Keyboard Driver is a kernel extension that gets input +from keyboard hardware, and makes these events available to other +parts of the operating system and applications. This section describes +how to implement a driver for your phone hardware. +

A Keyboard Driver is platform-specific, and is implemented +by the base port. Symbian platform provides template code for a driver. +A base port must also implement a keyboard mapping library, which +is used by user-side components to translate the codes used for hardware +keys into logical key codes.

+
+Key + Codes +Window + Server Component +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-D089C2E9-1BE4-4B37-B8A8-21E5B2425E6C.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-D089C2E9-1BE4-4B37-B8A8-21E5B2425E6C.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,45 @@ + + + + + +SDIO +Technology GuideProvides information about the concepts and the uses of the SDIO +card. +
Purpose +

The Secure Digital Input/Output (SDIO) protocol is based on the SD +memory card protocols. The SDIO bus enables high speed data transfers between +the host and a card. The SDIO consumes low power and is efficient for use +in mobile devices. SDIO cards like SD cards use star topology that have dedicated +command and data signals. The purpose of the SDIO APIs is to enable easy porting +of the Symbian SDIO services for a particular SDIO controller.

+
+
Key concepts
    +
  • SDIO controller:

    is the executable that manages access to +the SDIO card hardware interface and provides an API for class drivers to +access SDIO card functions.
  • +
    +
  • Stack:

    handles multiple requests simultaneously. It internally +schedules the requests on to the bus and allocates the appropriate card to +transfer data accordingly.
  • +
    +
  • Session:

    sets up a session object to perform SDIO specific +command sequences.
  • +
    +
  • Register interface:

    allows single byte read/write operations +to a given register address together with the corresponding ones for multi-byte +access.
  • +
+
Typical Uses
    +
  • Powering up stack containing a single SDIO Card.

  • +
  • Sending a command to PSL.

  • +
  • Acquiring new cards into the SDIO stack.

  • +
  • Configuring an SDIO card.

  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-D0F5D40A-28D2-4A2E-9B40-180537E60F56.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-D0F5D40A-28D2-4A2E-9B40-180537E60F56.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,87 @@ + + + + + +Interrupt Client Interface GuideProvides information to handle and control interrupts in +the system. +

The purpose of this document is to describe interrupt specific +functions for the kernel side device drivers.

+
+ Interface classes + + + +API +Description + + + + +

Interrupt

+

Exports interrupt functionality to device +drivers and other kernel-side code

+
+ + +
+
Interrupt +class

The Interrupt class provides functions +for using interrupts. The Symbian platform defines this class and +the implementation for each of the functions is defined by at the +hardware level.

The Interrupt class provides the following functions.

+ + + +Function +Return Type +Description + + + + +

Interrupt:: Bind(TInt anId, TIsr anIsr, TAny* aPtr)

+

TInt

+

Associates the specified Interrupt Service Routine (ISR) +function with the specified interrupt Id.

+
+ +

Interrupt::Unbind(TInt anId)

+

TInt

+

Unbinds the ISR function from the specified interrupt Id.

+
+ +

Interrupt::Enable(TInt anId)

+

TInt

+

Enables the specified interrupt.

+
+ +

Interrupt::Disable(TInt anId)

+

TInt

+

Disables the specified interrupt.

+
+ +

Interrupt::Clear(TInt anId)

+

TInt

+

Clears the interrupt pending signal at the interrupt controller +hardware level.

+
+ +

Interrupt::SetPriority(TInt anId, TInt aPriority)

+

TInt

+

Changes the priority of the specified interrupt to the new +specified value.

+
+ + +
+
+Interrupt +Technology Guide +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-D1C5BB01-6780-41D6-B47B-43D4C983B0B6.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-D1C5BB01-6780-41D6-B47B-43D4C983B0B6.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,48 @@ + + + + + +API ExportThis document discusses how to export a device driver API. +

A driver can export its API to be used by other Kernel code by +using IMPORT_C in the declaration and EXPORT_C in the definition. +When the driver is built, these functions are exported to a .def file. The .def file is specific +to the platform to which the driver is built.

+// Kernel extension internal API +class DExController: public DBase + { + … + void MyExAPI(); + … + }; + +// Client interface API +class TExClientInterface + { + … + // static function being exported, this API will go into def file + // generated while building + IMPORT_C static void MyExAPI(); + … + }; + +// Global instance of the object +DExController *ExController = NULL; + +// Implementation of the kernel extension's exported function +EXPORT_C void TExClientInterface::MyExAPI() + { + … + ExController->MyExAPI(); + … + } +

Kernel extensions can also provide information to user programs +by setting attributes that can be read through the system HAL (Hardware +Abstration Layer) API. See Handler Implementation for more information on this.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-D1F7D21F-BA9D-482C-9B58-7C53A680145A.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-D1F7D21F-BA9D-482C-9B58-7C53A680145A.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,12 @@ + + + + + +DMAThis document introduces the Symbian platform DMA framework. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-D207C135-EF02-4D1A-A48C-4AB8C6703496.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-D207C135-EF02-4D1A-A48C-4AB8C6703496.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,41 @@ + + + + + +Device +Driver StructureThis document describes the structures used to implement device +drivers as LDDs and PDDs. +

Both LDDs and PDDs are DLLs.

+

They implement a specific interface that allows the kernel to initialise +them, and for user-side code to communicate with them.

+

An LDD must implement:

+
    +
  • A DLogicalChannel or DLogicalChannelBase derived +class, representing the logical channel, which handles user requests.

  • +
  • A DLogicalDevice derived +class, which provides a factory for the logical channel objects, called the +LDD factory.

  • +
  • A DLL entry point function +at ordinal 1, which constructs the LDD factory object.

    It is possible +that a device driver is also an extension, in which case the entry point will +also be used for extension initialisation.

  • +
+

A PDD must implement:

+
    +
  • A DBase derived +class representing the physical channel, which is the interface between the +logical device and the physical device.

  • +
  • A DPhysicalDevice derived +class, which provides a factory for the physical channel objects, called the +PDD factory.

  • +
  • A DLL entry point function +at ordinal 1, which constructs the PDD factory object.

  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-D2163920-D448-5BFC-B655-B654FD657A94.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-D2163920-D448-5BFC-B655-B654FD657A94.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,35 @@ + + + + + +Level +2 CacheLevel 2 cache is cache memory that is external to the microprocessor. +The kernel provides functions to perform operations on this cache. +

In general, the presence of Level 2 cache is transparent to device drivers. +The cache is physically indexed and physically tagged, and this means that +L2 cache is not affected by the remapping of virtual-to-physical addresses +in the MMU.

+

However, where data is being transferred using DMA, then cached information +in the data buffers involved in a DMA transfer must be flushed before a DMA +write operation, for example when transferring data from memory to a peripheral, +and both before and after a DMA read operation, for example when transferring +data from a peripheral into memory.

+

The kernel provides three functions for this:

+
    +
  • Cache::SyncMemoryBeforeDmaWrite()

  • +
  • Cache::SyncMemoryBeforeDmaRead()

  • +
  • Cache::SyncMemoryAfterDmaRead()

  • +
+

All three functions are defined and implemented as part of the Cache class, +defined in ...\e32\e32\include\kernel\cache.h.

+

See also DMA +buffers in the Device +Driver Tutorial.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-D291C9E9-5207-4B23-B287-C240464087B9.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-D291C9E9-5207-4B23-B287-C240464087B9.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,76 @@ + + + + + +The +PDD Entry Point and FactoryThis document describes how PDDs are created. +

A PDD +must define an entry point function using the macro DECLARE_STANDARD_PDD, +or DECLARE_EXTENSION_PDD in the case of kernel extensions. +This must create a PDD factory object derived from DPhysicalDevice:

DECLARE_STANDARD_PDD() + { + return new DerivedPhysicalDevice; + }

This factory object is created on the kernel heap. Its +purpose is to create the physical channel, if needed.

DPhysicalDevice is +derived from DObject, and is, therefore a reference-counting +object. It also means that DPhysicalDevice objects are given +a name, as these objects are always subsequently found by name. Names are +also used to identify those PDDs that can be used with a given LDD; they have +a name of the form x.y where x is the name +used by the LDD and y is PDD-specific.

An LDD indicates +that it requires an accompanying PDD by setting the LDD factory object member DLogicalDevice::iParseMask with +the KDeviceAllowPhysicalDevice flag. There are two ways that +a suitable PDD can be found:

    +
  1. A user can specify the +name of a PDD through the RBusLogicalChannel::DoCreate() protected +function:

    TInt DoCreate(const TDesC& aDevice, const TVersion& aVer, TInt aUnit, const TDesC* aDriver, const TDesC8* anInfo, TOwnerType aType=EOwnerProcess, TBool aProtected=EFalse);

    The user side passes a pointer to a descriptor containing the name of +the required PDD as the fourth argument. A PDD with that name must already +have been loaded, and its factory object created. The device driver framework +searches for a PDD factory object with that name, and if found, calls Validate() on +that object; if this function returns KErrNone, then the +PDD is accepted as the required PDD.

  2. +
  3. If no explicit PDD name +is passed from the user side, then the device driver framework searches for +all PDD factory objects, i.e. DPhysicalDevice objects, +that have a name in the form x.y, where x is +the name of the LDD factory object. The device driver framework calls Validate() on +each matching PDD factory object, passing the unit number and the optional +extra information block; the first one to return KErrNone is +accepted as the required PDD.

  4. +

The file extension of a PDD DLL can be any permitted Symbian Platform +name but, by convention, the PDD DLL has the extension .PDD. +Device driver DLLs are polymorphic interface DLLs. When building PDDs, specify +a target type of pdd in the .mmp file.

A +PDD is loaded by calling User::LoadPhysicalDevice(). This +static function:

    +
  • loads the DLL into RAM, +if necessary

  • +
  • calls the exported function +at ordinal 1 to create the factory object, the DPhysicalDevice derived +object

  • +
  • places the factory object +into the appropriate object container.

  • +
This only needs to be done once, not every time the driver is +used.

If a PDD needs to perform initialisation at boot time (before +the driver is loaded by User::LoadPhysicalDevice()), then +specify the entry point macros DECLARE_STANDARD_EXTENSION and DECLARE_EXTENSION_PDD.

DECLARE_STANDARD_EXTENSION() + { + // initialise code here + } + +DECLARE_EXTENSION_PDD() + { + return new DMyPhysicalFactory; + }

In order for the kernel to initialise the PDD extension +at boot time then the .oby file must specify the extension keyword. +Also note that initialisation of the extension will not load the PDD - this +still has to be done through a call to User::LoadPhysicalDevice().

+
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-D2D41326-BA88-5A02-805B-5EAEC29ADB5D-master.png Binary file Adaptation/GUID-D2D41326-BA88-5A02-805B-5EAEC29ADB5D-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-D2D41326-BA88-5A02-805B-5EAEC29ADB5D_d0e19383_href.png Binary file Adaptation/GUID-D2D41326-BA88-5A02-805B-5EAEC29ADB5D_d0e19383_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-D34DB4A1-1B17-5FAF-A48B-E06D247B0A83.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-D34DB4A1-1B17-5FAF-A48B-E06D247B0A83.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,85 @@ + + + + + +Keyboard Mapping DLL Tutorial +

A keyboard mapping DLL provides a set of lookup tables that the +generic ektran.dll uses to convert scancodes +to keycodes. A keyboard mapping DLL is implemented in a base port.

+

The basic purpose of the tables is to provide a mapping from scancodes +to keycodes, so that, given a scancode, the corresponding keycode +can be found. The tables are organized so that there is, in effect, +one set of lookup tables for each likely combination of modifier key +states. ektran.dll compares the modifier keys +that have been pressed with the stored modifier key state combinations +to decide which set of lookup tables to use.

+

An outline set of tables is provided in the template port.

+

The following list outlines the structure of the tables.

+
    +
  1. The tables are +organized in a hierarchical structure. The start of this hierarchy +is the root table, defined by a SConvTable struct. +This contains:

      +
    • an array of +pointers to nodes, where each node is defined by the SConvTableNode struct. Each node corresponds to a specific combination of modifier +key states.

    • +
    • a field containing +the total number of such nodes.

    • +
    +Keyboard Mapping Table + +
  2. +
  3. The combination +of modifier key states that each node represents is encapsulated by +a TMaskedModifiers object. One of these objects +is embedded within each node.

    A TMaskedModifiers object consists of a mask, and a value for comparison. For example, +if an instance is set to the following:

    iMask = EModifierShift | EModifierCtrl | EModifierFunc +iValue = EModifierShift | EModifierFunc

    then a match +occurs only for the following combination of modifier key states:

    ctrl + shift + not Fn

    i.e. a match occurs only if ctrl and shift are pressed, and only if Fn is not pressed. Other modifier keys are ignored, +i.e. it does not matter whether or not they are pressed.

    In +C++ code, this is expressed as:

    inline TBool MatchesMaskedValue(TInt aModifiers,const TMaskedModifiers &aMaskedModifiers) + { + return (TBool)((aModifiers & aMaskedModifiers.iMask) == aMaskedModifiers.iValue); + }

    where aModifiers contains the +modifier key combination to be tested.

  4. +
  5. In principle, +each node represents scancode-to-keycode mappings by associating one +or more pairs (or range) of scancodes with corresponding blocks +of keycodes. Each pair represents an inclusive and contiguous range +of scancodes.

    Each pair (or range) of scancodes may be "discontiguous" +from the next.

    The association is made through a table defined +by the SConvSubTable struct. This has:

      +
    • a SScanCodeBlockList object that contains pointers to a number of SScanCodeBlock objects, each of which contains the start and end values defining +a range of scancodes.

    • +
    • a pointer to +a table containing the target keycodes. The target keycodes are arranged +so that successive scancode pairs are associated with successive blocks +of keycodes as the following diagram shows.

    • +
    +Target keycodes + +

    This means that successive scancodes, for example, from +"A1" through to "B1" are represented by the successive keycodes "keycode +for A1" through to "keycode for B1"; scancode "A2" is represented +by "keycode for A2", which follows "keycode for B1" in the keycode +table.

  6. +
  7. To allow for +possible reuse of keycode tables, a node can point to more than one SConvSubTable. The following diagram shows an example of +this:

    +Reusing keycode tables + +
  8. +
  9. If no keycode +can be found that matches the scancode, for a given modifier combination, +then the algorithm returns the EKeyNull keycode.

  10. +
+
See +also

Concepts

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-D43AB2F5-32AE-540C-80D8-DE8B2072F1E6-master.png Binary file Adaptation/GUID-D43AB2F5-32AE-540C-80D8-DE8B2072F1E6-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-D43AB2F5-32AE-540C-80D8-DE8B2072F1E6_d0e10612_href.png Binary file Adaptation/GUID-D43AB2F5-32AE-540C-80D8-DE8B2072F1E6_d0e10612_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-D477EB1F-89CF-5836-BAA2-6D731D50D99F.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-D477EB1F-89CF-5836-BAA2-6D731D50D99F.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,35 @@ + + + + + +ReferenceSummary of related documentation for the Sound Driver to which +you can refer. +
API Reference

Kernel +Architecture

+ + + +

Item

+

Header

+
+ +

RSoundSc

+

d32soundsc.h

+
+ +

DSoundScPdd

+

soundsc.h

+
+ + +
+
Engineering +Specifications

None published.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-D5030CC5-1FC1-40F3-9D68-4A454B25C58B-master.png Binary file Adaptation/GUID-D5030CC5-1FC1-40F3-9D68-4A454B25C58B-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-D5030CC5-1FC1-40F3-9D68-4A454B25C58B_d0e103563_href.png Binary file Adaptation/GUID-D5030CC5-1FC1-40F3-9D68-4A454B25C58B_d0e103563_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-D520CBC3-FCAC-5A53-AE1A-E5254ABBC6A2.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-D520CBC3-FCAC-5A53-AE1A-E5254ABBC6A2.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,18 @@ + + + + + +Symbian +platform Memory MapReference for users of the debug monitor tool to the Symbian platform +memory map for the moving memory model. +
Moving model + +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-D5ED62EB-744D-42EB-B8CF-D5623BDA5B38.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-D5ED62EB-744D-42EB-B8CF-D5623BDA5B38.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,107 @@ + + + + + +DMA Client Interface GuideExplains how to use the interface between the DMA platform +service and the Symbian platform. +

The DMA client interface specifies the connection between the Symbian +platform and the DMA platform service. This document describes how +to open and close a DMA channel along with how to use the DMA client +interface to perform a DMA transfer.

+
Interface +classes

The classes that process a DMA transfer are:

+ + + +

Name

+

Description

+
+ + + +

DDmaRequest

+

This class is used to handle transfer requests. It carries +out the configuration and initialization of the DMA transfer, along +with tracking the state of the transfer to the client. Communication +with the rest of the Symbian platform is carried out with the aid +of a callback function.

+
+ +

TDmaChannel

+

This class is used to open and close DMA channels.

+
+ + +

The steps involved in performing a DMA transfer are described +below.

+
Using +the DMA client interface

The sequence diagram of a DMA transfer +is:

+The sequence diagram of a DMA transfer + +

Initialization

Before any DMA operations can +be carried out, the data structure that holds the configuration of +the DMA channel must be initialized. An example of this is shown below:

TDmaChannel::SCreateInfo info; + + info.iCookie = iDMAChannelNumber; + info.iDesCount = 3; + info.iDfcPriority = 3; + info.iDfcQ = iDfcQue;

The iCookie parameter +is used to provide a unique ID for the channel. Its value is application +specific.

The iDesCount element is used to +specify how many descriptors this channel can use.

The iDfcPriority element is used to specify the priority of +the DMA callback relative to all the other callbacks on its DFC queue.

The iDfcQ element is used to specify which DFC +queue is to be used by this DMA channel.

Open a DMA channel

Next the DMA channel is opened and configured. An example +of this is show below:

r = TDmaChannel::Open(info, iDMAChannel); + +if (r) +{ + // [...] handle the error + return r; +}

The first parameter for the open method holds the +channel configuration details. The second parameter is the DMA channel +handle. In this example, if an error occurs during the open operation, +then the error code is returned to the rest of the system and the +transfer is aborted.

The first parameter contains the DMA channel +configuration information. The second parameter points to the instance +of the DMA channel class that is to be used. This class must be declared +before this method call can be made.

Create a request object

The next task is to create a request object, specifying the +channel it will be queued on and the callback when it completes. An +example of this is shown below:

new (iDMARequest) DDmaRequest(*iDMAChannel, DmaCallback, this);

The above line creates a new instance of the DDmaRequest class +which will be queued on the DMA channel specified in the first parameter. +The callback function (DmaCallback) that will process +the result of an operation is specified in the second parameter and +is optional. The third parameter specifies the argument passed to +the callback function.

Transfer

Once the DMA channel +has been setup, the DMA transfer can be carried out. Executing a DMA +transfer consists of two parts:

    +
  1. Specifying the +details of the DMA transfer.

  2. +
  3. Placing the +transfer onto the DMA transfer queue.

  4. +

Once a successful transfer has been completed, the specified +DMA callback function is executed.

An example of the use of +the fragment method call is:

retval = iDMARequest->Fragment(EDmaSDMMC, aDest, aCount, KDmaMemDest | KDmaIncDest, 0); + + if (retval) +{ + // [...] handle the error + return retval; +}

In this code snippet, the details of the DMA transfer +are specified. If an error is returned by the fragment method, then +the error code is passed on to the rest of the system and the transfer does +not take place. The first parameter specifies the data source. The +second specified the destination of the data. The third specifies +the number of bytes that are to be sent. The fourth parameter consists +of flags. The final parameter specifies any DMA PSL specific settings +(there are none in the example).

A code snippet that shows the +DMA transfer request being placed onto the DMA queue is:

iDMARequest->Queue();

Close a DMA channel

Finally, once the DMA functionality is no longer required, the +DMA channel is closed. A code snippet that shows this is:

iDMAChannel->Close();

Where iDMAChannel is the instance of the DMA channel that was being used.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-D5EE0A17-2246-4CB3-9CE5-538F1E01F8D4.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-D5EE0A17-2246-4CB3-9CE5-538F1E01F8D4.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,55 @@ + + + + + +What is Adaptation?Provides a brief overview of hardware adaptation . +
Adaptation

Adaptation is the process of adding a hardware or a platform service +to the device, it includes:

    +
  • the required hardware

  • +
  • a list of device drivers to be written

  • +
  • the list of required Platform services

  • +
  • the process of porting the operating system to the hardware

  • +
  • integration of peripherals possibly created by third parties

  • +

Base porting and device drivers involve platform specific +implementation on hardware.

+
The +Adaptation Layer and Platform services

The adaptation layer +interfaces between the operating system and hardware: it is a hardware +abstraction layer extended with modular functionality. It is partitioned +into platform services and client interfaces. The hardware manufacturers +implement the platform services in platform-specific instructions. +The device driver writers use the client interface in their code to +control various hardware.

+Adaptation Layer, Platform services and hardware + +

The purpose of Platform services:

    +
  • to make porting easier,

  • +
  • to enable hardware vendors to supply standard solutions, +and

  • +
  • to create a common interface for use by chipset vendors, phone +vendors and peripheral vendors.

  • +

The simplest Platform services are sets of APIs running in +kernel space and corresponding to discrete items of hardware. Other +Platform services form part of frameworks which may extend into user +space and higher levels of the operating system. Some Platform services +interact with other Platform services within the adaptation layer, +forming a logical stack which may cross the boundary between adaptation +layer and operating system at several points. A Platform service is +not necessarily implemented on hardware: some are implemented wholly +or partly as device specific software.

Implementers are provided +with:

    +
  • the APIs to be implemented, with an explanation of the intended +functionality

  • +
  • information about the associated framework and stack if appropriate

  • +
  • a statement of any associated standards and protocols

  • +
  • information about the tools required

  • +
  • tests to prove the implementation once it has been written

  • +
They are sometimes also given a reference implementation.
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-D683DBD8-15AA-5F2F-826C-B56CCE1DC06E.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-D683DBD8-15AA-5F2F-826C-B56CCE1DC06E.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,51 @@ + + + + + +ReferenceSummary of related documentation for the Digitizer Driver to which +you can refer +
API Reference

Kernel +Architecture

+ + + +

Item

+

Header

+
+ +

DDigitiser

+

xyin.h

+
+ +

TDigitizerCalibration

+

e32hal.h

+
+ +

TDigitiserHalFunction

+

e32hal.h

+
+ +

TDigitiserInfoV01

+

e32hal.h

+
+ +

TDigitiserInfoV02

+

e32hal.h

+
+ +

UserHal

+

e32hal.h

+
+ + +
+
Engineering +Specifications

None published.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-D6861A7A-1845-52AF-BB09-4B97E6B8AA13-master.png Binary file Adaptation/GUID-D6861A7A-1845-52AF-BB09-4B97E6B8AA13-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-D6861A7A-1845-52AF-BB09-4B97E6B8AA13_d0e10260_href.png Binary file Adaptation/GUID-D6861A7A-1845-52AF-BB09-4B97E6B8AA13_d0e10260_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-D729BD58-D4FE-5D46-ACD4-F78B37BA833A.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-D729BD58-D4FE-5D46-ACD4-F78B37BA833A.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,37 @@ + + + + + +GNU +Assembler Source FormatDescribes the rules that you must follow if you use GNU assembler +syntax. +

The platform-specific source code can be written in GNU assembler +syntax or ARM assembler syntax.

+

The generic source and header files are all written using the ARM assembler +syntax, as are the source files for the template and example ports. However +the bootstrap can be built using the GNU assembler; in this case, source files +are translated from ARM to GNU assembler syntax automatically.

+

The rules that you must follow to use GNU assembler syntax in the platform-specific +source are:

+
    +
  • The first non-blank +line of any GNU-syntax source or header file should start with an @ (the GNU +comment delimiter); this acts as a directive to the translation tool that +no translation is required.

  • +
  • Files included from +GNU source should be included with a .ginc extension +instead of the normal .inc extension. However the file +itself should have a .inc extension.

  • +
+

To enable the generic makefile to work correctly, assembler source files +should always be given the extension .s and assembler +include files .inc; this is independent of whether these +are ARM or GNU syntax.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-D7D7615F-B67D-44D0-82DF-24853159A114.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-D7D7615F-B67D-44D0-82DF-24853159A114.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,168 @@ + + + + + +Baseport Template Client Interface GuideProvides a basic framework consisting of base parts of +the Symbian platform. +

The Baseport Template platform service provide an interface to +the kernel-side client for hardware-specific functions (for example, +GPIO, DMA, IIC, USB Client Controller) that are used by the kernel.

+
+ Interface class

The client interface +for the Baseport Template platform service is: + + + +API +Description + + + + +

TemplateAssp

+

Provides common peripheral control functions such as power, +bootstrap, keymap, keyboard and sound that other extensions and device +drivers can use

+
+ + +

The Baseport Template interface provides the following +functions.

+ + + +Function +Return Type +Description + + + + +

TemplateAssp::Init1()

+void +

Initialize the ASSP interrupt controller

+
+ +

TemplateAssp::Init3()

+void +

Called in the context of the supervisor thread

+
+ +

TemplateAssp::StartupReason()

+TMachineStartupType +

Return the Startup reason of the Super Page (set up by Bootstrap)

+
+ +

TemplateAssp::MsTickPeriod()

+TInt +

Obtain the period of System Tick timer in microseconds

+
+ +

TemplateAssp::SystemTimeInSecondsFrom2000(TInt& +aTime);

+TInt +

Obtain System Time from the RTC

+
+ +

TemplateAssp::SetSystemTimeInSecondsFrom2000(TInt +aTime)

+TInt +

Obtain Adjust the RTC with new System Time

+
+ +

TemplateAssp::NanoWaitCalibration()

+TUint32 +

Obtain the time it takes to execute two processor instructions

+
+ + +
+
Pure +Virtual Functions for derivation by variant

These are the +functions whose implementation are not provided in the class, but +the behavior can be overridden within an inheriting class by a function +with the same return type.

External interrupt handling functions are used by second-level interrupt controllers at variant level.

+ + + +Functions +Return Type + + + + +

TemplateAssp::InterruptBind(TInt anId, TIsr anIsr, +TAny* aPtr)

+TInt +
+ +

TemplateAssp::InterruptUnbind(TInt anId)

+TInt +
+ +

TemplateAssp::InterruptEnable(TInt anId)

+TInt +
+ +

TemplateAssp::InterruptDisable(TInt anId)

+TInt +
+ +

TemplateAssp::InterruptClear(TInt anId)

+TInt +
+ + +

USB client controller functions are the called by +the USB PSL, and to be implemented by the variant .

+ + + +Functions +Return Type + + + + +

TemplateAssp::UsbClientConnectorDetectable()

+TBool +
+ +

TemplateAssp::UsbClientConnectorInserted()

+TBool +
+ +

TemplateAssp::RegisterUsbClientConnectorCallback(TInt +(*aCallback)(TAny*), TAny* aPtr)

+TInt +
+ +

TemplateAssp::UnregisterUsbClientConnectorCallback()

+void +
+ +

TemplateAssp::UsbSoftwareConnectable()

+TBool +
+ +

TemplateAssp::UsbConnect()

+TInt +
+ +

TemplateAssp::UsbDisconnect()

+TInt +
+ + +
+
+Baseport +Template Implementation Guide +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-D8911BE6-100D-588A-8E5C-A429A72AFCDA-master.png Binary file Adaptation/GUID-D8911BE6-100D-588A-8E5C-A429A72AFCDA-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-D8911BE6-100D-588A-8E5C-A429A72AFCDA_d0e19356_href.png Binary file Adaptation/GUID-D8911BE6-100D-588A-8E5C-A429A72AFCDA_d0e19356_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-D8A3C18B-A107-5557-B882-CD6CDD0F0F1D-master.png Binary file Adaptation/GUID-D8A3C18B-A107-5557-B882-CD6CDD0F0F1D-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-D8A3C18B-A107-5557-B882-CD6CDD0F0F1D_d0e76208_href.png Binary file Adaptation/GUID-D8A3C18B-A107-5557-B882-CD6CDD0F0F1D_d0e76208_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-DA382265-232F-40F4-92ED-C90E6DE3D709.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-DA382265-232F-40F4-92ED-C90E6DE3D709.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,74 @@ + + + + + +VersionThis document describes how to set the interface version used by +an LDD or a PDD and how to check version compatibility. +

An LDD and a PDD each have a version number which helps to identify the +interface. In order to communicate, an LDD and a PDD must have the same version +number.

+
Version +definition

Each LDD and PDD has their own version number. +LDDs and PDDs must set their version numbers in their respective factory objects, +using a TVersion object. TVersion specifies +a major number, a minor number and a build number.

A version number +defines the interface version supported by the LDD or PDD. It is used to check +that an LDD and PDD are compatible. It is also checked against the version +requested by a client when it opens a channel.

The following shows +how the example device drivers set their version numbers:

inline TVersion RExDriverChannel::VersionRequired() + { + return (TVersion(EUartMajorVersionNumber, + EUartMinorVersionNumber, + EUartBuildVersionNumber)); + } // LDD Factory object Constructor +DExDriverLogicalDevice::DExDriverLogicalDevice () + { + iVersion = RExDriverChannel::VersionRequired(); + } // PDD Factory object Constructor +DExH4PhysicalDevice::DExH4PhysicalDevice () + { + iVersion= RExDriverChannel::VersionRequired(); + }
+
Version compatibility

The +Kernel provides the Kern::QueryVersionSupported() API to +enforce a consistent set of rules for checking version compatibility. It returns +true if one of the following conditions is true:

    +
  • the major version of +the client is less than the major version of the driver.

  • +
  • the major version of +the client is equal to the major version of the driver, and the minor version +of the client is less than or equal to the minor version of the driver.

  • +

DLogicalChannel::DoCreate() typically checks +the client version against the driver using this API.

// Logical Channel Second stage constructor +TInt DExDriverLogicalChannel::DoCreate(TInt /*aUnit*/, const TDesC8* +/*anInfo*/, const TVersion& aVer) + { + ... + // Version check + if(!Kern::QueryVersionSupported(RExDriver::VersionRequired(), +aVer)) + return KErrNotSupported; + ... + }

When the device framework searches for a corresponding +PDD factory object for an LDD, it calls DPhysicalDevice::Validate() on +each matching PDD factory object, passing the unit number and the optional +extra information block. The first PDD to return KErrNone is +accepted as the required PDD.

The example PDD's Validate() implementation +checks the version of the LDD against the PDD, using the Kern::QueryVersionSupported() API:

// PDD: Validate +TInt DExH4PhysicalDevice::Validate(TInt aUnit, const TDesC8* +/*aInfo*/, const TVersion& aVer) + { + ... + // Version check + if (!Kern::QueryVersionSupported(iVersion,aVer)) + return KErrNotSupported; + ... + }
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-DA62FD4F-2E74-5B2F-B703-4A40DF5F01CA.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-DA62FD4F-2E74-5B2F-B703-4A40DF5F01CA.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,70 @@ + + + + + +MAKSYM +ToolMAKSYM is a command line tool that processes the log file generated +when building a ROM image, and creates a text file that lists the address +of every global and exported function in the ROM +

Reference: tools: +MAKSYM outlines the syntax of the command.

+

If you know the address of the instruction which caused an exception, you +can compare this address with the MAKSYM log to see which function this is +in. You can narrow this down to the exact code within the function by using ABLD +LISTING to get the assembler output from the compiler.

+

The following example MAKSYM log is taken from an EKA1 build; however, +the principle is the same for EKA2.

+From \Epoc32\Release\Misa\UREL\ekern.exe + +50003040 0094 _E32Startup +500030d4 002c ImpDma::Init1(void) +50003100 0004 ImpDma::Init3(void) +50003104 0008 ImpDma::MaxBlockSize(void) + +

If, for example, the code address of the exception is at 0x500030dc, +then you can see from the log that this is in the ImpDma::Init1() function, +at offset 8 from the start of the function. This function is in the file ...\e32\ekern\epoc\arm\sa1100\ka_dma.cpp, +so use ABLD LISTING to obtain the assembler:

+

cd \e32

+

abld listing misa urel ekern ka_dma

+

Notice that you must specify the component that the file is part of, in +this case EKERN, and that you do not put the .cpp extension +on the source file name. If you do not specify a source file ABLD will create +an assembler listing for every file in component EKERN.

+

The listing file will be placed in the same directory as ka_dma.cpp, +and will be called ka_dma.lis. If you look at this file you +will see something like this:

+7 Init1__6ImpDma: + 8 @ args = 0, pretend = 0, frame = 0 + 9 @ frame_needed = 0, current_function_anonymous_args = 0 + 10 @ I don't think this function clobbers lr + 11 0000 18209FE5 ldr r2, .L793 + 12 0004 0630A0E3 mov r3, #6 + 13 0008 003082E5 str r3, [r2, #0] + 14 000c 10309FE5 ldr r3, .L793+4 + 15 0010 10009FE5 ldr r0, .L793+8 + 16 0014 000083E5 str r0, [r3, #0] + 17 0018 1810A0E3 mov r1, #24 + 18 001c FEFFFFEA b FillZ__3MemPvi + +

Offset 8 is the first STR instruction. Comparing this with the C++ source:

+void ImpDma::Init1() +// +// Phase 1 initialisation of the Dma channels +// + { + PP::DmaMaxChannels=KNumberOfDmaChannels; + PP::DmaChannelTable=(TDma **)(&DmaChannels[0]); + Mem::FillZ(PP::DmaChannelTable,sizeof(TDma *)*KNumberOfDmaChannels); + } + +

The first store is to PP::DmaMaxChannels, so clearly there is a problem +writing this memory.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-DA7751A1-4EC5-5FBA-A42B-E254133A1D82-master.png Binary file Adaptation/GUID-DA7751A1-4EC5-5FBA-A42B-E254133A1D82-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-DA7751A1-4EC5-5FBA-A42B-E254133A1D82_d0e76254_href.png Binary file Adaptation/GUID-DA7751A1-4EC5-5FBA-A42B-E254133A1D82_d0e76254_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-DB0EDBC2-8204-59F3-9029-EBBCE04A9E3C-master.png Binary file Adaptation/GUID-DB0EDBC2-8204-59F3-9029-EBBCE04A9E3C-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-DB0EDBC2-8204-59F3-9029-EBBCE04A9E3C_d0e9220_href.png Binary file Adaptation/GUID-DB0EDBC2-8204-59F3-9029-EBBCE04A9E3C_d0e9220_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-DB441DFF-0075-5122-A2EB-A6EF76375D71.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-DB441DFF-0075-5122-A2EB-A6EF76375D71.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,842 @@ + + + + + + APIs affected by the platsecprocessisolation keywordCertain legacy APIs are insecure. Using the platsecprocessisolation keyword affects whether those APIs are allowed. +

Each Symbian platform release may include APIs, which are insecure. +These APIs are inherited from earlier versions of the OS, which are +based on EKA1 kernel. You may choose to allow or not allow such APIs +using the platsecprocessisolation Obey file keyword. The following is +a list of APIs, which are affected by platsecprocessisolation keyword.

+

Note: The list also states whether the API can be hidden +at build time by defining the __SECURE_API__ macro.

+ + + + + +

API

+

Restriction

+

Hidden by __SECURE_API__ macro ?

+
+ +

RThread::Kill(TInt aReason)

+

Not allowed on threads in a different process.

+

No

+
+ +

RThread::Terminate(TInt aReason)

+

Not allowed on threads in a different proces.

+

No

+
+ +

RThread::Panic(const TDesC& aCategory,TInt + aReason)

+

Not allowed on threads in a different process.

+

No

+
+ +

RThread::Suspend()

+

Not allowed on threads in a different process.

+

No

+
+ +

RThread::Resume()

+

Not allowed on threads in a different process.

+

No

+
+ +

RThread::SetPriority(TThreadPriority aPriority)

+

Not allowed on threads in a different process. (Unless the +process has enabled PriorityControl then it's priority can be changed +between Foreground and Background.)

+

No

+
+ +

RThread::RequestComplete(TRequestStatus*& aStatus, +TInt aReason)

+

Not allowed on threads in a different process.

+

No

+
+ +

RThread::Heap()

+

Removed. Not allowed on threads in a different process.

+

Yes

+
+ +

RThread::SetProcessPriority(TProcessPriority + aPriority)

+

Deprecated. Not allowed on threads in a different process.

+

No

+
+ +

RThread::Protected()

+

Removed.

+

Yes

+
+ +

RThread::SetProtected(TBool aState)

+

Removed. Use User::SetCritical() instead.

+

Yes

+
+ +

RThread::System()

+

Removed. Use User::Critical() instead.

+

Yes

+
+ +

RThread::SetSystem(TBool aState)

+

Removed. Use User::SetCritical() instead. +Not allowed on threads in a different process.

+

Yes

+
+ +

RThread::GetDesLength(const TAny *aPtr)

+

Removed.

+

Yes

+
+ +

RThread::GetDesMaxLength(const TAny *aPtr)

+

Removed.

+

Yes

+
+ +

RThread::ReadL(const TAny* aPtr, TDes8& aBuf, +TInt anOffset)

+

Removed.

+

Yes

+
+ +

RThread::ReadL(const TAny* aPtr, TDes16& aBuf, +TInt anOffset)

+

Removed.

+

Yes

+
+ +

RThread::WriteL(const TAny* aPtr, const TDesC8& +aBuf, TInt anOffset)

+

Removed.

+

Yes

+
+ +

RThread::WriteL(const TAny* aPtr, const TDesC16& +aBuf, TInt anOffset)

+

Removed.

+

Yes

+
+ +

RThread::Rename(const TDesC& aName)

+

Removed. Use User::RenameThread() instead. +Not allowed on threads in a different process

+

Yes

+
+ +

RThread::ExceptionHandler()

+

Removed. Use User::ExceptionHandler() instead. Can only be called to get the handler for the current thread.

+

Yes

+
+ +

RThread::SetExceptionHandler(TExceptionHandler + aHandler,TUint32 aMask)

+

Removed. Use User::SetExceptionHandler() instead. Can only be called to set the handler for the current thread.

+

Yes

+
+ +

RThread::ModifyExceptionMask(TUint32 aClearMask, +TUint32 aSetMask)

+

Removed. Use User::ModifyExceptionMask() instead. Can only be called to modify the exception mask for the +current thread.

+

Yes

+
+ +

RThread::RaiseException(TExcType aType)

+

Removed. Use User::RaiseException() instead. +Can only be called to raise an exception on the current thread.

+

Yes

+
+ +

RThread::IsExceptionHandled(TExcType aType)

+

Removed. Use User::IsExceptionHandled() instead. Can only be called to query the current thread.

+

Yes

+
+ +

RThread::Create(const TDesC& aName,TThreadFunction + aFunction,TInt aStackSize,TAny* aPtr,RLibrary* aLibrary,RHeap* +aHeap, TInt aHeapMinSize,TInt aHeapMaxSize,TOwnerType +aType)

+

Removed.

+

No

+
+ +

RProcess::Kill(TInt aReason)

+

Unless PowerMgmt capabilility is held this can only allowed +to be called by the process itself, or by the process which created +it (if it has not yet been resumed).

+

No

+
+ +

RProcess::Terminate(TInt aReason)

+

Unless PowerMgmt capabilility is held this can only allowed +to be called by the process itself or by the process which created +it (if it has not yet been resumed).

+

No

+
+ +

RProcess::Panic(const TDesC& aCategory,TInt + aReason)

+

Unless PowerMgmt capabilility is held this can only allowed +to be called by the process itself or by the process which created +it (if it has not yet been resumed).

+

No

+
+ +

RProcess::SetType(const TUidType& aType)

+

Removed.

+

Yes

+
+ +

RProcess::Resume()

+

Can only be called by the process which created the process +to be resumed.

+

No

+
+ +

RProcess::CommandLineLength()

+

Removed. Use User::CommandLineLength() instead.

+

Yes

+
+ +

RProcess::CommandLine(TDes& aCommand)S

+

Removed. Use User::CommandLine() instead.

+

Yes

+
+ +

RProcess::SetPriority(TProcessPriority aPriority)

+

Can only be called by a process to change it's own priority, +or by the process which created the process having it's priority changed +if it hasn't yet been resumed. Iff a process has enabled PriorityControl +then it's priority can be changed between Foreground and Background.

+

No

+
+ +

RProcess::Protected()

+

Removed. Use User::ProcessCritical() instead.

+

Yes

+
+ +

RProcess::SetProtected(TBool aState)

+

Removed. Use User::ProcessSetCritical() instead.

+

Yes

+
+ +

RProcess::System()

+

Removed. Use User::ProcessCritical() instead.

+

Yes

+
+ +

RProcess::SetSystem(TBool aState)

+

Removed. Use User::ProcessSetCritical() instead. Can only be used on the current process.

+

Yes

+
+ +

RProcess::SetJustInTime(TBool aState)

+

Can only be called by a process to change it's own JustInTime +state or by the process which created the process having it's JustInTime +state changed if it hasn't yet been resumed.

+

No

+
+ +

RProcess::Owner(RProcess& aOwner)

+

Removed.

+

Yes

+
+ +

RProcess::SetOwner(const RProcess& aProcess)

+

Removed.

+

Yes

+
+ +

RProcess::Rename(const TDesC& aName)

+

Removed. Use User::RenameProcess() instead. +Only allowed for a process renaming itself.

+

Yes

+
+ +

RMessagePtr2::Read(TInt aParam,TDes8& aDes,TInt + aOffset)O

+

The client descriptor refered to by aParam must be a TDesC8 (not a TDesC16). Failure is indicated by a return code of KErrBadDescriptor.

+

No

+
+ +

RMessagePtr2::Read(TInt aParam,TDes16& aDes,TInt + aOffset)

+

The client descriptor refered to by aParam must be a TDesC16 (not a TDesC8). Failure is indicated by a return code of KErrBadDescriptor.

+

No

+
+ +

RMessagePtr2::Write(TInt aParam,const TDesC8& +aDes,TInt aOffset)

+

The client descriptor refered to by aParam must be a TDes8 (not a TDes16). Failure is indicated by a return code of KErrBadDescriptor.

+

No

+
+ +

RMessagePtr2::Write(TInt aParam,const TDesC16& +aDes,TInt aOffset)

+

The client descriptor refered to by aParam must be a TDes16 (not a TDes8). Failure is indicated by a return code of KErrBadDescriptor.

+

No

+
+ +

RMessagePtr2::SetProcessPriority(TProcessPriority + aPriority)

+

Client must have enabled priority control with User::SetPriorityControl().

+

No

+
+ +

RMessage::ReadL(const TAny* aPtr,TDes8& aDes)

+

Removed.

+

Yes

+
+ +

RMessage::ReadL(const TAny* aPtr,TDes8& aDes,TInt + anOffset)

+

Removed.

+

Yes

+
+ +

RMessage::ReadL(const TAny* aPtr,TDes16& aDes)

+

Removed.

+

Yes

+
+ +

RMessage::ReadL(const TAny* aPtr,TDes16& aDes,TInt + anOffset)

+

Removed.

+

Yes

+
+ +

RMessage::WriteL(const TAny* aPtr,const TDesC8& + aDes)

+

Removed.

+

Yes

+
+ +

RMessage::WriteL(const TAny* aPtr,const TDesC8& +aDes,TInt anOffset)

+

Removed.

+

Yes

+
+ +

RMessage::WriteL(const TAny* aPtr,const TDesC16& + aDes)

+

Removed.

+

Yes

+
+ +

RMessage::WriteL(const TAny* aPtr,const TDesC16& + aDes,TInt anOffset)

+

Removed.

+

Yes

+
+ +

RMessage::RMessage(const RMessagePtr2& aPtr)

+

Removed.

+

No

+
+ +

RMessage (all other methods)

+

Removed.

+

Yes

+
+ +

TFindChunk::Next(TFullName& aResult)

+

Can't find objects without a name.

+

No

+
+ +

TFindLogicalDevice::Next(TFullName& aResult)

+

Can't find objects without a name.

+

No

+
+ +

TFindPhysicalDevice::Next(TFullName& aResult)

+

Can't find objects without a name.

+

No

+
+ +

TFindLibrary::Next(TFullName& aResult)

+

Can't find objects without a name

+

No

+
+ +

TFindServer::Next(TFullName& aResult)

+

Can't find objects without a name.

+

No

+
+ +

TFindMutex::Next(TFullName& aResult)

+

Can't find objects without a name.

+

No

+
+ +

TFindProcess::Next(TFullName& aResult)

+

Can't find objects without a name.

+

No

+
+ +

TFindSemaphore::Next(TFullName& aResult)

+

Can't find objects without a name.

+

No

+
+ +

TFindThread::Next(TFullName& aResult)

+

Can't find objects without a name.

+

No

+
+ +

RChunk::OpenGlobal(const TDesC& aName,TBool + isReadOnly,TOwnerType aType)

+

Can't open objects without a name or objects that are not +global.

+

No

+
+ +

RDevice::Open(const TDesC& aName,TOwnerType +aType)

+

Can't open objects without a name or objects that are not +global.

+

No

+
+ +

RMutex::OpenGlobal(const TDesC& aName,TOwnerType + aType)

+

Can't open objects without a name or objects that are not +global.

+

No

+
+ +

RCondVar::OpenGlobal(const TDesC& aName, TOwnerType + aType)

+

Can't open objects without a name or objects that are not +global.

+

No

+
+ +

RSemaphore::OpenGlobal(const TDesC& aName,TOwnerType + aType)

+

Can't open objects without a name or objects that are not +global.

+

No

+
+ +

RProcess::Open(const TDesC& aName,TOwnerType + aType)

+

Can't open objects without a name or objects that are not +global.

+

No

+
+ +

RThread::Open(const TDesC& aName,TOwnerType +aType)

+

Can't open objects without a name or objects that are not +global.

+

No

+
+ +

RMsgQueueBase::OpenGlobal(const TDesC& aName, +TOwnerType aType)

+

Can't open objects without a name or objects that are not +global.

+

No

+
+ +

RChunk::Duplicate(const RThread& aSrc,TOwnerType + aType=EOwnerProcess)

+

If the handle being duplicated belongs to a different process +then it can't be duplicated if the object doesn't have a name or isn't +global.

+

No

+
+ +

RDevice::Duplicate(const RThread& aSrc,TOwnerType + aType=EOwnerProcess)

+

If the handle being duplicated belongs to a different process +then it can't be duplicated if the object doesn't have a name or isn't +global.

+

No

+
+ +

RMutex::Duplicate(const RThread& aSrc,TOwnerType + aType=EOwnerProcess)

+

If the handle being duplicated belongs to a different process +then it can't be duplicated if the object doesn't have a name or isn't +global.

+

No

+
+ +

RCondVar::Duplicate(const RThread& aSrc,TOwnerType + aType=EOwnerProcess)

+

If the handle being duplicated belongs to a different process +then it can't be duplicated if the object doesn't have a name or isn't +global.

+

No

+
+ +

RSemaphore::Duplicate(const RThread& aSrc,TOwnerType + aType=EOwnerProcess)

+

If the handle being duplicated belongs to a different process +then it can't be duplicated if the object doesn't have a name or isn't +global.

+

No

+
+ +

RProcess::Duplicate(const RThread& aSrc,TOwnerType + aType=EOwnerProcess)

+

If the handle being duplicated belongs to a different process +then it can't be duplicated if the object doesn't have a name or isn't +global.

+

No

+
+ +

RThread::Duplicate(const RThread& aSrc,TOwnerType + aType=EOwnerProcess)

+

If the handle being duplicated belongs to a different process +then it can't be duplicated if the object doesn't have a name or isn't +global.

+

No

+
+ +

RMsgQueueBase::Duplicate(const RThread& aSrc,TOwnerType + aType=EOwnerProcess)

+

If the handle being duplicated belongs to a different process +then it can't be duplicated if the object doesn't have a name or isn't +global.

+

No

+
+ +

RThread::Open(TThreadId aID, TOwnerType + aType=EOwnerProcess)

+

Can't open objects without a name.

+

No

+
+ +

RHandleBase::Open(const TFindHandleBase& + aFindHandle,TOwnerType aType)

+

Can't open objects without a name or those which aren't +global.

+

No

+
+ +

UserSvr::CaptureEventHook()

+

Can only be called by the Window Server process.

+

No

+
+ +

class CSharableSession

+

Removed.

+

Yes

+
+ +

class CSession

+

Removed.

+

Yes

+
+ +

class CServer

+

Removed.

+

Yes

+
+ +

class RServer

+

Removed.

+

Yes

+
+ +

RSessionBase::Share(TAttachMode aAttachMode=EExplicitAttach)

+

Removed.

+

Yes

+
+ +

RSessionBase::Attach()

+

Removed.

+

Yes

+
+ +

RSessionBase::Send(TInt aFunction,TAny* aPtr)

+

Removed.

+

Yes

+
+ +

RSessionBase::SendReceive(TInt aFunction,TAny* + aPtr,TRequestStatus& aStatus)

+

Removed.

+

Yes

+
+ +

RSessionBase::SendReceive(TInt aFunction,TAny* +aPtr)

+

Removed.

+

Yes

+
+ +

RSubSessionBase::CreateSubSession(RSessionBase& + aSession,TInt aFunction,const TAny* aPtr)

+

Removed.

+

Yes

+
+ +

RSubSessionBase::Send(TInt aFunction,const TAny* +aPtr)

+

Removed.

+

Yes

+
+ +

RSubSessionBase::SendReceive(TInt aFunction,const +TAny* aPtr,TRequestStatus& aStatus)

+

Removed.

+

Yes

+
+ +

RSubSessionBase::SendReceive(TInt aFunction,const +TAny* aPtr)

+

Removed.

+

Yes

+
+ +

UserSvr::DllGlobalAlloc(TInt aHandle,TInt aSize)

+

Removed.

+

Yes

+
+ +

UserSvr::DllGlobalAllocated(TInt aHandle)

+

Removed.

+

Yes

+
+ +

UserSvr::DllGlobalRead(TInt aHandle,TInt aPos,TInt + aLength,TDes8& aDes)

+

Removed.

+

Yes

+
+ +

UserSvr::DllGlobalWrite(TInt aHandle,TInt aPos,const + TDesC8& aDes)

+

Removed.

+

Yes

+
+ +

Dll::GlobalAlloc(TInt aSize)

+

Removed.

+

Yes

+
+ +

Dll::GlobalAllocated()

+

Removed.

+

Yes

+
+ +

Dll::GlobalRead(TInt aPos, TInt aLength, TDes8& + aDes)

+

Removed.

+

Yes

+
+ +

Dll::GlobalWrite(TInt aPos,const TDesC8& aDes)

+

Removed.

+

Yes

+
+ +

TBusLocalDrive::Lock(TMediaPassword& aOldPassword, + TMediaPassword& aNewPassword, TBool aStorePassword)

+

Removed.

+

Yes

+
+ +

class CSecurityEncryptBase

+

Removed.

+

Yes

+
+ +

class CSecurityDecryptBase

+

Removed.

+

Yes

+
+ +

class CSecurityBase

+

Removed.

+

Yes

+
+ +

class CBoundedSecurityBase

+

Removed.

+

Yes

+
+ +

class Security

+

Removed.

+

Yes

+
+ +

RBusLogicalChannel::DoCreate(const TDesC& aDevice,const + TVersion& aVer,const TDesC* aChan,TInt aUnit,const +TDesC* aDriver,const TDesC8* anInfo,TOwnerType aType=EOwnerProcess)

+

Removed.

+

Yes

+
+ +

RHeap::Adjust(TAny* aCell,TInt anOffset,TInt aDelta)

+

Removed.

+

Yes

+
+ +

RHeap::AdjustL(TAny* aCell,TInt anOffset,TInt aDelta)

+

Removed.

+

Yes

+
+ +

RHeap::FreeAll()

+

Removed.

+

Yes

+
+ +

class THeapWalk

+

Removed.

+

Yes

+
+ +

enum TDllReason

+

Removed.

+

Yes

+
+ +

class RDebug

+

) Removed. (Apart from Printf functions

+

Yes

+
+ +

class TFindLogicalChannel

+

Removed.

+

Yes

+
+ +

Rdevice::IsAvailable(TInt aUnit, const TDesC* + aPhysicalDevice, const TDesC16* anInfo)

+

Removed.

+

Yes

+
+ +

RLibrary::EntryPoint()

+

Removed.

+

Yes

+
+ +

RLibrary::DllRefTable()

+

Removed.

+

Yes

+
+ +

RThread::GetRamSizes(TInt& aHeapSize,TInt& + aStackSize)

+

Removed. Use RThread::StackInfo() instead.

+

Yes

+
+ +

RProcess::GetRamSizes(TInt& aCodeSize, TInt& + aConstDataSize, TInt& anInitialisedDataSize, TInt& + anUninitialisedDataSize)

+

Removed. Use RThread::GetMemoryInfo() instead.

+

Yes

+
+ +

class TNotifyInfo

+

Removed.

+

Yes

+
+ +

class Password

+

Removed.

+

Yes

+
+ +

User::Adjust(TAny* aCell,TInt aOffset,TInt aDelta)

+

Removed.

+

Yes

+
+ +

User::AdjustL(TAny* aCell,TInt aOffset,TInt aDelta)

+

Removed.

+

Yes

+
+ +

User::__DbgMarkStart(RHeap::TDbgHeapType aHeapType)

+

Removed.

+

Yes

+
+ +

User::__DbgMarkCheck(RHeap::TDbgHeapType aHeapType,TBool + aCountAll,TInt aCount,const TDesC8& aFileName,TInt +aLineNum)

+

Removed.

+

Yes

+
+ +

User::__DbgMarkEnd(RHeap::TDbgHeapType aHeapType,TInt + aCount)

+

Removed.

+

Yes

+
+ +

User::__DbgSetAllocFail(RHeap::TDbgHeapType + aHeapType,RHeap::TAllocFail aType,TInt aRate)

+

Removed.

+

Yes

+
+ +

UserSvr::InitRegisterCallback(TCallBack, TInt)

+

Removed.

+

Yes

+
+ +

UserSvr::ChangeLocale(RLibrary aLibrary)

+

Removed.

+

Yes

+
+ +

UserSvr::DllInitialiseData(TInt aHandle)

+

Removed.

+

Yes

+
+ +

UserSvr::DllFreeData(TInt aHandle)

+

Removed.

+

Yes

+
+ +

UserSvr::WsRegisterThread(TThreadFunction)

+

Removed.

+

Yes

+
+ +

UserSvr::ServerStarted()

+

Removed.

+

Yes

+
+ +

RMutex::Count()

+

Removed.

+

Yes

+
+ +

RSemaphore::Count()

+

Removed.

+

Yes

+
+ + +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-DB55C1A0-2901-4661-B6B1-3B61BF6FF4FA.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-DB55C1A0-2901-4661-B6B1-3B61BF6FF4FA.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,129 @@ + + + + + +Register Access Client Interface GuideExplains how to use the Register Access client interface +functions. +

The Register Access client interface is intended for use in writing +device drivers. Writing device drivers involves frequent access to +hardware registers by reading, writing and modifying them.

+
Interface +class

The client interface for the Register +Access platform services is:

+ + + +Class +Description + + + + +AsspRegister +Provides read, write and modify functions to access hardware +registers of different widths. + + + +
+
Interface +functions

The Register Access client interface provides +the following functions:

+ + + + +Function +Return Type +Description + + + + +AsspRegister::Read8(TLinAddr aAddr) +TUint8 +Return the contents of an 8-bit register. + + +AsspRegister::Read16(TLinAddr aAddr) +TUint16 +Return the contents of a 16-bit register. + + +AsspRegister::Read32(TLinAddr aAddr) +TUint32 +Return the contents of a 32-bit register. + + +AsspRegister::Read64(TLinAddr aAddr) +TUint64 +Return the contents of a 64-bit register. + + +AsspRegister::Write8(TLinAddr aAddr, TUint8 aValue) +void +Store a new value in an 8-bit register. + + +AsspRegister::Write16(TLinAddr aAddr, TUint16 aValue) +void +Store a new value in a 16-bit register. + + +AsspRegister::Write32(TLinAddr aAddr, TUint32 aValue) +void +Store a new value in a 32-bit register. + + +AsspRegister::Write64(TLinAddr aAddr, TUint64 aValue) +void +Store a new value in a 64-bit register. + + +AsspRegister::Modify8(TLinAddr aAddr, TUint8 aClearMask, +TUint8 aSetMask) +void +Modify the contents of an 8-bit register. + + +AsspRegister::Modify16(TLinAddr aAddr, TUint16 aClearMask, +TUint16 aSetMask) +void +Modify the contents of a 16-bit register. + + +AsspRegister::Modify32(TLinAddr aAddr, TUint32 aClearMask, +TUint32 aSetMask) +void +Modify the contents of a 32-bit register. + + +AsspRegister::Modify64(TLinAddr aAddr, TUint64 aClearMask, +TUint64 aSetMask) +void +Modify the contents of a 64-bit register. + + + +

All these functions can be called in any context.

The address of a particular register on a particular platform +is typically expressed as a base address and an offset: this is what +you pass to the aAddr argument of these functions +as a TLinAddr.

The write functions take an +unsigned integer (TUint8, TUint16, TUint32 or TUint64) as the value +of the parameter aValue.

The modify functions +take two unsigned integers (TUint8, TUint16, TUint32 or TUint64) as arguments. +Both the parameters, aClearMask and aSetMask, are bitmasks. The aClearMask argument clears the +bits specified and the aSetMask sets the bits specified.

Addressing a register

The following code reads the current +value of a hardware register identified by a base address iBaseAddr plus an offset KHoPciStatus.

TUint status=AsspRegister::Read16(iBaseAddr+KHoPciStatus);Modifying a register

The following code clears the bits +specified by the bitmask KHtPciStatus_ParityError and sets the bits specified by the bitmask NULL (that is so say, none in this case).

AsspRegister::Modify16(baseAddr+KHoPciStatus,KHtPciStatus_ParityError,NULL);
+
+Register +Access Implementation Guide +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-DBEAD516-5DD4-5E33-B6DA-657C1AE60C4B.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-DBEAD516-5DD4-5E33-B6DA-657C1AE60C4B.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,166 @@ + + + + + +Dynamic +BehaviourDescribes the dynamic behaviour of the Digitizer Driver. The description +shows the use of the template port. +

The design assumes that interrupts are generated by pen-down events; however, +there is no difficulty in adjusting your implementation to deal with interrupts +generated by pen-up events.

+

The heart of the design is a DFC that reads digitizer data samples when +the pen goes down, and then samples the digitizer at regular intervals until +the pen goes up. These samples are accumulated in a buffer in the platform +independent layer. When enough samples have been gathered, the platform independent +layer averages them, processes them, and issues pen movement events.

+ + + + +

In the template port, the behaviour of the platform specific layer +is based on three states:

+

The template port represents these three states using the enum values +of the enum TSate, defined within the scope of the DTemplateDigitiser class +(derived from DDigitiser). The enum values are:

+
+ +

"power up"

+

E_HW_PowerUp

+
+ +

"collect sample"

+

E_HW_CollectSample

+
+ +

"pen up debounce"

+

E_HW_PenUpDebounce

+
+ + +
+
State diagram

The flow of control through the digitizer +is described by this state diagram. The notes following relate to this state +diagram on the left-hand side.

The diagram on the right-hand side +shows, in a simplified form, the flow of control. The numbers correspond to +the state diagram numbers. Calls into the platform independent layer are shown +in green boxes; important functions are shown in purple boxes.

+ + + + + + + + + + + + +
    +
  1. If the pen is down at +power on, i.e. when in the power up state, the device keeps sampling +the digitiser at regular intervals until the pen is up. In the template port, +the interval is defined by the constant KPenUpPollTime

  2. +
  3. If the pen is up at +power on, i.e. when in the power up state, or when the pen is first +lifted, the sampling is initialised; see Step +6 - initialise sampling

  4. +
  5. If the pen is down in +the collect sample state, then the digitiser coordinates are sampled +at regular intervals, and stored in a buffer allocated by the platform independent +layer. When a group of samples has been taken, the platform specific layer +calls DDigitiser::RawSampleValid() in the platform independent +layer to start the processing of the samples.

    In the template port, +the interval is defined by the constant KInterSampleTime; see Step +7 - take sample readings.

  6. +
  7. If the pen is lifted +while in the collect sample state, then the state changes to the pen +up debounce state. This state describes the situation where a pen is lifted +from the device and there is uncertainty as to whether this represents a positive +move by the user, or whether the pen pressure has just been reduced momentarily. +A delay is scheduled to decide to see which is case is true. At the end of +the interval the state of the pen is checked again. If the pen is found to +be down at the end of this interval, then the state changes back to the collect +sample state, and the sample buffer is reset.

    In the template +port, the delay interval is defined by the constant KPenUpDebounceTime.

  8. +
  9. If the pen is found +to be down at the end of this interval, then the state changes back to the collect +sample state, and the sample buffer is reset.

  10. +
  11. If the pen is found +to be still up at the end of this interval, then the pen is assumed to be +intentionally up. The sample buffer is reset in preparation for future readings, +and the platform independent layer is notified that the pen is now up by calling DDigitiser::PenUp().

  12. +
+
Interaction between the two layers

This section +shows the main interactions between the two layers:

1

+ +

When the device is started, the platform independent layer calls +the function DoCreate(). This is where the power handler +should be registered, interrupts bound and any other initialisation should +take place.

The platform independent layer then calls the function WaitForPenDown(). +This is declared as pure virtual in the DDigitiser class +and is implemented in the platform specific layer. This function is also called +from the ProcessPenUp() function that runs in a DFC thread +scheduled to run when the pen is lifted. This DFC is scheduled in the platform +specific layer.

See also Step +4 - implement DDigitiser::WaitForPenDown().

2

+ +

The platform specific layer calls RawSampleValid() when +it has a group of digitizer coordinates ready to be processed by the platform +independent layer. This is called in the context of a DFC thread, the DFC +being queued when the digitizer interrupt is fired.

3

+ +

The platform independent layer calls WaitForPenUp() to +request another sample from the hardware. This is declared as pure virtual +in the DDigitiser class and is implemented in the platform +specific layer. The function is called after the platform independent layer +has processed a group of raw samples while the pen is down, and also tells +the platform specific layer that the buffers in the platform independent layer +can be re-used.

4

+ +

The platform independent layer calls WaitForPenUpDebounce() if +a group of collected samples is not good enough. This is declared as pure +virtual in the DDigitiser class and is implemented in the +platform specific layer. The function is called after the platform independent +layer has processed a group of raw samples while the pen is down and also +tells the platform specific layer that the buffers in the platform independent +layer can be re-used.

5

+ +

When the pen is lifted, the platform specific layer calls PenUp() in +the platform independent layer, which then changes its internal state, issues +a pen up event to the device, and then calls WaitForPenDown() in +the platform specific layer.

6

+ +

The platform independent layer calls DigitiserOn() when +the device is turned on, or it may be called from the HAL. The function, implemented +in the platform specific layer, and turns the hardware on if it is not already +on. See also Step +3 - implement power on behaviour.

7

+ +

DigitiserOff() turns the digitizer off, and may +be called as a result of a power transition, or it may be called from the +HAL. If it is called from the Power Manager, the digitizer may already be +off if the platform is in silent running mode. See also Step 10 - implement DDigitiser::DigitiserOff().

8

There are two functions: DigitiserToScreen() and ScreenToDigitiser() that +convert digitizer coordinates to and from screen coordinates. Both are declared +as pure virtual in the DDigitiser class and need to be +implemented in the platform specific layer.

9

+ +

The platform independent layer provides the HAL handler for the EHalGroupDigitiser HAL groups and function-ids. This is DDigitiser::HalFunction(). +It delegates the handling of 5 of the individual behaviours, as represented +by the TDigitiserHalFunction function-ids, to the following +functions, declared as pure virtual in the DDigitiser class, +and implemented by the platform specific layer:

    +
  • DDigitiser::SetXYInputCalibration()

  • +
  • DDigitiser::CalibrationPoints()

  • +
  • DDigitiser::SaveXYInputCalibration()

  • +
  • DDigitiser::RestoreXYInputCalibration()

  • +
  • DDigitiser::DigitiserInfo()

  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-DC2CF276-95E2-5810-9B8D-EB8B72E04FEC.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-DC2CF276-95E2-5810-9B8D-EB8B72E04FEC.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,62 @@ + + + + + + Memory +Dump CommandsDescribes how to use the m command to get a dump +of memory. +

+

This command has two formats:

+m start end +m start+length +

Using the first format you provide the start and end addresses that you +want to inspect; for example:

+m 81240000 8124003F +

Using the second form you provide the start address and the number of bytes +to dump (in hex); for example:

+m 81240000 +40 +

Both of the above examples dump 64 bytes from address 0x81240000. The output +is a standard hex-dump:

+.m 81240000 +40 +81240000: 00 00 FF EB 08 01 BF D7 00 04 7D B6 02 00 BF EF ..........}..... +81240010: 00 01 DF EE 0A 40 7F F7 00 80 BF FF 20 10 FF EA .....@...... ... +81240020: 00 82 FF 77 04 24 FD FF 40 01 FF 7F 00 01 FF FF ...w.$..@....... +81240030: 08 10 FF BF 08 00 BF DE 08 00 EF FB 00 00 FF DF ................ + +
Dumping the contents of classes

You can use the m command +to inspect the contents of structures and class instances, but you need to +be aware of a few things about the memory layout:

    +
  • Symbian platform is +little-endian, which means that all values are stored so that the least significant +bytes are stored at the lower addresses in memory (or “backwards” as commonly +perceived).

    For example, the value 0x1234ABCD would be shown in the +memory dump as:

    CD AB 34 12
  • +
  • The compiler may add +padding between variables either to speed up access or to avoid alignment +restrictions; for example, words cannot be on odd addresses.

    As an +example, the following struct:

    struct SExample + { + TUint8 iByte; + TInt iInteger; + }; +

    would be laid out in memory as:

    +0(1) iByte ++1(3) padding ++4(4) iInteger +

    The padding and alignment is compiler-dependent. Generally, +fields must be aligned on a boundary equal to their size; for example, a TUint32 is +4 bytes wide so it must lie on a 4-byte boundary, i.e. the least significant +two bits of the address must be zero.

    When using GCC, classes which +derive from CBase will have a virtual table pointer as +the first word in the class data and classes which derive from DBase will +have a virtual table pointer as the second word in the class data.

    When +using an EABI-compliant compiler, the virtual table pointer is always the +first word of the class.

  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-DC8D3736-EDCF-54CB-A614-2AAC4664F1CA.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-DC8D3736-EDCF-54CB-A614-2AAC4664F1CA.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,27 @@ + + + + + +Kernel-Side ServicesThis section describes how device drivers can use the services +that the Kernel provides. +

The section begins with a discussion of the APIs for fundamental types +such as buffers and arrays. Kernel side programs cannot use all of the same +APIs as user-side programs, so you need to be aware of these restrictions, +and the alternative APIs provided by the Kernel.

+

The guide then discusses a number of idioms for communicating between different +threads and processes, including Publish and Subscribe, Kernel-side messages, +shared chunks, and environment slots.

+

Some more advanced programming issues are then discussed, including how +to design a device driver to behave correctly in a demand paged OS environment, +in which client programs may not be continuously in memory, and how to integrate +a device driver with system wide power resource management.

+

The section ends with a discussion of how Kernel APIs encourage safe programming +with the use of precondition checks.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-DCBBDFA7-1E6C-5B00-A13E-A25794668E12-master.png Binary file Adaptation/GUID-DCBBDFA7-1E6C-5B00-A13E-A25794668E12-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-DCBBDFA7-1E6C-5B00-A13E-A25794668E12_d0e13252_href.png Binary file Adaptation/GUID-DCBBDFA7-1E6C-5B00-A13E-A25794668E12_d0e13252_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-DCDD68C7-8EBE-4E91-A983-076460B2C2F3.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-DCDD68C7-8EBE-4E91-A983-076460B2C2F3.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,32 @@ + + + + + +IIC Quick StartIdentifies the documents needed to understand, use and +implement the Inter-Integrated Circuit (IIC) serial bus interface. +

The IIC is a technology-independent interface for serial bus technologies. +The IIC supports multi-master and multi-slave serial interfaces, used +by devices attached to the bus to exchange control information.

+
Getting +started with IIC

There are two categories of users who need +to understand IIC:

    +
  • Device driver creators - need to know how to use IIC

  • +
  • Hardware adaptation developers - need to understand how to +write software to allow IIC to communicate with their hardware.

  • +

Both categories of user need to understand the basic concepts +of IIC such as channels, nodes, transactions, transfers, the IIC controller. +You should read the IIC Concepts guide to understand these concepts.

+
Device +driver creators

After reading and understanding the IIC Concepts guide, the next step is to read the IIC Client Interface +Quickstart to understand how to use the APIs for your device +driver.

+
Hardware +adaptation developers

After reading and understanding the IIC Concepts guide, you should start with the IIC Implementation.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-DD0DA06D-4180-54F1-8807-A7BF31D6A1F1-master.png Binary file Adaptation/GUID-DD0DA06D-4180-54F1-8807-A7BF31D6A1F1-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-DD0DA06D-4180-54F1-8807-A7BF31D6A1F1_d0e70450_href.png Binary file Adaptation/GUID-DD0DA06D-4180-54F1-8807-A7BF31D6A1F1_d0e70450_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-DD568637-CD37-5E4C-AD78-4AA5AFE1E9D8.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-DD568637-CD37-5E4C-AD78-4AA5AFE1E9D8.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,23 @@ + + + + + +Entry +Point ImplementationMedia driver must implement an entry point function that creates +a PDD factory object that is derived from DPhysicalDevice. +

Because media drivers are implemented as kernel extensions, use the DECLARE_EXTENSION_PDD() macro +as a wrapper around the code that creates your factory object; the following +code fragment is typical:

+DECLARE_EXTENSION_PDD() + { + return new DMyPhysicalDevice; + } +

where DMyPhysicalDevice is an implementation of DPhysicalDevice.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-DD9DBB55-330E-4F43-A156-621979B675BC.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-DD9DBB55-330E-4F43-A156-621979B675BC.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,13 @@ + + + + + +Personality LayerDescribes what a personality layer is and how to design +one. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-DDD883A2-6784-4851-8E36-227EC564452A-master.png Binary file Adaptation/GUID-DDD883A2-6784-4851-8E36-227EC564452A-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-DDD883A2-6784-4851-8E36-227EC564452A_d0e90311_href.png Binary file Adaptation/GUID-DDD883A2-6784-4851-8E36-227EC564452A_d0e90311_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-DE7BD5C8-9966-5D5E-B81F-D57EA9FBA451-master.png Binary file Adaptation/GUID-DE7BD5C8-9966-5D5E-B81F-D57EA9FBA451-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-DE7BD5C8-9966-5D5E-B81F-D57EA9FBA451_d0e9161_href.png Binary file Adaptation/GUID-DE7BD5C8-9966-5D5E-B81F-D57EA9FBA451_d0e9161_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-DF2F0439-AE1A-599C-91B9-6EF2177C3C7E.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-DF2F0439-AE1A-599C-91B9-6EF2177C3C7E.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,24 @@ + + + + + +DMA FrameworkThe DMA Framework is a kernel extension that manages DMA (Direct +Memory Access) hardware. +

Device drivers use DMA to copy data quickly between memory locations, +and between memory and peripherals. This section describes how to create a +port of it for your phone hardware. The Device Driver Guide documentation +describes how to use the DMA Framework from a device driver.

+

The DMA Framework provides a Platform Independent Layer. You must provide +a Platform Specific Layer to implement the interface to the DMA Controller +hardware on your phone.

+
+ +DMA Framework in the Device Driver Tutorial +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-DF3045C7-4BDA-53AF-85E4-A8AAD99F40F7-master.png Binary file Adaptation/GUID-DF3045C7-4BDA-53AF-85E4-A8AAD99F40F7-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-DF3045C7-4BDA-53AF-85E4-A8AAD99F40F7_d0e18806_href.png Binary file Adaptation/GUID-DF3045C7-4BDA-53AF-85E4-A8AAD99F40F7_d0e18806_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-DF8CBC8C-9823-5FA9-962F-22215A6C0B74.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-DF8CBC8C-9823-5FA9-962F-22215A6C0B74.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,507 @@ + + + + + +ROMBUILD Obey File StructureA ROMBUILD obey file consists of a number +of section, each defining a ROM image. +

The sections are:

+
    +
  • a KernelRomSection that defines a bootable ROM image, and includes the Kernel

  • +
  • one or more ExtensionRomSection s that define ROM images that extend +the KernelRomSection.

  • +
+

Every section contains a list of obey statements that specify ROM +configuration information or specifies the files to be included in +the ROM image.

+

Extension ROM sections are marked by the extensionrom keyword, and can only contain those ROM information +statements that are not related to the Kernel configuration.

+

The structure is defined as:

+ObeyFile : KernelRomSection [ ExtensionRomList ] +KernelRomSection : ObeyStatementList +ExtensionRomList : ExtensionRomSection | ExtensionRomSection ExtensionRomList +ExtensionRomSection : extensionrom = <RomFileName> ObeyStatementList +ObeyStatementList : ObeyStatement | ObeyStatement ObeyStatementList +ObeyStatement : RomStatement | FileStatement +
    +
  • See RomStatement

  • +
  • See FileStatement

  • +
  • See extensionrom keyword

  • +
+
RomStatement

A RomStatement is one of the following.

+ + + +

romname =

+

<rom-file-name>

+
+ +

bootbinary =

+

<boot-file-name>

+
+ +codepagingpolicy +

[NOPAGING | ALWAYSPAGE | DEFAULTUNPAGED | DEFAULTPAGED]

+
+ +datapagingpolicy +

[NOPAGING | ALWAYSPAGE | DEFAULTUNPAGED | DEFAULTPAGED]

+
+ +codepagingoverride +

[NOPAGING | ALWAYSPAGE | DEFAULTUNPAGED | DEFAULTPAGED]

+
+ +datapagingoverride +

[NOPAGING | ALWAYSPAGE | DEFAULTUNPAGED | DEFAULTPAGED]

+
+ +

demandpagingconfig =

+

<MinLivePages> <MaxLivePages> + <YoungOldPageRatio> <NANDPageReadDelay> + <NANDPageReadCPUOverhead>

+
+ +

kerneldataaddress =

+

<hex-address>

+
+ +

kernelheapmin =

+

<hex-size>

+
+ +

kernelheapmax =

+

<hex-number>

+
+ +

maxunpagedsize

+

<hex-number>

+
+ +

kernelconfig =

+

<hex-number>

+
+ +

multikernel =

+

+
+ +

kerneltrace =

+

<32 bit hex-number | decimal number> [<32 +bit hex-number | decimal number>]{0,7}

The maximum number of bit mask is 8.

+
+ +

kernelromname =

+

<rom-file-name>

+
+ +

romnameodd =

+

<rom-file-name-odd>

+
+ +

romnameeven =

+

<rom-file-name-even>

+
+ +

srecordfilename =

+

<srec-file-name>

+
+ +

srecordbase =

+

<hex-address>

+
+ +

version =

+

[ <major> ] [ .<minor> ] [ (<build>) + ]

+
+ +

romsize =

+

<hex-size>

+
+ +

romlinearbase =

+

<hex-address>

+
+ +

romalign =

+

<hex-alignment>

+
+ +

dataaddress =

+

<hex-address>

+
+ +

romchecksum =

+

<base-checksum>

+
+ +

time =

+

dd/mm/yyyy hh:mm:ss

+
+ +

trace =

+

<32bit-hex-number>

+
+ +

debugport =

+

<32bit-number>

+
+ +

collapse =

+

<cpu> <compiler> <mode>

+
+ +

ascii =

+

+
+ +

unicode =

+

+
+ +

epocwrapper =

+

+
+ +

externaltool =

+

<toolname>

+
+ +

coffwrapper =

+

+
+ +

filecompressnone =

+

+
+ +

filecompressinflate =

+

+
+ +

filecompressbytepair =

+

+
+ +

filecompressnone =

+

+
+ +

filecompressinflate =

+

+
+ +

filecompressbytepair =

+

+
+ +

defaultstackreserve =

+

default stack reserve

+
+ +

demandpagingconfig =

+

<MinLivePages> <MaxLivePages> + <YoungOldPageRatio> <NANDPageReadDelay> + <NANDPageReadCPUOverhead>

+
+ +

dlldatatop =

+

address of data region

+
+ +

memmodel =

+

moving | direct | multiple <chunk size> <page + size>

+
+ +

nowrapper =

+

+
+ +

pagingoverride =

+

[NOPAGING | ALWAYSPAGE | DEFAULTUNPAGED | + DEFAULTPAGED]

+
+ +

pagingpolicy =

+

[NOPAGING | ALWAYSPAGE | DEFAULTUNPAGED | + DEFAULTPAGED]

+
+ +

platsecdiagnostics =

+

[on | off]

+
+ +

platsecdisabledcaps =

+

[on | off]

+
+ +

platsecenforcement =

+

[on | off]

+
+ +

platsecenforcesysbin =

+

[on | off]

+
+ +

platsecprocessisolation =

+

[on | off]

+
+ +

pagingoverride =

+

[NOPAGING | ALWAYSPAGE | DEFAULTUNPAGED | + DEFAULTPAGED]

+
+ +

pagingpolicy =

+

[NOPAGING | ALWAYSPAGE | DEFAULTUNPAGED | + DEFAULTPAGED]

+
+ +

patchdata =

+

<binary_name> ordinal <ordinal_no.> + <size_bytes> <new_value>

OR

<binary_name> addr <symbol_address> + <size_bytes> <new_value>

Where, <binary_name > is the name of the binary along with its +complete path, <ordinal_no. > is the ordinal +number of the symbol to be patched, <symbol_address > is the address of the data symbol to be patched, <size_bytes > is the size of the symbol in bytes, and <new_value > is the new value for the symbol.

Note: If you want to use the second version of patchdata, you must know the address of the data symbol to be patched.

+
+ +

BTrace =

+

N1 [N2 [N3 [N4 [N5 [N6 [N7 [N8]]]]]]]

+
+ +

BTraceBuffer =

+

N

+
+ +

BTraceMode =

+

N

+
+ + +
+
FileStatement FileStatement : ControlStatement | FileSpecificationStatement | RomDirectoryStatement

A ControlStatement is one of the following:

+ + + +

rem =

+

<comments>

+
+ +

section =

+

<section-offset>

+
+ +

extensionrom =

+

<rom-filename

+
+ +

align =

+

alignment

+
+ +

area =

+

<name> <run-address> <maxlength>

+
+ +

stop =

+

+
+ + +

A FileSpecificationStatement is one of +the following:

+ + + +

data[[HWVD]] =

+

<source-file> <destination-image-file> + [ FileAttributeList ]

+
+ +

file[[HWVD]] =

+

<Source-file> <destination-file> [ FileAttributeList] [OverrideAttributeList ] [paged | +unpaged]

+
+ +

primary[[HWVD]] =

+

<source-file> <destination-image-file> + [ FileAttributeList ] [OverrideAttributeList ]

+
+ +

secondary =

+

<source-file> <destination-image-file> + [ FileAttributeList ] [OverrideAttributeList ]

+
+ +

variant[[HWVD]] =

+

<source-file> <destination-image-file> + [ FileAttributeList ] [OverrideAttributeList ]

+
+ +

device[[HWVD]] =

+

<source-file> <destination-image-file> + [ FileAttributeList ] [OverrideAttributeList ]

+
+ +

extension[[HWVD]] =

+

<source-file> <destination-image-file> + [ FileAttributeList ] [OverrideAttributeList ]

+
+ +

dll[[HWVD]] =

+

<source-file> <destination-image-file> + [ FileAttributeList ] [OverrideAttributeList ]

+
+ +

filecompress[[HWVD]] =

+

<source-file> <destination-image-file> + [ FileAttributeList ] [OverrideAttributeList ]

+
+ +

fileuncompress[[HWVD]] =

+

<source-file> <destination-image-file> + [ FileAttributeList ] [OverrideAttributeList ]

+
+ + +

A RomDirectoryStatement is one of the +following:

+ + + +

hide[[HWVD]] =

+

<existing-file>

+
+ +

alias[[HWVD]] =

+

<existing-file> <destination-file> + [ FileAttributeList ]

+
+ +

rename[[HWVD]] =

+

<existing-file> <destination-file> [ FileAttributeList ] [ OverrideAttributeList ]

+
+ + +
+
FileAttributeList FileAttributeList : FileAttribute | FileAttribute FileAttributeList

A FileAttribute is one of the following:

+ + + +

attrib =

+

[ s | S ][ h | H ][ r | R | w | W ] | hide

+
+ + +
+
OverrideAttributeList OverrideAttributeList : OverrideAttribute | OverrideAttribute OverrideAttributeList

An overrideAttribute is one of the following:

+ + + +data-align +

<hex-number>

+
+ +capability = +

<capability>

+
+ +process = +

<filepath>

+
+ +preferred + + + +paged + + + +unpaged + + + +pagedcode + + + +unpagedcode + + + +pageddata + + + +unpageddata + + + +

stackreserve =

+

<hex-size>

+
+ +

stack =

+

<hex-size>

+
+ +

reloc =

+

<hex-address>

+
+ +

heapmin =

+

<hex-size>

+
+ +

heapmax =

+

<hex-size>

+
+ +

code-align =

+

<hex-number>

+
+ +

fixed

+

+
+ +

priority =

+

<hex-number> | <keyword>

+
+ +

patched

+

+
+ +

uid1 =

+

<uid value>

+
+ +

uid2 =

+

<uid value>

+
+ +

uid3 =

+

<uid value>

+
+ +

stackreserve =

+

<hex-size>

+
+ +

area =

+

<name>

+
+ + +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-DFADEB44-4D57-564F-ABDF-A3CCD38ACABC-master.png Binary file Adaptation/GUID-DFADEB44-4D57-564F-ABDF-A3CCD38ACABC-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-DFADEB44-4D57-564F-ABDF-A3CCD38ACABC_d0e15086_href.png Binary file Adaptation/GUID-DFADEB44-4D57-564F-ABDF-A3CCD38ACABC_d0e15086_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-DFDB6864-0F63-41EC-B549-791B750F3EB3.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-DFDB6864-0F63-41EC-B549-791B750F3EB3.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,19 @@ + + + + + +DMA Client InterfaceDescribes the DMA platform service to the higher layers +of the platform. +

The DMA client interface is the interface between DMA and the higher +layers of the platform

+
+DMA +Client Interface Guide +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-E081474F-6B17-5D2E-833B-E8177778577A.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-E081474F-6B17-5D2E-833B-E8177778577A.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,20 @@ + + + + + +Digitizer DriverThe Digitizer Driver is a kernel extension that manages digitizers +(touch screens). +

Graphic User Interface (GUI) that accept input from a pen or a stylus +must implement the driver. This section describes how to create a port of +it for your phone hardware.

+

Symbian platform provides a generic Platform Independent Layer for the +driver. You must provide a Platform Specific Layer to implement the interface +to the digitizer hardware on your phone.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-E0A0C542-2922-407D-88E9-2DC5D159E1F6.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-E0A0C542-2922-407D-88E9-2DC5D159E1F6.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,15 @@ + + + + + +Interrupt Tools GuideTools required for the Interrupt platform service. +

There are no specific tools required to use or implement the Interrupt +platform service.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-E0DCBDCF-C056-53E5-A375-778327F848E4.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-E0DCBDCF-C056-53E5-A375-778327F848E4.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,408 @@ + + + + + +Asic Class TutorialProvides a work through tutorial that allows you to port +an Asic implementation to the template variant. +

This tutorial +describes how to implement the Asic class. This is a pure virtual +interface that is defined and called by the Kernel, but which must +be implemented by the ASSP/Variant. The tutorial assumes that the +ASSP/Variant is split into an ASSP layer and a Variant layer.

+

For a minimal port, it isn't necessary to provide implementations +for the entire Asic class to be able to test that +the kernel boots, provided that those functions that are not fully +implemented have a dummy function so that the code will build.

+

The Asic class is defined in..\e32\include\kernel\arm\assp.h. For reference, the definition is:

+class Asic + { +public: + // initialisation + virtual TMachineStartupType StartupReason()=0; + virtual void Init1()=0; + virtual void Init3()=0; + + // debug + virtual void DebugOutput(TUint aChar)=0; + + // power management + virtual void Idle()=0; + + // timing + virtual TInt MsTickPeriod()=0; + virtual TInt SystemTimeInSecondsFrom2000(TInt& aTime)=0; + virtual TInt SetSystemTimeInSecondsFrom2000(TInt aTime)=0; + virtual TUint32 NanoWaitCalibration()=0; + + // HAL + virtual TInt VariantHal(TInt aFunction, TAny* a1, TAny* a2)=0; + + // Machine configuration + virtual TPtr8 MachineConfiguration()=0; + }; +

Taking the template port as a concrete example, the ASSP layer +implementation of the Asic class is defined and +implemented by the TemplateAssp class, and the Variant +implemention is defined and implemented by the Template class.

+
Asic::Init1() +implementation

Entry conditions

    +
  • called in the +context of the initial (null) thread

  • +
  • interrupts are +disabled

  • +
  • there is no +kernel heap

  • +
  • memory management +functions are not available.

  • +

What the function should do

This is called during +stage 1 of kernel initialisation.

In this function, you need +to:

    +
  • initialise the +real time clock

  • +
  • initialise the +interrupt dispatcher before CPU interrupts are enabled.

  • +
  • set the threshold +values for cache maintenance. You can set separate values for:

      +
    • purging (invalidating) +a cache

    • +
    • cleaning a cache

    • +
    • flushing (i.e. +cleaning and invalidating) a cache.

    • +

    You use the Cache::SetThresholds() interface +to set these values.

    As an example of what the threshold values +mean, if you purge a memory region from cache, and the size of that +region is greater than the threshold value, then the entire cache +is purged. If the size of that region is less than or equal to to +the threshold value, then only the region is purged.

    The threshold +values are platform specific, and you need to choose your values based +on your own performance measurements. Symbian cannot make recommendations. +If you choose not to set your own values, Symbian platform supplies +a set of default values, which are set by Cache::Init1().

    Note that there is also a Cache::GetThresholds() interface that you may find useful.

  • +
  • set up the RAM +zones. For details, see the RAM Zone Tutorial.

  • +

Typically, you would also initialise any memory devices not +initialised by the bootstrap. Any other initialisation that must happen +early on should also be done here.

The kernel calls the Variant's Init1() function. On the template port, this is the Variant +layer's Init1(), i.e. the functions Template::Init1(). The source for this is in ...\template_variant\specific\variant.cpp.

void Template::Init1() + { + __KTRACE_OPT(KBOOT,Kern::Printf("Template::Init1()")); + + // + // TO DO: (mandatory) + // + // Configure Memory controller and Memrory Bus parameters (in addition to what was done in the Bootstrap) + // + __KTRACE_OPT(KBOOT,Kern::Printf("Memory Configuration done")); + + // + // TO DO: (optional) + // + // Inform the kernel of the RAM zone configuration via Epoc::SetRamZoneConfig(). + // For devices that wish to reduce power consumption of the RAM IC(s) the callback functions + // RamZoneCallback() and DoRamZoneCallback() will need to be implemented and passed + // to Epoc::SetRamZoneConfig() as the parameter aCallback. + // The kernel will assume that all RAM ICs are fully intialised and ready for use from boot. + // + + // + // TO DO: (optional) + // + // Initialise other critical hardware functions such as I/O interfaces, etc, not done by Bootstrap + // + // if CPU is Sleep-capable, and requires some preparation to be put in that state (code provided in Bootstrap), + // the address of the idle code is writen at this location by the Bootstrap + // e.g. + // iIdleFunction=*(TLinAddr*)((TUint8*)&Kern::SuperPage()+0x1000); + // + TemplateAssp::Init1(); + }

The last line is a call into the ASSP layer, +which is implemented as shown below. On the template port, it is the +ASSP layer that initialises the interrupt dispatcher and the real +time clock. The source for this is in ...\template_assp\assp.cpp:

EXPORT_C void TemplateAssp::Init1() + { + __KTRACE_OPT(KBOOT,Kern::Printf("TemplateAssp::Init1()")); + // + // TO DO: (optional) + // + TemplateInterrupt::Init1(); // initialise the ASSP interrupt controller + + // + // TO DO: (optional) + // + // Initialises any hardware blocks which require early initialisation, e.g. enable and power the LCD, set up + // RTC clocks, disable DMA controllers. etc. + // + } + +

TemplateInterrupt::Init1(); is +static function that initialises the interrupt dispatcher. See Interrupt Layer Initialisation.

+
Asic::Init3() +implementation

Entry conditions

    +
  • called in the +context of the supervisor thread

  • +
  • the kernel is +ready to handle interrupts

  • +
  • the kernel heap +and memory management system is fully functional.

  • +

What the function should do

This is called during +stage 3 of kernel initialisation.

In this function, you need +to:

    +
  • enable interrupt +sources

  • +
  • start the millisecond +tick timer.

  • +
  • Optionally, +replace the implementation used by Kern::NanoWait().

  • +

Any other general initialisation can also be done here.

As an example, on the template port, the function is implemented +in the Variant layer, by Template::Init3().

Millisecond tick timer

The kernel expects that the +kernel's tick handler routine will be called at a fixed microsecond +period, the value of which is returned by the implementation of Asic::MsTickPeriod() function. The Init3() function must be implemented to start this. See Kernel Timers for background information.

The template implementation +is as follows:

EXPORT_C void TemplateAssp::Init3() + { + __KTRACE_OPT(KBOOT,Kern::Printf("TemplateAssp::Init3()")); + + TTemplate::Init3(); + + NTimerQ& m=*(NTimerQ*)NTimerQ::TimerAddress(); + iTimerQ=&m; + // + // TO DO: (mandatory) + // + // If Hardware Timer used for System Ticks cannot give exactly the period required store the initial rounding value + // here which is updated every time a match occurs. Note this leads to "wobbly" timers whose exact period change + // but averages exactly the required value + // e.g. + // m.iRounding=-5; + // + + TInt r=Interrupt::Bind(KIntIdOstMatchMsTimer,MsTimerTick,&m); // bind the System Tick interrupt + if (r!=KErrNone) + Kern::Fault("BindMsTick",r); + + // + // TO DO: (mandatory) + // + // Clear any pending OST interrupts and enable any OST match registers. + // If possible may reset the OST here (to start counting from a full period). Set the harwdare to produce an + // interrupt on full count + // + + r=Interrupt::Enable(KIntIdOstMatchMsTimer); // enable the System Tick interrupt + if (r!=KErrNone) + Kern::Fault("EnbMsTick",r); + + // + // TO DO: (optional) + // + // Allocate physical RAM for video buffer, as per example below. However with some hardware, the Video Buffer + // may not reside in main System memory, it may be dedicated memory. + // + // EXAMPLE ONLY + TInt vSize=VideoRamSize(); + r=Epoc::AllocPhysicalRam(2*vSize,TemplateAssp::VideoRamPhys); + if (r!=KErrNone) + Kern::Fault("AllocVRam",r); + }

Servicing the timer interrupt

The timer interrupt +service routine is required only to call the Ntimer::TickQ() function and perform any housekeeping necessary to ensure that the +handler itself is called again after the time reported by the MsTickPeriod() routine. Since the handler is called frequently, +it is written in assembler for the fastest execution.

__NAKED__ void MsTimerTick(TAny* aPtr) + { + // Service 1ms tick interrupt + asm("ldr ip, [r0, #%a0]" : : "i" _FOFF(NTimerQ,iRounding)); + asm("ldr r2, __KHwBaseOst "); + asm("adds ip, ip, #2 "); + asm("ldr r3, __KOst1000HzTickMatchIncrement "); + asm("subcs ip, ip, #5 "); + asm("str ip, [r0, #%a0]" : : "i" _FOFF(NTimerQ,iRounding)); + asm("addcs r3, r3, #1 "); + asm("mov r1, #%a0" : : "i" ((TInt)(1<<KHwOstMatchMsTimer))); + asm("str r1, [r2, #0x14] "); // clear interrupt + asm("ldr r1, [r2, #%a0]" : : "i" ((TInt)KHwOstMatchMsTimer*4)); // r1=old match value + asm("add r1, r1, r3 "); // step match value on + asm("ldr ip, [r2, #0x10] "); // r3=system timer value + asm("str r1, [r2, #%a0]" : : "i" ((TInt)KHwOstMatchMsTimer*4)); + asm("cmp ip, r1 "); // compare to next match value + +#ifdef _DEBUG + asm("addpl r1, ip, #10 "); // in DEBUG if timer>match value, set match value to timer + a bit + asm("strpl r1, [r2, #%a0]" : : "i" ((TInt)KHwOstMatchMsTimer*4)); + asm("b Tick__7NTimerQ "); // call interrupt handler anyway +#else + asm("bmi Tick__7NTimerQ "); // if timer<match value, OK - call interrupt handler +#endif + + // otherwise we are late for the next tick so force a data abort exception... + asm("mvn r2, #0x10000002 "); // r2=0xeffffffd + asm("str r2, [r2] "); // die + + // Constant data embedded in code. + asm("__KOst1000HzTickMatchIncrement: "); + asm(".word %a0" : : "i" ((TInt)KOst1000HzTickMatchIncrement)); + asm("__KHwBaseOst: "); + asm(".word %a0" : : "i" ((TInt)KHwBaseOst)); + }

Note that it is a requirement that the timer +period should be an integral number of microseconds, even if the exact +period is not 1000us. It is always possible to add code to the interrupt +handler to achieve this average so that over a large number of ticks, +the deviation from this average will tend to 0, by adjusting the exact +number of ticks from tick to tick. See also Timers

NanoWait() implementation

Kern::NanoWait() is a function that can be called if you want to wait for very short +periods of time within the kernel. You call this function and specify +the number of nanoseconds. The function is, in effect, a shell that +uses default implementation code provided by the generic platform. +You can provide your own implementation in your port, and register +this with the platform. This allows the wait functionality to be implemented +in the best possible way for your platform, possibly by using a hardware +timer whose frequency is independent of the CPU frequency.

To replace the default implementation, you need to:

    +
  • code your own +function. This has the same signature as Kern::NanoWait():

    void AsicImpl::DoNanoWait(TUint32 aInterval) +    { +    // Wait for aInterval nanoseconds +    }

    where AsicImpl is the class that is ultimately derived from Asic.

  • +
  • register this +implementation by adding the following call into your Asic::Init3() function:

    Kern::SetNanoWaitHandler(AsicImpl::DoNanoWait);
  • +

You can see where this goes by looking at the template port +at: ...\base\cedar\template\template_assp\template_assp.cpp

+
Asic::DebugOutput() +implementation

It is worth implementing this early so that +it is possible to get trace output to see what the kernel is doing. +This function is passed one character at a time. Normally this is +sent to a UART, though it can be output through any convenient communications +channel.

On the template port, this is implemented in the +Variant layer, by Template::DebugOutput() in ...\template_variant\specific\variant.cpp.

+
Asic::Idle() +implementation

If no power management has been implemented, +then this function is called when the system is to idle to allow power +saving. This function can just return, until power management is implemented. +Once power management has been implemented, then idling behaviour +will be handled by the power controller, i.e. the Variant's implementation +of the DPowerController class

+
Asic::MsTickPeriod() +implementation

This function is used to return the number +of microseconds per tick. To avoid timing drift, a tick frequency +should be chosen that gives a round number of microseconds per tick. +The function can return zero until the tick timer has been implemented.

On the template port, this function is implemented in the ASSP +layer, and can be found in the source file ...\template_assp\assp.cpp. It is a simple function that just returns the value.

EXPORT_C TInt TemplateAssp::MsTickPeriod() + { + // + // TO DO: (mandatory) + // + // Return the OST tick period (System Tick) in microseconds ( 10E-06 s ). + // + return 1000; // EXAMPLE ONLY + } +

See also Timers.

+
Asic::SystemTimeInSecondsFrom2000() + implementation

This is a function that the kernel +uses to get the system time. Its signature is

Tint SystemTimeInSecondsFrom2000(Tint& aTime);

An implementation must set the aTime reference +to the number of seconds that have elapsed since the start of the +year 2000. This is a positive number; a negative number is interpreted +as time before 2000.

For the template reference board, the +implementation is as follows:

EXPORT_C TInt TemplateAssp::SystemTimeInSecondsFrom2000(TInt& aTime) + { + aTime=(TInt)TTemplate::RtcData(); + __KTRACE_OPT(KHARDWARE,Kern::Printf("RTC READ: %d",aTime)); + return KErrNone; + } +

Until a real time clock is implemented, this function +can just return KErrNone.

This function +calls the register access functions in the TTemplate class. See ...\template_assp\template_assp.cpp for implementation details.

Note that tracing output is +provided when the KHARDWARE bit in the kerneltrace flags is set for +the debug build.

+
Asic::SetSystemTimeInSecondsFrom2000() +implementation

This is a function that the kernel uses +to set the system time. Its signature is

Tint SetSystemTimeInSecondsFrom2000(Tint aTime);

This sets the real time clock to the number of seconds that have +elapsed since the start of the year 2000. This is a positive number; +a negative number is interpreted as time before 2000.

For +the template reference board, the implementation is as follows:

EXPORT_C TInt TemplateAssp::SetSystemTimeInSecondsFrom2000(TInt aTime) + { + // + // TO DO: (optional) + // + // Check if the RTC is running and is stable + // + __KTRACE_OPT(KHARDWARE,Kern::Printf("Set RTC: %d",aTime)); + TTemplate::SetRtcData(aTime); + __KTRACE_OPT(KHARDWARE,Kern::Printf("RTC: %d",TTemplate::RtcData())); + return KErrNone; + } +

Note that tracing output is provided when the KHARDWARE +bit in the kerneltrace flags is set for the debug build. In this function, +the trace output shows the value passed in from the kernel and then +shows the value read back from the real time clock for verification.

+
Asic::NanoWaitCalibration() + implementation

The function Kern::NanoWait() can be called if you want to wait for very short periods of time +within the kernel. You call this function and specify the number of +nanoseconds. You can either use the default implementation of this +function, or you can provide your own.

The default implementation +provided by Symbian platform that Kern::NanoWait() uses is a busy loop that is calibrated by calling Asic::NanoWaitCalibration(). NanoWaitCalibration() should return the number +of nanoseconds taken to execute 2 machine cycles. This is obviously +dependent on the CPU clock speed, so if variants are likely to run +at different speeds, then this should be implemented in the Variant +layer.

This approach cannot always take into account factors +such as processor frequency scaling. An alternative approach is for +the Variant to supply its own implementation to be used by Kern::NanoWait(). Note that you do not replace Kern::NanoWait() itself as this is a shell function that results in a call to the +the implementation. See Asic::Init3() for detail on how to replace the implementation.

On the template port, Asic::NanoWaitCalibration() is implemented in the ASSP layer, and not in the Variant layer, +and can be found in the source file ...\template_assp\assp.cpp. It is a simple function that just returns the value.

EXPORT_C TUint32 TemplateAssp::NanoWaitCalibration() + { + // + // TO DO: (mandatory) + // + // Return the minimum time in nano-seconds that it takes to execute the following code: + // nanowait_loop: + // subs r0, r0, r1 + // bhi nanowait_loop + // + // If accurate timings are required by the Base Port, then it should provide it's own implementation + // of NanoWait which uses a hardware counter. (See Kern::SetNanoWaitHandler) + // + + return 0; // EXAMPLE ONLY + } +
+
Asic::VariantHal() +implementation

You might find it useful to review User-Side Hardware +Abstraction Technology first.

This is the HAL handler +for the HAL group THalFunctionGroup::EHalGroupVariant.

+
Asic::MachineConfiguration() + implementation

This returns a TPtr8 descriptor representing an area containing machine configuration +information.

The address of this object is obtained by calling Kern::MachineConfig(). However, the Variant (either the +ASSP layer or the Variant layer or both) is responsible for the content.

In the template port, the function is implemented in the Variant +layer:

TPtr8 Template::MachineConfiguration() + { + return TPtr8((TUint8*)&Kern::MachineConfig(),sizeof(TActualMachineConfig),sizeof(TActualMachineConfig)); + } +

Here, the machine configuration information is represented +by an object of type TTemplateMachineConfig, which +derives from TMachineConfig. In effect, TMachineConfig represents information that is common to all, while the Variant +can extend this to contain whatever information is appropriate.

Note that TActualMachineConfig is a typedef +for TTemplateMachineConfig.

+
Asic::StartupReason() +implementation

If a startup reason is available from hardware +or a preserved RAM location, it should be returned by the function. +The default is to return EStartupColdReset.

On the template port, this is implemented in the ASSP layer:

EXPORT_C TMachineStartupType TemplateAssp::StartupReason() + { + __KTRACE_OPT(KBOOT,Kern::Printf("TemplateAssp::StartupReason")); + #ifdef _DEBUG // REMOVE THIS + TUint s = Kern::SuperPage().iHwStartupReason; + __KTRACE_OPT(KBOOT,Kern::Printf("CPU page value %08x", s)); + #endif // REMOVE THIS + // + // TO DO: (mandatory) + // + // Map the startup reason read from the Super Page to one of TMachineStartupType enumerated values + // and return this + // + return EStartupCold; // EXAMPLE ONLY + } +
+
+ +ASSP/Variant Architecture +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-E1277A18-7201-4856-8712-067022F92123.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-E1277A18-7201-4856-8712-067022F92123.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,84 @@ + + + + + +DSDIOStack +Class TutorialDescribes the DSDIOStack API class. +
Description

The DSDIOStack class +provides the SDIO specific implementation of the initialization state machine +and the support for asynchronous IO read and write operations.

+ + + +

Header file

+

sdio.h

+
+ +

Source code file

+

sdiostack.cpp

+
+ +

Required libraries

+

EPBUSSDIO

+
+ +

Class declaration

+

class DSDIOStack : public DStackBase

+
+ + +
+
AcquireStackSM()

The +function declaration for the AcquireStackSM()method is:

IMPORT_C virtual TMMCErr AcquireStackSM();

Description

This adds a new SDIO card to the SDIO card stack. +This is an extension of the DSDStack::AcquireStackSM state +machine function. It handles the SDIO initialization procedure as described +in version 1.10f of the SDIO card specification.

Parameters

None

Return +value

+ + + +

TMMCErr

+

Return code of the operation. The return value is KErrNone if +the operation was successful, otherwise an error code.

+
+ + +
+
CIMIoReadWriteDirectSM()

The +function declaration for the CIMIoReadWriteDirectSM() method +is:

IMPORT_C TMMCErr CIMIoReadWriteDirectSM();

Description

Implements +the state machine for the IO_RW_DIRECT command (CMD52).

Parameters

None

Return +value

+ + + +

TMMCErr

+

Return code of the operation. The return value is KErrNone if +the operation was successful, otherwise an error code.

+
+ + +
+
CIMIoReadWriteExtendedSM()

The +function declaration for the CIMIoReadWriteExtendedSM() method +is:

IMPORT_C TMMCErr CIMIoReadWriteExtendedSM();

Description

Used +to write an CMD53 command to the card.

Parameters

None

Return +value

+ + + +

TMMCErr

+

Return code of the operation. The return value is KErrNone if +the operation was successful, otherwise an error code.

+
+ + +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-E1FEEDCE-0CD5-559C-9AE0-8090A613C166.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-E1FEEDCE-0CD5-559C-9AE0-8090A613C166.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,28 @@ + + + + + +Obey File Syntax Conventionsobey file contents must follow certain +conventions. +

The following conventions apply to all obey file statements:

+
    +
  • A line that +is a comment can be identified using the rem keyword.

  • +
  • Blank lines +are ignored.

  • +
  • The = symbol, where used, is optional; a blank character can +be used instead.

  • +
  • A file name +can, optionally, be enclosed within quotes; a file name that +contains spaces must be enclosed within quotes.

  • +
  • The stop statement causes the rest of the obey file to be ignored.

  • +
+

+ \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-E21C4AF8-852A-5BBD-A92A-5473D1DFFBB1.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-E21C4AF8-852A-5BBD-A92A-5473D1DFFBB1.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,12 @@ + + + + + +Media Driver TutorialDescribes the steps to implement a new Media Driver. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-E21E7992-607A-5A49-B022-189ECA9E76D1.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-E21E7992-607A-5A49-B022-189ECA9E76D1.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,61 @@ + + + + + +Code +Paging OverviewOverview of demand paging when applied to code paging. +

Purpose

Demand +paging is a technique where memory appears to application programs to be present +in RAM, but may in fact be stored on some external media and transparently +loaded into RAM when needed. Demand paging trades off increased available +RAM against decreased performance, increased media wear and increased power +usage. More RAM is made available by loading pages only on demand, but a cost +is incurred every time a page is loaded.

Demand paging is used to +reduce the amount of RAM that needs to be shipped with a device and so reduce +its cost.

For the code paging type of demand paging, the executable +is stored in a ROM. Since the memory locations that will be pointed to cannot +be determined ahead of time, the pointers in the executable have to be modified +after the page-in process. This process is known as 'relocation' and 'fix-up'. +It is usually done by loader.

+
Description

The +executable is in a ROM and so has to be loaded into RAM before it can be executed. +When the required part of the executable is not present in RAM, then a paging +fault is generated which starts the paging in process of specifying which +part of the ROM is to be paged-in along with which RAM page is to be used.

The +above process (in very simple terms) describes how ROM paging works. With +code paging, there is the added complication that the executable is not execute +in place (it is probably stored via the use of an operating system e.g. ROFS) +and so when it is paged in any pointers in the page will not point to any +valid location. Hence a new step has to be carried out that modifies the pointers +in the new page so that will point to meaningful locations once they are RAM. +This process is known as 'relocation' and 'fix-up'. It is usually done by +loader.

+
Components

These +are the main components of code demand paging:

    +
  • Rom image - The executable +is stored in a ROM.

  • +
  • RAM - Where the executable +will be executed.

  • +
  • Paging Fault Handler +- To detect that a page-in process is required and to carry it out.

  • +
  • Loader - This usually +does the 'relocation' and 'fix-up' process after the 'page-in' process.

  • +
+
Using ROM Paging

Which +type of paging is used and for which area of memory is first specified the oby and mmp files +and finally build by using specific parameters in the buildrom utility.

+
+Code Paging +Guide +ROM Paging + +Demand Paging +Overview +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-E2641957-8163-5EF4-B282-FC3FD9CA75A6.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-E2641957-8163-5EF4-B282-FC3FD9CA75A6.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,76 @@ + + + + + +Sound +Driver TechnologyDescribes the technology concepts that are used in the Sound Driver. +
Audio hardware +device

An audio hardware device is an individual hardware codec +device together with any associated controller hardware that allows the CPU +to communicate with it.

A basic audio hardware device typically provides +two communication paths: an input path for the audio recording and an output +path for audio playback.

Most basic audio hardware devices support +full duplex data transfer although some are only half-duplex or maybe just +simplex. Each input or output path may be used to transfer mono data or stereo +data. In the case of stereo this consists of two audio channels, the left +and the right; mono data consists of just a single audio channel.

A +more complex audio hardware device could be an AC 97 codec or similar, plus +its associated controller, which can support multiple input and output paths. +Each input or output path may be used to transfer mono data, stereo data or +'multichannel data'. For example, left, right, centre, left and right surround +and Low-Frequency Effects (LFE).

+
Unit

Units +are used to provide access to the various audio hardware devices. Each unit +supports just one communication path this is either input or output.

Clients +of the audio hardware system can open a separate connection to each unit. +The mapping between the units on a given phone and the audio hardware devices +themselves is platform specific; this is determined by the implementer of +the Sound Driver PDD for that platform.

A basic full-duplex audio +hardware device is presented as two units, one input/record unit and one output/playback +unit. A more complex audio hardware device such as an AC 97 codec may be represented +to the rest of the OS as a number of audio input and output units.

+
Audio channel

An +audio channel is a data stream between a client and an audio unit. There are +one or more audio channels per driver channel.

+
Driver channel

A +driver channel is a session between a client and an audio unit. A client may +have driver channels open on more than one unit.

The difference +between a driver channel and an audio channel. A driver channel is a session +between the client and an audio device which can consist of one or more audio +channels. An audio channel refers to the audio stream, for example, left or +right output.

+ The relationship between audio channels and device channels. + + +
+
Mono to stereo +conversion

Many codecs that support stereo playback can only accept +audio data that is delivered with the samples for each of the channels interleaved, +for example, LRLRLR. For these audio hardware devices, in order to operate +the channel in mono mode and to play audio data which contains only samples +for a single channel it is necessary to perform mono-to-stereo conversion +on the audio data before delivering it to the codec. So, for a section of +mono audio data that contains three samples, lets call them S1, S2 and S3, +each sample is duplicated, so we have S1,S1,S2,S2,S3,S3, with identical samples +being delivered to each channel.

Unfortunately, the only way for the +PDD to implement this conversion is for it to allocate a conversion buffer +and to copy each sample twice into this buffer. The PDD has to allocate a +separate conversion buffer for each simultaneous transfer operation it supports, +for example, for the template playback driver, a conversion buffer count equal +to KTemplateMaxTxDmaRequests.

When performing conversion +in this manner, the maximum transfer size that the PDD can accept from the +LDD becomes half the size of each conversion buffer, and when configured in +this mode, the value returned to the LDD in response to DSoundScPdd::MaxTransferLen must +equal this value.

Likewise, the record data may be delivered by the +audio hardware device only in stereo format with the data samples for each +channel interleaved. If the driver channel is configured in mono record mode, +stereo to mono conversion has to be performed in the PDD to discard each alternate +sample.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-E3C70135-EC0C-504C-B428-53A5750B520B.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-E3C70135-EC0C-504C-B428-53A5750B520B.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,144 @@ + + + + + +BUILDROM Specific StatementsThere are certain statements that BUILDROM can process. +

BUILDROM understands the following statements:

+ + + + +

##

+

Performs textual substitution. All subsequent instances +of the two characters ## are replaced with an empty string.

+
+ +

ABI_DOWNGRADE =

+

from->to

+
+ +

AUTO-BITMAP =

+

<source> <dest>

+
+ +

BITMAP =

+

<source> <dest>

+
+ +

BINARY_SELECTION_ORDER =

+

<source-build1>,<source-build2>,...

+
+ +

compress

+ +
+ +

COMPRESSED-BITMAP =

+

<source> <dest>

+
+ +DATA_IMAGE +<id> <name> [size=<partition size>] [FAT16 +| FAT32] [compress | no-compress] + + +

DEFAULT_LANGUAGE =

+

NN

+
+ +

DEFINE =

+

<name> <replacement>

+
+ +

ECHO =

+

<anything at all>

+
+ +

__ECOM_PLUGIN =

+

(<local build directory>, <rom binary directory>, + <local epoc32\data\Z directory>, <rom resources +directory>, <DLL filename>, <resource filename>)

+
+ +

EPOCROOT =

+ +
+ +

ERROR =

+

<anything at all>

+
+ +

EXCLUDE_FEATURE =

+

<feature>

+
+ +

externaltool =

+

<toolname>

+
+ +

FEATURE =

+

<feature>

+
+ +

_HIDE__ECOM_PLUGIN =

+

(<local build directory>, <rom binary directory>, + <local epoc32\data\Z directory>, <rom resources +directory>, <DLL filename>, <resource filename>)

+
+ +

LANGUAGE_CODE =

+

NN

+
+ +

patchdata =

+

<binary_name> @ <symbolname> + <newvalue>

+
+ +

RIGHT_NOW =

+ +
+ +

ROMBUILD_OPTION =

+

<command line option>

+
+ +

ROM_IMAGE =

+

<id> <name> [size=<rom max size>] [xip +| non-xip] [compress | no-compress] [extension]

+
+ +

SECTION2 =

+

<anything>

+
+ +

spidata =

+

<source-file> <original-destination-file> + <spi-id> <target-spi-dir>

+
+ +

spidatahide =

+

<source-file> <spi-id> <target-spi-dir>

+
+ +

TODAY =

+ +
+ +

WARNING =

+

<anything at all>

+
+ +

<xxx>=MULTI_LINGUIFY =

+

(<ext> <sourcename> <destname>)

+
+ + +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-E3C7CB78-8A68-4FFA-BD00-04D27E67C1F3.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-E3C7CB78-8A68-4FFA-BD00-04D27E67C1F3.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,43 @@ + + + + + +Interrupt Quick StartDescribes how to get started with the Interrupt +platform service. +
Getting +started
    +
  • The Interrupt Technology Guide describes the key concepts of the +Interrupt platform service.

  • +
  • The Interrupt Client Interface section describes the Interrupt +platform service API and its use by device drivers.

  • +
  • The Interrupt Implementation section describes the implementation +of the Interrupt PSL.

  • +
  • The Interrupt Build Guide describes how to include the Interrupt +platform service in a ROM image.

  • +
  • The Interrupt Tools Guide describes the tools that are specific +to the Interrupt platform service.

  • +
  • The Interrupt Testing Guide explains how to test the functionality +of the Interrupt platform service.

  • +
+
Architecture

The following diagram shows the architecture of the Interrupt +platform service:

+Interrupt platform service architecture + +

The Interrupt platform service provides an interface between +the interrupt controller in the hardware and device drivers in the +kernel-side. The Interrupt platform service is implemented in the +ASSP/Variant module.

+
Key +users
    +
  • Device driver developers – to bind and unbind interrupts.

  • +
  • Hardware implementers and base port developers - to implement +an interrupt dispatcher to manage interrupts.

  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-E4447BEF-33D2-5099-BCC1-C72FBB3B0463.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-E4447BEF-33D2-5099-BCC1-C72FBB3B0463.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,365 @@ + + + + + +BUILDROM +

BUILDROM is the Symbian platform ROM configuration tool. It is +a unified ROM building front end to prepare the configurations. It +then invokes the ROMBUILD to generate the ROM image or ROFSBUILD to +generate the ROFS image.

+
BUILDROM +command syntax

If the OBY files are encoded in UTF-8 with +non-ASCII character support, use the following the BUILDROM command +syntax:

BUILDROM [options] <–oby-charset=utf-8 obyfile > [<obeyfile2> [obeyfile3 [...

If the OBY files are encoded in local character set +with non-ASCII character support, use the following the BUILDROM command +syntax:

BUILDROM [options] <obeyfile1> [<obeyfile2> [obeyfile3 [...

options can be one or more of the following:

+ + + +

–argfile=<parameter file>

+

Accepts a parameter file, which contains a list of command-line +parameters specific to the ROM tools, as input.

+
+ +

-Dxxx

+

C++ preprocessor arguments. A common, but not exhaustive +set is:

+ + + +

-D_DEBUG

+

Selects debug versions of some files.

+
+ +

-D_FULL_DEBUG

+

Selects debug versions of all files.

+
+ +

-D_ARM4T

+

Specifies the target platform.

+
+ +

-D_KABI=xxxx

+

Specifies the target platform for the kernel (for example, +ARMv5).

+
+ +

-D_EABI=xxxx

+

Specifies the target for all files (for example, ARMv5).

+
+ +

-DFEATUREVARIANT=xxxx

+

Specifies the name of feature-based variant (for example, +myvar).

BUILDROM automatically looks for the binary names +and properties of the selected variant, using the data generated by +build system.

+
+ +

-D_NAND2

+

Specifies to generate the image for NAND flash.

+
+ +

-D_ONENAND

+

Specifies to generate the image for ONENAND flash.

+
+ + +

+ + +

-lowmem

+

Reduces the physical memory consumption during image generation.

+
+ +

-loglevel<level>

+

Level of information to log file. The following valid log +levels are available:

+ + + +

0

+

Default level of information to log file.

+
+ +

1

+

Logs the host or the ROM filenames, the file size, and the +hidden attribute in addition to the loglevel 0 information.

+
+ +

2

+

Logs the E32 file header attributes such as UIDs, data size, +heap size, stack size, VID, SID, and priority in addition to the loglevel 1 information.

+
+ + +

+
+ +

-nospi

+

Instructs BUILDROM not to produce any static +plug-in information (.spi) files. See the __ECOM_PLUGIN keyword for details of these files. The default +is to produce .spi files.

+
+ +

-noimage

+

Instructs BUILDROM to suppress only the +generation of any ROM or ROFS images, while allowing generation of +all other relevant files.

+
+ +

-o<image name>

+

The name of the ROM image. This overrides any name specified +using the romname keyword in an Obey file.

+
+ +

-s

+

The strict option. Specifying this means that any missing +files will stop BUILDROM without generating a ROM +image.

If this option is not specified, then it is possible +to generate a ROM image with missing files.

+
+ +

-p

+

Preserves the intermediate files and folders (data drive +and Z drive) generated by BUILDROM.

+
+ +

-e

+

Specifies the external tools that need to be invoked. These +are the names of the Perl modules (without the .pm extension). Multiple +modules names must be separated by commas. This is an optional parameter.

Alternatively, external tools can be invoked by using IBY file +keyword externaltool.

+
+ +

-fm =<feature_manager_database_file >.xml

+

Parses the specified feature manager database XML files +and generates the features data file(s) (features.dat) in the present working directory. The number of features.dat files generated depends on the total number of ROM image partitions +specified in the OBEY file that is used to create the ROM image.

Notes

    +
  • You can provide +multiple feature manager database XML files delimited by commas.

  • +
  • If a feature +manager option (-fm or -nofm) is +not passed to BUILDROM explicitly, the -fm option is used internally to generate a feature data file using +the default featuredatabase.xml file in \epoc32\rom\include. For more information, refer to Enabling feature +data file generation.

  • +
+
+ +

-nofm =<Existing_features_data_file_name >.dat

+

Includes the specified features data file in the ROM image.

Note: This option is ignored by BUILDROM if used with the -fm option.

+
+ +

-z=xxx or -zdrivepath=xxx

+

Specifies the location to create the Z drive directory.

By default, a Z drive directory is created in the location from +where BUILDROM was invoked.

+
+ +

-d=xxx or -datadrivepath=xxx

+

Specifies the location to create data drive directory.

By default, the data drive directory is created in the location +from where BUILDROM was invoked.

+
+ +

-k or -keepgoing

+

Enables BUILDROM to continue to create the data drive image +even if the SIS file(s), non-SIS file(s), or the Z drive image file(s) +are missing or corrupted.

+
+ +

-zdriveimage="<image_1.img>,[...,<image_n.img>]" +

+

Specifies the Z drive image (ROM, ROFS, and CORE image).

+
+ +

–r or -retainfolder

+

Instructs BUILDROM not to delete any pre-existing data drive +folder.

+
+ +

-pfile=xxx

+

Specifies a parameter file for INTERPRETSIS to take additional +parameters.

+
+ +

-l=<logfile.txt> or -logimageentry=<logfile.txt>

+

Logs all stub-sis and SWI certificate file(s) that are part +of the Z drive image onto a log file.

+
+ +

-argforinterpretsis

+

Specifies the command-line argument for the InterpretSIS +tool. These command-line arguments take precedence over the arguments +in the parameter file.

+
+ +

-i=<optional path>

+

Specifies an optional path in which the IBY files are stored. +This option is case-sensitive.

Notes:

    +
  • If the IBY files +are found both in the default path (\epoc32\rom\include), and the <optional path>, BUILDROM uses the +IBY files in the <optional path>.

  • +
  • If the IBY files +are not found in the default path, BUILDROM uses +the IBY files in the <optional path>.

  • +
+
+ +

-j<NUM_OF_WORKING_THREADS>

+

Specifies the number of working threads that can run concurrently +to create a ROM image. The <NUM_OF_WORKING_THREADS> must be an integer in the range 1-128.

If the -j option is not specified or an invalid value is specified, BUILDROM +automatically takes the number of working threads in the following +ways:

    +
  • If the NUMBER_OF_PROCESSORS environment variable is set properly, +BUILDROM uses the number of processors as the number of working threads.

  • +
  • If the NUMBER_OF_PROCESSORS environment variable is not set or +is invalid, the default value 8 is used as the number +of working threads.

  • +
+
+ +

-compress

+

Compresses the ROM image. It supports three types of compression:

    +
  • -compress: Compresses the entire ROM image.

  • +
  • -compress=paged: Compresses the paged section +in the ROM image.

  • +
  • -compress=unpaged: Compresses the unpaged +section in the ROM image.

  • +
+
+ +

—w

+

Warns if an incorrect input file is selected. For example, +a warning is displayed, if an incorrect binary file is selected when +binary variant is enabled.

+
+ +

-nosymbols

+

Suppresses the generation of any ROM or ROFS symbol file. +This option generates all the relevant files except symbol files.

+
+ +

-geninc

+

Generates an INC file of ROM image. The INC file contains +size information of the paged and the unpaged section within the ROM +image. The name of the output file is the same as that of the output +ROM image, with .inc as extension.

+
+ +

-spi

+

Creates an SPI file.

+
+ +

-spiplacement

+

Enables positioning of the SPI file.

+
+ +

-compressionmethod [none | inflate | bytepair]

+

Specifies the compression algorithm to use. The following +options are available with the -compressionmethod keyword:

+ + + +

none

+

No compression is used.

+
+ +

inflate

+

Compresses executable files using the default (Deflate, +Huffman+LZ77) algorithm.

+
+ +

bytepair

+

Compresses executable files using the bytepair algorithm. +Bytepair compression allows faster decompression than the default +Deflate, Huffman+LZ77 algorithm. It also supports demand paging by +performing compression and decompression of code in independent 4 +KB pages.

+
+ + +

+
+ +

-cache

+

Enables cache mechanism. It ensures that BUILDROM uses cached +executable files while creating a ROFS image. This allows BUILDROM +to reuse or generate cached files.

Notes:

    +
  • The cache mechanism +is disabled by default.

  • +
  • The cached files +are stored on the hard disk.

  • +
  • The cache command +line options (-cache, -nocache, +and -cleancache) are mutually exclusive. This means +that you can use only one cache option at a time.

  • +
+
+ +

-nocache

+

Disallows BUILDROM from using cached files while creating +a ROFS image.

+
+ +

-cleancache

+

Deletes all cached files from the hard disk.

+
+ +

-gendep

+

Generates dependencies file describing a internal dependencies +among executables or dlls in a ROM image.

Note: You can +only generate dependence information in the paged section of a ROM +image.

+
+ +

-checkcase

+

Checks the character case of the path or name in OBY or +IBY files. By default, this option is disabled.

Note: + This option is only valid on Windows.

+
+ + +

-workdir <output-location>

+

Generates the output files at the specified location.

+
+ + +

-prependepocroot

+

Prepends EPOCROOT to the file location, if the specified +location starts from \epoc32 without EPOCROOT.

+
+ + +

Note: <obeyfile1> and <obeyfile2> and are standard text files containing statements +that are used to control the building of ROM images.

See the OBEY files reference for the full syntax.

+
Passing +parameters using a file

BUILDROM allows to pass parameters +in a file using the -argfile option. It provides +a solution to the limited command line length. It also reduces the +risk of error and saves time in typing from a command prompt.

BUILDROM –argfile=arg.txt -s

In +the BUILDROM command above, arg.txt is the text +file with the parameters. An example of this file is as follows:

; sample parameter-file +-fm=\epoc32\rom\include\featuredatabase.xml ;generate features data file. +-noimage -nosymbols -s ;do not generate ROM image and symbol file + ;and invoke buildrom in strict mode. +-D_PLAT=ARMV5 +; EOF

Rules of this argument file are as follows:

    +
  • Single line +comments begin with a semicolon (;).

  • +
  • Comments can +also be specified after the parameters.

  • +
  • Parameters can +be specified either in a single line separated a by space, or in multiple +lines.

  • +
  • Parameters provided +in a parameter file override those specified in the command line.

  • +
  • Environment +variables must be specified in the command line and not in the parameter +file.

  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-E49A8036-EACF-5181-91DA-AE89D3B6E815.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-E49A8036-EACF-5181-91DA-AE89D3B6E815.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,538 @@ + + + + + +HAL Attributes +and Function IDsList of HAL attributes, their related function IDs and links to +the related reference documentation. +

This topic The list is ordered by group.

+

Symbian defines capabilities for each function ID. To find out a function +ID's capabilities, follow the link to its reference information. If no capabilities +are listed in the reference documentation for a function ID, it means that +no capabilities are required.

+

Note:

+
    +
  • An attribute can map +to more than one function ID. This reflects the fact that any given attribute +can be passed to both HAL::Get() and HAL::Set(), +but the set behavior and get behavior map to two different function IDs.

  • +
  • There are group/function +ID pairs for which there is no attribute. This reflects the fact that the +hardware specific information represented by that group/function ID cannot +be accessed from the user side using the generic interface.

  • +
+

Attributes are defined as values of the TAttribute enum +within the scope of the HALData class in ...\os\kernelhwsrv\halservices\hal\inc\hal_data.h, +which is exported to ...\epoc32\include.

+

HAL groups are defined as values of the THalFunctionGroup enum +in ...\os\kernelhwsrv\kernel\eka\include\u32hal.h, which +is exported to ...\epoc32\include.

+

Function IDs are defined as values of various enums in ...\os\kernelhwsrv\kernel\eka\include\u32hal.h.

+
    +
  • Group EHalGroupVariant

  • +
  • Group EHalGroupPower

  • +
  • Group EHalGroupDisplay

  • +
  • Group EHalGroupDigitiser

  • +
  • Group EHalGroupKeyboard

  • +
  • Group EHalGroupKernel

  • +
  • Group EHalGroupMedia

  • +
  • Group EHalGroupEmulator

  • +
  • Group EHalGroupSound

  • +
  • Group EHalGroupMouse

  • +
+
Group EHalGroupVariant + + + +

Attribute

+

Function ID

+
+ +

ECPUSpeed

+

EVariantHalVariantInfo

+
+ +

ELEDs

+

EVariantHalVariantInfo

+
+ +

ELEDmask

+

EVariantHalLedMaskSet

EVariantHalLedMaskGet

+
+ +

ESwitches

+

EVariantHalSwitches

+
+ +

EDebugPort

+

EVariantHalDebugPortSet

EVariantHalDebugPortGet

+
+ +

ECustomRestart

+

EVariantHalCustomRestart

+
+ +

ECustomRestartReason

+

EVariantHalCustomRestartReason

+
+ +

ECpuProfilingDefaultInterruptBase

+

EVariantHalProfilingDefaultInterruptBase

+
+ + +
+
Group EHalGroupPower + + + +

Attribute

+

Function ID

+
+ +

EPowerGood

+

EPowerHalSupplyInfo

+
+ +

EPowerBatteryStatus

+

EPowerHalSupplyInfo

+
+ +

EAccessoryPower

+

EPowerHalAcessoryPowerPresent

+
+ +

EPowerBackup

+

EPowerHalBackupPresent

+
+ +

EPowerBackupStatus

+

EPowerHalSupplyInfo

+
+ +

EPowerExternal

+

EPowerHalSupplyInfo

+
+ +

EPenDisplayOn

+

EPowerHalSetPointerSwitchesOn

EPowerHalPointerSwitchesOn

+
+ +

ECaseSwitchDisplayOn

+

EPowerHalSetCaseOpenSwitchesOn

EPowerHalCaseOpenSwitchesOn

+
+ +

ECaseSwitchDisplayOff

+

EPowerHalSetCaseCloseSwitchesOff

EPowerHalCaseCloseSwitchesOff

+
+ +

No attributes

+

EPowerHalOnOffInfo

+
+ +

No attributes

+

EPowerHalSetAutoSwitchOffBehavior

+
+ +

No attributes

+

EPowerHalAutoSwitchOffBehavior

+
+ +

No attributes

+

EPowerHalSetAutoSwitchOffTime

+
+ +

No attributes

+

EPowerHalAutoSwitchOffTime

+
+ +

No attributes

+

EPowerHalResetAutoSwitchOffTimer

+
+ +

No attributes

+

EPowerHalSwitchOff

+
+ +

No attributes

+

EPowerHalSetBatteryType

+
+ +

No attributes

+

EPowerHalBatteryType

+
+ +

No attributes

+

EPowerHalSetBatteryCapacity

+
+ +

No attributes

+

EPowerHalBatteryCapacity

+
+ +

No attributes

+

EPowerHalAutoSwitchOffType

+
+ +

No attributes

+

EPowerHalTestBootSequence

+
+ + +
+
Group EHalGroupDisplay + + + +

Attribute

+

Function ID

+
+ +

EDisplayContrast

+

EDisplayHalSetDisplayContrast

EDisplayHalDisplayContrast

+
+ +

EDisplayBrightness

+

EDisplayHalSetDisplayBrightness

EDisplayHalDisplayBrightness

+
+ +

EDisplayPaletteEntry

+

EDisplayHalSetPaletteEntry

EDisplayHalPaletteEntry

+
+ +

EDisplayNumModes

+

EDisplayHalModeCount

+
+ +

EDisplayState

+

EDisplayHalSetState

EDisplayHalState

+
+ +

EDisplayColors

+

EDisplayHalColors

+
+ +

EDisplayBrightnessMax

+

EDisplayHalMaxDisplayBrightness

+
+ +

EDisplayContrastMax

+

EDisplayHalMaxDisplayContrast

+
+ +

EDisplayXPixels

+

EDisplayHalCurrentModeInfo

+
+ +

EDisplayYPixels

+

EDisplayHalCurrentModeInfo

+
+ +

EDisplayXTwips

+

EDisplayHalCurrentModeInfo

+
+ +

EDisplayYTwips

+

EDisplayHalCurrentModeInfo

+
+ +

EDisplayMemoryAddress

+

EDisplayHalCurrentModeInfo

EDisplayHalGetDisplayMemoryAddress

+
+ +

EDisplayIsPixelOrderRGB

+

EDisplayHalCurrentModeInfo

+
+ +

EDisplayIsPixelOrderLandscape

+

EDisplayHalCurrentModeInfo

+
+ +

EDisplayMemoryHandle

+

EDisplayHalGetDisplayMemoryHandle

+
+ +

EBacklight

+

EDisplayHalBacklightOn

+
+ +

EBacklightState

+

EDisplayHalSetBacklightOn

EDisplayHalBacklightOn

+
+ +

No attributes

+

EDisplayHalScreenInfo

+
+ +

No attributes

+

EDisplayHalWsRegisterSwitchOnScreenHandling

+
+ +

No attributes

+

EDisplayHalWsSwitchOnScreen

+
+ +

No attributes

+

EDisplayHalSetBacklightBehavior

+
+ +

No attributes

+

EDisplayHalBacklightBehavior

+
+ +

No attributes

+

EDisplayHalSetBacklightOnTime

+
+ +

No attributes

+

EDisplayHalBacklightOnTime

+
+ +

No attributes

+

EDisplayHalBlockFill

+
+ +

No attributes

+

EDisplayHalBlockCopy

+
+ +

No attributes

+

EDisplayHalSecure

+
+ +

No attributes

+

EDisplayHalSetSecure

+
+ + +
+
Group EHalGroupDigitiser + + + +

Attribute

+

Function ID)

+
+ +

EPen

+

EDigitiserHalXYInfo

+
+ +

EPenX

+

EDigitiserHalXYInfo

+
+ +

EPenY

+

EDigitiserHalXYInfo

+
+ +

EPenState

+

EDigitiserHalSetXYState

EDigitiserHalXYState

+
+ +

No attributes

+

EDigitiserHalSetXYInputCalibration

+
+ +

No attributes

+

EDigitiserHalCalibrationPoints

+
+ +

No attributes

+

EDigitiserHalSaveXYInputCalibration

+
+ +

No attributes

+

EDigitiserHalRestoreXYInputCalibration

+
+ + +
+
Group EHalGroupKeyboard + + + +

Attribute

+

Function ID

+
+ +

EKeyboardState

+

EKeyboardHalSetKeyboardState

EKeyboardHalKeyboardState

+
+ +

EKeyboard

+

EKeyboardHalKeyboardInfo

+
+ +

EKeyboardDeviceKeys

+

EKeyboardHalKeyboardInfo

+
+ +

EKeyboardAppKeys

+

EKeyboardHalKeyboardInfo

+
+ + +
+
Group EHalGroupKernel

This +group is defined as internal and is listed here for information purposes only. +However, the attributes are public.

+ + + +

Attribute

+

Function ID

+
+ +

ESystemStartupReason

+

EKernelHalStartupReason

+
+ +

ESystemException

+

EKernelHalExceptionId

+
+ +

EMemoryRAM

+

EKernelHalMemoryInfo

+
+ +

EMemoryRAMFree

+

EKernelHalMemoryInfo

+
+ +

EMemoryROM

+

EKernelHalMemoryInfo

+
+ +

EFastCounterFrequency

+

EKernelHalFastCounterFrequency

+
+ +

ENanoTickPeriod

+

EKernelHalNTickPeriod

+
+ + +
+
Group EHalGroupMedia + + + +

Attribute

+

Function ID

+
+ +

No attribute - the group and function ID pair is used internally.

+

EMediaHalDriveInfo

+
+ + +
+
Group EHalGroupEmulator

This +group is defined as internal and is listed here for information purposes only. +However, the attributes are public.

+ + + +

Attribute

+

Function ID

+
+ +

No attribute - the group and function ID pair is used internally.

+

EEmulatorHalStringProperty

EEmulatorHalIntProperty

EEmulatorHalBoolProperty

EEmulatorHalMapFilename

EEmulatorHalColorDepth

EEmulatorHalSetFlip

EEmulatorHalCPUSpeed

EEmulatorHalNumberOfScreens

+
+ + +
+
Group EHalGroupSound + + + +

Attribute

+

Function ID

+
+ +

EKeyboardClick

+

ESoundHalKeyClickEnabled

+
+ +

EKeyboardClickVolumeMax

+

ESoundHalKeyClickVolumeMax

+
+ +

EKeyboardClickState

+

ESoundHalSetKeyClickEnabled

ESoundHalKeyClickEnabled

+
+ +

EKeyboardClickVolume

+

ESoundHalKeyClickVolumeMax

ESoundHalSetKeyClickLoud

ESoundHalKeyClickLoud

+
+ +

EPenClick

+

ESoundHalPointerClickEnabled

+
+ +

EPenClickVolumeMax

+

ESoundHalPointerClickVolumeMax

+
+ +

EPenClickState

+

ESoundHalSetPointerClickEnabled

ESoundHalPointerClickEnabled

+
+ +

EPenClickVolume

+

ESoundHalPointerClickVolumeMax

ESoundHalSetPointerClickLoud

ESoundHalPointerClickLoud

+
+ + +
+
Group EHalGroupMouse + + + +

Attribute

+

Function ID

+
+ +

EMouse

+

EMouseHalMouseInfo

+
+ +

EMouseX

+

EMouseHalMouseInfo

+
+ +

EMouseY

+

EMouseHalMouseInfo

+
+ +

EMouseButtons

+

EMouseHalMouseInfo

+
+ +

EMouseState

+

EMouseHalSetMouseState

EMouseHalMouseState

+
+ +

EMouseSpeed

+

EMouseHalSetMouseSpeed

EMouseHalMouseSpeed

+
+ +

EMouseAcceleration

+

EMouseHalSetMouseAcceleration

EMouseHalMouseAcceleration

+
+ +

EMouseButtonState

+

Not supported

+
+ + +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-E539FF7D-C221-4961-8227-9E94FBAA624C.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-E539FF7D-C221-4961-8227-9E94FBAA624C.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,12 @@ + + + + + +Time ImplementationDescribes how to implement the Time platform service. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-E5459A54-14BC-55C1-B911-63415E4C61A6.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-E5459A54-14BC-55C1-B911-63415E4C61A6.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,16 @@ + + + + + +ConceptsThis section describes the technology, architecture, and source +code organization of the Base Starter. +Port Implementation +Tutorial + \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-E55B4FE5-517C-5A23-8ACA-E28EE202330B.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-E55B4FE5-517C-5A23-8ACA-E28EE202330B.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,1012 @@ + + + + + +Platform +Specific Layer ImplementationDescribes how to implement the Platform Specific Layer of the MMC +Controller. +
DMMCStack derived +class

This class controls access to the MultiMediaCard stack. This +class has a number of pure virtual functions that need to be implemented in +your Variant DLL. The diagram at MultiMediaCard +controller basic structure shows the class in context.

There +is one virtual function with a default implementation that needs to be overridden.

    +
  • Init()

  • +
  • MachineInfo()

  • +
  • ProgramPeriodInMilliSeconds()

  • +
  • AdjustPartialRead()

  • +
  • GetBufferInfo()

  • +
  • SetBusConfigDefaults()

  • +
  • InitClockOff()

  • +
  • ASSPDisengage()

  • +
  • ASSPReset()

  • +
  • CardDetect()

  • +
  • WriteProtected()

  • +
  • DoPowerDown()

  • +
  • DoPowerUpSM()

  • +
  • InitClockOnSM()

  • +
  • IssueMMCCommandSM()

  • +

Init()

DMMCStack::Init()

The +function is intended to initialize the stack, and is called during initialization +of the MultiMediaCard controller Variant DLL from DMMCSocket::Init():

You +will almost certainly need to provide your own implementation to perform any +platform-specific MultiMediaCard stack initialization. Whatever your implementation +provides, it is important that you call the base class function from within +your derived version.

Return KErrNone if initialization +is successful, otherwise return one of the system-wide error codes to indicate +initialization failure. Note that returning a value other than KErrNone will +cause the kernel to panic and to fail to boot.

You will allocate a +data transfer buffer here. The MultiMediaCard media driver needs a memory +buffer to perform data transfer operations. Where supported, DMA is generally +used to do this, and requires physically contiguous memory. However, the media +driver is created each time a card is inserted into a machine and destroyed +when the card is removed, and giving the media driver the responsibility for +allocating the memory buffer means that it might not always be possible to +allocate physically contiguous pages for it as memory becomes fragmented over +time.

The MultiMediaCard media driver uses the GetBufferInfo() function each time it is created to get a pointer +to the buffer, and to get its length.

Although the MultiMediaCard +media driver only expects a single buffer, it actually uses this as two separate +buffers:

    +
  • a minor buffer which +must have at least enough space for the MBR (512 bytes)

  • +
  • a cache buffer to cache +data blocks from the card.

  • +

The ideal size of the cache buffer depends on the characteristics +of the card present at the time, and it is possible to customize the MultiMediaCard +controller at the platform specific layer for a particular card.

The +following example code allocates a physically contiguous buffer - a minor +buffer size of one block is allocated together with a cache buffer size of +eight blocks. The whole buffer is then rounded up to a whole number of memory +pages.

// The constant calculations could be explicitly folded, but this illustrates +// how the values are derived. +const TUint blkSzLog2 = 9; +const TUint blkSz = 1 << blkSzLog2; +const TInt minorBufLen = Max(KDiskSectorSize, blkSz); + +const TInt KMinBlocksInBuffer = 8; +const TInt cchBufLen = KMinBlocksInBuffer << blkSzLog2; + +TInt totalBufLen = minorBufLen + cchBufLen; + +// Allocate contiguous physical memory +totalBufLen = Kern::RoundToPageSize(totalBufLen); + +TPhysAddr physAddr = 0; +r = Epoc::AllocPhysicalRam(totalBufLen, physAddr); +__KTRACE_OPT(KHARDWARE, Kern::Printf("mmc:ini:physical = %08x", physAddr)); +if (r != KErrNone) + { + return r; + } + +DPlatChunkHw* bufChunk = NULL; +r = DPlatChunkHw::New(bufChunk, physAddr, totalBufLen, EMapAttrCachedWBRA|EMapAttrSupRw); + +if(r != KErrNone) + { + if (physAddr) + { + Epoc::FreePhysicalRam(physAddr, totalBufLen); + } + return r; + } + +iMDBuf = reinterpret_cast<TUint8*>(bufChunk->LinearAddress()); +iMDBufLen = totalBufLen; +

MachineInfo()

DMMCStack::MachineInfo()

The +function returns configuration information for the MultiMediaCard stack.

The +function takes a reference to a TMMCMachineInfo object, +and your implementation must fill the public data members of the object.

ProgramPeriodInMilliSeconds()

DMMCStack::ProgramPeriodInMilliSeconds()

When a data block is written to a card, the data is read into an +internal buffer on the card and is then programmed into the payload memory. +While the card is in programming mode, it cannot be read from, or written +to, but it is possible to query its status using CMD13.

Immediately +after a block of data is written by CIMReadWriteBlocksSM(), +the MultiMediaCard controller requests the card's state using CMD13. If the +card is still in the programming state, then the state machine ProgramTimerSM() launches +a timer with the period returned by ProgramPeriodInMilliSeconds(). +The state of the card is periodically checked until it is no longer in programming +mode.

For platforms that do not provide an interrupt to indicate when +programming mode is finished, ProgramPeriodInMilliSeconds() should +return the interval, in milliseconds, to be used by the poll timer.

AdjustPartialRead()

DMMCStack::AdjustPartialRead()

Some +cards support a partial read feature, which is indicated by the READ_BL_PARTIAL bit +in the CSD register. When this is the case, it is possible +to read a section within a single physical block, without having to read the +entire block.

The MultiMediaCard media driver uses this feature to +read small amounts of data more quickly. However, many hardware implementations +impose restrictions on the granularity of the data that can be read from the +card. For example, they may use a 32-bit FIFO.

This function allows +you to enforce the limits imposed by the hardware.

The aStart and aEnd arguments +of AdjustPartialRead() define the range on the card from +which the media driver would like to read. Your implementation should return +in *aPhysStart and *aPhysEnd the range that +the hardware will allow to be read.

For example, to word align data, +the function would be implemented using the following code:

void AdjustPartialRead(const TMMCard* aCard, TUint32 aStart, TUint32 aEnd, TUint32* aPhysStart, TUint32* aPhysEnd); + { + ... + const TUint32 KWordMask = 3; + *aPhysStart = aStart & ~KWordMask; + *aPhysEnd = (aEnd + KWordMask) & ~KWordMask; + ... + } +

GetBufferInfo()

DMMCStack::GetBufferInfo()

The +MultiMediaCard media driver needs a memory buffer to perform data transfer +operations, and this is, typically, allocated once only by the Init() function when this stack object is initialized.

The +MultiMediaCard media driver is created each time a card is inserted into a +machine and destroyed when the card is removed, and it uses this function, +each time it is created to get a pointer to the memory buffer, and to get +its length. The MultiMediaCard media driver then uses this buffer, over its +lifetime, for data transfer operations.

SetBusConfigDefaults()

DMMCStack::SetBusConfigDefaults()

The function returns information about the MultiMediaCard bus configuration +for this platform.

The function takes a TUint value +containing the bus speed that the controller intends to use, and a reference +to a TMMCBusConfig object. The implementation of this function +must fill the public data members of this object. See the class reference +documentation for the data members.

DMMCStack has +two private data members of type TMMCStackConfig:

    +
  • iMasterConfig

  • +
  • iConfig

  • +

The information returned by the call to SetBusConfigDefaults() is +stored in iMasterConfig's iBusConfig private +data member.

iMasterConfig contains the master bus +configuration settings for the platform. Each time a new session is made current, +the master bus configuration settings are merged with the specific bus configuration +settings for that session, (as set up in the public data member DMMCSession::iConfig), +and the result is stored in iConfig. It is these merged bus +configuration settings that are used to configure the hardware interface. +The platform specific layer can access these settings with a call to MasterDMMCStack::BusConfig().

SetBusConfigDefaults() is called at two stages in the execution of the macro CIM_UPDATE_ACQ to +update the iMasterConfig object.

    +
  • First, it is called +at the start of the card initialization stage with the bus speed argument, aClock, +set to the fOD rate (400kHz).

  • +
  • Second, it is called +after the CSD registers for each card have been read with the bus speed argument, aClock, +set to the slowest maximum transfer rate (TRAN_SPEED) reported by any of the +CSD registers.

  • +

InitClockOff()

DMMCStack::InitClockOff()

Switches +from identification mode of operation to data transfer mode operation.

When +this function is called, the clock information in the iBusConfig member +(see SetBusConfigDefaults()) +will not have been updated to the new data transfer rate.

This function +should, in general, just switch from open drain to push-pull bus mode, with +the clock rate being changed at the start of DMMCStack::IssueMMCCommandSM(), +when iBusConfig will be valid.

ASSPDisengage()

DMMCStack::ASSPDisengage()

This +function is called by the platform independent layer each time a session has +completed or has been aborted.

The function gives the platform specific +layer the chance to free resources or disable any activities that were required +to perform the session.

The implementation should not turn off the +clock to the hardware interface as this will be turned off by the inactivity +timer. Typically, the implementation disables DMA and interface interrupts, +and forces the hardware interface into idle.

At the end of your implementation, +you must add a call DMMCStack::ReportASSPDisengaged() to +report to the platform independent layer that platform specific layer resources +have been disengaged.

ASSPReset()

DMMCStack::ASSPReset()

This +function is called by the platform independent layer when the current session +is being aborted, and platform specific asynchronous activity is to be cancelled. +The function may also be called by the platform specific layer as part of +the DoPowerDown() implementation.

The function gives the platform specific layer the chance to stop all activities +on the host stack. It will, in general, perform the same operations as ASSPDisengage() but, +in addition, will turn off the clock to the hardware interface and release +any requested power requirements made on the power model, i.e. release any +power requirements made by InitClockOnSM().

At the end of your implementation, you must add a call DMMCStack::ReportASSPDisengaged() to +report to the platform independent layer that platform specific layer resources +have been disengaged.

CardDetect()

DMMCStack::CardDetect()

Implement +this function to report whether a card is present in a specified card socket.

This +function takes a TUint value containing the card socket +that is to be queried.

WriteProtected()

DMMCStack::WriteProtected()

Implement +this function to report whether a card in a specified card socket is mechanically +write protected.

This function takes a TUint value +containing the card socket that is to be queried.

DoPowerDown()

DMMCStack::DoPowerDown()

This +function is called as part of the bus power down sequence:

    +
  • by the power model, +in power standby and power emergency standby situations

  • +
  • when a door-open event +occurs

  • +
  • when the bus inactivity +timer has timed out

  • +
  • if a power supply unit +(PSU) voltage check fails.

  • +

The function should stop all activities on the host stack, turn off +the clock to the hardware interface and release any requested power requirements +made on the power model. The function is very often implemented as a call +of ASSPReset().

The +function should not turn off the MultiMediaCard power supply unit as this +will be performed immediately afterwards by a call to the DMMCPsu::DoSetState() derived +class function from the platform independent layer.

DoPowerUpSM()

DMMCStack::DoPowerUpSM()

This +is a state machine function, called as a child function at the start of the CIM_UPDATE_ACQ macro +state machine.

The function should perform the necessary platform +specific actions associated with powering up the bus. This includes turning +on the MultiMediaCard PSU. However, the hardware interface clock should not be +turned on as part of this function.

If the controller has to request +power resources from the power model, e.g. where a fast system clock is required +all the time the bus is powered, then this state machine function can be used +to wait asynchronously for this resource to become available.

If the +activity performed by this function completes successfully:

    +
  • it must call DMMCStack::ReportPowerUp().

  • +
  • it returns KMMCErrNone.

  • +

The function should return KMMCErrNone if it completes +successfully or one of the other TMMCErr error codes.

See +the general background information on the +state machine.

InitClockOnSM()

DMMCStack::InitClockOnSM()

This +is a state machine function, called as part of the CIM_UPDATE_ACQ macro +state machine.

The function should turn on the clock to the hardware +interface. The function is so named because this clock is always first turned +on at the identification mode frequency.

The function is implemented +as a state machine function because it may be necessary to include a short +delay after the clock has been turned on to allow it to stabilize.

If +it is necessary for the MultiMediaCard controller to request any power resources +from the power model on this platform, for example, requesting a necessary +system clock, then it should be performed as part of this function. In some +cases, it may be necessary to wait for this power resource to become available.

At +the beginning of your implementation, you must add a call DMMCStack::ReportASSPEngaged() to +report to the platform independent layer that platform specific layer resources +have been engaged.

The function should return KMMCErrNone if +it completes successfully or one of the other TMMCErr error +codes.

Note:

    +
  • the function is only +called once for each invocation of the CIM_UPDATE_ACQ macro and the important +thing to stress is that the interface clock is being turned on after a period +when it has been off, and therefore often requires time to stabilize.

  • +
  • In the course of executing +a session, the MultiMediaCard controller may switch the clock more than once +between the identification mode frequency and the data transfer mode frequency, +but this function only ever gets called once.

  • +

See the general background information on the +state machine.

IssueMMCCommandSM()

DMMCStack::IssueMMCCommandSM()

This +is a state machine function +that executes a single command over the bus. The implementation of this function +is an important part in the process of porting the MultiMediaCard controller.

The +input parameters for the command are passed via the current command descriptor, +an instance of the TMMCCommandDesc class, on the session’s +command stack. The parameters contain information such as: the type of command, +the response type, the command arguments, the data source/destination for +data transfer commands etc. Use DMMCSession::Command() to +get the current command descriptor.

Information about the command +response, the number of bytes transferred etc., is passed back using the same +command descriptor. Specifically, the platform independent layer relies on +responses to the following commands being returned in the TMMCCommandDesc::iResponse member, +in big-endian format:

    +
  • Returns the OCR register +value in response to a SEND_OP_COND command (CMD1). Note that there is no +CRC with this response. Your code should ignore any CRC failure indication +from the MultiMediaCard controller hardware, and just copy the response into TMMCCommandDesc::iResponse.

  • +
  • Returns the CID register +value in response to an ALL_SEND_CID command (CMD2) and a SEND_CID command +(CMD10).

  • +
  • Returns the CSD register +value in response to a SEND_CSD command (CMD9).

  • +
  • Returns the card status +in response to all R1 and R1b commands.

  • +

Note that you can use the functions TMMC::BigEndian4Bytes() and +TMC::to help with conversion to big-endian format.

The function should +return KMMCErrNone if it completes successfully or one +of the other TMMCErr error codes.

See also background +information:

    +
  • Issuing +commands

  • +
  • The +state machine.

  • +
+
DMMCPsu derived +class

This class controls the MultiMediaCard socket's power supply. +A class needs to be derived from this in the platform specific layer to handle +the Variant specific functionality of the power supply.

This class +has a number of pure virtual functions that need to be implemented in your +Variant DLL. The diagram at MultiMediaCard +controller basic structure shows the class in context.

There +is one virtual function with an empty default implementation that needs to +be overridden.

    +
  • DoCreate()

  • +
  • PsuInfo()

  • +
  • DoSetState()

  • +
  • DoCheckVoltage()

  • +

DoCreate()

DMMCPsu::DoCreate()

The +function is intended to perform hardware initialization on the MultiMediaCard +power supply, for example, setting port direction registers.

The function +is called after creation of the DMMCPsu derived class instance, +which is done during kernel initialization when the MultiMediaCard controller +Variant DLL extension is loaded.

The function has a default implementation +that just returns KErrNone.

Your implementation +should KErrNone if the hardware initialization is successful, +otherwise it should return one of the system-wide error codes to indicate +initialization failure. Note that returning a value other than KErrNone will +cause the kernel to panic and to fail to boot.

PsuInfo()

DMMCPsu::PsuInfo()

The +function returns information about the MultiMediaCard power supply.

The +function takes a reference to a TPBusPsuInfo object, and +your implementation must fill the public data members of the object.

Note:

    +
  • You can use the constant KMMCAdjustableOpVoltage to +set bit 31 in TPBusPsuInfo::iVoltageSupported.

  • +
  • Set TPBusPsuInfo::iNotLockedTimeOut to +0.

  • +

DoSetState()

DMMCPsu::DoSetState()

The +function is called to turn the PSU on or off.

The requested state +of the PSU depends on the TPBusPsuState value passed to +it.

If the PSU supports voltage adjustment, rather than a single fixed +value, then the required voltage setting is contained in the protected data +member DMMCPsu::iVoltageSetting.

Note that the +stack may call this function to request the power to be turned on when it +is already on. You should check for this and do nothing if the power is already +in the requested state.

DoCheckVoltage()

DMMCPsu::DoCheckVoltage()

The +function is called to check that the voltage level of the PSU is as expected.

Checking +the voltage level may be a long running operation (e.g. using an ADC), and +it may not always be appropriate to perform and complete the check directly +within this function.

When voltage checking is complete, either synchronously +in this function, or asynchronously at some later stage, the result should +be returned by calling the base class function DPBusPsuBase::ReceiveVoltageCheckResult(). +Pass KErrNone to indicate a successful check; pass KErrGeneral to +indicate a failed check.

Note that this function is not called as +part of DMMCStack::DoPowerUpSM() processing, which means +that it is not possible to use this function to introduce a delay until power +is stable when the PSU is turned on. If such a delay is required while the +power lines stabilize, then it will be necessary to make this function part +of the DoPowerUpSM state machine.

+
DMMCMediaChange +derived class

This class provides support for dealing with media +change events, i.e. the insertion and removal of removable media.

A +class needs to be derived from this in the platform specific layer to handle +the Variant specific functionality.

This class has a number of pure +virtual functions that need to be implemented in your Variant DLL. The diagram +at MultiMediaCard +controller basic structure shows the class in context.

There +is one virtual function with an empty default implementation that needs to +be overridden.

    +
  • Create()

  • +
  • MediaState()

  • +
  • DoDoorOpen()

  • +
  • DoDoorClosed()

  • +
  • ForceMediaChange()

  • +

Create()

DMMCMediaChange::Create()

The +function is intended to perform hardware initialization on the MultiMediaCard +media change hardware, for example, setting port direction registers, binding +to the door open interrupt etc.

The function is called after creation +of the DMMCMediaChange derived class instance, which is +done during kernel initialization when the MultiMediaCard controller Variant +DLL extension is loaded.

The function has a default implementation +that just returns KErrNone.

Your implementation +should return KErrNone if the hardware initialization is +successful, otherwise it should return one of the system-wide error codes +to indicate initialization failure. Note that returning a value other than KErrNone will +cause the kernel to panic and to fail to boot.

MediaState()

DMMCMediaChange::MediaState()

The +function should return the current state of the media, i.e. whether the media +door is open or closed. To indicate the state, it should return one of the TMediaState enum +values.

DoDoorOpen()

DMMCMediaChange::DoDoorOpen()

This +function should handle a media door open event. What needs to be done depends +on how door open and door closed events are detected.

The most common +pattern is where the platform hardware is capable of generating an interrupt +when a door open event occurs, but cannot generate an interrupt when a door +closed event occurs. In this situation, the hardware provides a readable door +status that can be checked for the door closed state on a periodic basis (i.e. +polling).

Assuming this, DoDoorOpen() would need +to enable a tick timer to poll for the door closing. The timer callback function +would check the state of the door, and if this showed a closed door, the timer +would be disabled and the function DMediaChangeBase::DoorClosedService() called. +This results in a call to DoDoorClosed().

Note that the door open interrupt is cleared before this function is +called. The interrupt results in a call to DMediaChangeBase::DoorOpenService(), +which in turn results in a call to this function DoDoorOpen().

Your +implementation would necessarily be different if an open door event could +not be signalled by an interrupt and a tick timer were to be used to poll +for an open door status.

DoDoorClosed()

DMMCMediaChange::DoDoorClosed()

This +function should handle a media door closed event. What needs to be done depends +on how door open and door closed events are detected.

The most common +pattern is where the platform hardware is capable of generating an interrupt +when a door open event occurs, but cannot generate an interrupt when a door +closed event occurs. In this situation, the hardware provides a readable door +status that can be checked for the door closed state on a periodic basis (i.e. +polling).

Assuming this, DoDoorClosed() would be +called by the timer callback function established by DoDoorOpen() when the door status indicates a closed door; the function +would need to re-enable the door open interrupt.

Your implementation +would necessarily be different if a closed door event were to be signalled +by an interrupt.

ForceMediaChange()

DMMCMediaChange::ForceMediaChange()

This function is called by the local media device driver to force a remount +of the media device. For example to reopen a media driver in secure mode.

It +should result in the same sequence of operations as would occur if a door +open event had taken place; for example, disabling the door open interrupt +and calling DMediaChangeBase::DoorOpenService().

+
TMMCardControllerInterface +derived class (The factory class)

This is a class, also known as the +controller factory that is responsible for deciding which peripheral +bus sockets are sockets that have been designated as a MultiMediaCard sockets +on this platform. It is also responsible for creating the platform-specific +layer objects associated with those MultiMediaCard sockets, i.e. the DMMCSocket, +DMMCStack, DMMCMediaChange, and DMMCPsu objects.

This class defines +a number of pure virtual functions that need to be implemented in your Variant +DLL to provide the functionality that is specific to your platform.

An +instance of your TMMCardControllerInterface derived class +is created in the Variant +DLL entry point code.

    +
  • IsMMCSocket()

  • +
  • NewSocket()

  • +
  • NewStack()

  • +
  • MediaChangeID()

  • +
  • NewMediaChange()

  • +
  • VccID()

  • +
  • NewVcc()

  • +
  • Init()

  • +

IsMMCSocket()

TMMCardControllerInterface::IsMMCSocket()

Implement this function to indicate whether the peripheral bus socket, as +identified by the specified peripheral bus socket number, is designated as +a MultiMediaCard socket on this platform. It should return ETrue if +the socket has been so designated, and return EFalse if +not.

The function is called from TMMCardControllerInterface::Create(), +which passes a socket number that can fall into the range 0 to KMaxPBusSockets.

Internally, +Symbian platform reserves space for an array of pointers to DPBusSocket objects, +and this function allows the platform specific layer to identify which slot +is to be used for the DMMCSocket object.

GLDEF_D DPBusSocket* TheSockets[KMaxPBusSockets];

(This +array is internal to Symbian platform.)

If, on this platform, a socket +has been designated as a MultiMediaCard stack, then the function not only +returns ETrue, but also provides the media information +for that socket, by filling in the members of the SMediaDeviceInfo object +passed in.

NewSocket()

TMMCardControllerInterface::NewSocket()

Implement +this function to create, and return a pointer to, an instance of the DMMCSocket class. +This can be a class derived from DMMCSocket, but this should +rarely be necessary.

The function is called from TMMCardControllerInterface::Create().

If +you create a DMMCSocket object, simply forward the peripheral +bus socket number and pointer to the password store; there is no need to do +anything with them.

If you create an instance of a DMMCSocket derived +class, then just pass the socket number and pointer to the DMMCSocket constructor +in your constructor's ctor list.

Note:

    +
  • The socket number can +fall into the range 0 to KMaxPBusSockets, and is a value +for which IsMMCSocket() returned ETrue.

  • +
  • This function is only +called for sockets that are associated with MultiMediaCard devices as reported +by the function IsMMCSocket().

  • +

NewStack()

TMMCardControllerInterface::NewStack()

Implement +this function to create, and return a pointer to, an instance of a DMMCStack derived class.

The function is called from TMMCardControllerInterface::Create().

The +peripheral bus socket number and pointer to the socket object should be forwarded +to the DMMCStack constructor in your class constructor's +ctor list.

Note:

    +
  • The socket number can +fall into the range 0 to KMaxPBusSockets, and is a value +for which IsMMCSocket() returned ETrue.

  • +
  • The socket is the object +created by NewSocket().

  • +
  • This function is only +called for sockets that are associated with MultiMediaCard devices as reported +by the function IsMMCSocket().

  • +

MediaChangeID()

TMMCardControllerInterface::MediaChangeID()

Implement this function to report which media change object is to be +associated with the specified peripheral bus socket number.

The function +is called from TMMCardControllerInterface::Create().

The +media change object is represented by a number, which is simply an index value +that ranges from 0 to KMaxMediaChanges. Internally, Symbian +platform reserves space for an array of pointers to DMediaChangeBase objects, +and this function allows the platform specific layer to identify which slot +is to be used for the DMMCMediaChange object that will +correspond to the specified socket number.

GLDEF_D DMediaChangeBase* TheMediaChanges[KMaxMediaChanges];

(This array is internal to Symbian platform.)

Note:

    +
  • The socket number can +fall into the range 0 to KMaxPBusSockets, and is a value +for which IsMMCSocket() returned ETrue.

  • +
  • This function is only +called for sockets that are associated with MultiMediaCard devices as reported +by the function IsMMCSocket().

  • +

NewMediaChange()

TMMCardControllerInterface::NewMediaChange()

Implement this function to create, and return a pointer to, an instance +of a DMMCMediaChange +derived class.

The function is called from TMMCardControllerInterface::Create().

The +media change number should be forwarded to the DMMCMediaChange constructor +in your class constructor's ctor list.

Note:

    +
  • The media change number +can fall into the range 0 to KMaxMediaChanges, and is the +value returned by MediaChangeID().

  • +
  • This function is only +called for sockets that are associated with MultiMediaCard devices as reported +by the function IsMMCSocket().

  • +

VccID()

TMMCardControllerInterface::VccID()

Implement +this function to report which power supply unit (PSU) object is to be associated +with the specified peripheral bus socket number.

The function is called +from TMMCardControllerInterface::Create().

The +PSU object is represented by a number, which is simply an index value that +ranges from 0 to KMaxPBusVccs. Internally, Symbian platform +reserves space for an array of pointers to DPBusPsuBase objects, +and this function allows the platform specific layer to identify which slot +is to be used for the DMMCPsu object that will correspond +to the specified socket number.

GLDEF_D DPBusPsuBase* TheVccs[KMaxPBusVccs]; +

(This array is internal to Symbian platform.)

Note:

    +
  • The socket number can +fall into the range 0 to KMaxPBusSockets, and is a value +for which IsMMCSocket() returned ETrue.

  • +
  • This function is only +called for sockets that are associated with MultiMediaCard devices as reported +by the function IsMMCSocket().

  • +

NewVcc()

TMMCardControllerInterface::NewVcc()

The +function should create, and return a pointer to, an instance of a DMMCPsu derived class.

The function is called from TMMCardControllerInterface::Create().

The +Power Supply Unit (PSU) number and the media change number should be forwarded +to the DMMCPsu constructor in your class constructor's +ctor list.

Note:

    +
  • The PSU number can fall +into the range 0 to KMaxPBusVccs, and is the value returned +by VccID().

  • +
  • The media change number +can fall into the range 0 to KMaxMediaChanges, and is the +value returned by MediaChangeID().

  • +
  • This function is only +called for sockets that are associated with MultiMediaCard devices as reported +by the function IsMMCSocket().

  • +

Init()

TMMCardControllerInterface::Init()

Implement +this function to perform any initialization that the platform specific layer +needs to do.

It should return KErrNone to indicate +successful completion, or return one of the other system-wide error codes +to indicate initialization failure.

Note that you should not do +any initialization that is specifically associated with:

    +
  • the stack - use DMMCStack::Init() for +this.

  • +
  • the power supply unit +- use DMMCPsu::DoCreate() for +this.

  • +
  • dealing with media change +events - use DMMCMediaChange::Create() for +this.

  • +
+
Variant DLL +entry point code

The platform-specific layer as implemented in +the Variant DLL is a standard kernel extension. The entry point for all standard +kernel extensions is declared by a

DECLARE_STANDARD_EXTENSION()

statement, +followed by the block of code that runs on entry to the DLL.

Initialization +of the MultiMediaCard DLL is done at this point, and follows the pattern shown +below. It needs to create an instance of your TMMCardControllerInterface derived +class, followed by a call to Create() on this object. This +starts a cascade of effects resulting in calls to your implementation of the TMMCardControllerInterface functions, +which in turn result in the creation of the platform-specific layer objects +associated with the MultiMediaCard sockets, i.e. the DMMCSocket, DMMCStack, +DMMCMediaChange, and DMMCPsu objects.

DECLARE_STANDARD_EXTENSION() +// +// Extension Entry Point +// + { + __KTRACE_OPT(KPBUS1,Kern::Printf("Starting MMC interface")); + + TInt r=KErrNoMemory; + TVARMMCardControllerInterface* pI=new TVARMMCardControllerInterface; + if (pI) + { + r=pI->Create(); + } + + __KTRACE_OPT(KPBUS1,Kern::Printf("MMC: Returns %d",r)); + return r; + } +

In this example, TVARMMCardControllerInterface is +your class derived from TMMCardControllerInterface

+
Direct memory +addressing

To transfer data between a user side process and the +media device, the Platform Specific Layer allocates a DMA-safe buffer at initialization. +This buffer is allocated from physical memory. The memory in the user side +process is virtual and you perform an inter-process copy of data between the +user side process and the buffer allocated by the Platform Specific Layer.

Data +transfer is faster if the MultiMediaCard controller knows that an address +passed in an I/O request is a physical address. The File caching and Demand +Paging features in the file server and kernel can pass physical addresses. +A physical address avoids the need for an inter-process copy operation.

If +you use a mechanism like DMA to +transfer data, and your platform specific layer can deal with physical addresses, +you need to make changes to the platform specific layer listed below.

    +
  • Implement double buffers

  • +
  • Register support for physical addresses

  • +
  • Modify the data transfer phase to handle physical memory

  • +

Implement double buffers

If +you enable double buffer behavior, the MultiMediaCard subsystem can perform +multiple data transfers in a single bus transaction. The double buffer implementation +performs many data transfers in a single bus transaction. The MultiMediaCard +subsystem logically splits the buffer allocated by the platform specific layer +into two segments. Data transfer to the media device is in progress from one +segment - this is the active segment. Concurrently, the media driver can prepare +data in the other segment.

To implement double buffers, you need to +make changes to the platform specific layer.

Use the command descriptor functions

    +
  • Use the function TMMCCommandDesc::BlockLength() to +get the block length of the transaction. Find all direct references in the +source code of the platform specific layer to TMMCCommandDesc::iBlockLength. +Replace each reference with a call to TMMCCommandDesc::BlockLength()

  • +
  • Use the function TMMCCommandDesc::BufferLength() to +get the length of the next active segment. Find all references to TMMCCommandDesc::iTotalLength. +There are two areas in the code where this data member can be referenced:

      +
    • code where you test +the progress of the data transfer operation and set up the MMC command. Do +not change this code, because TMMCCommandDesc::iTotalLength still +represents the total amount of data to be transferred.

    • +
    • code where you set up +the DMA controller to transfer a number of blocks of data. Replace references +to TMMCCommandDesc::iTotalLength with calls to TMMCCommandDesc::BufferLength(). +This describes the size of the current segment. Note that if double buffers +are not enabled, the value returned by this function is the same as TMMCCommandDesc::iTotalLength.

    • +
  • +
  • You can use the function TMMCCommandDesc::IsDoubleBuffered() to +determine if the current transaction uses double buffers.

  • +

Separate the command and data phases

Without double buffer +behavior, a single MMC command is always associated with a single buffer into +which the hardware transfers data. With double buffer behavior, multiple buffers +or segments are used to transfer data within a single command. You need to +separate the command and data transfer phases.

This code fragment +is a simplified example of a platform specific layer that sets up the command +and the data transfers in separate stages:

+ TMMCErr DExampleMMCStack::IssueMMCCommandSM() + { + enum states + { + EStBegin=0, + EStSetUpCommand, + EStWaitComplete, + EStEnd + }; + + TMMCCommandDesc& cmd = Command(); + + SMF_BEGIN + + /** ...omitted for clarity */ + + SMF_STATE(EStSetUpCommand) + + /** + * Set up the controller to issue the command. Depending on + * the command type, this will prepare DMA transfers and wait + * for a response to be received before unblocking the stack. + */ + BlockCurrentSession(KMMCBlockOnASSPFunction); + + SetupCommand(cmd); + + If(iDataTransfer) + SetupDataTransfer(cmd); + + /** + * Wait for all events to be received + * - command sent, data transferred, response received + */ + SMF_WAITS(EStWaitComplete); + + SMF_STATE(EStWaitComplete) + + /** + * Command issued, data transferred and response received. + * - check for and report any errors + * + * - Note, functionality omitted for clarity – in practice this will + * check the controller status and wait for more events as appropriate. + */ + TMMCErr err = KMMCErrNone; + + if(iResponseExpected) + err = ExtractResponse(); + + if(iDataTransfer && err == KMMCErrNone) + err = CheckDataTransferErrors(); + + if(err) + SMF_RETURN(err); + + SMF_END + } + +

If you depend on the MMC controller to signal the completion +of data transfer after all blocks have been transmitted or received, change +the DMA controller. Change the code to block the stack when DMA transfer starts, +and unblock the stack when the current DMA transfer finishes. Do this operation +while you wait for the final interrupt that signals the end of the data transfer.

The +following code fragment shows how to set the KMMCBlockOnASSPFunction blocking +condition before the start of DMA transfer. After DMA transfer has finished, +unblock the stack in the DMA complete service routine, DmaService().

+ void DExampleMMCStack::SetupDataTransfer(const TMMCCommandDesc& aCmd) + { + TUint8* bufPtr = reinterpret_cast<TUint8*>(aCmd.iDataMemoryP); + TUint32 bufLen = aCmd.BufferLength(); + + /** ...omitted for clarity */ + + BlockCurrentSession(KMMCBlockOnASSPFunction); + iDmaController::Start(aCmd.Direction(), bufPtr, bufLen); + } + + + void DExampleDmaController::DmaService() + { + /** ...omitted for clarity */ + + Session().iState |= KMMCSessStateDoDFC; + UnBlockCurrentSession(KMMCBlockOnASSPFunction, KErrNone); + } +

Implement the double buffer state machine

Update the platform +specific layer to implement the double buffer state machine. You use the function DMMCSession::RequestMoreData(). +The platform specific layer uses this function to tell the MMC subsystem to +prepare the next segment for data transfer. You call this function when the +hardware is busy performing a DMA transfer for the current segment. This allows +the MMC Media Driver to copy data to/from the client process ready for the +next transfer while the MMC card is transferring it’s current payload.

This +function sets the static KMMCBlockOnMoreData blocking condition. +The platform specific layer must use SMF_WAITS (or equivalent) +to suspend the platform specific layer state machine until the media driver +has processed the current segment. When finished, the command descriptor is +populated with the details of the next segment to be transferred. The KMMCBlockOnMoreData block +condition set by this function can be set with the KMMCBlockOnASSPFunction condition. +It allows the hardware to perform useful work, (for example, transfer the +current buffer to or from the card) while the media driver is busy preparing +the next buffer. In this case, the platform specific layer is unblocked when +both the hardware and media driver have completed their tasks.

The +following code fragment shows how you do this:

TMMCErr DExampleMMCStack::IssueMMCCommandSM() + { + enum states + { + EStBegin=0, + EStSetUpCommand, + EStWaitDataTransfer + EStWaitComplete, + EStEnd + }; + + TMMCCommandDesc& cmd = Command(); + + SMF_BEGIN + + /** ...omitted for clarity */ + + SMF_STATE(EStSetUpCommand) + + /** + * Set up the controller to issue the command. Depending on + * the command type, this will prepare DMA transfers and wait + * for a response to be received before unblocking the stack. + */ + BlockCurrentSession(KMMCBlockOnASSPFunction); + + SetupCommand(cmd); + + If(iDataTransfer) + { + /** + * Kick off DMA transfer for the first buffer. + * …the stack will be blocked on KMMCBlockOnASSPFunction until DMA complete + */ + SetupDataTransfer(cmd); + + /** + * DMA is now active. Now request the Media Driver to prepare the next + * buffer in parallel. While active, the stack will be blocked with + * the KMMCBlockOnMoreData blocking condition and unblocked when complete. + */ + Session().RequestMoreData(); + } + + /** + * Wait for DMA and Media Driver completion. + */ + SMF_WAITS(EStWaitDataTransfer); + + SMF_STATE(EStWaitDataTransfer) + + /** + * DMA is complete and the Media Driver has prepared the next buffer. + * - Start the next DMA transfer and request more data from the media driver. + */ + + if(cmd.BufferLength() > 0) + { + /** + * There is more data to transfer. + * ..start DMA transfer, prepare the next buffer and wait for completion. + */ + SetupDataTransfer(cmd); + Session().RequestMoreData(); + SMF_WAITS(EStWaitDataTransfer); + } + + /** + * There is no more data to transfer. + * ..do whatever we need to do to wait for hardware completion + */ + + // …omitted for clarity + + SMF_WAITS(EStWaitComplete); + + SMF_STATE(EStWaitComplete) + + /** + * Command issued, data transferred and response received. + * - check for and report any errors + * + * - Note, functionality omitted for clarity – in practice this will + * check the controller status and wait for more events as appropriate. + */ + TMMCErr err = KMMCErrNone; + + if(iResponseExpected) + err = ExtractResponse(); + + if(iDataTransfer && err == KMMCErrNone) + err = CheckDataTransferErrors(); + + if(err) + SMF_RETURN(err); + + SMF_END + } +

Register support for double buffers with the platform independent layer

You +must tell the platform +independent layer that you support double buffers. Set TMMCMachineInfo::ESupportsDoubleBuffering into +the TMMCMachineInfo object that you pass to DMMCStack::MachineInfo().

Choose the size of the buffer

To choose the optimum size +of buffer, you must perform benchmark tests on your system. A small buffer +gives you a lower command setup latency, but DMA transfers and calls to the +callback function DMMCSession::RequestMoreData() occur +more frequently. The time taken to set up the DMA transfers can exceed the +time taken to transfer the data into or out of the active segment.

Testing

You need to do the standard E32 and F32 automated +tests to check the operation of the MMC subsystem. You also need to perform +the MMC specific manual test, T_MMCDRV. The test listed below performs data +transfers in excess of the PSL buffer size to make sure that double buffer +behavior is exercised.

+ /** + @SYMTestCaseID PBASE-T_MMCDRV-0558 + @SYMTestCaseDesc Test Long Read/Write Boundaries + @SYMTestPriority High + + @SYMTestActions + + Perform and Write/Read/Verify for the given length (L) of data across the following boundaries. + Depending on the length, this will also perform a partial write/read at the end sector. + + -------------- + | Start | End | + |--------------| + | 0 | L | + | 507 | L-507 | + | 10 | L | + | 0 | L-3 | + | 27 | L-512 | + | 0 | L-509 | + | 3 | L-3 | + -------------- + + For each combination, the write/read/verify operations are performed in the following sequence: + +a: Write and Read in single 512-byte blocks. +b: Write in a single operation (multiple blocks), Read in 512-Byte blocks. +c: Write in 512-Byte blocks, Read in a single operation (multiple-blocks). +d: Write and Read in a single operation (multiple-blocks). + + In the cases where a partial read/write operation occurs (ie - the start and/or end position + don't lie within a sector boundary), the original contents of the start and/or end sectors are + read and stored at the start of the test, and compared with the contents of the sectors at the + end of the test to ensure that unwritten data within the sectors remain unaffected. + + @SYMTestExpectedResults All tests must pass + + @SYMPREQ1389 REQ6951 Double Buffering and SD Switch + * + */ + +

The test T_MMCDRV must be performed on versions of the platform +specific layer that has: double buffers enabled, double buffers disabled, +and with a number of different buffer sizes (for example, from 32k to 256k).

The +test cannot dynamically set the size of the buffer. You must do manual configuration +of the buffer to test all configurations.

To measure performance, +use T_FSYSBM, with and without double buffers enable.

Register support for physical +addresses

There are three items to do:

    +
  • you must tell the platform +independent layer that you support physical addresses in your implementation +of DMMCStack::MachineInfo(). +The function takes a TMMCMachineInfo type. Set the THardwareConfig::ESupportsDMA flags +into the iFlags member of TMMCMachineInfo.

    If +you set the THardwareConfig::ESupportsDMA flag, you also +set the THardwareConfig::ESupportsDoubleBuffering flag +automatically. This flag enables double buffer support. You must alsoimplement +double buffers if you use physical addresses.

  • +
  • You must tell the platform +independent layer the maximum transfer length that you support. This +can be a limit imposed on you by the hardware. For example, if you use DMA, +the DMA controller can impose a limit. You set one of the flags listed below +into the iFlags member of TMMCMachineInfo in +your implementation of DMMCStack::MachineInfo().

    Each flag represents a maximum transfer length. The MultiMediaCard +subsystem splits a data transfer request that is bigger than the maximum into +multiple data transfers.

      +
    • THardwareConfig::EMaxTransferLength_256K

    • +
    • THardwareConfig::EMaxTransferLength_512K

    • +
    • THardwareConfig::EMaxTransferLength_1M

    • +
    • THardwareConfig::EMaxTransferLength_2M

    • +
    • THardwareConfig::EMaxTransferLength_4M

    • +
    • THardwareConfig::EMaxTransferLength_8M,

    • +
    • THardwareConfig::EMaxTransferLength_16M

    • +
    • TMMCMachineInfoV4.iFlags

    • +
  • +
  • You must tell the platform +independent layer the address scheme that the hardware uses. Mis-alignment +of memory can corrupt data. You set one of the flags shown in the list +below into the iFlags member of TMMCMachineInfo in +your implementation of DMMCStack::MachineInfo(). Each flags represents a different address scheme. You can set only one +flag. If you set more than one of these flags, the creation of the media driver +fails.

      +
    • THardwareConfig::EDma8BitAddressing

    • +
    • THardwareConfig::EDma16BitAddressing

    • +
    • THardwareConfig::EDma32BitAddressing

    • +
    • THardwareConfig::EDma64BitAddressing

    • +
  • +

The following code is an example implementation of DMMCStack::MachineInfo().

void DVariantMmcHwStack::MachineInfo(TMMCMachineInfoV4& aMachineInfo) +/** + * Gets the machine info for the hardware variant + * + * @param aMachineInfo Info structure to populate + */ + { + aMachineInfo.iTotalSockets=MMC_DRIVECOUNT; + aMachineInfo.iTotalMediaChanges=0; // Not used at present + aMachineInfo.iTotalPrimarySupplies=0; // Not used at present + + aMachineInfo.iBaseBusNumber=0; + aMachineInfo.iVersion = TMMCMachineInfoV4::EVersion4; + aMachineInfo.iMaxBusWidth = EBusWidth4; + + // Report support for Physical Addressing + aMachineInfo.iFlags = TMMCMachineInfo::ESupportsDMA; + aMachineInfo.iFlags |= TMMCMachineInfo::EMaxTransferLength_1M; + aMachineInfo.iFlags |= TMMCMachineInfo::EDma16BitAddressing; + + // High voltage (3.6V) power class. Set to maximum = 2000mA RMS + aMachineInfo.iHighVoltagePowerClass = TMMCMachineInfoV4::EHi200mA; + + // Low voltage (1.95V) power class. Set to maximum = 200mA RMS + aMachineInfo.iLowVoltagePowerClass = TMMCMachineInfoV4::ELo200mA; + + // 52 Mhz clock supported + aMachineInfo.iMaxClockSpeedInMhz = TMMCMachineInfoV4::EClockSpeed52Mhz; + }

Modify the data transfer +phase to handle physical memory

The implementation of double +buffers has separated the command setup and the data transfer phases. You +need to change the data transfer phase to handle physical memory.

    +
  • The data member TMMCCommandDesc::iDataMemoryP contains +the source or target memory address for the current data transfer command. +Use the function TMMCCommandDesc::IsPhysicalAddress() to +determine if this address is a physical address or a virtual address. If you +do not register +support for physical addresses, this function always returns EFalse.

  • +
  • You do not need to perform +virtual address to physical address translation on physical addresses.

  • +
  • you do not need to perform +DMA synchronization for physical addresses, because the local media subsystem +performs DMA synchronization for you. You need to perform DMA synchronization +for virtual addresses. DMA synchronization is performed by calls to Cache::SyncMemoryBeforeDmaRead() or Cache::SyncMemoryBeforeDmaWrite().

  • +

The following code is an example of the changes needed for a read +operation.

TInt DMMCDmaRx::Start(const TMMCCommandDesc& aCmd) +/** + * Queues a DMA request after checking the buffer alignment constraints. + * + * @param aCmd The command structure containing the details about the command. + */ +{ + … + TUint flags = KDmaMemDest; + + // Check if a physical address has been provided with this request + if(aCmd.IsPhysicalAddress()) +{ + // …if so, set the appropriate flag for this DDmaRequest +flags |= KDmaPhysAddrDest; +} + + TInt retval = iRequest->Fragment( KMMC_Buf_Dt_Reg, + (TUint32)aCmd.iDataMemoryP, + aCmd.BufferLength(), + flags, + 0 /* no HW Flags*/); + + if(retval != KErrNone) +Kern::Fault("MMC DMA RX Start Fragment", retval); + + … + return KErrNone; +} + void DMMCRxDmaHelp::ChannelTransfer(const SDmaPseudoDes& aDes) + { +… + TPhysAddr dest; + +// Don’t perform Linear to Physical translation if we + // have already been supplied with a Physical Address + if (aDes.iFlags & KDmaPhysAddrDest) + dest = (TPhysAddr) aDes.iDest; + else + dest = Epoc::LinearToPhysical(aDes.iDest); + + TPlatDma::SetDMARegister(KHoDMA_CDSA(iChno), dest); +… + } +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-E55B594F-CC84-5984-9307-9819F6EBEB7F-master.png Binary file Adaptation/GUID-E55B594F-CC84-5984-9307-9819F6EBEB7F-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-E55B594F-CC84-5984-9307-9819F6EBEB7F_d0e29647_href.png Binary file Adaptation/GUID-E55B594F-CC84-5984-9307-9819F6EBEB7F_d0e29647_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-E6F9A60A-0112-4C9B-A880-7E2908A74DAA.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-E6F9A60A-0112-4C9B-A880-7E2908A74DAA.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,12 @@ + + + + + +InterruptDescribes the Interrupt platform service. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-E7C55048-5B7A-5BF2-B7F4-4D731659B88C.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-E7C55048-5B7A-5BF2-B7F4-4D731659B88C.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,206 @@ + + + + + +Device +Driver Writing and Migration Technology TutorialExplains techniques for writing device drivers on data paged systems +and migrating device drivers to data paged systems. +
Impact of data +paging on kernel APIs

The use of data paging impacts on the task +of writing and migrating device drivers in two main ways: the preconditions +for kernel API calls and the performance of the kernel APIs.

Firstly, +kernel APIs which access user memory may only be called subject to preconditions. +The preconditions are that

    +
  • no fast mutex may be +held while calling them, and

  • +
  • no kernel mutex may +be held while calling them.

  • +

The APIs are these:

    +
  • Kern::KUDesInfo

  • +
  • Kern::InfoCopy

  • +
  • Kern::KUDesGet

  • +
  • Kern::KUDesPut

  • +
  • Kern::KUDesSetLength

  • +
  • umemget, kumemget, umemget32, kumemget32

  • +
  • umemput, kumemput, umemput32, kumemput32

  • +
  • umemset, kumemset, umemset32, kumemset32

  • +
  • Kern::RequestComplete

  • +
  • Kern::ThreadRawRead

  • +
  • Kern::ThreadRawWrite

  • +
  • Kern::ThreadDesRead

  • +
  • Kern::ThreadDesWrite

  • +
  • Kern::ThreadGetDesLength

  • +
  • Kern::ThreadGetDesMaxLength

  • +
  • Kern::ThreadGetDesInfo

  • +
+
Impact of data +paging on execution

Device drivers use kernel side APIs to access +user memory, and even when they are called in accordance with their preconditions +they are no longer guaranteed to execute in a short and bounded time. This +is because they may access paged memory and incur page faults which propagate +from one thread to another. This document discusses how to mitigate the impact +of data paging on device drivers.

+
Mitigating +data paging: general principles

Three general principles are involved +in mitigating the impact of data paging on device drivers.

    +
  • Device drivers should +not use shared DFC queues.

  • +
  • Device drivers should, +as far as possible, not access paged memory.

  • +
  • If a device driver needs +to access paged memory, it should do so in the context of the client thread.

  • +
+
Driver frameworks

There +are three main categories of device driver:

    +
  • Boot-Loaded Non-Channel +Drivers

    Boot loaded drivers are built as kernel extensions. They +are typically simple device drivers such as keyboard drivers with limited +or no client side interface and are not much impacted by data paging. It is +generally safe for them to pass data structures using the HAL in the context +of a kernel thread and for them to execute in the context of a kernel thread: +however, this assumption must always be verified for individual cases.

  • +
  • Media Drivers

    Media +drivers are both channel based drivers and kernel extensions. When written +according to the recommended model they either execute wholly in the context +of their clients or use a unique DFC queue and associated kernel thread. If +these recommendations are followed, no additional measures to mitigate the +impact of data paging are required.

  • +
  • Dynamically loaded +channel based IO device drivers

    Channel based IO device drivers +are based on various models: all are dynamically loaded. They are derived +either from DLogicalChannelBase or DLogicalChannel. +

    Channel based drivers derived from DLogicalChannelBase usually +execute in the context of their client, mitigating the impact of data paging. +Where they are multi-threaded, they typically create separate and unique kernel +threads and do not use shared DFC queues, mitigating the impact of data paging: +if they use a shared DFC queue and associated kernel thread, they are impacted +by data paging and must be written so as to mitigate the effects. Channel +based drivers derived from DLogicalChannel may communicate +with the hardware directly (LDD to hardware) or indirectly (LDD to PDD to +hardware). If a PDD is involved, mitigation of data paging should take place +at that level and not the LDD. Channel based drivers may have single or +multiple clients, channels and hardware. It is these drivers which require +most work to mitigate the impact of data paging.

  • +
+
Mitigation +techniques

The impact of data paging on device drivers is mitigated +by the use of various different techniques which are the subject of the rest +of this document.

Passing +data by value

Clients should pass data by value not as pointers. +Return values of calls should be return codes not data.

Using dedicated DFC queues

All drivers which use DFCs should +use a dedicated DFC queue to service them. You should not use the kernel queues Kern::DfcQue0 and Kern::DfcQue1 for this purpose. How you create a dedicated DFC queue depends on the nature +of the driver.

To service boot loaded drivers and media drivers, you +create a DFC queue by calling Kern::DfcQueueCreate().

To +service dynamically loaded drivers derived from DLogicalChannelBase you call Kern::DynamicDfcQCreate() with +a TDynamicDfcQue as argument:

TInt Kern::DynamicDfcQCreate(TDynamicDfcQue*& aDfcQ, TInt aPriority, const TDesC& aBaseName);

To service a dynamically loaded driver derived from DLogicalChannel, +you use the DFC queue supplied with it (the member iDfc, +accessed by pointer). To use the queue you call the SetDfcQ() function +during the second phase construction of the LDD.

You destroy queues +by calling their function Destroy() which also terminates +the associated thread.

Setting +realtime state

The realtime state of a thread determines whether +it is enabled to access paged memory. If a thread is realtime (its realtime +state is on) it is guaranteed not to access paged memory, so avoiding unpredictable +delays. The realtime state of a thread may be set to ERealtimeStateOn, ERealtimeStateOff and ERealtimeStateWarn as defined in the enumeration TThreadRealtimeState and +set by the kernel function SetRealtimeState.

If +a driver uses DFC threads and is subject to performance guarantees, their +realtime state should be set to on (this is the default when data paging is +enabled). Otherwise the state should be set to off: the warning state is used +for debugging.

Validating +arguments in client context

It is often necessary to validate +the arguments of a request function. This should be done in the context of +the client thread as far as possible.

When a driver derived from the +class DLogicalChannelBase makes a request this happens +automatically as a call to the Request() function takes +place in the client thread. When the driver is derived from the class DLogicalChannel the +request involves a call to the SendMsg() function inherited +from the base class and it is necessary to override the base implementation +to force evaluation of the arguments within the client thread.

Accessing user memory from client context

The DFC should access +user memory as little as possible. Whenever there is a need to access user +memory and it can be accessed in the context of the client thread, it should +be.

When the driver is derived from the class DLogicalChannelBase, +read and write operations on user memory can be performed with calls to the Request() function +and these take place in the context of the client thread.

When the +driver is derived from the class DLogicalChannel it is +possible to read from and write to user memory by overriding the SendMsg() function +before passing the message on to be processed by the DFC thread if necessary. +If the message is passed on, data must be stored kernel side either on the +client thread's kernel stack or in the channel object.

Message data +can only be stored on the client thread's kernel stack if the message is synchronous +and the size of the data is less than 4Kb. Since the stack is local to the +client it can be used by more than one thread. One way of doing this is to +implement SendMsg() with a call to SendControl() which +is itself implemented to perform the copying in the client thread context +and independently call the SendMsg() function of the parent +class.

Where the message is asynchronous you can use a similar strategy +for overriding the SendMsg() function but this time perform +the copying to a buffer owned by the channel independently of a call to the SendMsg() function +of the parent class. In this case the size of the data must be small (in the +region of 4Kb), there must be only one client using the buffer, and data cannot +be written back to the client.

Using +TClientDataRequest

An asynchronous request often needs to copy +a structure of fixed size to its client to complete a request. The TClientDataRequest object +exists for this purpose: it writes a fixed size structure to user memory and +completes the request in the following steps.

    +
  1. The driver creates a TClientDataRequest object +for each asynchronous client which may be outstanding concurrently: either +one per client or one per request as appropriate.

  2. +
  3. When the client makes +a request the TClientDataRequest object is set to contain +the address of the client's buffer or descriptor and the address of the client's TRequestStatus. +This takes place in the client context.

  4. +
  5. The data to be written +is copied into the buffer of the TClientDataRequest object.

  6. +
  7. A call to Kern::QueueRequestComplete() passes +the address of the TClientDataRequest object.

  8. +
  9. The client is signalled +immediately.

  10. +
  11. When the client thread +next runs, the buffer contents and completion value are written to the client.

  12. +

Using +TClientBufferRequest

When it is necessary to access user memory +from a DFC thread context, that memory must be pinned for the duration of +the request and unpinned when the request is completed. The pinning must be +performed in the context of the client thread. The TClientBufferRequest object +exists for this purpose.It is used in the following way.

    +
  1. The driver creates a TClientBufferRequest object +for each client request which may be outstanding concurrently: either one +per client or one per request as appropriate.

  2. +
  3. Whe a client makes a +request, the TClientBufferRequest object is set to contain +the address of any buffers used and the address of the client's TRequestStatus. +Doing so pins the contents of the buffers: they can be specified as descriptors +or by start address and length. This takes place in the client context.

  4. +
  5. The driver calls Kern::ThreadBufRead() and Kern::ThreadBufWrite() to access the client's buffers. This takes place in the context of the DFC.

  6. +
  7. When the request is +complete, the driver calls Kern::QueueBufferRequestComplete() passing +the TClientBufferRequest object. This signals the client +immediately and unpins the buffers.

  8. +
  9. When the client thread +next runs, the completion value is written back to the client along with the +updated length of any descriptors.

  10. +

Using +Kern::RequestComplete()

The function Kern::RequestComplete() exists +in two versions:

static void Kern::RequestComplete(DThread* aThread, TRequestStatus*& aStatus, TInt aReason);

which is now deprecated, and its overloaded replacement

static void Kern::RequestComplete(TRequestStatus*& aStatus, TInt aReason);

The +overloaded version should always be used, as it does not take a thread pointer +argument.

Using +shared chunks

Shared chunks are a mechanism by which kernel side +code shares buffers with user side code. As an alternative to pinning memory +they have the following advantages:

    +
  • Shared chunks cannot +be paged and therefore paging faults never arise.

  • +
  • Shared chunks transfer +data with a minimum number of copying operations and are useful where high +speeds and large volumes are required.

  • +

Shared chunks present disadvantages when a driver is being migrated +rather than written from scratch, as the client API must be rewritten as well +as the driver code.

+
See Also

Performance Guarantee Tutorial

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-E7E67A52-0725-446B-A49C-CF571C4A0C64.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-E7E67A52-0725-446B-A49C-CF571C4A0C64.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,86 @@ + + + + + +DMA +Buffer OperationsThis document describes how a device driver allocates and deallocates +DMA buffers. +
Allocation

DMA +requires contiguous memory chunks to be allocated to do copy and read operations. +A driver can do this by using the Symbian Kernel API. A contiguous block of +memory can be allocated using Epoc::AllocPhysicalRam(), +which provides the physical address of the contiguous memory block allocated.

After +allocating the buffer, a global hardware chunk must be created, and its attributes +set. The attributes define chunk properties such as whether it is non-cacheable, +or whether it can be accessed only in supervisor mode, and so on.

TInt DExDriverUartTxDma::Init() + { + // Round up the transmit chunk size to the page size. + // Kern::RoundToPageSize() rounds up the argument to the size of + // a MMU page. The size of one MMU page can be found out by calling + // Kern::RoundToPageSize(1). + // + iTxBufSize = Kern::RoundToPageSize (KRxTxDMABufferSize); + + // Epoc::AllocPhysicalRam() allocate contiguous physical memory + // for the transmit buffer of the specified size, and returns the physical address + // of the buffer. We need contiguous block of memory and its + // physical address for DMA. + // + TInt r = Epoc::AllocPhysicalRam (iTxBufSize, iTxPhysAddr); + if (r != KErrNone) + { + return r; + } + + // Create a global hardware chunk for the buffer allocated using + // Epoc::AllocPhysicalRam() and set attributes to make it + // uncached and accessible only by kernel-side code. + // Contiguous, uncached, unbuffereable RAM pages avoids + // coherency and fragmentation issues while using DMA. + // However, in case of making buffers cacheable other APIs are + // provided to synch, i.e. flush cache before doing a DMA + // transfer + // + r = DPlatChunkHw::New(iTxChunk, iTxPhysAddr, iTxBufSize, + EMapAttrSupRw // Supervisor mode, user has no access + |EMapAttrFullyBlocking); // uncached, unbuffered + if (r != KErrNone) + { + // Free the allocated RAM, that was earlier allocated by + // Epoc::AllocPhysicalRam(). + Epoc::FreePhysicalRam(iTxPhysAddr, iTxBufSize); + return r; + } + ... + }

Buffers can also be made cacheable, in which case, the +driver has to ensure to synchronise by flushing the cache before writing and +after reading.

// Synchronises cache(s) prior to a DMA write operation. i.e. +// before DMA is used write to a peripheral data which is read +// from RAM. +void Cache::SyncMemoryBeforeDmaWrite(TLinAddr aBase, + TUint aSize, TUint32 aMapAttr) + +// Synchronizes cache(s) prior to a DMA read operation. +// i.e. before DMA is used read from a peripheral data which is +// written to RAM. +void Cache::SyncMemoryBeforeDmaRead(TLinAddr aBase, + TUint aSize, TUint32 aMapAttr) + +// Synchronises cache(s) after a DMA read operation. +void Cache::SyncMemoryAfterDmaRead(TLinAddr aBase, TUint aSize)

However, +unless required by design, DMA chunks are used in non-cacheable and non-buffered +mode.

+
Deallocation

DMA buffers have to be deallocated +when they are no longer used. Buffers are deallocated in the physical channel +destructor.

Like allocation, deallocation is performed in two stages. +When you allocate, the contiguous buffer is allocated and a hardware chunk +is created; when you de-allocate, the contiguous buffer is deallocated and +the chunk is closed.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-E7F91A65-235D-589C-9A8C-0B207D19A24B.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-E7F91A65-235D-589C-9A8C-0B207D19A24B.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,58 @@ + + + + + +Port client drivers to use the PRMThis document describes how to port client drivers to use +the PRM. +
Purpose

Device drivers must register as clients to access services of +the PRM.

Introduction

Kernel side components +can access PRM services through exported kernel side APIs by including resourceman.h and linking against the static library provided +by the PRM. See setup and configuration requirements.

+
Porting +client drivers

Kernel side components register as clients +with the PRM from their entry point during kernel boot and device +drivers register as clients on channel opening.

User side +components can access PRM services through a user side proxy interface. +See user-side for more information.

To guarantee deterministic +behaviour during resource state change and read operations (mainly +on a long latency resource), clients should pre-allocate ‘client level’ +objects and request objects using AllocReserve(). This needs to be done immediately after registering as clients +of the PRM.

Before de-registering as clients from PRM, device +drivers must:

    +
  • Cancel any pending +asynchronous request with CancelAsyncRequestCallback(). If CancelAsyncRequestCallback returns KErrInUse the client must wait for the request to complete +before proceeding with deregistration as the asynchronous request +has started processing and will run to completion,

  • +
  • Cancel all resource +state change notification requests issued by this client using CancelNotification(),

  • +
  • Delete the asynchronous +callback objects and notification objects created by this client to +avoid memory leak.

  • +

Omissions

PRM APIs cannot be called from +a Null thread, ISR or from DFC thread1. However it might be possible +that ISR need to operate on a power resource, for example, a power +supply may need to be turned on before a hardware register that an +ISR is interested on can be read. In this case Base port developers +need to access the power resource directly. In order for the PRM to +provide a consistent view of power resources any resource manipulators +in an ISR must leave them unchanged, so in the above example, the +ISR must turn OFF the power supply after it read the registers.

+
+Porting +the Power Resource Manager +Implement +the controllable power resources +Implement +the PSL for the target +Debugging +the PRM +Testing +the PRM PSL +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-E90DBF35-0A05-4751-904D-4F06987FFF48.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-E90DBF35-0A05-4751-904D-4F06987FFF48.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,16 @@ + + + + + +Memory +ManagementThese documents describe how device drivers handle memory buffers +and transfer data. +

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-E96E4542-7017-4069-BD9C-97467A99F211.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-E96E4542-7017-4069-BD9C-97467A99F211.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,12 @@ + + + + + +Testing and performance issuesThis section describes testing and performance issues. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-E9999276-6861-4ECA-B542-1B6C3471BFC9.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-E9999276-6861-4ECA-B542-1B6C3471BFC9.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,16 @@ + + + + + +IIC Tools GuideDescribes the tools required for building the IIC platform +service. +

There are no specific tools required to build the IIC platform +service. Refer to Using ROM tools section for standard ROMBUILD tools.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-EA0C5715-7CE8-5415-A915-D5701E3C957A-master.png Binary file Adaptation/GUID-EA0C5715-7CE8-5415-A915-D5701E3C957A-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-EA0C5715-7CE8-5415-A915-D5701E3C957A_d0e10709_href.png Binary file Adaptation/GUID-EA0C5715-7CE8-5415-A915-D5701E3C957A_d0e10709_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-EAA6A9FB-A470-550C-B7B4-FF68A733A2D5.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-EAA6A9FB-A470-550C-B7B4-FF68A733A2D5.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,613 @@ + + + + + +Thread +SynchronisationKernel-side techniques to protect critical regions in code or to +allow safe access to shared data. +

Kernel-side code can use a number of techniques to perform thread synchronisation, +to protect critical regions within threads or to ensure that shared data can +be safely read or modified.

+
    +
  • Mutexes

  • +
  • Semaphores

  • +
  • Thread critical section

  • +
  • Atomic operations

  • +
  • The system lock

  • +
  • The kernel lock

  • +
  • Disabling interrupts

  • +
+
Mutexes

A +mutex (mutual exclusion) is a mechanism to prevent more than one thread from +executing a section of code concurrently. The most common use is to synchronise +access to data shared between two or more threads.

There are two types +of mutex: the fast mutex, and a more general heavyweight mutex - the Symbian +platform mutex. Which one you use depends on the needs of your code and the +context in which it runs.

    +
  • The fast mutex

  • +
  • The Symbian platform mutex

  • +

The fast mutex

A +fast mutex is the fundamental way of allowing mutual exclusion between nanokernel threads. +Remember that a Symbian platform thread, and a thread in a personality layer +are also nanokernel threads.

A fast mutex is represented by a NFastMutex object. +It is designed to be as fast as possible, especially in the case where there +is no contention, and is also designed to occupy as little RAM as possible. +A fast mutex is intended to protect short critical sections of code

    +
  • Rules

  • +
  • How to use

  • +
  • Example using NFastmutex to protect a critical region

  • +

Rules

A +fast mutex is, be definition, fast and the price to be paid is that there +are a few rules that must be obeyed:

    +
  • a thread can only hold +one fast mutex at a time, i.e. a thread cannot wait on a fast mutex if it +already holds another fast mutex

  • +
  • a thread cannot wait +on the same fast mutex more than once

  • +
  • a thread must not block +or exit while holding a fast mutex because the thread is in an implied critical +section.

  • +

In the moving memory model, the user address space is not guaranteed +to be consistent while a kernel thread holds a fast mutex.

How +to use

Typically you declare a fast mutex in a class declaration, +for example:

class DImpSysTest : public DLogicalChannelBase + { + ... +public: + ... + NFastMutex iMutex; + ... + }; +

When you want to get hold of the fast mutex, i.e. when you +are about to enter a section of code that no other thread is executing concurrently, +you wait on that fast mutex. If no other thread has the mutex, then your thread +gets the mutex, and control flows into your critical code. On exiting the +section of code, you signal the fast mutex, which relinquishes it.

If, +on the other hand, another thread already has the fast mutex, then your thread +blocks, and only resumes when the other thread exits the code section by signalling +the fast mutex.

Getting and relinquishing the mutex is done using +the Wait() and Signal() functions of the NFastMutex class. +However, you will normally use the nanokernel functions:

    +
  • NKern::FMWait()

  • +
  • NKern::FMSignal()

  • +

respectively, passing a pointer to your NFastMutex object.

The +kernel lock must be held when NFastMutex::Wait() and NFastMutex::Signal() are +called. NKern::FMWait() and NKern::FMSignal() do +this for you. They make sure that the kernel lock is on while NFastMutex::Wait() and NFastMutex::Signal() are +called by wrapping them in a pair of NKern::Lock() and NKern::Unlock() calls.

Although +this sounds like you will be blocking while holding the kernel lock, in reality +you do not because the thread is not blocked until after the kernel lock is +released.

Be aware however that there may be situations where you +already have the kernel lock, or in the case of IDFCs, you do not need to +acquire it as no preemption can occur. In these cases, you just call NFastMutex::Wait() and NFastMutex::Signal().

The following diagram illustrates the general principle:

+Fast mutex + +

There are a number of assumptions here, one of which is that the +priorities are such that thread T1 does not run until a reschedule occurs, +after T2 has been interrupted.

Example +using NFastmutex to protect a critical region

The file ...\f32test\nkern\d_implicit.cpp is +a device driver that contains 3 threads and 3 separate sub-tests. The third +test, identified as ETestDummy, shows how to protect a critical +region using a nanokernel fast mutex.

The mutex itself is declared +in the channel class:

class DImpSysTest : public DLogicalChannelBase + { + ... +public: + ... + NFastMutex iMutex; + ... + }; +

The function Start() takes an argument that +sets the test number. This function initialises some test variables, creates +three threads, and also initialises the mutex:

TInt DImpSysTest::Start(TInt aTest) + { + ... + new (&iMutex) NFastMutex; + ... + } +

The overloaded new operator is called with +the existing mutex as its argument, with the side effect of calling the constructor +to initialise the mutex. There is also a corresponding Stop() function +to kill the threads and return the results to the caller.

Look at +the test case for iTestNum == ETestDummy, where thread 1 +and thread 3 use the mutex as if sharing a critical resource.

void DImpSysTest::Thread1(TAny* aPtr) + { + DImpSysTest& d=*(DImpSysTest*)aPtr; + ... + FOREVER + { + NKern::FMWait(&d.iMutex); + // this is a critical region protected by d.iMutex + NKern::FMSignal(&d.iMutex); + ... + } + } void DImpSysTest::Thread3(TAny* aPtr) + { + DImpSysTest& d=*(DImpSysTest*)aPtr; + ... + if (d.iTestNum==RImpSysTest::ETestPriority) + { + ... + } + else if (d.iTestNum==RImpSysTest::ETestDummy) + { + FOREVER + { + ... + if (x<85) + { + ... + } + else + { + NKern::FMWait(&d.iMutex); + // this is a critical region protected by d.iMutex + NKern::FMSignal(&d.iMutex); + } + } + } + } +

Each thread takes a pointer to the channel object as an argument, +this is the aPtr value passed to both Thread1() and Thread3() and +each thread dereferences it to find the mutex. The important point is that +there is only one mutex object, which is accessed by all interested threads.

Before +entering the critical region, the threads call NKern::FMWait() to +gain ownership of the mutex. Before leaving the critical region, they call NKern::FMSignal() to +relinquish ownership.

The +Symbian platform mutex

The Symbian platform mutex provides mutual +exclusion between Symbian platform threads without the restrictions imposed +by the fast mutex.

The Symbian platform mutex is represented by a DMutex object.

    +
  • Characteristics

  • +
  • How to use

  • +
  • Example using DMutex to protect critical regions

  • +

Characteristics

Operations +on a DMutex are more complicated, and therefore slower, than +those on a NFastMutex. However, a DMutex gives +you the following:

    +
  • it is possible to wait +on a Symbian platform mutex multiple times, provided it is signalled the exact +same number of times

  • +
  • It is possible to hold +several Symbian platform mutexes simultaneously, although care is needed to +avoid deadlock situations

  • +
  • A thread can block while +holding a Symbian platform mutex

  • +
  • A Symbian platform mutex +provides priority inheritance, although there is a limit on the number of +threads that can wait on any DMutex (currently this is 10).

  • +

When a Symbian platform mutex is created it is given an 'order' value. +This is a deadlock prevention mechanism, although it is used only in debug +builds. When waiting on a mutex the system checks that the order value is +less than the order value of any mutex that the thread is already waiting +on.

In general, most code written for device drivers should use values +which are greater than any used by the kernel itself. There are 8 constants +defined in kernel.h that are available for this purpose: KMutexOrdGeneral0 through KMutexOrdGeneral7.

The kernel faults with “Mutex Ordering Violation” if you try to +wait on a mutex that violates the ordering rules.

Note: the only time +when these values would not be suitable is when the kernel calls back into +non-kernel code while a mutex is already held by the kernel. This occurs in +only two cases:

    +
  • The debug event handler +callback

  • +
  • The various timer classes +like TTimer. This should not be an issue because device +drivers should use the NTimer class which does not callback +while DMutexes are held.

  • +

How to use

Typically +you declare the mutex in a class declaration, for example:

class DCrashHandler : public DKernelEventHandler + { + ... +private: + DMutex* iHandlerMutex; + ... + }; + +

You do not create a DMutex object directly; +instead you use the kernel function Kern::MutexCreate(). +You pass a DMutex* type to the kernel function, which creates +the DMutex object and returns a reference to it through the DMutex pointer.

Getting +and relinquishing the mutex is done using the kernel functions:

    +
  • Kern::MutexWait()

  • +
  • Kern::MutexSignal()

  • +

respectively, passing a reference to the DMutex object +created earlier. Note that although you pass a DMutex object +around, the member functions and member data of the class are considered as +internal to Symbian platform. However, you can call Open() and Close() on DMutex as +they are members of the base class DObject.

Example +using DMutex to protect critical regions

This example code fragment +uses two DMutex objects to protect a critical region of code +in a device driver. It implements a minimal debug agent in a device driver. +When a channel is opened to the device driver, the DoCreate() function +creates a crash handler (in 2 phases). The DCrashHandler class +contains two DMutex objects:

class DCrashHandler : public DKernelEventHandler + { + ... +private: + DMutex* iHandlerMutex; // serialise access to crash handler + ... + DMutex* iDataMutex; // serialise access to following members + ... + };

The two DMutex objects are created +in the second phase of the crash handler creation, i.e. when the member function DCrashHandler::Create() is +called. Here's the code:

TInt DCrashHandler::Create(DLogicalDevice* aDevice) + { + TInt r; + ... + r = Kern::MutexCreate(iHandlerMutex, KHandlerMutexName, KMutexOrdDebug); + ... + r = Kern::MutexCreate(iDataMutex, KDataMutexName, KMutexOrdDebug-1); + ... + }

The names of the mutexes are passed as the literal descriptors: KHandlerMutexName and KDataMutexName, and have the values CtHandlerMutex and CtDataMutex respectively.

Notice +that the data mutex has an order value less than the handler mutex. This guards +against deadlock - we are asking the kernel to check that any thread waits +on the handler mutex before it waits on the data mutex.

When a thread +panics, or an exception occurs, program control eventually reaches DCrashHandler::HandleCrash(). +The device driver is derived from DLogicalChannelBase, +and the current thread is the one that crashed and this is a Symbian platform +thread, which means that it can wait on a DMutex. In fact, +it waits on two mutexes, and does so in the order mentioned above. The mutexes +are signalled further on in the same function.

void DCrashHandler::HandleCrash(TAny* aContext) + { + ... + // Ensure that, at any time, at most one thread executes the + // following code. This simplifies user-side API. + Kern::MutexWait(*iHandlerMutex); + ... + Kern::MutexWait(*iDataMutex); + ... + // access crash handler data <------------------------------------- + ... + Kern::MutexSignal(*iDataMutex); + ... + Kern::MutexSignal(*iHandlerMutex); + }

iHandlerMutex ensures that only one +thread at a time uses the above code. iDataMutex protects +a smaller critical region where the crash handler’s data is accessed. This +data is also protected by iDataMutex in the DCrashHandler::Trap() function.

void DCrashHandler::Trap(TRequestStatus* aRs, TAny* aCrashInfo) + { + ... + Kern::MutexWait(*iDataMutex); + ... + // access crash handler data <------------------------------------- + ... + Kern::MutexSignal(*iDataMutex); + ... + } +

A DMutex is a reference counting object, +and is derived from DObject. This means that once you have +finished with it, you must call Close() on it to reduce the +number of open references.

In this example, both DMutex objects +are closed in the DCrashHandler destructor:

DCrashHandler::~DCrashHandler() + { + ... + if (iDataMutex) + { + iDataMutex->Close(NULL); + } + if (iHandlerMutex) + { + iHandlerMutex->Close(NULL); + } + ... + }
+
Semaphores

A +semaphore is synchronisation primitive that you can use:

    +
  • to signal one thread +from another thread

  • +
  • to signal a thread from +an Interrupt Service Routine using an IDFC.

  • +

In EKA2, there are two types of semaphore: the fast semaphore, and +a more general semaphore - the Symbian platform semaphore. Which one you use +depends on the needs of your code and the context in which it is runs.

    +
  • The fast semaphore

  • +
  • The Symbian platform semaphore

  • +

The fast semaphore

A +fast semaphore is a fast lightweight mechanism that a thread can use to wait +for events. It provides a way of posting events to a single thread because +the semaphore can keep count of the number of events posted.

A fast +semaphore is represented by a NFastSemaphore object, and +this is implemented by the nanokernel. Remember that a Symbian platform +thread, and a thread in a personality layer are also nanokernel threads.

    +
  • Rules

  • +
  • How to use

  • +
  • Example using NFastSemaphore and the NKern functions

  • +
  • Example using the NFastSemaphore::Signal() function

  • +

Rules

Because +of its lightweight structure, only the owning thread is allowed to +wait on it.

How +to use

Typically you declare a fast semaphore in a class declaration, +for example:

class DCrashHandler : public DKernelEventHandler + { + ... +private: + NFastSemaphore iSem; + ... + }; + +

You need to initialise the NFastSemaphore by:

    +
  • constructing the semaphore

  • +
  • setting the thread that +owns the semaphore, i.e. the thread that will be allowed to wait in it.

  • +

The semaphore is initialised when its constructor is called. However, +setting the owning thread requires explicit code. For example, the following +code fragment is typical and sets the owning thread to be the current thread:

iSem.iOwningThread = (NThreadBase*)NKern::CurrentThread();

Waiting +and signalling the fast semaphore is done by using the Wait() and Signal() functions +of the NFastSemaphore class. However, you will normally +use the nanokernel functions:

    +
  • NKern::FSWait()

  • +
  • NKern::FSSignal()

  • +

respectively, passing a pointer to your NFastSemaphore object.

The +kernel lock must be held when NFastSemaphore::Wait() and NFastSemaphore::Signal() are +called. NKern::FSWait() and NKern::FSSignal() do +this for you. They make sure that the kernel lock is on while NFastSemaphore::Wait() and NFastSemaphore::Signal() are called by wrapping them in a pair of NKern::Lock() and NKern::Unlock() calls.

Although +this sounds like you will be blocking while holding the kernel lock, in reality +you do not because the thread is not blocked until after the kernel lock is +released.

Be aware however that there may be situations where you +already have the kernel lock, or in the case of IDFCs, you do not need to +acquire it as no preemption can occur. In these cases, you just call NFastSemaphore::Wait() and NFastSemaphore::Signal().

You can use use a fast semaphore to block a thread until an interrupt +occurs, but you cannot signal the semaphore directly from the interrupt service +routine (ISR) that services that interrupt; instead, you must queue an IDFC, +and signal from there.

Example +using NFastSemaphore and the NKern functions

This is an example +that synchronises threads using the NFastSemaphore class, +and is part of code that implements a minimal debug agent in a device driver. +The full code for this can be found in ...\e32utils\d_exc\minkda.cpp.

When +a channel is opened, the DoCreate() function creates a crash +handler (in 2 phases).This is a DCrashHandler object, and +importantly, contains a NFastSemaphore.

class DCrashHandler : public DKernelEventHandler + { + ... +private: + NFastSemaphore iSuspendSem; // for suspending crashed thread + ... + };

When a thread panics, or an exception occurs, program +control eventually reaches DCrashHandler::HandleCrash(). +It is in this function that the owning thread is set – to the current nanokernel +thread (i.e. the one that crashed). This is the only thread allowed to wait +on the semaphore. The wait is just a few lines further down in the same function:

void DCrashHandler::HandleCrash(TAny* aContext) + { + DThread* pC = &Kern::CurrentThread(); + ... + if (iTrapRq != NULL) + { + iCrashedThread = pC; + iSuspendSem.iOwningThread = &(iCrashedThread->iNThread); + ... + } + ... + if (iCrashedThread) + { + ... + NKern::FSWait(&(iSuspendSem)); // Waits on the semaphore + ... + } + ... + }

At a later time, the debugger calls the driver’s Request() function +with either the ECancelTrap or EKillCrashedThread parameters. +One or other of the corresponding functions is called; each function is implemented +to signal the semaphore.

void DCrashHandler::CancelTrap() + { + ... + if (iCrashedThread != NULL) + { + NKern::FSSignal(&(iSuspendSem)); + } + ... + } void DCrashHandler::KillCrashedThread() + { + ... + NKern::FSSignal(&iSuspendSem); + }

Example +using the NFastSemaphore::Signal() function

This is an example +code fragment taken from ...\e32test\misc\d_rndtim.cpp.

This +a device driver that uses a timer. The driver's logical channel can start +the timer, and it can wait for the timer to expire. The expiry of the timer +results in an interrupt; this results in a call to an ISR that schedules an +IDFC, which, in turn, signals the driver's logical channel.

Because +the kernel is implicitly locked when the IDFC runs, there is no need to explicitly +lock the kernel, and NFastSemaphore::Signal() can be called +instead of NKern::FSSignal().

The relevant part +of the driver's logical channel class is:

class DRndTim : public DLogicalChannelBase + { + ... +public: + NFastSemaphore iSem; + ... + };

The semaphore's owning thread is set in the logical +channel's constructor. Note that the constructor is called in the context +of the client thread, and it is this thread that is the owner of the semaphore. +This must also be the thread that waits for the semaphore, which it does when +at some later time it sends an EControlWait request to the +device driver to wait for the timer to expire.

DRndTim::DRndTim() + { + iThread=&Kern::CurrentThread(); + iThread->Open(); + iSem.iOwningThread = &iThread->iNThread; + ... + }

The following code shows the implementation of this wait. +Note that it assumes that the timer has already been started, which we have +not shown here.

The wait is initiated using the NKern::FSWait() function +as the kernel must be locked when the wait operation is done on the NFastSemaphore.

TInt DRndTim::Request(TInt aFunction, TAny* a1, TAny* a2) + { + TInt r = KErrNotSupported; + switch (aFunction) + { + case RRndTim::EControlWait: + NKern::FSWait(&iSem); + r = KErrNone; + break; + ... + } + ... + }

When the timer expires, the ISR runs, and this schedules +the IDFC, which in turn signals the client thread. The following code is the +IDFC implementation.

void DRndTim::IDfcFn(TAny* aPtr) + { + DRndTim* d = (DRndTim*)aPtr; + d->iSem.Signal(); + }

Note that this calls NFastSemaphore::Signal() rather +that NKern::FSSignal() because IDFCs are called with the +kernel locked.

The +Symbian platform semaphore

Symbian platform semaphores are standard +counting semaphores that can be used by one or more Symbian platform threads. +The most common use of semaphores is to synchronise processing between threads, +i.e. to force a thread to wait until some processing is complete in one or +more other threads or until one or more events have occurred.

The +Symbian platform semaphore is represented by a DSemaphore object.

    +
  • Characteristics

  • +
  • Rules

  • +
  • How to use

  • +

Characteristics

A +Symbian platform semaphore is based on the value of a count, which the DSemaphore object +maintains. The value of the count indicates whether there are any threads +waiting on it. The general behaviour is:

    +
  • if the count is positive +or zero, then there are no threads waiting

  • +
  • if the count is negative, +the magnitude of the value is the number of threads that are waiting on it.

  • +

There are two basic operations on semaphores:

    +
  • WAIT - this decrements +the count atomically. If the count remains non-negative the calling thread +continues to run; if the count becomes negative the calling thread is blocked.

  • +
  • SIGNAL - this increments +the count atomically. If the count was originally negative the next highest +priority waiting thread is released.

  • +

Waiting threads are released in descending order of priority. Note +however that threads that are explicitly suspended as well as waiting on a +semaphore, are not kept on the semaphore wait queue; instead they are kept +on a separate suspended queue. Such threads are not regarded as waiting for +the semaphore; this means that if the semaphore is signalled, they will not +be released, and the semaphore count will just increase and may become positive.

Symbian +platform semaphore operations are protected by the system lock fast mutex rather than by locking the kernel. To guarantee +this, semaphore operations are done through kernel functions.

Although +somewhat artificial, and not based on real code, the following diagram nevertheless +shows the basic idea behind Symbian platform semaphores.

+Symbian platform semaphore + +

Rules

There +are a few rules about the use of Symbian platform semaphores:

    +
  • Only Symbian platform +threads are allowed to use Symbian platform semaphores

  • +
  • An IDFC is not allowed +to signal a Symbian platform semaphore.

  • +

How to use

Typically +you declare the Symbian platform semaphore in a class declaration, for example:

class X + { + ... +private: + DSemaphore* iSemaphore; + ... + }; + +

You cannot create a DSemaphore object directly; +instead you must use the kernel function Kern::SemaphoreCreate(). +You pass a DSemaphore* type to the kernel function, which +creates the DSemaphore object and returns a reference to +it through the DSemaphore pointer.

Waiting on the +semaphore and signalling the semaphore are done using the kernel functions:

    +
  • Kern::SemaphoreWait()

  • +
  • Kern::SemaphoreSignal()

  • +

respectively, passing a reference to the DSemaphore object +created earlier. Note that although you pass a DSemaphore object +around, the member functions and member data of the class are considered as +internal to Symbian platform, and indeed the member functions are not exported +and are not accessible except to the kernel itself. However, you can call Open() and Close() on DSemaphore as they are members of the base class DObject.

+
Thread critical +section

Putting a thread into a thread critical section prevents +it being killed or panicked. Any kill or panic request is deferred until the +thread leaves the critical section.

A thread critical section is used +to protect a section of code that is changing a global data structure or some +other global resource. Killing a thread that is in the middle of manipulating +such a global data structure might leave it in a corrupt state, or marked +is being "in use".

A thread critical section only applies to code +that is running on the kernel side but in the context of a user thread. Only +user threads can be terminated or panicked by another thread.

In practice, +a thread critical section only applies to code implementing a DLogicalChannelBase::Request() function +or a HAL function handler.

How +to use

Enter a thread critical section by calling: NKern::ThreadEnterCS().

Exit +a thread critical section by calling: NKern::ThreadLeaveCS().

Note:

    +
  • it is important that +you only hold a thread critical section for the absolute minimum amount of +time it takes to access and change the resource.

  • +
  • you do not need to be +in a critical section to hold a fast +mutex because a thread holding a fast mutex is implicitly in a critical +section.

  • +

There are a large number of examples scattered throughout Symbian +platform source code.

+
Atomic operations

There +are a number of functions provided by the nanokernel that allow you +to do atomic operations, and may be useful when synchronising processing or +ensuring that data is safely read and/or updated.

This is a list of +the functions that are available. The function descriptions provide sufficient +information for their use.

    +
  • NKern::SafeSwap()

  • +
  • NKern::SafeSwap8()

  • +
  • NKern::LockedInc()

  • +
  • NKern::LockedDec()

  • +
  • NKern::LockedAdd()

  • +
  • NKern::LockedSetClear()

  • +
  • NKern::LockedSetClear8()

  • +
+
The system +lock

The system lock is a specific fast mutex that only provides +exclusion against other threads acquiring the same fast mutex. Setting, and +acquiring the system lock means that a thread enters an implied critical section.

The +major items protected by the system lock are:

    +
  • DThread member +data related to thread priority and status.

  • +
  • the consistency of the +memory map. On the kernel side, the state of user side memory or the mapping +of a process is not guaranteed unless one or other of the following conditions +is true:

      +
    • you are a thread belonging +to the process that owns the memory.

    • +
    • you hold the system +lock.

    • +
  • +
  • the lifetime of DObject type +objects and references to them, including handle translation in Exec dispatch.

  • +

Note that the system lock is different from the kernel lock; the +kernel lock protects against any rescheduling. When the system lock is set, +the calling thread can still be preempted, even in the locked section.

    +
  • How to use

  • +
  • When to use

  • +

How to use

The +system lock is set by a call to NKern::LockSystem().

The +system lock is unset by a call to NKern::UnlockSystem()

When to use

Only +use the system lock when you access a kernel resource that is protected by +the system lock. Generally you will not access these directly but will use +a kernel function, and the preconditions will tell you whether you need to +hold the system lock.

+
The kernel +lock

The kernel lock disables the scheduler so that the currently +running thread cannot be pre-empted. It also prevent IDFCs from running. If +the kernel lock is not set, then IDFCs can run immediately after ISRs

Its +main purpose is to prevent code from being reentered and corrupting important +global structures such as the thread-ready list.

How +to use

The kernel lock is set by a call to NKern::Lock().

The +kernel lock is unset by a call to NKern::Unlock()

When to use

ALMOST +NEVER.

The kernel exports this primarily for use by personality +layers, which need to modify the thread-ready list. In general, you should +use a fast +mutex for thread synchronisation.

+
Disabling interrupts

This +is the most drastic form of synchronisation. With interrupts disabled, timeslicing +cannot occur. If interrupts are disabled for any length of time, the responsiveness +of the whole system may be threatened, and real time guarantees may be invalidated.

How +to use

There are three functions supplied by the nanokernel involved +in disabling and enabling interrupts.

    +
  • NKern::DisableInterrupts()

  • +
  • NKern::DisableAllInterrupts()

  • +
  • NKern::RestoreInterrupts()

  • +

When to use

NEVER.

Unless there is +absolutely no other suitable technique. You would probably only use this to +protect some data that is shared between an interrupt service routine and +a thread (or a DFC). Nevertheless, you may find that atomic operations are more suitable.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-EB2566BD-8F65-5A81-B215-E8B05CFE21C3.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-EB2566BD-8F65-5A81-B215-E8B05CFE21C3.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,281 @@ + + + + + +Migration +Tutorial: Demand Paging and Media DriversDescribes how to change media drivers when demand paging is used. +

Demand paging is a change made from Symbian platform v9.3 to how the Kernel +uses RAM and storage media. This topic

+
Introduction

If the ROM has been built with paging +enabled, the image is divided into two sections: an unpaged section and a +paged section. In addition to this, code that is not part of the ROM can be +loaded on demand into RAM from other non-XIP partitions and/or media, for +example FAT or ROFS partitions.

Two types of paging are currently +supported:

    +
  • ROM paging - paging +from the paged section of the ROM image

  • +
  • code paging - paging +from non-removable media, for example, a FAT partition on an internal Multi +Media Card (MMC) drive or an internal NAND ROFS/FAT partition.

    See +also Paging from an +internal MMC.

  • +

: A difference between ROM paging and code paging is that +all ROM pages are contiguous, whereas code that is paged from other drives +may be split over several potentially non-contiguous clusters. This puts an +extra burden on the paging subsystem as it needs to identify the layout of +the DLL on the media before it is deemed pageable. This is achieved by using +the file servers blockmap API.

Media drivers are typically +PDDs with a filename of med.pdd. Normally they are declared +in the rombuild.oby file with the keyword extension or device and +are therefore flagged as unpaged. That is, once loaded their code and read-only +data sections are not paged out.

A media driver that is capable of +servicing page requests from the paging subsystem must ensure that the thread +in which the media driver runs takes the page fault itself otherwise a deadlock +could occur. In theory, the only time this can happen is when a media driver +accepts a write request from a user side client that points to data in the +paged section of the ROM or to code that has been loaded into RAM from code +paging enabled media. To remedy this, the local media subsystem has been modified +to lock write requests to paging media drivers before they are dispatched +and to split large write requests into a series of smaller ones to avoid exhausting +available RAM.

The two initial stages relevant to this discussion +are:

    +
  • the kernel extension +entry point - identified by the DECLARE_STANDARD_EXTENSION macro

  • +
  • the PDD entry point +- identified by the DECLARE_EXTENSION_PDD macro.

  • +

To enable demand paging as soon as possible in the boot sequence +it is desirable to instantiate and install the PDD factory object earlier, +for example in the kernel extension entry point.

Some media +drivers have no kernel extension entry point defined, the MMC media driver +is an example. These drivers have a DECLARE_STANDARD_PDD macro +defined rather than DECLARE_EXTENSION_PDD. They require +modification to have a DECLARE_EXTENSION_PDD and a DECLARE_STANDARD_EXTENSION.

The +steps needed to support ROM and/or code paging are as follows:

    +
  1. determine whether code +paging is supported, and if so, identify the relevant local drive number or +numbers

  2. +
  3. modify variantmediadef.h

  4. +
  5. modify the media drivers kernel extension entry point to register +the media driver with the paging subsystem and to instantiate and install +the DPhysicalDevice derived factory object

  6. +
  7. modify the DLocalDrive::Ecaps() handling

  8. +
  9. modify the media drivers DMediaDriver::Request function +to accept the four new paging +request types

  10. +
  11. Handling fragmented write requests.

  12. +
+
Changes to +variantmediadef.h

The following should be defined using appropriate +names in the variant's variantmediadef.h file:

    +
  • PAGING_TYPE - +flags that indicate whether code paging and/or ROM paging is supported

  • +
  • NAND_PAGEDRIVELIST - +a list of the paging drives

  • +
  • NAND_PAGEDRIVECOUNT - +the total number of paging drives

  • +
  • NUM_PAGES - +if a write request points to data that resides in paged ROM, the request is +split up into separate fragments of the specified size. This value needs to +be chosen with care, as if it is too small writes can take too long to finish.

  • +

Normal write requests which point to data that is not in paged +ROM are not fragmented. However, large requests are split up into smaller +requests by the file server, providing clients with a more responsive system.

The +macros defined in the file variantmediadef.h are passed to LocDrv::RegisterPagingDevice(). +This function is similar to LocDrv::RegisterMediaDevice() in +that it takes a drive list as a parameter, but it identifies the drive or +drives to be used for code paging. If code only ROM paging is needed, set +the drive count to zero.

Changes made to support paging on NAND:

// Variant parameters for NAND flash media driver (mednand.pdd) +#define NAND_DRIVECOUNT 8 +#define NAND_DRIVELIST 2,3,5,6,7,9,10,11 +#define NAND_NUMMEDIA 1 +#define NAND_DRIVENAME "Nand" + +#define PAGING_TYPE DPagingDevice::ERom | DPagingDevice::ECode + +// code paging from writeable FAT, Composite FAT and first ROFS +#define NAND_PAGEDRIVELIST 2,5,6 +#define NAND_PAGEDRIVECOUNT 3 + +// defines the size of fragment +#define NUM_PAGES 8
+
Changes to +the media driver kernel extension point

The kernel-extension entry +point must create a DFC queue to satisfy any page fault that occurs in the +drive thread. Failure to do so results in a kernel fault. The entry point +must then create a DPrimaryMediaBase object and register +it with the local media subsystem. To support paging, the entry point needs +altering to register the paging device with the demand paging subsystem and +instantiate and install the factory object.

DECLARE_STANDARD_EXTENSION() + { + TInt r=Kern::DfcQInit(&TestMediaDfcQ,KTestThreadPriority,&KTestMediaThreadName); + if (r|=KErrNone) + return r; + + DPrimaryMediaBase* pM=new DPrimaryMediaBase; + if (!pM) + return r; + + pM->iDfcQ=&TestMediaDfcQ; + r=LocDrv::RegisterMediaDevice( + MEDIA_DEVICE_NAND, + NAND_DRIVECOUNT, + NAND_DRIVELIST, + pM, + NAND_NUMMEDIA, + NAND_DRIVENAME); + if (r != KErrNone) + return r; + + r = LocDrv::RegisterPagingDevice( + pM, + NAND_PAGEDRIVELIST, + NAND_PAGEDRIVECOUNT, + PAGING_TYPE, + SECTOR_SHIFT, + NUM_PAGES); + if (r == KErrNone) + { + device = new DPhysicalDeviceMediaTest; + if (device == NULL) + return KErrNoMemory; + r = Kern::InstallPhysicalDevice(device); + } + // Ignore error if demand paging not supported by kernel + else if (r == KErrNotSupported) + r = KErrNone; + else + return r; + + pM->iMsgQ.Receive(); + return KErrNone; + }

The fifth parameter passed to the function LocDrv::RegisterPagingDevice() named SECTOR_SHIFT is the log2 of the sector size for the given media. For example, passing +a value of 9 corresponds to a sector size of 512 for most media.

The DECLARE_EXTENSION_PDD entry +point is called some time later when the file server tries to load all the +media drivers in the system. When this happens a second factory object is +created by the media driver, but this is deleted by the kernel when it discovers +that another factory object bearing the same name is already in its internal +list.

+
Changes to +DLocalDrive::ECaps handling

The TLocalDriveCaps structure +needs to be modified so that:

    +
  • the KMediaAttPageable flag +is set in iMediaAtt

  • +
  • the KDriveAttPageable flag +is set if a particular drive has been registered as code paging. This is determined +by testing TLocDrvRequest::Drive() ->iPagingDrv.

  • +

Additionally, the TLocalDriveCaps ::iDriveAtt must +have the KDriveAttLocal and KDriveAttInternal bits +set and the KDriveAttRemovable bit cleared.

TInt DMediaDriverTest::Request(TLocDrvRequest& aRequest) + { + TInt r=KErrNotSupported; + TInt id=aRequest.Id(); + + if (id == DLocalDrive::ECaps) + { + TLocDrv* drive = aRequest.Drive(); + TLocalDriveCapsV4& c = *(TLocalDriveCapsV4*)aRequest.RemoteDes(); + r=Caps(*drive,c); + } + // etc… + } + +TInt DMediaDriverTest::Caps(TLocDrv& aDrive, TLocalDriveCapsV4& caps) + { + // fill in rest of caps structure as usual… + + if(aDrive.iPrimaryMedia->iPagingMedia) + caps.iMediaAtt|=KMediaAttPageable; + if(aDrive.iPagingDrv) + caps.iDriveAtt|=KDriveAttPageable; + }
+
Handling page +requests

Four new request types need to be handled to support paging:

    +
  • EWriteRequestFragment marks +the start and middle of a sequence of writes.

  • +
  • Each sequence is terminated +by a EWriteRequestFragmentLast request as long as none +of the prior requests completed with an error.

  • +
  • ERomPageInRequest is +treated as a normal read except that:

      +
    1. the list of partitions +reported by DMediaDriver::PartitionInfo does not normally +include the partition containing the ROM image. Therefore, the local media +subsystem does not know the absolute position from the start of the media +of a particular ROM page. The position stored in ERomPageInRequest is +offset from the start of the ROM image, rather than the start of the media. +Therefore, the media driver must add the offset of the start of the ROM image +to the position stored in ERomPageInRequest to obtain the +absolute position before issuing a read request.

    2. +
    3. when the read is complete +the media driver needs to call TLocDrvRequest::WriteToPageHandler to +write the data back to the client, rather than TLocDrvRequest::WriteRemote as +for a normal read,

    4. +
  • +
  • ECodePageInRequest is +treated as a normal read, except that the function TLocDrvRequest::WriteToPageHandler should +be used to write the data back to the demand paging subsystem. However, the +position in the request is offset from the start of the media as for a normal +read.

  • +

These request types are enumerated in the DMediaPagingDevice class:

NONSHARABLE_CLASS(DMediaPagingDevice) : public DPagingDevice + { +public: + enum TPagingRequestId + { + /** + Identifies any middle fragment of a Write request on a partition of a media that supports paging. + */ + EWriteRequestFragment = + DLocalDrive::EFirstReqNumberReservedForPaging, + + /** + Identifies the last fragment of a Write request on a partition of a media that supports paging. + */ + EWriteRequestFragmentLast = + DLocalDrive::EFirstReqNumberReservedForPaging+1, + + /** + Request for paging in (read) data from the ROM store area. + */ + ERomPageInRequest = + DLocalDrive::EFirstReqNumberReservedForPaging+2, + + /** + Request for paging in (read) data from the code store area. + */ + ECodePageInRequest = + DLocalDrive::ELastReqNumberReservedForPaging + }; + //etc… + }
+
Handling fragmented +write requests

In many respects, EWriteRequestFragment and EWriteRequestFragmentLast can +be treated as normal write requests. It should be noted however, that these +write requests can be interleaved with requests from other file server threads +if the media supports more than one partition, the resulting operations may +be perceived as a functional break in behaviour.

If it is important +to maintain backwards compatibility and to prevent write requests from being +interleaved, the media driver must keep track of the current write-request +chain and defer requests from other drive threads while a write-fragment chain +is in progress by:

    +
  • ensuring the local media +subsystem LDD has been built with the __ALLOW_CONCURRENT_FRAGMENTATION__ macro +undefined. This ensures that the local media subsystem never issues more than +one write fragment at a time

  • +
  • modifying the paging-media +driver so that it keeps track of write-request chains and defers any read +or format requests received after the first fragment and before the last in +a sequence. When undefined, the macro subsystem does not issue more than one +write-request chain at a time.

  • +

Write fragments should never be deferred, only read or format +requests may be deferred.

To achieve this the media driver +can maintain a bit mask, each bit of which represents a write in progress +flag for a particular drive:

iFragmenting|=(0x1<<iCurrentReq->Drive()->iDriveNumber);

If a read or format request is received while any of the bits in iFragmenting are +set, that request may be deferred.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-EB76FAF8-CD4B-5CB6-9F23-C852ED91866F.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-EB76FAF8-CD4B-5CB6-9F23-C852ED91866F.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,18 @@ + + + + + +ConceptsThis section describes the architecture and behavior of +the Keyboard Driver. +Keyboard + Driver Implementation Tutorial +Keyboard + Mapping DLL Tutorial + \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-EBF025DB-1552-5E99-8C07-09932DB60552.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-EBF025DB-1552-5E99-8C07-09932DB60552.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,543 @@ + + + + + +Physical +Channel ImplementationA media driver must implement a physical channel class derived +from the DMediaDriver base class. +

+

This includes those drivers associated with fixed media, such as the internal +drive, or removable media, such as a PC Card or MultiMediaCard.

+

DMediaDriver is an abstract class that has virtual functions +that must be implemented by your derived class. The following class definition +is typical:

+class DMyMediaDriver : public DMediaDriver + { +public: + DMyMediaDriver (TInt aMediaId); + ~DMmcMediaDriver (); +public: + virtual void Close(); +public: + virtual void Disconnect(DLocalDrive* aLocalDrive, TThreadMessage*); + virtual TInt Request(TLocDrvRequest& aRequest); + virtual TInt PartitionInfo(TPartitionInfo& anInfo); + virtual void NotifyPowerDown(); + virtual void NotifyEmergencyPowerDown(); +public: + TInt DoCreate(TInt aMediaId); + }; + +

All the functions except the constructor and DoCreate() either +implement or re-implement virtual functions defined by DMediaDriver.

+

The framework does not require the DoCreate() function, +but it is useful to implement such a function to act as a second-phase constructor +in the creation of the media driver. In the example code fragments, we call DoCreate() from +the PDD +factory object's Create() function that is responsible for creating +the media driver.

+

There is, of course, nothing to stop you from adding your own functions +and data members, if this is appropriate for your implementation. In addition, +your are also free to add other classes, functions and enums to your media +driver implementation.

+
    +
  • Constructor

  • +
  • DoCreate() - second phase constructor

  • +
  • PartitionInfo() - return the partition information

  • +
  • Request() - handling requests

  • +
+
Constructor

The +media driver object is created by your PDD factory object's implementation +of the Create() function. +The following is the relevant line of code:

... +//Create my DMediaDriver derived object +DMyMediaDriver* pD=new DMyMediaDriver (aMediaId); +...

Your constructor, prototyped as:

DMyMediaDriver (TInt aMediaId);

gives you the chance to do any initialisation that is safe, i.e. that +cannot fail. Typically, this is the kind of initialisation that does not need +to acquire resources. This is the first phase of the typical Symbian platform +two-phase construction process.

DMyMediaDriver::DMyMediaDriver (TInt aMediaId) + :DMediaDriver(aMediaId) + { + //…do safe initialisation here + } +

As this code fragment shows, you need to call the +base class constructor first, forwarding the TInt aMediaId value. +You do not need to do anything else with this value. Note that this value +is the unique media ID used when the media driver was registered.

+
DoCreate() +- second phase constructor

The media driver object is created by +your PDD factory object's implementation of the Create() function. The following is the relevant line of code, which is called after +successful creation of the media driver object:

... +// Call my media driver’s second-stage constructor +Tint r = KErrNoMemory; + if(pD) + { + r = pD->DoCreate(aMediaId); + } +... +

This is a second-phase constructor that allows you +to do more complex initialisation, and initialisation that might fail. Typically, +this is initialisation that acquires resources (including memory). The outline +implementation of DoCreate() is:

TInt DMyMediaDriver::DoCreate(TInt aMediaId) + { + TInt r = KErrNone; + //…do complex initialisation here + return r; + } +

Depending on the complexity of your initialisation, +you can either do all your initialisation here, and complete immediately, +or you can do the initialisation as an asynchronous operation, in which case +initialisation will complete at some later time.

If you do this synchronously, +then the return code should reflect the success or failure of the operation. +In practice, this will almost always be KErrNone.

If +you do this asynchronously, then, on completion of the initialisation +processing, a call should be made to: DMediaDriver::OpenMediaDriverComplete() passing +either KErrNone or one of the other system-wide codes as +appropriate.

+
PartitionInfo() +- return the partition information

Once the media driver has been +successfully created and initialised, and has informed the media driver subsystem +of this fact by a call to DMediaDriver::OpenMediaDriverComplete(), +then the subsystem makes a call to the media driver's PartitionInfo() function +to get partition information for the media device.

The prototype function +is:

TInt PartitionInfo(TPartitionInfo& anInfo);

A TPartitionInfo object is passed to the function, which the media driver must fill in.

Decoding +of partition information may require media access, and as such may be a long +running activity. Support is provided that allows this to be done asynchronously. +You use the return code from PartitionInfo() to tell +the media driver subsystem which operational mode you are using:

    +
  • return KErrNone, +if the decoding operation is to be done asynchronously. Note that on +completion, the asynchronous operation must call DMediaDriver::PartitionInfoComplete(), +returning KErrNone, or one of the other system-wide error +codes, if appropriate.

  • +
  • return a value other +than KErrNone , if the decoding operation has been done synchronously. +If the synchronous operation is successful, return KErrCompletion, +otherwise return one of the other system-wide error codes, but not KErrNone.

  • +

Decoding +simple partitions

The following example shows the implementation +of a simple PartitionInfo() function. Such an implementation +would be provided for non-removable media, such as internal Flash memory, +where the layout is simple and known to the system.

This implementation +reports a single partition with the size of the entire media. The partition +expects to be mounted with the FAT filesystem.

Note that this operation +is done synchronously, and the function returns KErrCompletion to +indicate this.

TInt DMyMediaDriver::PartitionInfo(TPartitionInfo& aInfo) + { + aInfo.iPartitionCount = 1; + aInfo.iEntry[0].iPartitionBaseAddr = 0; + aInfo.iEntry[0].iPartitionLen = TotalSizeInBytes(); + aInfo.iEntry[0].iPartitionType = KPartitionTypeFAT12; + + aInfo.iMediaSizeInBytes = TotalSizeInBytes(); + + return KErrCompletion; + } +

Decoding +FAT Partitions

More complex implementations of PartitionInfo() may +be required when handling removable media or more complex internal media where +the layout of the media is unknown to the system.

This example shows +a typical implementation for a FAT based removable media device. Here, PartitionInfo() starts +the operation, which is done asynchronously by the DoPartitionInfo() function.

Note +that PartitionInfo() returns KErrNone, which +tells the media driver subsystem that the operation will be done asynchronously.

Note +also that on completion, DoPartitionInfo() calls PartitionInfoComplete() to +tell the media driver subsystem that the operation is complete.

TInt DMyMediaDriverFlash::PartitionInfo(TPartitionInfo& aInfo) + { + iPartitionInfo = &anInfo // Store aInfo until needed + + TInt errCode = LaunchPartitionInfoRequest(); // Start the asynchronous request + + return(errCode); // This needs to be KErrNone to indicate that the operation + // will be completed asynchronously (unless an error occurs launching + // the asynchronous request!) + } +

This is the function that runs asynchronously

TInt DMyMediaDriver::DoPartitionInfo() + { + TInt partitionCount = iPartitionInfo->iPartitionCount = 0; + + // Read of the first sector successful so check for a Master Boot Record + if (*(TUint16*)(&iIntBuf[KMBRSignatureOffset])!=0xAA55) + { + return(KErrCorrupt); + } + + // Move the partition entries to a 4 byte boundary + memcpy(&iIntBuf[0],&iIntBuf[KMBRFirstPartitionEntry],(sizeof(TMBRPartitionEntry)<<2)); + + // Search for a x86 default boot partition - let this be the first + TMBRPartitionEntry *pe=(TMBRPartitionEntry*)(&iIntBuf[0]); + + TInt i; + TInt defaultPartitionNumber=-1; + for (i=0;i<KMaxPartitionEntries;i++,pe++) + { + if (pe->IsDefaultBootPartition()) + { + SetPartitionEntry(&iPartitionInfo->iEntry[0],pe->iFirstSector,pe->iNumSectors); + iHiddenSectors=pe->iFirstSector; + defaultPartitionNumber=i; + partitionCount++; + break; + } + } + + // Now add any other partitions + pe=(TMBRPartitionEntry*)(&iIntBuf[0]); // Reset it + for (i=0;i<KMaxPartitionEntries;i++,pe++) + { + if (defaultPartitionNumber==i) + { + continue; // Already sorted + } + if (pe->IsValidDosPartition()) + { + SetPartitionEntry(&iPartitionInfo->iEntry[partitionCount],pe->iFirstSector,pe->iNumSectors); + if (partitionCount==0) + iHiddenSectors=pe->iFirstSector; + partitionCount++; + } + } + + if (defaultPartitionNumber==(-1) && partitionCount==0) + { + // Assume it has no MBR, and the Boot Sector is in the 1st sector + SetPartitionEntry(&iPartitionInfo->iEntry[0], 0, iMediaSize); + iHiddenSectors=0; + partitionCount=1; + } + + iPartitionInfo->iPartitionCount=partitionCount; + iPartitionInfo->iMediaSizeInBytes=TotalSizeInBytes(); + + PartitionInfoComplete(err); + + return(KErrNone); + } +
+
Request() - +handling requests

You handle requests by implementing your media +driver's Request() function. This is prototyped as:

TInt Request(TLocDrvRequest& aRequest)=0;

This +function is usually called in the context of the client thread that originally +initiated the I/O request to the file server, although you should never assume +so. Note that you may also see the originating thread referred to as the +remote thread.

The request type, as identified by the request +ID, and the information associated with the request is accessed through the TLocDrvRequest object, +which is passed to the Request() function. The information +supplied includes offsets, data lengths, the requesting thread etc, but clearly +depends on the request ID. You get the request ID by calling TLocDrvRequest::Id(), +and this will be one of the DLocalDrive::TRequestId enum +values.

Each request ID, as defined by DLocalDrive::TRequestId has +a specific meaning. The information that is available also depends on the +request ID.

Depending on the request ID, the operation can be done +synchronously or asynchronously. However, it is the responsibility of the +implementor of the media driver to handle the incoming requests and to handle +them as appropriate to the specific media, i.e. synchronously or asynchronously.

In +general, the function should return once the request is initiated. If the +entire operation cannot be completed immediately, then further request processing +must occur within ISRs and DFCs, i.e. using some hardware specific mechanism +to indicate completion, or by the use of considerate poll timers to considerately +poll the device for it’s current status, with the final request completion +being done from within a DFC. The code that implements the asynchronous requests +can run within its own thread, or use one of the default threads provided +by the kernel (DFC queue thread 0).

The underlying media driver framework +allows multiple requests to be processed simultaneously. However, other than +being able to issue multiple requests, there is no inherent support in the +media driver framework to support the handling of multiple requests, so such +functionality must be handled by the media driver itself. The underlying media +driver framework does, however, provide basic support for deferring requests +for later processing should the media driver not be capable of supporting +multiple requests.

+ + + +

ECaps

+

This is a request for information about the size, type, attributes +etc of the media. TLocDrvRequest::RemoteDes() gives you +access to the object into which the media driver should put the requested +information. The object passed across is a TLocalDriveCapsV2 type, +and this is passed by the media driver subsystem in the form of a package +buffer, a TPckgBuf type.

In practice, you just +need to use a simple cast to access the object. The following code fragment +is always used:

... +if (id == DLocalDrive::ECaps) + { + TLocalDriveCapsV2& c = *(TLocalDriveCapsV2*)aRequest.RemoteDes(); + ... + } +.... +

This request type is synchronous.

+
+ +

ERead

+

This is a request to read data from the media device asynchronously.

You +need to start an asynchronous operation that reads TLocDrvRequest::Length() bytes +from the media, starting at position TLocDrvRequest::Pos() on +the media.

You transfer the data to the requesting thread's process +by calling TLocDrvRequest::WriteRemote(), where the first +parameter is the source descriptor representing the data you have just read. +For example:

... +TPtrC8 des((const TUint8*)(iBase),len); +TInt r=iReadReq->WriteRemote(&des,0); +... +

In this example, iBase is the +location of the data that has just been read in from the device, and len is +the length of this data. The code fragment also assumes that the data to be +returned starts at iBase, and not at some offset from iBase.

As this +is an asynchronous operation, then when all data has been transferred, the +request must be completed by calling DMediaDriver::Complete(), +passing the original request and a completion code.

+
+ +

EWrite

+

This is a request to write data to the media device asynchronously.

You +need to start an asynchronous operation that writes TLocDrvRequest::Length() bytes +to the media, starting at position TLocDrvRequest::Pos() on +the media.

Before doing the write, then you need to transfer the data +to be written from the requesting thread's process by calling TLocDrvRequest::ReadRemote(), +where the first parameter is the target descriptor.

As this is an +asynchronous operation, then when all data has been transferred, the request +must be completed by calling DMediaDriver::Complete(), +passing the original request and a completion code.

+
+ +

EFormat

+

This is a request to format a section of the media asynchronously.

The +start position of the section to be formatted can be found by calling TLocDrvRequest::Pos(), +and the number of bytes to be formatted can be found by calling TLocDrvRequest::Length().

Following +a format operation, the state of the formatted section depends on the type +of media. In practice, you should access locations within the specified section, +so that bad regions can be detected and reported.

The length of each +format request is usually based on the value of TLocalDriveCapsV2::iEraseBlockSize, +as returned by the ECaps request. If you need to adjust the +start address of the next format request, you can return a positive value +that is interpreted as indicating the actual number of bytes formatted in +the current step. This feature is useful for media that prefers format operations +to be performed on specific boundaries; for example MultiMedia Cards.

As +this is an asynchronous operation, then when the format operation has been +done, the request must be completed by calling DMediaDriver::Complete(), +passing the original request and a completion code.

+
+ +

EEnlarge

+

This is a request to enlarge the accessible range of the media asynchronously. +For example, this is used on the internal RAM drive.

Calling TLocDrvRequest::Length() gives +you the number of bytes by which the accessible range is to be increased.

The +media attributes, as defined by the settings in TLocalDriveCapsV2::iMediaAtt returned +by the ECaps request, must have KMediaAttVariableSize set, +otherwise the request fails with KErrNotSupported.

As +this is an asynchronous operation, then when the operation is complete, the +request must be completed by calling DMediaDriver::Complete(), +passing the original request and a completion code.

+
+ +

EReduce

+

This is a request to reduce the accessible range of the media asynchronously. +For example, this is used on the internal RAM drive.

The range to +be removed is defined as TLocDrvRequest::Length() bytes +starting at TLocDrvRequest::Pos(). In effect, the request +removes the section from Pos() to Pos() + Length(), +and the length is reduced by Length().

The media +attributes, as defined by the settings in TLocalDriveCapsV2::iMediaAtt returned +by the ECaps request, must have KMediaAttVariableSize set, +otherwise the request fails with KErrNotSupported.

As +this is an asynchronous operation, then when the operation is complete, the +request must be completed by calling DMediaDriver::Complete(), +passing the original request and a completion code.

+
+ + +

A simple implementation

TInt DMyMediaDriver::Request(TLocDrvRequest& aRequest) + { + TInt err = KErrNotSupported; + TInt id = aRequest.Id(); + + if (id == DLocalDrive::ECaps) + { + TLocalDriveCapsV2& c = *(TLocalDriveCapsV2*)aRequest.RemoteDes(); + err = Caps(c); + c.iSize = m.Drive()->iPartitionLen; + c.iPartitionType = m.Drive()->iPartitionType; + return(err); + } + + if(iCurrentReq != NULL) + { + return(KMediaDriverDeferRequest); + } + + iCurrentReq = &aRequest; + + switch(id) + { + case DLocalDrive::ERead: + r = StartRead(); + break; + case DLocalDrive::EWrite: + r = StartWrite(); + break; + case DLocalDrive::EFormat: + r = StartErase(); + break; + } + + if (err < 0) + { + iCurrentReq = NULL; + DMediaDriver::Complete(aRequest, err); + } + + return(err); + } +

This demonstrates the following behaviour:

    +
  • The ECaps request +is inherently synchronous, and must complete immediately.

  • +
  • This example only handles +a single request at a time. If the media driver is busy handling a request, +it can return the value KMediaDriverDeferRequest which +defers the message until the current request is complete.

  • +
  • Each message is passed +on to the specific function that is responsible for handling the message. +This provides readability and ease of maintenance.

  • +
  • If an error occurs, +the request is completed immediately with the specified error code.

  • +

The following code is the implementation of the StartWrite() function +that initiates the asynchronous write operation. It gets the length and position +information, and then calls DoWriteStep():

TInt DMyMediaDriver::StartWrite() + { + // Start an asynchronous write operation + + iCurrentPos = iCurrentReq->Pos(); + iCurrentLength = iCurrentReq->Length(); + + TInt err = DoWriteStep(); + + return(err); + } +

DoWriteStep() performs a +single write operation. In this example, a single write operation cannot exceed +the capabilities of the hardware, so the request is split up into chunks of KMyMediaDriverWriteLength bytes.

TInt DMyMediaDriver::DoWriteStep() + { + // Perform a single write step + + TUint8* destAddress = iBaseAddress + iCurrentPos; + TInt writeLength = MIN(iCurrentLength, KMyMediaDriverWriteLength); + + TPtr8 des(iData, writeLength); + TInt err = iCurrentReq->ReadRemote(&des, iCurrentPos - iCurrentReq->Pos()); + if (err != KErrNone) + { + return(err); + } + + iCurrentPos += writeLength; + iCurrentLength -= writeLength; + + TheHardware::StartWrite(iCurrentPos, writeLength, iData); + } +

The write operation to the hardware is performed +by TheHardware::StartWrite(). For most hardware, completion +is signalled by an interrupt, and the ISR handling the interrupt will queue +a DFC. This in turn can call a function like WriteComplete() shown +below:

TInt DMyMediaDriver::WriteComplete(TInt aResult) + { + // Called upon completion of the write operation + // (ie – in DFC after completion interrupt or polled status completion) + + TBool completeRequest = (iCurrentLength == 0) || (aResult ! = KErrNone); + + if(!completeRequest) + { + // There is more data remaining, so write some more data… + if((aResult = DoWriteStep()) != KErrNone) + { + completeRequest = ETrue; + } + } + + if(completeRequest) + { + // We are all done, or an error occurred… + DMediaDriver::Complete(iCurrentReq, aResult); + iCurrentReq = NULL; + } + } +

WriteComplete() is an example +of a callback or completion function, and shows how a single request may be +broken up into a number of smaller chunks. The write request is only completed +when the entire write operation is complete or an error occurs.

This +simple example has demonstrated how a simple EWrite request +may be handled. The ERead and EFormat requests +are handled in exactly the same way, taking into account the message parameters +shown in the previous table.

Issues about physical addresses

If +the media driver can use physical addresses, you need to be aware of a number +of issues.

    +
  • The address scheme +used by the hardware

    All media devices have a minimum number +of bytes that they can transfer. For example, the architecture of some memory +card types requires data transfer in blocks of 512 bytes. To read one byte +from this type of media device, the media driver must read a block of 512 +bytes and extract the byte from the block. To write one byte to a media device, +the media driver must read a block of 512 bytes, change the content of the +byte, and write the block to the media device.

  • +
  • Data transfer smaller +than the minimum size

    If the local media subsystem receives a +request to transfer data with a length smaller than the minimum transfer size, +the local media subsystem does not make a physical address available to the +media driver. A call to TLocDrvRequest::IsPhysicalAddress() returns +false. It is considered unsafe to give access to the physical data surrounding +the requested memory location.

  • +
  • Data transfer not +aligned to the media device block boundary

    If the local media +subsystem receives a request to transfer data, and the address on the media +device is not aligned to the media device block boundary, you need +to adopt the technique suggested below. The local media subsystem will make +the physical address available to the media driver. A call to TLocDrvRequest::IsPhysicalAddress() returns +true.

    Consider the following case. A request has been made to read +1024 bytes from a media device that has a block size of 512 bytes. The 1024 +bytes start at offset +256 on the media device.

    + +

    To get the first 256 bytes, you must read the first block of 512 +bytes from the media device. This can corrupt the physical memory passed in +the I/O request. The solution is to read the first block from the media device +into an intermediate buffer. Copy the 256 bytes from that buffer into the +physical memory passed in the I/O request.

    To get the last 256 bytes, +you must read the third block of 512 bytes from the media device into the +intermediate buffer. Copy the 256 bytes from that buffer into the correct +position in the physical memory passed in the I/O request.

    The middle +512 bytes are aligned on the media device block boundary. The media driver +can read this data into the correct position in the physical memory passed +in the I/O request.

  • +
  • Scatter/Gather DMA +controllers

    DMA controllers can support the Scatter/Gather mode +of operation. Each request in this mode of operation consists of a set of +smaller requests chained together. This chain of requests is called the Scatter/Gather +list. Each item in the list consists of a physical address and a length.

    Use TLocDrvRequest::GetNextPhysicalAddress() to +help you populate the Scatter/Gather list.

    The following code fragment +shows how you do this. The example assumes that the DMA controller supports +a Scatter/Gather list with an unlimited number of entries. In practice, the +number of entries in the list is finite.

    TPhysAddr physAddr; + TInt physLength; + TInt err = KErrNone; + + while (iRemaining > 0) + { + err = iCurrentReq->GetNextPhysicalAddress(physAddr, physLength); + if(err != KErrNone) + return err; + + iRemaining -= physLength; + PopulateScatterGatherList(physAddr, physLength); + } + + return DoDataTransfer(pos, length);
  • +

See also Register +media driver support for physical addresses

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-EBF4F1F1-F76B-455B-B8EE-B7965CF0717E.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-EBF4F1F1-F76B-455B-B8EE-B7965CF0717E.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,49 @@ + + + + + +The LDD/PDD +ModelThis document describes how device drivers are implemented as logical +device drivers (LDDs) and physical device drivers (PDDs). +

Device +driver DLLs come in two types - the logical device driver (LDD), and the physical +device driver (PDD). Typically, a single LDD supports functionality common +to a class of hardware devices, whereas a PDD supports a specific member of +that class. This means that the generic code in the LDD only needs to be written +once, and the same user-side API can be used for all variants of a device.

Many +PDDs may be associated with a single LDD. For example, there is a single serial +communications LDD (ECOMM.LDD) which is used with all +UARTs. This LDD provides buffering and flow control functions that are required +with all types of UART. On a particular hardware platform, this LDD will be +accompanied by one or more PDDs, which support the different types of UART +present. A single PDD can support more than one UART of the same type; separate +PDDs are only required for UARTs with different programming interfaces. Typically, +the PDD is kept as small as possible.

Only LDDs communicate with user-side +code; PDDs communicate only with the corresponding LDD, with the variant or +kernel extensions, and with the hardware itself. Device drivers provide their +interface for user side applications by implementing a class derived from +the Kernel API RBusLogicalChannel. The functions of the +derived class form a thin layer over the functions defined in RBusLogicalChannel and +are commonly implemented inline and published in a header file. However, if +the API functions need to do more complex tasks, then they can be implemented +in their own DLL. The kernel also provides a API RDevice, +which enables user side code to get information about a device.

The +following diagram shows the general idea:

+ Device driver LDD/PDD model + +

To make porting to particular hardware platforms easier, some drivers +make a further logical split in their PDD code between a platform-independent +layer (PIL), which contains code that is common to all the hardware platforms +that the driver could be deployed on, and a platform-specific layer (PSL), +which contains code such as the reading and writing of hardware-specific registers.

Depending +on the device or the type of device to access, this split between LDD and +PDD may not be necessary; the device driver may simply consist of an LDD alone.

+
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-EBFD653D-6E6A-5F6F-88D7-8CCE07B4002D.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-EBFD653D-6E6A-5F6F-88D7-8CCE07B4002D.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,606 @@ + + + + + +Publish +and SubscribePublish and Subscribe allows global variables to be set and retrieved, +and allows subscribers to be notified that variables have changed. +

The general pattern for using on the kernel side is almost the same as +for the user side. However, different classes are used on the kernel side. +It may be useful to compare kernel side usage with user side usage as described +in the Publish and +Subscribe guide for the user-side API.

+
    +
  • Properties

  • +
  • Creating and closing a reference to a property

  • +
  • Defining a property

  • +
  • Deleting a property

  • +
  • Publishing a property value

  • +
  • Retrieving a property value

  • +
  • Subscribing to, and unsubscribing from, a property

  • +
  • Usage patterns

  • +
+
Properties

A +property has the two attributes: identity and type.

Identity

A +property is identified by a 64-bit integer made up of two 32-bit parts: the +category and the key.

A property belongs to a category, and a category +is identified by a UID.

A key is a 32-bit value that identifies a +specific property within a category. The meaning applied to the key depends +on the kind of enumeration scheme set up for the category. At its simplest, +a key can be an index value. It can also be another UID, if the category is +designed to be generally extensible.

Type

A property +can be:

    +
  • a single 32-bit value

  • +
  • a contiguous set of +bytes, referred to as a byte-array, whose length can vary from 0 to 512 bytes

  • +

Once defined, a property value can change, but the property type cannot. +Byte-array type properties can also change length provided the length does +not exceed the value RProperty::KMaxPropertySize. The limit +on size of property ensures some limit on RAM usage.

The API allows +a byte-array text type property to be pre-allocated when it is defined. This +means that the time taken to set the values is bounded. However, if the length +of this property type subsequently increases, then memory allocation may take +place, and no guarantees can be made on the time taken to set them.

Note +that the RProperty::ELargeByteArray property type can never +provide a real-time guarantee.

For code running kernel side, properties +and their values are defined, set and retrieved using a RPropertyRef object.

+
Creating and +closing a reference to a property

On the kernel side, all accesses +to a property must be done through a property reference, an instance +of a RPropertyRef.

You must create a reference +to a property, before doing any operation on that property. By operation, +we mean defining a property, subscribing to a property, publishing and retrieving +a property value. The kernel will fault if you have not first created a reference.

Only +one property, as uniquely identified by its category and key, can be accessed +by an instance of RPropertyRef; however a property can +be referenced by more than one instance of RPropertyRef.

Internally, +properties are represented by TProperty objects, and these +are reference counted. The act of creating a reference to a property results +either in the creation of a TProperty object or an increase +in the reference count of an existing object. The property itself has no attributes +or "structure" until it is defined.

Please note that the structure +and management of TProperty objects are part of Symbian platform's +internal implementation and will not be discussed further.

+Objects internal to Symbian platform + +

To establish a reference to a property, create an RPropertyRef object, +and then use one of the following functions:

    +
  • RPropertyRef::Attach() - +tries to open the property identified by the category and key, if it exists, +but creates that property if it does not exist. Creation is simply the act +of creating the internal TProperty object. The object has +no type or "structure" associated with it other than the use of the category +and key as identification markers.

  • +
  • RPropertyRef::Open() - +tries to open the property identified by the category and key, and assumes +that the property already exists; this fails if the property does not exist.

  • +

You can call these functions from a user thread running in supervisor +mode, from a kernel thread or from a DFC. If calling from a user thread running +in supervisor mode, then your thread must be running in a critical section. +In debug mode, if a user thread is not in a critical section, then the kernel +will fault.

On successful return from these functions, the RPropertyRef object +owns a resource, the property, and this can then be defined and accessed through +the RPropertyRef object.

It is difficult to make +firm rules as to which one your code should use, but generally, you use Open() if +you have no responsibility or interest in ensuring that the property exists. +You would use Attach() if you were to have single or joint responsibility +for ensuring that the property exists. It depends on the intent of the property +and the role of your driver code in the system.

Note that responsibility +for creating the property does not necessarily align with who can define, +delete, publish (write) or retrieve (read) a property value. This is governed +by the intent of the property and, for retrieving and publishing, by the security +policies in place.

When the property is no longer needed, you can +release it by calling RPropertyRef::Close(). Closing the +reference does not cause the property to disappear. This only happens when +the final reference to the property is closed.

Note that it +is quite legitimate to attach to, or to open, a property that has not been +defined, and in this case no error will be returned either. This enables the +lazy definition of properties as used in some of the usage patterns.

const TUid KMyPropertyCat={0x10012345}; +enum TMyPropertyKeys={EMyPropertyCounter,EMyPropertyName}; + +. . . + +// Attach to the ‘counter’ property. This creates the property +// if it does not already exist. +RPropertyRef counter; +TInt r; +r=counter.Attach(KMyPropertyCat,EMyPropertyCounter); + +// r should be KErrNone if sucessful or KErrNoMemory if there +// is an out of memory failure. +if (r != KErrNone) + { + // Handle the bad return value + } + +// use the counter object... + +// when finished, release the property +counter.Close(); +
+
Defining a +property

Defining a property gives it "structure" i.e. attributes +such as the property type, and the security policies that define the capabilities +that a process must have to publish and retrieve the property value.

A +property is defined using the RPropertyRef::Define() function. +You can call this function from a user thread running in supervisor mode, +from a kernel thread or from a DFC. If calling from a user thread running +in supervisor mode, then your thread must be running in a critical section. +In debug mode, if a user thread is not in a critical section, then the kernel +will fault.

You can call this function from a user thread running +in supervisor mode, from a kernel thread or from a DFC. If calling from a +user thread running in supervisor mode, then your thread must be running in +a critical section. In debug mode, if a user thread is not in a critical section, +then the kernel will fault.

The information needed to define the property +is passed to Define(). Note that a reference to the property +must already have been established using RPropertyRef::Attach() or RPropertyRef::Open().

A +property does not need to be defined before it can be accessed. This supports +programming patterns where both publishers and subscribers may define the +property.

Once defined, a property persists until the system reboots, +or the property is explicitly deleted. Its lifetime is not tied to that of +the thread or process that originally defined it. This means that, when defining +a property, it is important to check the return code from the call to RPropertyRef::Define() to +deal with the possibility that the property has previously been defined.

The +following code shows the definition of two properties, which we call: 'name' +and 'counter':

const TUid KMyPropertyCat={0x10012345}; +enum TMyPropertyKeys={EMyPropertyCounter,EMyPropertyName}; + +static _LIT_SECURITY_POLICY_PASS(KAllowAllPolicy); +static _LIT_SECURITY_POLICY_C1(KPowerMgmtPolicy,ECapabilityPowerMgmt); + +TInt r; + +// Attaches to the ‘counter’ property. +// If the property already exists, a new reference to it is created. +// If the property does not exist, it is created. +RPropertyRef counter; +r=counter.Attach(KMyPropertyCat,EMyPropertyCounter); +if (r != KErrNone) + { + // Handle the bad return value + } + +// Attaches to the ‘name’ property. +// If the property already exists, a new reference to it is created. +// If the property does not exist, it is created. +RPropertyRef name; +r=name.Attach(KMyPropertyCat,EMyPropertyName); +if (r != KErrNone) + { + // Handle the bad return value + } + +// Now define the 'counter' property: +// 1. Integer type +// 2. Pre-allocated size has no meaning, and must be zero. +// 3. Allow all processes to retrieve (read) the property. +// 4. Only processes with power managament capability can write. +// 5. Capability checks to be done against client thread's process. + +r=counter.Define(RProperty::EInt,KAllowAllPolicy,KPowerMgmtPolicy,0,iClientProcess); + +// You will probably need to check the return value. +// It may legitimately by non-KErrNone. + +... + +// Now define the 'name' property: +// 1. Byte array +// 2. Pre-allocate 100 bytes. +// 3. Allow all processes to retrieve (read) the property. +// 4. Only processes with power managament capability can write. +// 5. Capability checks to be done against client thread's process. + +r=name.Define(RProperty::EByteArray,KAllowAllPolicy,KPowerMgmtPolicy,100,iClientProcess); + +// You will probably need to check the return value. +// It may legitimately be non-KErrNone. +...

Once defined, a property value can change, but the property +type cannot. Byte-array type properties can also change length provided the +length does not exceed the 512 bytes, for RProperty::EByteArray types +or 65535 bytes or RProperty::ELargeByteArray types.

The +API allows byte-array type properties to be pre-allocated when they are defined. +This means that the time taken to set the values is bounded. However, if the +length of these property types subsequently increases, then memory allocation +may take place, and no guarantees can then be made on the time taken to set +them.

Security notes:

    +
  • Symbian platform defines +a property category known as the system category that is reserved for system +services, and is identified by the KUidSystemCategoryValue UID. +To define a property within this category, then the process on whose behalf +your code is doing the define operation must have the writeDeviceData capability, ECapabilityWriteDeviceData.

    To +ensure that this security check is made, you must pass a pointer to the appropriate DProcess object +as the second parameter to Define(). If you omit this parameter, +a null pointer is assumed by default, and the security check is bypassed. +This may be legitimate if you are doing this on behalf of the kernel or on +behalf of the driver itself.

  • +
  • Whether you pass a DProcess pointer +or not, the owner of the property is deemed to be the process that is current when +the code runs. It is this, the current process, that you will need to pass +to RPropertyRef::Delete() at a later time.

  • +
  • You also need to define +two security policies: one to define the capabilities that will be required +to publish (write to) the property, and the other to define the capabilities +that will be required to retrieve (read) the property. Security policies are TSecurityPolicy objects +or their static equivalents.

    In the above code fragment, we specify +that all processes in the system will be able to read the defined property +but only those with power management capability will be able to write to the +property - this is an arbitrary choice and is for illustration only.

  • +

In the above code fragments, iClientProcess is a +pointer to the client thread's owning process object, and assumes that the +driver code is making the request on behalf of a client, although this may +not necessarily be so. Typically, if you need to keep this information, you +could set this up in the logical channel constructor using the following code:

iClientProcess=&Kern::CurrentProcess();

The +constructor code runs in the context of the client user thread. Note that DProcess is +internal to Symbian.

+
Deleting a +property

Deleting a property is the opposite of defining it. It +removes type and security information. It does not remove a reference +to the property.

A property is deleted using the RPropertyRef::Delete() function. +You can call this function from a user thread running in supervisor mode, +from a kernel thread or from a DFC. If calling from a user thread running +in supervisor mode, then your thread must be running in a critical section. +In debug mode, if a user thread is not in a critical section, then the kernel +will fault.

Any outstanding subscriptions for this property complete +with KErrNotFound.

Security notes:

    +
  • Only the owning process +is allowed to delete the property. This is deemed to be the process that was +current when the property was defined. However, to enforce this, you must pass +into RPropertyref::Delete() a pointer to the DProcess object +that represents the owning process. If you omit to pass this parameter to Delete(), +a null pointer is assumed by default, and the security check is bypassed.. +This may be legitimate if you are doing this on behalf of the kernel or on +behalf of the driver itself.

  • +

For example, extending the code fragment introduced in defining a +property above:

const TUid KMyPropertyCat={0x10012345}; +enum TMyPropertyKeys={EMyPropertyCounter,EMyPropertyName}; + +static _LIT_SECURITY_POLICY_PASS(KAllowAllPolicy); +static _LIT_SECURITY_POLICY_C1(KPowerMgmtPolicy,ECapabilityPowerMgmt); + +TInt r; + +// Attaches to the ‘counter’ property. +// If the property already exists, a new reference to it is created. +// If the property does not exist, it is created. +RPropertyRef counter; +r=counter.Attach(KMyPropertyCat,EMyPropertyCounter); +if (r != KErrNone) + { + // Handle the bad return value + } + +// Attaches to the ‘name’ property. +// If the property already exists, a new reference to it is created. +// If the property does not exist, it is created. +RPropertyRef name; +r=name.Attach(KMyPropertyCat,EMyPropertyName); +if (r != KErrNone) + { + // Handle the bad return value + } + +// Now define the 'counter' property: +// 1. Integer type +// 2. Pre-allocated size has no meaning, and must be zero. +// 3. Allow all processes to retrieve (read) the property. +// 4. Only processes with power managament capability can write. +// 5. Capability checks to be done against client thread's process. + +r=counter.Define(RProperty::EInt,KAllowAllPolicy,KPowerMgmtPolicy,0,iClientProcess); + +// You will probably need to check the return value. +// It may legitimately by non-KErrNone. + +... + +// Now define the 'name' property: +// 1. Byte array +// 2. Pre-allocate 100 bytes. +// 3. Allow all processes to retrieve (read) the property. +// 4. Only processes with power managament capability can write. +// 5. Capability checks to be done against client thread's process. + +r=name.Define(RProperty::EByteArray,KAllowAllPolicy,KPowerMgmtPolicy,100,iClientProcess); + +// You will probably need to check the return value. +// It may legitimately by non-KErrNone. + +... + +// Delete the ‘name’ property. +// Assumes that the owning process is iClientProcess. This will be checked +// as being the valid owner of the property. +r=name.Delete(iClientProcess); +if (r != KErrNone) + { + // deal with a non-KErrNone return value. + } + +// Delete the ‘counter’ property. +// Assumes that the owning process is iClientProcess. This will be checked +// as being the valid owner of the property. +r=name.Delete(iClientProcess); +if (r != KErrNone) + { + // deal with a non-KErrNone return value. + }
+
Publishing +a property value

A property is published (written), using the RPropertyRef::Set() family +of functions.

This is guaranteed to have bounded execution time, suitable +for high-priority, real-time tasks, except when publishing a byte-array property +that requires the allocation of a larger space for the new value, or when +publishing a large byte-array property type, as identified by ELargeByteArray.

Property +values are written atomically. This means that it is not possible for threads +reading a property to get a garbled value.

All outstanding subscriptions +for a property are completed when the value is published, even if it is exactly +the same as the existing value. This means that a property can be used as +a simple broadcast notification service.

Publishing a property that +is not defined is not necessarily a programming error. The Set() functions +just return an error. If this is not expected for any particular usage, then +the error must be checked and processed by the caller.

Security +notes:

    +
  • If you pass a pointer +to a DProcess object, then the capabilities of that process +will be checked against those contained in the write security policy that +was created and passed to RPropertyRef::Define(). If you +omit this DProcess parameter, a null pointer is assumed by +default, and the security check is bypassed. This may be legitimate +if you are doing this on behalf of the kernel or on behalf of the driver itself.

  • +

See the code fragment in the section Retrieving +a property value

+
Retrieving +a property value

The current value of a property is retrieved +(read) using the RPropertyRef::Get() family of functions.

This +is guaranteed to have bounded execution time, suitable for high-priority, +real-time tasks, except when retrieving a large byte-array property type, +as identified by ELargeByteArray.

Property values +are read atomically. This means that it is not possible for threads reading +a property to get a garbled value.

Retrieving a property that is not +defined is not necessarily a programming error. The Get() functions +just return an error. If this is not expected for any particular usage, then +the error must be checked and processed by the caller.

Integer properties +must be accessed using the overload that takes an integer reference, whereas +a byte-array property is accessed using the overload that takes a descriptor +reference.

The following code fragment shows publication and retrieval +of a property. Note that it contains a race condition, especially if another +thread is executing the same sequence to increment the ‘counter’ value.

Security +notes:

    +
  • If you pass a pointer +to a DProcess object, then the capabilities of that process +will be checked against those contained in the read security policy that was +created and passed to RPropertyRef::Define(). If you omit +this DProcess parameter, a null pointer is assumed by default, +and the security check is bypassed. This may be legitimate if you are +doing this on behalf of the kernel or on behalf of the driver itself.

  • +
const TUid KMyPropertyCat={0x10012345}; +enum TMyPropertyKeys={EMyPropertyCounter,EMyPropertyName}; + +TInt r; + +RPropertyRef counter; +RPropertyRef name; + + +// Assume that the 'name' and 'counter' property references have +// already been created. They may have been defined. +// +// Assume that the process to be used for security checking is iClientProcess. + +... + +// publish a new name value. +_LIT8(KSomeExampleName,"My example name"); +r=name.Set(KSomeExampleName, iClientProcess); +if (r != KErrNone) + { + // Check the return value. KErrNotFound means that the property has not yet been + // defined which may be legitimate. + // KErrArgument is a serious problem at this stage. + // KErrPermissionDenied is a security violation; the process iClientProcess has + // insufficient capability to do this operation. + } + + +// Retrieve the first 10 characters of the name value. +// We are not doing any security checking for this operation, so no DProcess pointer +// is passed to Get(). +TBuf<10> n; +r=name.Get(n); + +if ((r!= KErrNone) && (r != KErrOverflow)) + { + // Handle error value. + } + +// retrieve and publish a new value using the attached ‘counter’ property +TInt count; +r=counter.Get(count); +if (r==KErrNone) + { + r=counter.Set(++count); + } +else + { + // Handle bad return value + } +... + +// When finised, release the property references. +counter.Close(); +name.Close();
+
Subscribing +to, and unsubscribing from, a property

Subscribing to a property +is the act of making an asynchronous request to be notified of a change to +that property.

You make a request for notification of a change to +a property by calling the RPropertyRef::Subscribe() member +function on a property reference object. Only one subscription request can +be outstanding at any time for a given RPropertyRef instance.

You +can cancel an outstanding subscription request by calling RPropertyRef::Cancel(). +This is unsubscribing from the property.

Subscribing to a property +is a single request to be notified when the property is next updated, it does +not generate an ongoing sequence of notifications for every change to that +property's value. Neither does it provide the caller with the new value. In +essence, the act of notification should be interpreted as “Property X has +changed” rather than “Property X has changed to Y”. This means that the new +value must be explicitly retrieved, if required. As a result, multiple updates +may be collapsed into one notification, and subscribers may not have visibility +of all intermediate values.

This might appear to introduce a window +of opportunity for a subscriber to be out of synchronisation with the property +value – in particular, if the property is updated again before the subscriber +thread has had the chance to process the original notification. However, a +simple programming pattern, outlined in the second example below ensures this +does not happen. The principle is that, before dealing with a subscription +completion event, you should re-issue the subscription request.

Note +that if the property has not been defined, then a subscription request does +not complete until the property is subsequently defined and published. Note +that the request will complete with KErrPermissionDenied if +the subscribing process does not have sufficient capability as defined by +the TSecurityPolicy object supplied by the process defining +the property.

If the property is already defined, then the request +completes immediately with KErrPermissionDenied if the +subscribing process does not have sufficient capability.

The essence +of subscribing to a property is that you pass a function into RPropertyRef::Subscribe() and +that this function is called when the property value is published. You pass +the function by wrapping it in TPropertySubsRequest object +and then pass this into Subscribe(). What the function does +depends on the implementation, but you may want to re-subscribe to the property +and then retrieve the property value, or you may want to set some flag. It +all depends on the intent of the property and the driver code.

The +following code fragments show the general idea.

const TUid KMyPropertyCat={0x10012345}; +enum TMyPropertyKeys={EMyPropertyCounter,EMyPropertyName}; class DMyLogicalChannel : public DLogicalChannel + { + public : + DMyLogicalChannel(); + void OpenReference(); + void SetUpSubscription(); + ... + private : + static void HandleSubsComplete(TAny* aPtr, TInt aReason); + ... + private: + RCounterRef iName; + TBuf<10> iNameValue; + DProcess iClientProcess; + TPropertySubsRequest iSubsRequest; + TInt iReason; + } DMyLogicalChannel::DMyLogicalChannel() : iSubsRequest(&HandleSubsComplete, this) + { + iClientProcess = &Kern::CurrentProcess(); + // Other code omitted + } void DMyLogicalChannel::OpenReference() + { + // Open a reference to the ‘name’ property, and assume that + // the property has already been created and defined. + + TInt r + ... + r=iName.Open(KMyPropertyCat,EMyPropertyName); + if (r != KErrNone) + { + // Handle bad return value. + } + ... + } void DMyLogicalChannel::SetUpSubscription() + { + // Now ask to be notified when the 'name' property is updated. + // This will eventually result in a call to the function HandleSubsComplete() + // at some later time (asynchronously). + // When eventually called, the pointer to this DMyLogicalChannel object will + // be passed to HandleSubsComplete(). + // + ... + iReason = KRequestPending; + TInt r = iName.Subscribe(iSubsRequest); // ignoring security issues here. + if (r != KErrNone) + { + // handle bad return code. + } + return; + } void DMyLogicalChannel::CancelSubscription() + { + if (iReason == KRequestPending) + { + iName.Cancel(iSubsRequest); + } + } void DMyLogicaChannel::SubsCompleteFn(TAny* aPtr, TInt aReason) + { + // A static function called when a change to the property occurs. + // aPtr will point to the DMyLogicalChannel object + // (see the DMyLogicalChannel constructor) + // aReason is the reason for the subscription completing. This may be: + // KErrNone - for a normal completion. + // KErrPermissionDenied - if the security check has failed. + // KErrCancel - if the request was cancelled. + // For a normal completion, setup another notification request before + // getting the current value of the property. + // + DMyLogicaChannel* self = (DMyLogicaChannel*) aPtr; + self->iReason = aReason; + if (iReason == KErrNone) + { + self->SetUpSubscription(); + self->Get(iNameValue,iClientProcess); + return; + } + // Investigate the non-zero reason code. + }
+
Usage patterns

There +are three usage patterns that can easily be identified, labelled as: standard +state, pure event distribution, and speculative publishing.

Standard state

This +pattern is used for events and state that are known to be used widely in the +system. Examples of this might be battery level and signal strength, which +are important in every phone.

The publisher calls RPropertyRef::Define() to +create the appropriate property. For byte array or text properties, a size +sufficient for all possible values should be reserved. An error of KErrAlreadyExists should +be ignored. The publisher then publishes the property values as, and when, +appropriate. If the RPropertyRef::Set() call fails, this +should be treated as a serious error, since it indicates that important system +state is not getting through. Appropriate action might include panicking or +rebooting the system. Subscribers will use RPropertyRef::Subscribe() to +request notification, and RPropertyRef::Get() to retrieve +the property value on notification.

The memory to store the property +value will be permanently allocated, even if it turns out that no-one in the +system needs that value. This does ensure that the value can always be published, +even if the system is in an out of memory situation. For this reason, this +approach should be limited to widely used and important state. The Speculative publishing pattern offers an approach for dealing with +less important state.

Pure event distribution

This +pattern is used when events need to be distributed, not values.

The +publisher of the event simply uses an integer property, and calls RPropertyRef::Set() with +any value. Even if the value of the property is not changed by this operation, +all subscribers will be notified that a Set() has occurred, +and by implication that the related event has occurred.

Subscribers +will be able to detect that an event has occurred, but will get no other information. +The minimum possible memory is wasted on storage for the dummy value.

Speculative publishing

This +pattern is used when it is not known whether a value will be of interest to +others or not. Unlike the standard +state pattern, the publisher of the event does not call RPropertyRef::Define() to +create the property. Instead, it simply calls RPropertyRef::Set() as +appropriate, and ignores any KErrNotFound error.

When +other code in the system, i.e. a potential subscriber, is interested in the +state, it calls RPropertyRef::Define() to create the property +and allocate the memory for the value. An error of KErrAlreadyExists should +be ignored, as this only indicates that some other code in the system is also +interested in the value and has already created the property.

The +subscriber then calls RPropertyRef::Subscribe() and RPropertyRef::Get() as +usual to interact with the property. On the first Get(), +the subscriber may retrieve the property default value (zero, or a zero length +descriptor). This must be substituted with a sensible default value for the +property in question.

Using this pattern, no memory is wasted on properties +that have no subscribers, while the publisher code is simpler as there is +no need for configuration as to which properties to publish.

The publisher, +however, wastes some time attempting to publish unneeded values, but this +should not be an issue unless the value is very frequently updated.

Where +events are published very infrequently, the subscriber could have a dummy +value for a long time, until the next publish event updates the value. Often +this is not a problem as a default value can be substituted. For example a +full/empty indicator for a battery level, none for signal strength etc. This +pattern is unlikely to be useful if there is no suitable default value.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-EC2D5CA5-538C-5375-B00D-3107CD87CFFC-GENID-1-2-1-8-1-1-5-1-1-20-1.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-EC2D5CA5-538C-5375-B00D-3107CD87CFFC-GENID-1-2-1-8-1-1-5-1-1-20-1.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,172 @@ + + + + + +Remapping +Cache Attributes and Access Permissions on ARMv6K and ARMv7 PlatformsDescribes the behavior change brought about by remapping the cache +attributes and the access permissions on the ARMv6K (ARM1176 & ARM11MPCore), +ARMv7 (Cortex-8N), and future platforms. +
    +
  • Reduced set access permissions

      +
    • Affected kernel interface

    • +
  • +
  • Remapping cache attributes

      +
    • Types of memory supported

    • +
    • Mapping existing memory types

    • +
    • Mapping ARMv6K or ARMv7 onto TMappingAttributes.

    • +
  • +
+
Reduced set +access permissions

The ARMv6-style page table reserves three bits +in the page/directory table for access permission, so eight possible values +are available. The use of four possible access permissions is sufficient. +Therefore, removing the surplus access permissions frees up one page table +bit that is used by Symbian platform internally.

Affected kernel interface

The +shadow pages kernel interface is valid on all platforms except for the emulator. +On ARMv6 and previous platforms, shadow pages are created using access permission PrivilegedRW/UserRO, +this is not supported by the limited set of encoding. Shadow pages are now +mapped as PrivilegedRO/UserRO, instead.

class Epoc + { +public: + ... + IMPORT_C static TInt AllocShadowPage(TLinAddr aRomAddr); + IMPORT_C static TInt FreeShadowPage(TLinAddr aRomAddr); + IMPORT_C static TInt FreezeShadowPage(TLinAddr aRomAddr); + ... + };

This represents a serious behaviour break in the kernel +interface. A device driver (running on ARMv7) that creates a shadow page and +then attempts to alter the content of the page now panics.

This is +a common use case for run-mode debuggers. However, a debugging interface is +already provided, see DebugSupport in ...\memmodel\epoc\platform.h, +where breakpoints are managed internally by the kernel. Therefore, it is believed +that a run-time debugger that uses the CodeModifier implementation +in the kernel should not be affected by this change.

After a shadow +page is created using Epoc::AllocShadowPage(), the kernel +allows the device driver to alter its content using Epoc::CopyToShadowMemory().

Epoc::FreezeShadowPage() is obsolete for platforms that use the reduced set of access permissions, +as the shadow memory is always in a “frozen” state, because it can only be +changed through the kernel interface.

+
Remapping cache +attributes

ARMv6 architecture uses a large number of bits in the +page table to describe all of the options for inner and outer cachability. +No applications use all of these options simultaneously so a smaller number +of configurable options has been implemented to meet the needs of the system.

This +alternative cache mapping allows up to eight different mappings in page tables. +The Symbian platform kernel and device drivers do not need more +than four or five different cache mappings.

Cache mapping cannot be +altered during run-time. It must be configured before the MMU is initialised.

See +the Bootstrap Port +Implementation Tutorial.

Types of memory supported

The +kernel supports the following types of memory:

+ + + +

Memory type

+

Description

+
+ +

EMemAttStronglyOrdered

+

Writes are not combined. The order of memory accesses is preserved. +Serves as a memory barrier, which means:

    +
  • previous accesses to +any type of memory must complete before accesses to strongly ordered memory +start

  • +
  • accesses to strongly +ordered memory must complete before any further access to any type of memory +takes place.

  • +

This type is used for hardware mapping.

+
+ +

EMemAttDevice

+

Writes are not combined. The order of memory accesses is preserved. +This type is used for hardware mapping.

+
+ +

EMemAttNormalUncached

+

Non cacheable memory: The order of accesses is not preserved. Writes +may be combined. For example, this is used for video memory.

+
+ +

EMemAttNormalCached

+

Write-back read/write allocate cached memory, inner and outer. Used +for “ordinary” memory.

+
+ + +

Device memory and normal memory can be set as shared or +non-shared, strongly ordered accesses are assumed to be shared.

The +complete set of memory types supported by Symbian platform are represented +by the values of the TMemoryType enum.

Mapping existing memory +types

The TMappingAttributes constants allow +the cache attributes to be manipulated. On remapped platforms, these map into TMemoryType as +follows:

+ + + +

Memory type described by TMappingAttributes

+

Memory type

+
+ +

EMapAttrFullyBlocking

+

EMemAttStronglyOrdered

+
+ +

EMapAttrBufferedNC

EMapAttrBufferedC

+

EMemAttDevice

+
+ +

EMapAttrL1Uncached

EMapAttrCachedWTRA

EMapAttrCachedWTWA

+

EMemAttNormalUncached

+
+ +

EMapAttrCachedWBRA

EMapAttrCachedWBWA

EMapAttrL1CachedMax

EmapAttrCachedMax

+

EMemAttNormalCached

+
+ +

EMapAttrAltCacheWTRA

EMapAttrAltCacheWTWA

EMapAttrAltCacheWBRA

EMapAttrAltCacheWBWA

+

Return error

+
+ +

EMapAttrL2CachedWTRA

EMapAttrL2CachedWTWA

EMapAttrL2CachedWBRA

EMapAttrL2CachedWBWA

EMapAttrL2CachedMax

+

Takes no effect. Only the inner cache description matters.

This +policy is already in place on ARMv5 platforms with L210, where the page table +does not support a separate description of the inner and outer cache attributes.

+
+ + +

Mapping ARMv6K or ARMv7 +onto TMappingAttributes

To describe memory on ARMv6K or ARMv7 +using the original TMappingAttributes bit mask, the device +driver should use the following values:

+ + + +

ARMv6K/v7 memory type TMemoryType

+

TMappingAttributes mask to use

+
+ +

EMemAttStronglyOrdered

+

EMapAttrFullyBlocking

+
+ +

EMemAttDevice

+

EMapAttrBufferedNC

+
+ +

EMemAttNormalUncached

+

EMapAttrL1Uncached

+
+ +

EMemAttNormalCached

+

EmapAttrCachedMax

+
+ + +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-EC2D5CA5-538C-5375-B00D-3107CD87CFFC-GENID-1-2-1-9-1-8-1-16-1.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-EC2D5CA5-538C-5375-B00D-3107CD87CFFC-GENID-1-2-1-9-1-8-1-16-1.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,172 @@ + + + + + +Remapping +Cache Attributes and Access Permissions on ARMv6K and ARMv7 PlatformsDescribes the behavior change brought about by remapping the cache +attributes and the access permissions on the ARMv6K (ARM1176 & ARM11MPCore), +ARMv7 (Cortex-8N), and future platforms. +
    +
  • Reduced set access permissions

      +
    • Affected kernel interface

    • +
  • +
  • Remapping cache attributes

      +
    • Types of memory supported

    • +
    • Mapping existing memory types

    • +
    • Mapping ARMv6K or ARMv7 onto TMappingAttributes.

    • +
  • +
+
Reduced set +access permissions

The ARMv6-style page table reserves three bits +in the page/directory table for access permission, so eight possible values +are available. The use of four possible access permissions is sufficient. +Therefore, removing the surplus access permissions frees up one page table +bit that is used by Symbian platform internally.

Affected kernel interface

The +shadow pages kernel interface is valid on all platforms except for the emulator. +On ARMv6 and previous platforms, shadow pages are created using access permission PrivilegedRW/UserRO, +this is not supported by the limited set of encoding. Shadow pages are now +mapped as PrivilegedRO/UserRO, instead.

class Epoc + { +public: + ... + IMPORT_C static TInt AllocShadowPage(TLinAddr aRomAddr); + IMPORT_C static TInt FreeShadowPage(TLinAddr aRomAddr); + IMPORT_C static TInt FreezeShadowPage(TLinAddr aRomAddr); + ... + };

This represents a serious behaviour break in the kernel +interface. A device driver (running on ARMv7) that creates a shadow page and +then attempts to alter the content of the page now panics.

This is +a common use case for run-mode debuggers. However, a debugging interface is +already provided, see DebugSupport in ...\memmodel\epoc\platform.h, +where breakpoints are managed internally by the kernel. Therefore, it is believed +that a run-time debugger that uses the CodeModifier implementation +in the kernel should not be affected by this change.

After a shadow +page is created using Epoc::AllocShadowPage(), the kernel +allows the device driver to alter its content using Epoc::CopyToShadowMemory().

Epoc::FreezeShadowPage() is obsolete for platforms that use the reduced set of access permissions, +as the shadow memory is always in a “frozen” state, because it can only be +changed through the kernel interface.

+
Remapping cache +attributes

ARMv6 architecture uses a large number of bits in the +page table to describe all of the options for inner and outer cachability. +No applications use all of these options simultaneously so a smaller number +of configurable options has been implemented to meet the needs of the system.

This +alternative cache mapping allows up to eight different mappings in page tables. +The Symbian platform kernel and device drivers do not need more +than four or five different cache mappings.

Cache mapping cannot be +altered during run-time. It must be configured before the MMU is initialised.

See +the Bootstrap Port +Implementation Tutorial.

Types of memory supported

The +kernel supports the following types of memory:

+ + + +

Memory type

+

Description

+
+ +

EMemAttStronglyOrdered

+

Writes are not combined. The order of memory accesses is preserved. +Serves as a memory barrier, which means:

    +
  • previous accesses to +any type of memory must complete before accesses to strongly ordered memory +start

  • +
  • accesses to strongly +ordered memory must complete before any further access to any type of memory +takes place.

  • +

This type is used for hardware mapping.

+
+ +

EMemAttDevice

+

Writes are not combined. The order of memory accesses is preserved. +This type is used for hardware mapping.

+
+ +

EMemAttNormalUncached

+

Non cacheable memory: The order of accesses is not preserved. Writes +may be combined. For example, this is used for video memory.

+
+ +

EMemAttNormalCached

+

Write-back read/write allocate cached memory, inner and outer. Used +for “ordinary” memory.

+
+ + +

Device memory and normal memory can be set as shared or +non-shared, strongly ordered accesses are assumed to be shared.

The +complete set of memory types supported by Symbian platform are represented +by the values of the TMemoryType enum.

Mapping existing memory +types

The TMappingAttributes constants allow +the cache attributes to be manipulated. On remapped platforms, these map into TMemoryType as +follows:

+ + + +

Memory type described by TMappingAttributes

+

Memory type

+
+ +

EMapAttrFullyBlocking

+

EMemAttStronglyOrdered

+
+ +

EMapAttrBufferedNC

EMapAttrBufferedC

+

EMemAttDevice

+
+ +

EMapAttrL1Uncached

EMapAttrCachedWTRA

EMapAttrCachedWTWA

+

EMemAttNormalUncached

+
+ +

EMapAttrCachedWBRA

EMapAttrCachedWBWA

EMapAttrL1CachedMax

EmapAttrCachedMax

+

EMemAttNormalCached

+
+ +

EMapAttrAltCacheWTRA

EMapAttrAltCacheWTWA

EMapAttrAltCacheWBRA

EMapAttrAltCacheWBWA

+

Return error

+
+ +

EMapAttrL2CachedWTRA

EMapAttrL2CachedWTWA

EMapAttrL2CachedWBRA

EMapAttrL2CachedWBWA

EMapAttrL2CachedMax

+

Takes no effect. Only the inner cache description matters.

This +policy is already in place on ARMv5 platforms with L210, where the page table +does not support a separate description of the inner and outer cache attributes.

+
+ + +

Mapping ARMv6K or ARMv7 +onto TMappingAttributes

To describe memory on ARMv6K or ARMv7 +using the original TMappingAttributes bit mask, the device +driver should use the following values:

+ + + +

ARMv6K/v7 memory type TMemoryType

+

TMappingAttributes mask to use

+
+ +

EMemAttStronglyOrdered

+

EMapAttrFullyBlocking

+
+ +

EMemAttDevice

+

EMapAttrBufferedNC

+
+ +

EMemAttNormalUncached

+

EMapAttrL1Uncached

+
+ +

EMemAttNormalCached

+

EmapAttrCachedMax

+
+ + +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-EDC1C30B-4078-4434-95AC-2E37AF809A51.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-EDC1C30B-4078-4434-95AC-2E37AF809A51.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,19 @@ + + + + + +DMA Implementation How to implement the Platform Specific Layer (PSL) for +your particular hardware. +

The DMA Framework provides the DMA platform service API to clients +(usually drivers). It is necessary to implement a number of hardware-specific +functions when adapting the framework to a new board. hardware. This +section contains information about the Framework's implementation +and hardware requirements.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-EE2F64B2-A2E3-524F-8E04-68BE9AA9EA36-master.png Binary file Adaptation/GUID-EE2F64B2-A2E3-524F-8E04-68BE9AA9EA36-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-EE2F64B2-A2E3-524F-8E04-68BE9AA9EA36_d0e29378_href.png Binary file Adaptation/GUID-EE2F64B2-A2E3-524F-8E04-68BE9AA9EA36_d0e29378_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-EE50283A-543C-446F-A5D1-E64043F988ED.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-EE50283A-543C-446F-A5D1-E64043F988ED.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,40 @@ + + + + + +DMA Device Driver GuideExplains the key concepts that the device driver creator +needs to know before developing a device driver. +

The DMA framework bypasses the CPU for data transfers. Without +DMA, the CPU would have to copy each piece of data from the source +to the destination.

    +
  • Device Driver: A set of methods that tells the platform +how to use a specific piece of hardware.

  • +
    +
  • DMA Framework: The DMA framework provides a simplified +and unified access to DMA resources in a device. Generic transfer +parameters abstract the underlying DMA hardware for basic services, +and fine-grained control is still available for platform-specific +features.

  • +
    +
  • DMA Operation: Before any DMA transfers can be undertaken, +the DMA channel to be used and the source and destination addresses +of the data to be transferred have to be specified. The transfer details +are placed onto a queue for the DMA channel specified. The item at +the head of the queue will be the active transfer and the rest of +the queue will be pending transfers.

  • +

+
+DMA +Tutorials Overview +DMA +Implementation Overview +DMA +Technology Guide +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-EE7086B4-A60A-55B2-85DC-28F07F9E227E-master.png Binary file Adaptation/GUID-EE7086B4-A60A-55B2-85DC-28F07F9E227E-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-EE7086B4-A60A-55B2-85DC-28F07F9E227E_d0e55772_href.png Binary file Adaptation/GUID-EE7086B4-A60A-55B2-85DC-28F07F9E227E_d0e55772_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-EF73C56D-AEB1-558B-BAD1-D076BA6EA889.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-EF73C56D-AEB1-558B-BAD1-D076BA6EA889.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,109 @@ + + + + + +Impact +of Data Paging on User Side Code GuideExplains cases in which data paging degrades the performance of +user side code and sets out strategies to mitigate these effects. +
Purpose

Data paging degrades the performance of +user side code. This document describes strategies to mitigate these effects. +It is intended for application developers whose code uses device drivers.

Intended Audience:

Application developers writing modules +which involve device drivers.

+
Mitigating the impact of data paging on user side code

Data +paging is a technique which increases the size of virtual RAM by holding data +on external media and read into physical RAM when accessed. The technique +trades off an increase in available RAM against decreased performance. Developers +must allow for the impact on performance and aim to mitigate it by using the +practices described in this document.

Data paging is mainly a property +of processes. Processes can be configured to be paged or unpaged when they +are built or put into a ROM image. Threads and the data which they use inherit +the data paging configuration of the creating process and that configuration +can be modified at the level of the thread or the individual items of data.

Thread scheduling

When a platform uses data paging there is +a higher risk of delays, timing-related defects and race conditions.

When +a thread accesses paged memory, the required page may be paged in (actually +in RAM) or paged out (stored in media). If it is paged out, a page fault results, +slowing performance by a factor of thousands and sometimes up to a million. +The delay can also expose latent race conditions and timing-related defects +in existing code: for instance an asynchronous request to a server may appear +to complete synchronously, returning control to the client before the request +has completed with incorrect behavior as a result.

The cure for this +problem is to configure data paging when chunks, heaps and threads are created.

When +creating a thread of class RThread you can call the creating +function RThread::Create() with an argument of class TThreadCreateInfo as +argument. You use an instance of this class to configure the data paging attributes +to one of

    +
  • EUnspecified (the +thread inherits the paging attributes of the creating process),

  • +
  • EPaged (the +thread will data page its stack and heap), or

  • +
  • EUnpaged (the +thread will not data page its stack and heap).

  • +

When creating a chunk of class RChunk you can +call the creating function RChunk::Create() with an argument +of class TChunkCreateInfo as argument. You use an instance +of this class to configure the data paging attributes to one of

    +
  • EUnspecified (the +chunk inherits the paging attributes of the creating process),

  • +
  • EPaged (the +chunk will be data paged), or

  • +
  • EUnpaged (the +chunk will not be data paged).

  • +

The RChunk class also has a function IsPaged() to +test whether a chunk is data paged.

When creating a chunk heap of +class UserHeap you can call the creating function UserHeap::ChunkHeap() with +an argument of class TChunkHeapCreateInfo as argument. +You use an instance of this class to configure the data paging attributes +to one of

    +
  • EUnspecified (the +heap inherits the paging attributes of the creating process),

  • +
  • EPaged (the +heap will be data paged), or

  • +
  • EUnpaged (the +heap will not be data paged).

  • +

Inter-process +communication

Data paging impacts on inter-process communication +when a non-paged server accesses paged memory passed from a client. If the +memory being accessed is not paged in, unpredictable delays may occur, and +when the server offers performance guarantees to its clients, all the other +clients will be affected as well. There are three separate solutions to this +problem:

    +
  • pinning memory automatically,

  • +
  • pinning memory as requested +by the client, and

  • +
  • using separate threads +for paged and unpaged clients.

  • +

Pinning paged memory means paging it into the RAM cache (if it is +not already present) and preventing it from being paged out until it is unpinned.

You +can set a server so that all memory passed to it by a client call gets pinned +for the duration of the call. You do so by calling the function SetPinClientDescriptors() of +a CServer2 object after construction but before calling CServer2::Start() for +the first time. This method is easy but wasteful, as all memory gets pinned +not just the data needs and the performance of the paging cache is impacted. +Automatic pinning should therefore only be used as a last resort.

You +can pin specified items of memory at the request of the client by calling +the PinArgs() function of the TIpcArgs class. +This is the more efficient method as it allows fine-grained control over what +memory is pinned.

Separate threads for paged and unpaged clients.

Thread performance

The set of pages accessed by a thread over +a given period of time is called its working set. If the working set is paged, +the performance of the thread degrades as the working set increases. When +working with paged memory it is therefore important to minimise the working +set.

The main solution to this problem is to choose data structures +with high locality, that is data structure residing in single or adjacent +pages. An example of this is a preference for arrays rather than linked lists, +since arrays are usually in adjacent pages while the elements of linked lists +may reside on multiple pages.

+
+Code Paging +Overview +Code Paging +Guide +Demand Paging +Overview +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-EFEACBE5-B9E1-5315-88CA-DA3B7C1BFCE0-master.png Binary file Adaptation/GUID-EFEACBE5-B9E1-5315-88CA-DA3B7C1BFCE0-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-EFEACBE5-B9E1-5315-88CA-DA3B7C1BFCE0_d0e29694_href.png Binary file Adaptation/GUID-EFEACBE5-B9E1-5315-88CA-DA3B7C1BFCE0_d0e29694_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F09740DA-015B-449D-A124-0BEABBDDCB52.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-F09740DA-015B-449D-A124-0BEABBDDCB52.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,78 @@ + + + + + +Enabling +and DisablingThis document describes how device drivers enable and disable interrupts. +

Drivers can enable and disable the interrupts on the relevant interrupt +sources while handling the interrupts using the Interrupt class. +Typically, handling an interrupt is done with disabled interrupts. The interrupt +is then enabled after the completion of interrupt handling.

+Interrupt::Disable(aIntId); +... +// handle interrupt +... +Interrupt::Enable(aIntId); + +/** + Interrupt Service Routine (ISR) for the UART driver. This function + is associated with the UART interrupt, EUartIrq (value obtained from + TRM). This function is called whenever there is an interrupt on this + interrupt line and the interrupt source is enabled. The ISR must be a + static void function, taking a single TAny* parameter, which is an + object passed at the time of binding, usually a pointer to the owning + class. Interrupt::Enable() must be called to start receiving + interrupts. + + The ISR implementation is hardware and driver specific. The ISR must + be self-contained as the state of the system is indeterminate. It + should not signal threads, allocate or de-allocate memory, copy + memory to or from user processes, or call most Kernel functions. + Also the whole system is blocked while the ISR is running, so it must be + kept as short as possible. Any lengthy processing must be done in a + delayed function call (DFC). + + A typical ISR would, + Clear the interrupt in the peripheral. + Disable the interrupt. + Read or write peripheral registers, e.g. to determine errors, or + to start a new task. + Read data from, or write data to, the peripheral. + Start or stop NTimers or DMA transfer operations. + Queue DFCs. + + @param aParam + pointer to object passed as parameter while binding + */ + +void DExUartPhysicalChannelH4::UartIsr(TAny* aParam) + { + // Do the high priority device specific interrupt handling + // i.e. read the interrupt type from device, clear the + // interrupt. + ... + // Defer the remaining processing by queuing the respective + // DFC based on the interrupt type + ... + } +

Some operations may need to be performed with all the interrupts, not just +the particular interrupt source, disabled. In this case, the NKern class +must be used to disable and enable all interrupts globally at the Interrupt +controller. NKern::DisableAllInterrupts() can disable all +IRQs, or IRQs and FIQs. NKern::RestoreInterrupts() can +restore the interrupts to their state before disabling.

+alevel = 1; // 1 to disable IRQs and 2 to disable IRQs and FIQs +state = NKern::DisableAllInterrupts(aLevel); +... +// perform the required operations +... +NKern::RestoreInterrupts(state); + +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F123D574-44DE-528A-806C-DB64229BCEA2.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-F123D574-44DE-528A-806C-DB64229BCEA2.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,14 @@ + + + + + +Demand Paging +

Describes the concepts of Demand Paging and how to use Demand Paging.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F12437C5-BD96-5B43-AD76-614CFAB104D2-master.png Binary file Adaptation/GUID-F12437C5-BD96-5B43-AD76-614CFAB104D2-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F12437C5-BD96-5B43-AD76-614CFAB104D2_d0e69275_href.png Binary file Adaptation/GUID-F12437C5-BD96-5B43-AD76-614CFAB104D2_d0e69275_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F127644A-6072-52CA-9B17-E9DDEA784BE0-master.png Binary file Adaptation/GUID-F127644A-6072-52CA-9B17-E9DDEA784BE0-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F127644A-6072-52CA-9B17-E9DDEA784BE0_d0e8997_href.png Binary file Adaptation/GUID-F127644A-6072-52CA-9B17-E9DDEA784BE0_d0e8997_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F20D5802-7B83-5B78-8753-A88E74E28398.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-F20D5802-7B83-5B78-8753-A88E74E28398.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,256 @@ + + + + + +PSL ImplementationThis topic describes how to implement the DUsbClientController interface to provide a platform-specific layer implementation for +the USB client controller. +

The platform-specific layer only contains functionality that cannot +be abstracted and made generic because different USB device controller +designs operate differently. For example, the internal (and therefore +external) management of the endpoint FIFOs can be different. In some +USB device controller designs, the endpoints have hardwired FIFOs +of specific sizes, which may possibly be configured, whereas other +designs have a defined maximum amount of FIFO RAM available that has +to be shared by all endpoints in use in a given configuration. The +way that the chip is programmed can also differ. Some designs have +a single register into which all commands and their parameters are +written, whereas others are programmed via a number of special purpose +control registers.

+

Everything else that has to be common because it is defined in +the USB specification, is contained in the platform-independent +layer.

+

The operation of the USB device controller is hardware specific +and the implementers of the platform-specific layer is free to do +whatever is necessary to use the hardware. All of this is transparent +to the platform-independent layer, which uses only the fixed set of +pure virtual functions defined in DUsbClientController to communicate with the platform-specific layer, and therefore with +the hardware.

+

The platform-specific layer is also responsible for managing the +transfer of data over the endpoints, and it is important that it can +provide the services expected by the platform-independent layer. Data +transfers are normally set up by the platform-independent layer by +calling one of the following member functions of DUsbClientController:

+TInt SetupEndpointRead(TInt aRealEndpoint, TUsbcRequestCallback& aCallback) = 0; +TInt SetupEndpointWrite(TInt aRealEndpoint, TUsbcRequestCallback& aCallback) = 0; +TInt SetupEndpointZeroRead() = 0; +TInt SetupEndpointZeroWrite(const TUint8* aBuffer, TInt aLength, TBool aZlpReqd=EFalse) = 0; +TInt SendEp0ZeroByteStatusPacket() = 0; +

which the platform-specific layer implements.

+

These data transfer functions fall into two groups: one for handling +endpoint-0 and another for handling general endpoints. Endpoint-0 +is handled differently from general endpoints throughout the USB stack. +The functions for handling general endpoints are used to transfer +user data. In addition to taking an endpoint number, these functions +also take a reference to a TUsbcRequestCallback object. This is a request callback, it is key to the data transfer +mechanism.

+
Reading +data
    +
  • General endpoints

  • +
  • Endpoint-0

  • +

General endpoints

The platform-independent layer issues a request to read +data by calling DUsbClientController::SetupEndpointRead(), which is implemented by the platform-specific layer, passing it +the endpoint and a TUsbcRequestCallback object.

Data is read into a large buffer, whose address and length are +passed as data members of the TUsbcRequestCallback object: TUsbcRequestCallback::iBufferStart and TUsbcRequestCallback::iLength respectively. For Bulk reads, +this buffer is intended to catch a burst of data transmitted from +the host rather than just a single packet.

For all other transfer +types (Control, Interrupt, Isochronous) it is usual to return only +single packets to the LDD. The amount of data returned is controlled +– and limited - by the USB client driver (the LDD) through the iLength value.

The TUsbcRequestCallback object also supplies a pair of arrays:

    +
  • TUsbcRequestCallback::iPacketIndex containing the offset(s) into the data buffer of the single packet +or burst data.

  • +
  • TUsbcRequestCallback::iPacketSize containing the size(s) of the packet or burst data.

  • +

These arrays are logically linked; both are the same size +and can hold information for two entries each.

Therefore, +received single packets have to be merged into one 'superpacket' in +the read buffer. It is assumed that these merged packets consist of +maximum packet sized packets, possibly terminated by a short packet. +A zero length packet or ZLP must appear separately; this would be +the optional second packet in the respective array.

For example, +for a Bulk endpoint with a maximum packet size of 64 bytes:

    +
  • If 10 x 64 byte +packets and one 10 byte packet arrive, then these are marked as a +single large 650 byte packet.

  • +
  • If 10 x 64 byte +packets and one ZLP arrive, then these should be entered as two packets +in the arrays; one of size 640 bytes and one of size zero.

  • +

The general aim when servicing a Bulk read request from the +platform-independent layer is to capture as much data as possible +whilst not holding onto data too long before returning the data to +the LDD and receiving another buffer. There is considerable flexibility +in how this is achieved and the design does not mandate any particular +method; it also depends to a certain extent on the USB device controller +hardware used.

The platform implementation can use a re-startable +timer to see whether data has been received in the time (usually milliseconds) +since the last data was received. If data has been received, then +the timer is restarted. If data has not been received, then the timer +is not restarted, and the buffer is marked as complete for the platform-independent +layer by calling DUsbClientController::EndpointRequestComplete().

Note the following:

    +
  • In the interrupt +service routine (ISR), the flag iRxMoreDataRcvd is +used to indicate that data has been received.

  • +
  • The timer is +not restarted in the ISR - the timer is allowed to expire and then +a test is made for received data.

  • +
  • Typical values +for the timer range from 1—5 ms.

  • +
  • Each OUT endpoint +requires a separate timer.

  • +
  • The read is +not flagged as complete to the platform-independent layer if no data +has been received. The timer is only started once the first packet/transfer +has been received.

  • +
  • The bare minimum +of work is done in the ISR. After draining the FIFO, update the iPacketSize and iPacketIndex arrays and +recalculate the buffer address ready for the next packet, taking into +account any alignment restrictions.

  • +

The platform-specific layer completes a non endpoint-0 read +request by calling the platform-independent layer function DUsbClientController::EndpointRequestComplete(). This function +takes as its sole argument a pointer to the updated request callback +structure that was initially passed to the platform-specific layer +for that read. Members that need to be updated, in addition to the +packet arrays TUsbcRequestCallback::iPacketIndex and TUsbcRequestCallback::iPacketSize, are:

    +
  • TUsbcRequestCallback::iRxPackets, with possible values: 1 or 2.

  • +
  • TUsbcRequestCallback::iError

  • +

Summary of Completion Criteria for general Endpoints

The platform-specific layer completes a read request by calling DUsbClientController::EndpointRequestComplete() when any +of the following conditions are met:

    +
  • The requested +number of bytes has been received.

  • +
  • A short packet, +including a ZLP, is received. In the case of a ZLP being received, +it must be represented separately in the DUsbClientController::iPacketIndex and DUsbClientController::iPacketSize arrays.

  • +
  • If the number +of bytes in the current packet (still in the FIFO) were to cause the +total number of bytes to exceed the buffer length DUsbClientController::iLength.

  • +
  • The timer has +expired, data is available, but no further packets have been received.

  • +

Endpoint-0

The handling of endpoint-0 read requests is similar to general +endpoints except for the following:

    +
  • The platform-independent +layer issues the request by calling DUsbClientController::SetupEndpointZeroRead(). This function does not take any parameters because:

      +
    • The endpoint +number is known, this is zero.

    • +
    • The request +is completed after every received packet, and a TUsbcRequestCallback object is not needed.

    • +
  • +

All the platform-specific layer needs to know is where to +place the received data, and its size. Both are fixed values: DUsbClientController::iEp0_RxBuf and KUsbcBufSzControl respectively.

An endpoint-0 read request is completed by +calling DUsbClientController::Ep0RequestComplete(), passing the endpoint number (0, or symbolically, KEp0_Out), the number of bytes received, and the resulting error code for +this request.

+
Writing +data
    +
  • General endpoints

  • +
  • Endpoint-0

  • +

General endpoints

The platform-independent layer issues a request to write +data by calling DUsbClientController::SetupEndpointWrite(), which is implemented by the platform-specific layer, passing the +function an endpoint and a TUsbcRequestCallback object.

The address of the buffer, containing the data to +be written, is passed into the data member TUsbcRequestCallback::iBufferStart. The length of this buffer is passed into TUsbcRequestCallback::iLength. The buffer is a single contiguous piece of memory.

The +platform-specific layer's implementation needs to set up the transfer, +either using DMA or a conventional interrupt driven mechanism, and +then wait for the host to collect, by sending an IN token, the data +from the respective endpoint’s primed FIFO. This continues until all +data from the buffer has been transmitted to the host.

If +the ZLP request flag iZlpReqd in the TUsbcRequestCallback structure is set (=ETrue), then the platform +specific layer must determine, after all data has been sent, whether +to send a ZLP or not. The decision is based on the size of the last +packet sent and the current maximum packet size of the endpoint.

To summarize, a ZLP should be sent at the end of a write request +if:

    +
  • The ZLP flag +is set.

  • +
  • The last packet +of the write request was not a short packet (i.e. it was a max-packet-sized +packet).

  • +

The platform-specific layer completes a non endpoint-0 write +request by calling the platform-independent layer function DUsbClientController::EndpointRequestComplete(). This function +takes only one argument, a pointer to the updated request callback +structure passed to the platform-specific layer for this write. Members +that need to be updated are:

    +
  • TUsbcRequestCallback::iTxBytes

  • +
  • TUsbcRequestCallback::iError

  • +

Endpoint-0

The handling of endpoint-0 write requests is similar to general +endpoints except for the following:

The platform-independent +layer issues the request by calling DUsbClientController::SetupEndpointZeroWrite(). Unlike the equivalent read function, this function takes a number +of parameters:

    +
  • the address +of the location containing the data to be written

  • +
  • the length of +the data to be written

  • +
  • a TBool parameter that indicates whether a zero length packet (ZLP) is to +be sent immediately after the data has been sent.

  • +

An endpoint-0 write request is completed by calling DUsbClientController::Ep0RequestComplete(), in the platform-independent +layer, passing the function the endpoint number (0, or symbolically KEp0_In), the number of bytes written, and the error code +for this write request.

There is another endpoint-0 write +function, DUsbClientController::SendEp0ZeroByteStatusPacket(), which is used for sending a zero length packet (ZLP) on its own. +This separate function is provided because the USB device controller +mechanism for transmitting a ZLP on its own can be different to the +mechanism for transmitting the ZLP at the end of a data transmission.

+
Using +DMA

When planning to use DMA for transferring data from +and to the endpoints’ FIFOs, there are two things that must be considered:

    +
  • Flushing cached information for the data buffers

  • +
  • Implementing DMA mode for OUT transfers (DMA reads)

  • +

Flushing cached +information for the data buffers

The cached information +for the data buffers must be flushed before a DMA write operation, +(i.e. transfer memory to a FIFO), and both before and after a DMA +read operation, (i.e. transfer a FIFO to memory).

The kernel +provides three functions for that purpose. These are static functions +in the class Cache, declared in ...\e32\include\kernel\cache.h:

    +
  • Cache::SyncMemoryBeforeDmaWrite()

  • +
  • Cache::SyncMemoryBeforeDmaRead()

  • +
  • Cache::SyncMemoryAfterDmaRead()

  • +

Implementing DMA +mode for OUT transfers (DMA reads)

The implementation +of DMA mode for IN transfers is normally relatively straightforward, +however complications can occur with OUT transfers (DMA reads), depending +on the DMA controller, the USB device controller and the way the two +are connected.

There are two issues:

    +
  1. If we set up +a DMA read for 4kB, for example, and this request returns after a +short packet, we must be able to tell how much data has been received +and is now in our buffer. In other words, the DMA controller must +provide a way of finding out how many bytes have been received, otherwise +we cannot complete the read request to the LDD.

    Here is a +theoretical solution for a Scatter/Gather controller that doesn’t +provide information about the number of bytes transferred directly. Note: This proposal has not been tested in practice!

    Instead of using one large DMA descriptor for 4kB, we could set up +a chain of descriptors for max-packet-size bytes each. When the DMA +completes, it will be:

      +
    • for the whole +transfer, in which case we know the number of bytes received.

    • +
    • because it is +a short packet. In this case we can try and find out which descriptor +was being served at the time. The number of bytes received is then

      number of completed descriptors * max-packet-size + number of bytes in short packet.
    • +
  2. +
  3. Another potential +problem is posed by the restartable OUT endpoint timer described in +the section Reading data. The situation in the timer callback DFC, when +the LDD read request is about to complete, has to be handled with +care in order to avoid data loss. If at this point the pending DMA +request has already started transferring data from the endpoint FIFO +into our data buffer, then we cannot complete the LDD request anymore +(this data would be lost because the LDD would not know about it as +the variables in the request structure do not take account of it). +The buffer cannot be removed while it is receiving data from a DMA +transfer. A possible solution would be as follows: (again, this is +just an idea and therefore untested). In the timer DFC, before we +complete to the LDD, we cancel the pending DMA request. If a DMA transfer +was already happening, then this will somehow complete and the DMA +complete DFC will be queued. What we need to find out in that situation +is whether or not that DFC is pending:

      +
    • if not, then +there was no DMA transfer ongoing, and we can just complete our read +request to the LDD.

    • +
    • otherwise we +have to abandon, at this point, the plan to complete and return from +the timer callback (without doing any damage). In this case, the DMA +complete DFC will run next, the LDD read request structure will be +updated, the RX timer will be set again, and we can proceed as normal.

    • +
  4. +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F367F6C9-66F7-4061-81A7-0C845D8F39C4.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-F367F6C9-66F7-4061-81A7-0C845D8F39C4.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,61 @@ + + + + + +Cancellation +of Asynchronous RequestsThis document describes how a device driver cancels an asynchronous +request. +

Any outstanding asynchronous request can be cancelled. DoCancel() is +implemented to handle cancel requests. Cancel requests are either explicitly +made by the user or made when there is a close message. Any pending requests +and queued DFCs are cancelled and the request is completed with KErrCancel.

+/** + Cancel Asynchronous Requests. This is called from HandleMsg() to + cancel pending asynchronous requests. This function determines which + operation is to be cancelled and tidies up the resources specific to + the request being cancelled, any outstanding DFCs, and timers, and + signals the client that the operation is completed. + + @param aMask + Mask containing the request number that has to be cancelled + */ +void DExDriverLogicalChannel::DoCancel(TUint aMask) + { + ... + // Any pending asynchronous operation can be + // cancelled. Check a valid asynchronous request + // to cancel has been specified. + // + if(aMask&(1<<RExDriverChannel::ERequestTransmitData)) + { + if (iTxDataStatus) + { + // If it is a Transmit request, cancel the Transmit DFC. + // TDfc::Cancel() cancels the DFC if it is already + // queued. It does nothing if the DFC is not queued. + // + iTxDfc.Cancel(); + + // Notify the client (iClient) that the request is + // completed. The TRequestStatus object is updated with the + // status and the completion code is provided to the + // client. KErrCancel indicates that the request has been + // cancelled. Typically, a client thread, waiting on + // User::WaitForRequest(TRequestStatus &aStatus) or using + // the active object framework, is unblocked and notified. + // Then the client may read the request status from the + // TRequestStatus object. + // + Kern::RequestComplete(iClient,iTxDataStatus,KErrCancel); + } + } + ... + } +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F3B93325-E30E-456A-B281-5451B7C47AAE.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-F3B93325-E30E-456A-B281-5451B7C47AAE.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,13 @@ + + + + + +Baseport Template ImplementationProvides information on implementation, build and testing +of Baseport Template platform service. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F461CBB3-F8D1-5961-AD51-5741143A1CB1.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-F461CBB3-F8D1-5961-AD51-5741143A1CB1.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,255 @@ + + + + + +Client of Slave Channel TutorialThis document describes a simple implementation of a client +of an IIC slave channel. +
Required +background

Before you start, you must:

    +
  • Have installed +the platform specific implementation of IIC channels that is required +to support the IIC platform service API.

  • +
  • Ensure that +the iic.dll has been included in the kernel.iby file.

  • +
  • Include the iic.h and iic_channel.h header files.

  • +
+
Introduction

An application communicates over an IIC channel by operating +as a client of the channel. When the channel uses a slave node, a +transmission must be conducted at the level of the transfer because +slaves react to transfers between it and a master node. For this reason, +a large part of the client functionality is implemented as a callback +function which is passed to the channel object and placed on the client +thread’s DFC queue for execution. The callback notifies the client +of the individual transfers and is the entry point to the application +functionality which uses the data being transmitted. The other client +API functions control the transmission as a whole.

+
Procedure +for writing a client
    +
  1. Capture the +channel by calling IicBus::CaptureChannel().

      +
    1. Pass the channel +Id as its TInt aBusId parameter.

    2. +
    3. Pass the channel +configuration header as TDes8* aConfigHdr.

    4. +
    5. Pass a pointer +to the callback function as TIicBusSlaveCallback* aCallback.

    6. +
    7. Pass the boolean ETrue as TBool aAsynch to specify asynchronous +channel capture and otherwise pass EFalse.

    8. +

    + TInt channelId = 0; + // capture channel.. + r = IicBus::CaptureChannel(TInt aBusId, &header, iSlaveCallback, channelId, aAsynch); + if (r != KErrNone) + { + __KTRACE(Kern::Printf("Error capturing the channel, r %d", r)); + } +

    In synchronous transmission when the function +returns the parameter TInt& aChannelId is set +to a token value, the channel Id, which is used by the other functions +to acquire the exclusive use of the channel. In asynchronous transmission +the channel Id is set immediately before calling the client callback.

  2. +
  3. Register receive +and transmit buffers by calling IicBus::RegisterRxBuffer() and IicBus::RegisterTxBuffer().

      +
    1. Pass the channel +Id as the aChannelId parameter.

    2. +
    3. A buffer is +represented by a descriptor containing a point to the start of the +buffer, its total size in bytes and an indication of how much of it +is in use. Initialise a descriptor with these values and pass it as TPtr8 aRxBuffer, and similarly for TPtr8 aTxBuffer

    4. +

    + TPtr8 rxBuf(0, 0); + TPtr8 txBuf(0, 0); + + rxBuf.Set((TUint8*) iRxBuf.Ptr(), iSlaveBufSize, iRxBuf.MaxLength()); + txBuf.Set((TUint8*) iTxBuf.Ptr(), iSlaveBufSize, iTxBuf.MaxLength()); + + r = IicBus::RegisterRxBuffer(iChannelId, rxBuf, 8, iSlaveBufSize, 0); + if(r != KErrNone) + { + __KTRACE(Kern::Printf("Error Register Rx Buffer, r %d", r)); + } + else + { + r = IicBus::RegisterTxBuffer(iChannelId, txBuf, 8, iSlaveBufSize, 0); + } + + return r; +

  4. +
  5. Call IicBus::SetNotificationTrigger(). This function informs +the channel of the conditions under which the callback is to be called.

      +
    1. Pass the channel +Id as TInt& aChannelId.

    2. +
    3. The callback +is called when the state of the channel satisfies one of a number +of conditions called triggers which are specified in the enumeration TIicBusSlaveTrigger. Determine which triggers are appropriate, +create a bitmask of them and pass it as TInt aTrigger.

    4. +

    +/* + ERxAllBytes = 0x01, // Master has written the required number of bytes + ERxUnderrun = 0x02, // Master has written less than the required number of bytes, and ceased transmitting + ERxOverrun = 0x04, // Master has written the required number of bytes and is continuing to transmit + ETxAllBytes = 0x08, // Master has read the required number of bytes + ETxUnderrun = 0x10, // Master has read the required number of bytes and is continuing to read + ETxOverrun = 0x20, // Master has read less than the required number of bytes, and ceased reading + EGeneralBusError = 0x40, // An error has occurred during a transaction + EAsyncCaptChan = 0x80 // Completion of asynchronous CaptureChannelr = IicBus::SetNotificationTrigger(iChannelId, aTrigger); +*/ + r = SetNotificationTrigger(iChannelId, aTrigger); + if (r != KErrNone) + { + __KTRACE(Kern::Printf("Error setting notification trigger, r %d", r)); + } + + return r; +

    The transmission of data will now take place, +controlled by the mechanism of callback and triggers. Different buses +signal that a transmission has been completed in different ways: for +instance I2C uses a stop bit and SPI changes the voltage on Chip Select.

  6. +
  7. When you have +finished using the channel, release it by calling IicBus::ReleaseChannel() with the channel Id as its argument.

    + r = IicBus::ReleaseChannel(iChannelId); + if (r == KErrNone) + { + // resetting channel Id + iChannelId = 0; + if(iSlaveCallback) + { + // callback object no longer needed, so delete + delete iSlaveCallback; + iSlaveCallback = NULL; + } + + } +

  8. +
+
Next +steps
    +
  • Implement the +callback as a function containing a series of conditions on the triggers. +Its prototype must match the typedef for (*TIicBusSlaveCbFn).

    typedef void (*TIicBusSlaveCbFn)(TInt /*aChannelId*/, + TInt /*aReturn*/, + TInt /*aTrigger*/, + TInt16 /*aRxWords*/, + TInt16 /*aTxWords*/, + TAny* /*aParam*/); +

    These functions serve three purposes.

      +
    • The callback +must react to the completion of an asynchronous transmission between +it and the bus master.

    • +
    • It must implement +the actual functionality of the application by doing something with +the data which is written to or read from the buffers.

    • +
    • It must react +to cases where the physical transfer of the data has not taken place +exactly as expected. For example there may be more data to transfer +than had been anticipated.

    • +
      +
    • Implement the +reaction to a completed asynchronous transmission as a conditional +statement where EAsyncaptChan is true. The callback +should return and control should revert to the client.

      + // aTrigger and aReturn are the arguments provided to the clients + // callback functions as defined by TIicBusSlaveCbFn + if(aTrigger & (EAsyncCaptChan)) + { + if(aReturn == KErrCompletion) + { + // a is a pointer to the client's object + // which stores the channel Id, client Id etc + a->iChannelId = aChannelId; + __KTRACE(Kern::Printf("channelId %d", aChannelId)); + } + + Kern::RequestComplete(a->iClient, a->iSlaveReqStatus, aReturn); + return; + } +
    • +
    • Implement the +actual functionality of the application as a conditional statement +where EAllBytes is true. The callback should return +at the end of this condition.

      + if(aReturn & (ETxAllBytes | ERxAllBytes)) + { + Kern::RequestComplete(a->iClient, a->iSlaveReqStatus, KErrNone); + } + + if(aTrigger & (/*ERxAllBytes |*/ ETxAllBytes)) + { + Kern::RequestComplete(a->iClient, a->iSlaveReqStatus, KErrNone); + } + } +
    • +
    • Implement the +other cases as conditional statements where the other triggers in TIicBusSlaveTrigger are true. In the event of EGeneralBusError the callback should simply complete. The +other triggers involve buffer underruns and overruns which may require +new buffers which the unexpected data can be read from and written +to.

        +
      • Register the +new buffers by calling IicBus::RegisterRxBuffer() and IicBus::RegisterTxBuffer() as explained before.

      • +
      • Start data transfer +to and from the new buffers by calling IicBus::SetNotificationTrigger() as explained before.

        The channel is implemented as a state +machine as illustrated. The channel starts and finishes in the EInactive state. During operation it alternates between +the two states EWaitForClient and EWaitForMaster as the client notifies the channel of new triggers and the channel +reacts to them. There is a timer on these two states and the state +machine returns to EInactive either when there are +no triggers remaining to be detected or the timers time out. When +the client fails to respond on time it enters the state EClientTimeout.

      • +
      + if(aTrigger & ETxUnderrun) + { + TPtr8 txBuf(0, 0); + + txBuf.Set((TUint8*) a->iTxBuf.Ptr(), a->iTxBuf.MaxLength(), a->iTxBuf.MaxLength()); + + // if there is more data to transmit + // use aTxWords as an offset.. + if(aTxWords + 32 <= KMaxSlaveTestBufferSize) + { + // register the next buffer + r = IicBus::RegisterTxBuffer(a->iChannelId, txBuf, 8, 32, aTxWords); + // check it was successful + if (r != KErrNone) + { + Kern::Printf("Error Register Tx Buffer, r %d", r); + } + else + { + // set the trigger to transmit the required number of bytes + r = IicBus::SetNotificationTrigger(a->iChannelId, ETxAllBytes); + // check the request was accepted + if (r != KErrNone) + { + Kern::Printf("Error setting notification trigger, r %d", r); + } + } + + // updated the buffer - so return.. + return; + } + } +
    • +
  • +
+ Client state machine 1 + + + + + Client state machine 3 + +
+
+Client +of Master Channel Tutorial +IIC +Concepts +I2C +Technology Guide +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F4B2D20B-8F1D-4A4B-8ECB-65BE8E9824DD.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-F4B2D20B-8F1D-4A4B-8ECB-65BE8E9824DD.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,103 @@ + + + + + +Interrupt OverviewHardware or software uses interrupts to indicate an event +has occurred, such as a data buffer being ready or a key has been +pressed. +

Interrupts are sent by hardware or software to indicate an event +has occurred. Interrupts typically cause an Interrupt Service Routine +(ISR) to be executed. The Interrupt platform service specifies the +interface APIs for setting up the ISRs and connecting them to specific +Interrupt IDs.

+

Interrupts can be managed using the GPIO platform +service when an interrupt source is connected through GPIO pins.

+

The Interrupt platform service is used by the device drivers that +use an interrupt source routed directly to the interrupt controller +hardware. For more information on how to use GPIO to manage interrupts, +see GPIO Design +Considerations.

+

Not all hardware events are indicated by interrupts; hardware may +indicate a status change by setting a value in a register or sending +a command/signal over a bus.

+
What +is the Interrupt platform service

The Interrupt platform +service specifies certain APIs for attaching an Interrupt Service +Routine to an API. It is the low level interface between hardware/software +interrupts, and the kernel and kernel level device drivers.

+
Required +background

You should be familiar with the following:

    +
  • Writing a C++ +function that is either global or is in a static class so that the +function address can be used for the ISR.

  • +
  • The specification +for your hardware, including determining interrupt IDs.

  • +
+
Key +concepts and terms

The following concepts are relevant +to this component:

+ +
Interrupt ID
+

An identifier which says which interrupt has occurred. Typically +an unsigned integer.

+
+ +
Interrupt Service Routine (ISR)
+

An ISR is a static function which is called when an interrupt +is received. It should be very short, allocate no memory on the heap, +store any volatile information that needs to be captured for that +event, and, if required, queue a DFC for further processing.

+
+ +
Bind
+

Connects an Interrupt ID to an Interrupt Service Routine. Unbind +removes the connection.

+
+ +
Enable
+

When an interrupt occurs, execute the associated Interrupt +Service Routine.

+
+
+
The +Interrupt class

The interrupt interface is provided by +functions of the Interrupt class. The class is +defined in the os/kernelhwsrv/kernel/eka/include/kernel/arm/assp.h file.

+
Key +users

The key users of the Interrupt platform service are +kernel and kernel-level device driver writers, and anyone who needs +to specify code to be run when a system event occurs.

+
Limitations
    +
  • The ISR needs to complete in short and finite time to prevent +excessive interrupt latency.

  • +
  • To keep ISRs short, most of the event processing should be +delegated to a DFC. The DFC will execute in the context of a DFC thread +allocated to itself by the device driver.

  • +
  • It is safe to access the device driver objects using appropriate +synchronization techniques such as spin-locks.

  • +
  • The ISR should store critical data which may not be available +later.

  • +
  • Interrupts can happen in the middle of updating kernel heap +free list or other non-atomic actions. ISRs must be coded with that +in mind.

  • +

This means that ISRs cannot:

    +
  • access user process memory. This includes completing an asynchronous +request.

  • +
  • perform any allocation / de-allocation on heaps. The current +interrupt might have occurred when a heap operation is already in +progress.

  • +

It is therefore necessary that ISRs must only use pre-allocated +objects on the kernel heap.

+
+Interrupt +Client Interface +Interrupt +Implementation Guide +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F4E04E00-D9C6-5E8F-9EC6-F90BC951D4D0-master.png Binary file Adaptation/GUID-F4E04E00-D9C6-5E8F-9EC6-F90BC951D4D0-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F4E04E00-D9C6-5E8F-9EC6-F90BC951D4D0_d0e63912_href.png Binary file Adaptation/GUID-F4E04E00-D9C6-5E8F-9EC6-F90BC951D4D0_d0e63912_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F50E1C81-E80F-5692-996B-3AC2BE995425-master.png Binary file Adaptation/GUID-F50E1C81-E80F-5692-996B-3AC2BE995425-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F50E1C81-E80F-5692-996B-3AC2BE995425_d0e39862_href.png Binary file Adaptation/GUID-F50E1C81-E80F-5692-996B-3AC2BE995425_d0e39862_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F5430A12-D89D-4936-B846-E917B434F755.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-F5430A12-D89D-4936-B846-E917B434F755.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,12 @@ + + + + + +Power managementProvides background information on power management. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F54BB3B5-D069-4524-A215-6F2CCA372666.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-F54BB3B5-D069-4524-A215-6F2CCA372666.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,65 @@ + + + + + +Nanokernel +TimerThis document describes nanokernel timers. +
Creation

NTimer is +a basic relative timer provided by the nanokernel. It can generate either +a single interrupt or periodic interrupts. A timeout handler is called when +the timer expires, either from the timer ISR or from the nanokernel timer +thread. These timer objects can manipulated from any context. The timers are +driven from a periodic system tick interrupt, usually a 1ms period. The use +of NTimer is as follows:

+
Start

The +nanokernel timer can be used in either single mode or in periodic mode. Typically, +the timer is started with NTimer::OneShot() for a timeout +period and then is made periodic by calling NTimer::Again(). +The timeout value specified for the timer is in nanokernel ticks. The time +out callback function can be chosen to be called in either an ISR context +or a DFC context (running in the kernel's nanokernel timer thread, called DfcThread1).

TInt NTimer::OneShot(TInt aTime, TBool aDfc); +// If aDfc is TRUE then, the timeout function is called in a DFC context; +// if aDfc is FALSE, the timeout function is called in a ISR context. + +// Starts timer in zero-drift mode, to avoid delays in re-queuing +// the timer +TInt NTimer::Again(TInt aTime); + +// NTimer::OneShot() starts a nanokernel timer in one-shot mode with +// ISR callback. It queues the timer to expire in the specified number +// of nanokernel ticks. The actual wait time will be at least that +// much and may be up to one tick more. The expiry handler will be +// called in ISR context. +// +iRxPollTimer.OneShot(KRxTimeout);
+
Callback function

The +timeout callback function is called when a timer started with NTimer::OneShot() or NTimer::Again() expires. +A driver should implement the function to process the timeout event as appropriate +for the situation.

/** + Timer callback function. Called when the NTimer expires + typedef void(* NTimerFn)(TAny*); is the nanokernel timer callback + function. This is used for Rx timeout. + + @params aPtr + pointer refernce passed during timer initialization + */ +void DExUartPhysicalChannelH4::RxPollTimerCallback(TAny* aPtr) + { + ... // design specific + }
+
Cancellation

A +timer can be cancelled using NTimer::Cancel(). It removes +the timer object from the nanokernel timer queue. If the timer has already +expired, or is inactive, then it does nothing.

If a timer was queued +and a DFC callback was requested, then the expiry handler might run even after Cancel() has +been called. This occurs when the DfcThread1 is preempted +just before calling the expiry handler for this timer, and the preempting +thread/ISR/IDFC calls Cancel() on the timer.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F55A0CB4-0AB6-4DE3-9DFA-FBCB7131BB3A-master.png Binary file Adaptation/GUID-F55A0CB4-0AB6-4DE3-9DFA-FBCB7131BB3A-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F55A0CB4-0AB6-4DE3-9DFA-FBCB7131BB3A_d0e98263_href.png Binary file Adaptation/GUID-F55A0CB4-0AB6-4DE3-9DFA-FBCB7131BB3A_d0e98263_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F5DC77CD-4730-4FD8-A483-F5D22F34887E.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-F5DC77CD-4730-4FD8-A483-F5D22F34887E.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,15 @@ + + + + + +IIC Client InterfaceThe basic steps to use the client interface of IIC. +

The IIC client interface API provides the IIC bus interface functionality +to the OS.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F60E5156-38B0-4781-8088-180E6716FC63.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-F60E5156-38B0-4781-8088-180E6716FC63.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,12 @@ + + + + + +IIC TutorialsThe tutorials relating to the IIC platform service API. \ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F67AFC0F-5245-48DE-8901-79461FB6EADE-master.png Binary file Adaptation/GUID-F67AFC0F-5245-48DE-8901-79461FB6EADE-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F67AFC0F-5245-48DE-8901-79461FB6EADE_d0e93180_href.png Binary file Adaptation/GUID-F67AFC0F-5245-48DE-8901-79461FB6EADE_d0e93180_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F67AFC0F-5245-48DE-8901-79461FB6EADE_d0e94068_href.png Binary file Adaptation/GUID-F67AFC0F-5245-48DE-8901-79461FB6EADE_d0e94068_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F67FA7B5-F6D1-5C5C-8E10-A8E317A778E4.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-F67FA7B5-F6D1-5C5C-8E10-A8E317A778E4.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,178 @@ + + + + + +Public +FunctionsDescribes how to implement the three exported functions of the +platform-specific layer. +
<codeph>InitialiseHardware()</codeph>

See +the Template port (os/kernelhwsrv/bsptemplate/asspandvariant/template_variant/bootstrap/template.s) +to see how this function is coded in practice.

The code can be found +at the label:

... + EXPORT InitialiseHardware +InitialiseHardware ROUT + ...

Entry +conditions

This function is called immediately after reset with +the CPU in supervisor mode, with all interrupts disabled, and R12 pointing +to the ROM header (a TRomHeader object). There is no valid +stack on entry to this function, i.e. R13 is undefined.

What the function should do

The function is intended to perform +the basic hardware initialisation that is required immediately after reset. +It also sets up the address of the boot +table.

In detail, it should:

    +
  1. Initialise the CPU/MMU +registers. This is done by making a call to the generic function InitCpu(), +passing the address of the boot parameter table. For more information on the +boot parameter table, see BTF_Params, +which is one of the boot +table functions.

    InitCpu() flushes all caches, +sets up the MMU control registers, and enables the instruction cache (on a +split cache device). Note that R14 needs to be preserved +before making the function call. As there is no valid stack, R14 is typically +saved in R13.

  2. +
  3. Interrogate the hardware +to determine the reset reason. In a transparent reset, all RAM contents are +preserved and the reset should be invisible to the user, for example waking +up from a low power mode such as the SA1110 sleep mode. In this case, perform +whatever device-dependent sequence is required to restore the processor state, +and jump back into the power down code: InitialiseHardware() will +never return to the generic boot code.

    For bootloader bootstraps, +if the reset reason is power on reset or hardware cold reset, +or if it is a software reset and a rerun of the bootloader was requested +(i.e. Kern::Restart() was called with a parameter value of 0x80000000), +then proceed to step 3. If these conditions are not true, for example when +the reset reason is software reset with any other parameter value or +a reset caused by waking up from a low power mode, then control should immediately +be transferred to the image already loaded. The state of the system at the +point where control is transferred should be as close as possible to the state +immediately after reset, to provide proper conditions for the bootstrap in +the already loaded image.

    If the system contains FLASH memory which +can be programmed with a ROM image, an additional check may be needed to see +if an image already present in FLASH should be run instead of the bootloader +following a hardware reset. A spare switch on the board is often used for +this purpose.

  4. +
  5. Initialise enough hardware +to satisfy the rest of the bootstrap. The precise split between what is initialised +here, what is initialised later in the bootstrap, and what is done during +variant initialisation is flexible, but as an absolute minimum this function +must make some RAM accessible. Typically this function should set up ROM and +RAM controllers, set the CPU clock frequency, set sensible states for GPIO +lines and set up whatever bus controller is necessary to communicate with +any external peripheral chips present. Note also that it is often useful to +allow the ROM image to run from either ROM or RAM - this is one of the main +reasons for making the bootstrap position independent. To allow for this, +the intialisation code must check the PC when setting up the memory controllers; +if code is already running from RAM then RAM must already have been initialised +and it may not be necessary to touch the RAM controller.

  6. +
  7. Determine the physical +address of the super page. This will usually be at the beginning of physical +RAM, unless there is a good reason for it not to be. The main reason why the +super page might not be at the beginning of physical RAM is usually because +either that address is reserved for hardware (e.g. video RAM), or that code +is running from that address. R10 should be loaded with the +physical address determined. Note that, if it is not possible to determine +the final address of the super page here, a temporary address can be used +and the super page relocated to its final address later on. See BTF_Alloc for more detail.

    The super page is defined by the SSuperPageBase struct +in os/kernelhwsrv/kernel/eka/include/kernel/kernboot.h

  8. +
  9. Fill in valid values +for the following minimum set of super page fields:

      +
    • iBootTable should +contain the address of the boot +table.

    • +
    • iCodeBase should +contain the base address of the bootstrap code. It is used to resolve offset +addresses such as those in the boot table.

    • +
    • iActiveVariant is +the hardware variant discriminator (such as 05040001) for the hardware platform +in use. It is used to find the corresponding primary (kernel) executable image.

    • +
    • iCpuId should +be set to the value of the CP15 main ID register, obtained by MRC P15, 0, +Rd, C0, C0, 0.

    • +
  10. +
  11. The super page field iMachineData is +used to communicate hardware-specific data between the bootstrap and the variant. +It must be set to point to somewhere in the super page or CPU page. Typically, +it points to the beginning of the CPU page.

  12. +
  13. The super page field iHwStartupReason is +used to pass the detailed reset reason to the variant. It is a hardware specific +value.

  14. +
  15. In debug builds of the +bootstrap, as indicated by the symbol CFG_DebugBootRom being TRUE, +the debug tracing port should be initialised here. See also Platform-Specific +Configuration Header.

  16. +
  17. If Level 2 cache is +included in the bootstrap (i.e. specifically L210 cache or L220 cache), then:

      +
    • the function must initialise +the cache. This involves setting cache properties: size, type, N-ways and +cache invalidation. The following code is an example of L210 cache initialisation, +but it is also valid for L220 cache initialisation:

      ;Configure L2 cache +;------------------- + + LDR r0, =L210CtrlBasePhys ; Base phys. addr. of L210 Cache Controller + ;Set L210 Control Register + + LDR r1, #L210CTRLReg ; L210CTRLReg comes from Ref.Manual + STR r1, [r0, #0x104] ; 104h is address offset of Control Register + + ;Invalidate entire L2 cache by way (8 ways are presumed) + MOV r1, #0xFF + STR r1, [r0, #0x77c] ; 77Ch is address offset of InvalidateByWay Register + + ;Loop while invalidate is completed +_L2loop + LDR r1, [r0, #0x77c] + CMP r1, #0 + BNE _L2loop +
    • +
    • the superpage field SSuperPageBase::iArmL2CacheBase must +be set to the base physical address of the L2 cache control area, like in +the following example:

      ;Initialise SSuperPageBase::iArmL2CacheBase + ;------------------------------------------ + LDR r0, =L210CtrlBasePhys ; this is base physical address of L210 cache controller + STR r0, [r10, #SSuperPageBase_iArmL2CacheBase];r10 holds the base address of super page +

      Note that the superpage is defined by the SSuperPageBase struct +in os/kernelhwsrv/kernel/eka/include/kernel/kernboot.h

    • +
  18. +

Exit +conditions

The function can modify any CPU registers subject to +the conditions that:

    +
  • it returns in supervisor +mode with all interrupts disabled

  • +
  • it returns the physical +address of the super page in R10.

  • +
+
Fault()

Entry conditions

The processor state is completely undefined +except that R14 of the current mode points to the instruction +after the fault.

What +the function should do

This function is called if a fatal error +is detected during boot.

The implementation should halt the system +and produce whatever diagnostics are possible. Typically, if debug tracing +is enabled, the CPU state can be dumped over the debug port. A generic function +is provided to do this, as the minimal implementation is simply:

EXPORT Fault +Fault ROUT + B BasicFaultHandler ; generic handler dumps registers via + ; debug serial port +
+
RestartEntry()

Entry conditions

On entry the CPU state is indeterminate, +as the restart may be caused by a kernel fault, with the exception that R0 contains +the reboot reason, the parameter passed to Kern::Restart().

This +value is hardware specific except for the following two values:

    +
  • 0x00000000 means +restart the same ROM image, preserving RAM contents if possible.

  • +
  • 0x80000000 means +restart the boot loader and load a new image. This code is generated by the +crash debugger in response to the X +command of the crash debugger.

  • +

What +the function should do

The function is called by the kernel when +a system restart is required, and should perform whatever actions are necessary +to restart the system. If possible, a hardware reset should be used. Failing +that, it should reset all peripheral controllers and CPU registers, disable +the MMU and jump back to the reset vector.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F6E83530-3F8E-5930-8C6C-4D58B675E67A.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-F6E83530-3F8E-5930-8C6C-4D58B675E67A.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,23 @@ + + + + + +Digitizer +Driver TechnologyDescribes how screen coordinates work with the Digitizer Driver. +

The digitizer hardware provides coordinate values that are digitized raw +voltage values. These values are not the same as screen coordinates, which +are based on pixel positions. The digitizer converts the raw values into screen +coordinates and vice-versa.

+

Screen coordinates always have their origin at the top left hand corner +of the screen, but the digitizer has no such constraint - its origin, orientation +and scaling are generally different from the screen coordinate system. This +means that the digitizer needs to be calibrated so that digitizer coordinates +can be translated to screen coordinates.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F7249C66-B62F-45DF-B733-BC6D5FCDA003.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-F7249C66-B62F-45DF-B733-BC6D5FCDA003.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,33 @@ + + + + + +Completion and NotificationThis document describes how a device driver notifies completion +of an asynchronous request. +

On completion of the request, the driver calls Kern::RequestComplete(), +passing the TRequestStatus object and completion error code, +to notify the request completion to the user. This API internally sets the +passed error code in the TRequestStatus object. It also signals +the client's thread semaphore.

+void DExDriverLogicalChannel::DoTxDataComplete() + { + ... + // Notify the client (iClient) that the request is completed. The + // TRequestStatus object is updated with the status and the + // completion code is provided to the client. Typically, the client + // thread, waiting using User::WaitForRequest(TRequestStatus + // &aStatus) or the active object framework, is unblocked and + // notified. Then the client may read the request status from the + // TRequestStatus object. + // + Kern::RequestComplete(iClient,iTxDataStatus,iTxResult); + } +

The user retrieves the result of the request by calling TRequestStaus::Int().

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F75F975B-A490-4EB5-96CD-B2F8DFC63C7C.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-F75F975B-A490-4EB5-96CD-B2F8DFC63C7C.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,35 @@ + + + + + +Asynchronous +RequestsThis document describes how device drivers use asynchronous requests. +

An +asynchronous request is one which is used, typically, to communicate with +the hardware itself. The time taken for such a request to complete depends +on the hardware, and the client user-side thread may want to continue with +some other processing. The user-side thread is not blocked and can continue +with other operations, including issuing other requests (synchronous or asynchronous).

An +asynchronous request is started by a call to RBusLogicalChannel::DoRequest(). +Control normally returns as soon as the request has been issued, successfully +or otherwise. Typically, the hardware indicates completion of an operation +by generating an interrupt. This is handled by an Interrupt Service Routine +(ISR) provided by the driver. This, in turn, schedules a DFC, which at some +later time, runs in the context of a kernel-side thread, and signals the client-user +side thread, marking the asynchronous request as complete.

More than +one asynchronous request can be outstanding at the same time, each one associated +with its own TRequestStatus object and each identified +by a specific request number. The device driver framework puts no explicit +limit on the number of concurrent outstanding asynchronous requests; any limit +must be enforced by the driver itself. However, the API to cancel a request +implicitly prevents you from uniquely identifying more than 32 concurrent +requests.

An outstanding asynchronous request can be cancelled by +a call to RBusLogicalChannel::DoCancel().

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F7ABA3C6-60DD-4AE1-916B-BE2BCF6285CE-master.png Binary file Adaptation/GUID-F7ABA3C6-60DD-4AE1-916B-BE2BCF6285CE-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F7ABA3C6-60DD-4AE1-916B-BE2BCF6285CE_d0e89266_href.png Binary file Adaptation/GUID-F7ABA3C6-60DD-4AE1-916B-BE2BCF6285CE_d0e89266_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F7ABA3C6-60DD-4AE1-916B-BE2BCF6285CE_d0e91217_href.png Binary file Adaptation/GUID-F7ABA3C6-60DD-4AE1-916B-BE2BCF6285CE_d0e91217_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F84E18B8-5883-5A3A-A9DB-EC25BB86149F.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-F84E18B8-5883-5A3A-A9DB-EC25BB86149F.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,42 @@ + + + + + +TimersThe kernel implements timing functions using a 1 millisecond +tick timer. +

The phone hardware must therefore provide a high-speed timer that +can provide regular 1 ms interrupts. The ASSP/Variant part of the +base port must use this timer hardware to call the kernel every millisecond.

+

The base port provides the timer service in an interrupt-service +routine called a tick handler. The functions used for this are as +follows:

+
    +
  • The tick handler +must be started by the Variant's implementation of the Asic::Init3() function.

  • +
  • The tick handler +calls the kernel's NTImer::TickQ() function.

  • +
  • The Variant +reports the exact number of microseconds between ticks in its implementation +of Asic::MsTickPeriod().

  • +
+

The ASSP/Variant must decide how to implement a repeating tick +interrupt for the hardware available. Typically this involves using +either a free running timer with a match register, which is reset +on each match, or a self-reloading countdown timer, to generate a +periodic interrupt.

+

A base port can implement other timers that are required by peripherals +that have sub-millisecond timing requirements. This is optional, and +depends on the available hardware.

+
+ +Asic::Init3() implementation +Symbian OS Internals - Chapter 5.5 Timers + +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F8A32666-5003-5B14-A700-C6E6388D2D38-master.png Binary file Adaptation/GUID-F8A32666-5003-5B14-A700-C6E6388D2D38-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F8A32666-5003-5B14-A700-C6E6388D2D38_d0e63938_href.png Binary file Adaptation/GUID-F8A32666-5003-5B14-A700-C6E6388D2D38_d0e63938_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F8B8C030-B5E1-5EB3-A672-83BF35555801.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-F8B8C030-B5E1-5EB3-A672-83BF35555801.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,38 @@ + + + + + +halcfg.pl +Syntaxhalcfg.pl is a Perl script that is used by +the build system to generate the C++ source files from the Config and Values +files. +

+

There are four modes in which the Perl script halcfg.pl can +be used.

+
    +
  • perl halcfg.pl hal_data.h values.hda values.cpp

    takes the values.hda text file and generates a table +of initial values for items stored by the HAL.

  • +
  • perl halcfg.pl -x hal_data.h config.hcf config.cpp

    generates three tables:

      +
    • the properties, i.e. +whether valid and/or writable, for each item

    • +
    • the offset of each item +within the DllGlobal block

    • +
    • the function implementing +each item, for derived attributes (i.e. those attributes that are not simply +stored by the HAL.

    • +
  • +
  • perl halcfg.pl -s hal_data.h config.hcf source.cpp

    generates a source file containing skeleton code for the implementation +of the accessor function for each derived attribute

  • +
  • perl halcfg.pl -h hal_data.h config.hcf header.h

    generates a header file containing prototypes for the accessor functions +for each derived attribute

  • +
+

Note that the header file hal_data.h containing the +attributes and values used by the HAL is passed on all calls to the Perl script.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F8BD699A-E926-5434-9F35-3DC6DC9FFBB6.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-F8BD699A-E926-5434-9F35-3DC6DC9FFBB6.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,43 @@ + + + + + +BuildThis topic describes how to include the ported driver in +a ROM. +

The USB client driver, EUSBC.LDD, and the +USB client controller, USBCC.DLL (the PDD) and +any other required component (a USB transceiver DLL) must be added +to the ROM image by adding suitable definitions to the ROM .oby files. In the template port add definitions to two +files:

+
    +
  • the kernel.iby file in ...\template_variant\rom\, if building a text-shell ROM image; it contains the lines:

    // USB Client +device[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\USBC.LDD \sys\bin\EUSBC.LDD +// USB Device Driver +extension[VARID]= \Epoc32\Release\##KMAIN##\##BUILD##\_##VARIANT##_USBCC.DLL \sys\bin\USBCC.DLL +
  • +
  • the base_template.iby file in ...\template_variant\rom\, if building a full ROM image; it contains the lines:

    // USB Drivers +extension[VARID]=KERNEL_DIR\DEBUG_DIR\_template_usbcc.dll \sys\bin\usbcc.dll +device[VARID]= KERNEL_DIR\DEBUG_DIR\usbc.ldd \sys\bin\eusbc.ldd +
  • +
+

Add the command line test applications. This can be done in a special +purpose .oby file which is used to create the +text shell, test ROM image:

+FILE=/EPOC32/RELEASE/ARMV5/UREL/T_USB.EXE SYS\BIN\T_USB.EXE +FILE=/EPOC32/RELEASE/ARMV5/UREL/T_USBAPI.EXE SYS\BIN\T_USBAPI.EXE + + Both these test applications are also pulled in by default +by the standard e32tests.oby file. +

The macro EUSBC needs to be defined +for the base port to pull in the user-mode components (e.g. USBMan) for a full ROM image. For template, this is done +in ...\template_variant\template.oby:

+REM Define whether or not to include USB client support: +#define EUSBC +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F8E8CCB1-E239-5285-BA99-48E2168C9E31.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-F8E8CCB1-E239-5285-BA99-48E2168C9E31.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,35 @@ + + + + + +ReferenceProvides a summary of related documentation for the Serial Port +Driver to which you can refer. +
API Reference

Kernel +Architecture

+ + + +

Item

+

Header

+
+ +

DComm

+

comm.h

+
+ +

TStopMode

+

comm.h

+
+ + +
+
Engineering Specifications

No specifications are +published.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F9051D21-3E4C-4645-BD04-06606E849AEF.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-F9051D21-3E4C-4645-BD04-06606E849AEF.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,66 @@ + + + + + +Interrupt Interface OverviewProvides a summary of the Interrupt platform service interface. +

The Interrupt interface is provided by functions of the Interrupt class. The class is defined in the os/kernelhwsrv/kernel/eka/include/kernel/arm/assp.h file. +The Interrupt class functions must be implemented +by the baseport variant to enable device drivers and other kernel +side code to handle the interrupts.

+
+ Interrupt handling functions + + + +API +Description + + + + +Interrupt::Bind(TInt anId, TIsr anIsr, TAny* aPtr) +Allows an Interrupt Service Routine (ISR) to be associated +with a specified interrupt ID in the anId parameter. + + +Interrupt::Unbind(TInt anId) +Unbinds an ISR from a specified interrupt ID. + + +Interrupt::Enable(TInt anId) +Enables a specified interrupt to be active and allows the associated +ISR to handle the interrupts. + + +Interrupt::Disable(TInt anId) +Disable a specified interrupt. + + +Interrupt::Clear(TInt anId) +Clears the interrupt pending condition in the interrupt controller +hardware. + + +Interrupt::SetPriority(TInt anId, TInt aPriority) +Change the priority of a specified interrupt. + + +Interrupt::AddTimingEntropy() +Adds high resolution timestamp to the interrupt. This function +should be called by the device driver where the timing of the interrupts +are considered to be random. + + + +

The header file for the Interrupt platform service can +be found here.

The Interrupt platform service is +only used to associate an interrupt with an ISR. The Interrupt platform +service is not used to dispatch interrupts.
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-F9558573-7C79-57C5-809A-9257BF84758A.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-F9558573-7C79-57C5-809A-9257BF84758A.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,65 @@ + + + + + +ArchitectureThis topic describes the architecture of keyboard drivers +and related components. +

This topic describes the architecture of keyboard drivers and related +components on Symbian platform.

+

There are five components involved in this process:

+
    +
  • The keyboard +hardware.

  • +
  • A keyboard +device driver.

    The keyboard driver is implemented as a +standard kernel extension, and is loaded by the kernel at boot time. +A keyboard driver must be implemented in the base port, and has no +platform independent parts.

  • +
  • A keyboard +mapping DLL.

    A keyboard mapping DLL provides a set of +lookup tables that map codes for the hardware keys to standard logical +keycodes that user-side applications can process.

    The DLL +is platform specific. It must be implemented in the base port, and +has no platform independent parts. It is usually called ekdata.dll.

  • +
  • The Window +Server.

    The Window Server is a system server that manages +access to the screen and input devices for user-side programs.

  • +
  • The keyboard +translator.

    The keyboard translator DLL translates scancodes +into keycodes using the data in the platform specific keyboard mapping +DLL.

    It is part of Symbian platform generic code and is built +as part of the Text Window Server component.

  • +
+

The following diagram shows how these components fit together and +gives an overview of the data flow.

+ +Overview of data flow + + +

Depending on the keyboard hardware, key presses in the form of +key-down and key-up events are registered by the keyboard driver, +either as a result of hardware interrupts, or as a result of polling +the hardware. The driver assigns a standard scancode value to the +key. This is one of the values defined by the TStdScanCode enum. The value is a representation of the hardware key.

+

The driver creates TRawEvent objects, of type TRawEvent::EKeyUp and TRawEvent:EKeyDown, and includes the standard scancode value and modifiers as part +of the object. These objects are added to the kernel's event queue, +using the Kern::AddEvent() function.

+

The Window Server captures these events and passes the scancode +value to ektran.dll, which has the responsibility +for translating this value into a keycode value. A keycode value is +a logical representation of the key; it is this logical representation +that has meaning for the generic Symbian platform. The logical keycode +is one of the values defined by the TKeyCode enum. +Also, ektran.dll tells the Window Server whether +a capture key has been pressed - this is explained in Dynamic Behaviour.

+

ekdata.dll encapsulates a set of tables that +are used to map hardware scancodes to logical keycode values. This +is platform specific code, and is used by the generic ektran.dll when doing the translation.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-FA026EBD-7867-4A2C-9FA4-EC70A5243526.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-FA026EBD-7867-4A2C-9FA4-EC70A5243526.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,193 @@ + + + + + +Transferring Data with DMAExplains how to transfer data using DMA. +

The client +will typically have a DMA class containing pointers to:

    +
  • a TDmaChannel object,

  • +
  • one or more DDmaRequest objects,

  • +
  • a TDfcQueue object, and

  • +
  • a callback which returns when the data transfer completes (successfully +or not).

  • +

These classes are discussed in DMA OS Interface.

+

To allow +a client application to receive or transmit a block of data by DMA +you set up a transfer between a source or a destination buffer and +a source or a destination peripheral. Data is copied between the client +process and kernel memory by IPC form data transfer between two buffers. +When a shared chunk or a shared data buffer is used, copying of data +to kernel memory is required. At the level of implementation there +is no difference between receiving and transmitting. Client drivers +using DMA sometimes have separate receive and transmit functions defined +from the driver point of view.

You transfer data in this sequence:

    +
  • Open a DMA channel.

  • +
  • Fragment the data if necessary.

  • +
  • Queue the transfer.

  • +
  • Close the channel.

  • +

Example code in this tutorial is taken from the DMemoryCardDma class which transfers data to and from MMC cards by DMA.

+ +Initialize +the client object by allocating a request and setting buffers. + //pre-allocate space for DDmaRequest + iDMARequest = (DDmaRequest*)Kern::AllocZ(sizeof(DDmaRequest)); + + // Check Buffer Length + if (aBuffLen) + { + // Set Buffer Start + iBufferStart = (TUint32)aBuffer; + // Set Buffer End + iBufferEnd = iBufferStart + aBuffLen; + // Set DFC Queue + iDfcQue = aDfcQue; + + return KErrNone; + } + +The client object is now initialized. + +Open the +channel by creating an SCreateInfo object and initializing +it as follows: + +Set the iCookie member to a platform specific channel identifier. + +Set the iDesCount member to the number of descriptors the channel +can use. +

The value should be set to a value based on number of simultaneous +transfers, transfer length and type of memory used for transfer. If +you select too high a value, no descriptors will be left for other +clients, and if you select too low a value the transfer may fail.

+
+Set the iDfcPriority member to the DFC priority. + +Set the iDfcQueue member to the client class queue: it will be +used to service transfer completion events. + +
+ // Open and configure the channel + if (!iDMAChannelOpen) + { + if (!iDfcQue) + return KErrGeneral; + + TDmaChannel::SCreateInfo info; + + info.iCookie = (TUint32)iChannelId; + info.iDesCount = 3; + info.iDfcPriority = 3; + info.iDfcQ = iDfcQue; + + +The channel is now initialized. +
+Pass the SCreateInfo object and a channel ID to the Open() function of TDmaChannel to open a DMA channel. +

This is not necessary if the channel is already open due +to a previous transfer request by the same application on the same +channel.

+ // Open DMA Channel + r = TDmaChannel::Open(info, iDMAChannel); + + if (r) + return r; + + // Set DMA Channel Open + iDMAChannelOpen = ETrue; + +At what point you open the channel depends on platform configuration. +If a channel is dedicated to a particular function such as USB, it +is typically opened by the channel constructor method and closed by +the destructor as there is never any contention for it. In other cases, +you must open the channel at the start of a transfer and close it +at the end. +The channel is now open. +
+Call the Fragment() function of DDmaRequest to +fragment the data. +:If your buffers are cacheable you must flush them before a +write transfer and both before and after a read transfer, using these +functions of the Cache class:
    +
  • Cache::SyncMemoryBeforeDmaWrite() (takes source +buffer as argument)

  • +
  • Cache::SyncMemoryBeforeDmaRead() (takes destination +buffer as argument)

  • +
  • Cache::SyncMemoryAfterDmaRead() (takes destination +buffer as argument)

  • +
+The data is now fragmented. +
+Call the Queue() function of TDmaChannel to queue +the data on the channel. + TInt retval = KErrNone; + + if (iDMABusy) + { + if (iDMAChannel) + { + iDMAChannel->CancelAll(); + } + } + + iDMABusy = ETrue; + + iDMAReadStarted = EFalse; + + if (!iDMAChannelOpen) + { + retval = Open(); + } + + if (iDMAChannelOpen) + { + iDMADestination = aDest; + iDMACount = aCount; + + // aDest cached, ivalidate RAM + Cache::SyncMemoryBeforeDmaRead(aDest, aCount); + retval = iDMARequest ? iDMARequest->Fragment(EDmaSDMMC, aDest, aCount, KDmaMemDest | KDmaIncDest, 0 /* no HW Flags*/) : KErrGeneral; + + if (retval) + { + return retval; + } + + iDMAReadStarted = ETrue; + if (iDMARequest) + { + iDMARequest->Queue(); + } + } + +

The data is now queued on the channel.

+
+Close the +channel. First check whether the channel is busy and take appropriate +action if it is (in the following example code you cancel all pending +transfers). Then call the Close() function of TDmaChannel. + if (iDMAChannelOpen && iDMAChannel && !iDMABusy) + { + iDMAChannel->CancelAll(); + iDMARequestsCount = 0; // All DMA requests have been now canceled! + + if (iDMARequest) + { + //just call destructor explicitly and the object can reused + iDMARequest->~DDmaRequest(); + } + ... + iDMAChannel->Close(); + +

The channel is now closed.

+
+
+

You have +now conducted a data transfer by DMA.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-FB063C1A-EF9F-4292-827F-A3DBC7C7F13A.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-FB063C1A-EF9F-4292-827F-A3DBC7C7F13A.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,16 @@ + + + + + +Adaptation GlossaryThis section provides definitions of terms that are commonly +used in the adaptation documentation. +
+
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-FB69F45C-2256-5F2D-8D2C-98C93B865962-master.png Binary file Adaptation/GUID-FB69F45C-2256-5F2D-8D2C-98C93B865962-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-FB69F45C-2256-5F2D-8D2C-98C93B865962_d0e14972_href.png Binary file Adaptation/GUID-FB69F45C-2256-5F2D-8D2C-98C93B865962_d0e14972_href.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-FBE6E61F-5A2E-5A7A-BC59-51F072EBED7D.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-FBE6E61F-5A2E-5A7A-BC59-51F072EBED7D.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,68 @@ + + + + + +Media +Driver Migration GuideDescribes the issues that need to be considered, when migrating +media drivers to a writable data demand paging environment. +
Purpose

This +document explains the points that have to be considered when migrating existing +media drivers to a writable data paging environment.

+
Issues Involved

The +two main issues that have to be addressed when migrating existing media drivers +are:

    +
  • A deadlock condition +can occur between the driver and the client process, where both are trying +to access the same page of paged memory

  • +
  • A deadlock condition can occur between the driver and the client process, +where the client is allocating on the kernel heap, the paging system tries +to page out some data and the media driver also tries to allocate on the kernel +heap while servicing the resulting request.

  • +
  • Unpredictable delays +in servicing a DFC can occur, since memory might need to be paged in.

  • +

To address the above issues, the following points will have to be +considered/undertaken:

    +
  • Pass data by value to +DoRequest/DoControl

  • +
  • Return results by using +a return code

  • +
  • Use of a dedicated DFC +queue

  • +
  • Determine if unpredictable +delays in servicing DFCs are acceptable

  • +
  • Validate the arguments +in the client context as far as possible

  • +
  • Move user memory accesses +to client context where possible

  • +
  • Replace the use of small +fixed-size structures with the use of the TClientDataRequest object

  • +
  • Pin user memory accessed +from DFCs

    Do not allocate on the kernel heap while handling page out +requests.

    The paging algorithm can be over ridden and pages of memory +can be kept in memory (pinned). This situation can be reversed by 'unpinning' +the page. The TClientBufferRequest API provides this functionality.

  • +
  • Re-write the driver +to use shared chunks

  • +
  • No fast mutex may be +held when calling APIs that access user memory

  • +
  • No kernel mutex may +be held

  • +
  • Use the new APIs, (See +the Writable Data Paging +Overview ).

  • +
+
See +also
    +
  • Device +Driver Writing and Migration Guide

    This document explains +techniques for writing device drivers on data paged systems and migrating +device drivers to data paged systems.

  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-FCCF9634-0610-5199-A37A-CF2EC9B73261.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-FCCF9634-0610-5199-A37A-CF2EC9B73261.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,112 @@ + + + + + +Adaptation Quick StartAdaptation involves extending software on the device to +support a given hardware component. +
Adaptation +environment

The functionality of a particular hardware +technology is enabled when an interface to the standard for that technology +is defined.

The hardware is enabled when the following exist:

    +
  • LDD – Logical +Device Driver

  • +
  • PDD – Physical +Device Driver

  • +
+
Kernel +extensions

Kernel extensions provide additional functionality +in the kernel and run with the same access rights and permissions +as the rest of the kernel.

Adaptation device drivers (LDD/PDD) +require low-level access to the device and implementing them as a +kernel extension gives them this access.

LDD

Each LDD has the following features:

    +
  • the LDD is a +packaged DLL

  • +
  • provides user +side functionality

  • +
  • loaded into +the kernel

  • +
  • calls a function +that opens a DLogicalChannel

  • +
  • opens an RBusLogicalChannel

  • +
  • allows user +code to communicate with the hardware and send commands to control +the hardware

  • +
  • defines an abstract +class that must be implemented in the PDD

  • +

Mandatory – there must be one LDD for each hardware component.

PDD

PDDs have the following features:

    +
  • the PDD is a +packaged DLL

  • +
  • provides access +to hardware

  • +
  • loaded into +the kernel

  • +
  • calls a function +that opens a physical channel

  • +
  • receives control +commands and other communications through its interface with the LDD

  • +
  • may be an extension +to an existing device driver

  • +

Mandatory – there must be one PDD for each hardware platform +for each hardware component.

+
Using +Kernel extensions

A Kernel Extension is additional functionality +that runs as part of the kernel.

For example, access to the +SD Card is provided through a kernel extension.

Adaptation ready architecture

Adaptation ready architecture +means the following have been created:

    +
  • The LDD

  • +
  • The abstract +class that must be implemented in the PDD

  • +
  • The interface +to the user code

  • +
  • Any optional +kernel extension DLLs

  • +
  • Optional reference +implementation PDD

  • +

Adaptation options

There are broadly two types of hardware adaptation:

    +
  • New hardware

  • +
  • Updated hardware

  • +

New hardware

The entire adaptation architecture, +as described above, must be defined. This includes:

    +
  • Defining an +abstract class that the PDD creators are required to implement, creating +an LDD and so on.

  • +
  • The architecture +enables the new hardware.

  • +
  • The architecture +allows hardware manufacturers to create their own implementation (PDD).

  • +

New hardware adaptation will be supported with a reference +implementation, which will go a long way towards guiding the device +developer’s efforts.

Updated hardware

Updated +hardware which provides new or modified functionality requires a new +PDD to be created to either extend the functionality of the existing +PDD or to replace the existing PDD.

In most cases the new +functionality of the hardware will be enabled by extending the architecture +with a new extension PDD or be writing a new PDD that incorporates +all the existing and new functionality.

There are situations +where the entire adaptation architecture needs to be extended or redesigned, +such as when a hardware component is extended in a way that was not +expected. The Bluetooth baseband radio being extended to provide Bluetooth, +802.11, and FM radio from the same hardware component, for example, +will require a redesign of the adaptation architecture so the LDD +knows about 802.11 and FM as well as Bluetooth. Such a redesign should +ensure older Bluetooth PDDs will still work while extending the possible +PDDs that will work with the LDD to include Bluetooth, 802.11, FM +radio, and a combination of the above.

+
Where +to go next

Adaptation is described in more detail in these +documents:

    +
  • What is +Adaptation?
  • +
  • What is +a Platform Service?
  • +
  • Adaptation +Process Guide
  • +
+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-FD8634B8-E522-4AC4-8129-ED807A7754A2-GENID-1-2-1-9-1-5-1-6-1.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-FD8634B8-E522-4AC4-8129-ED807A7754A2-GENID-1-2-1-9-1-5-1-6-1.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,48 @@ + + + + + +Kernel-side +ImplementationThis document describes kernel-side implementation of requests +to device drivers. +

Requests from the user-side are initially handled by the driver +in the context of the client user-side thread. All requests are passed to +the "gateway" function: DLogicalChannelBase::Request(). +This is defined as pure virtual in DLogicalChannelBase, and +needs to be implemented in a derived class as part of your logical channel +implementation.

+ + Device driver logical channel communication + + + +

There are two options for implementing this:

+
    +
  1. Use the ready-made framework +provided by the DLogicalChannel class, which handles a +request in the context of a single kernel-side thread. This framework uses +the kernel-side messaging mechanism for queuing requests on a DFC that runs +in that single kernel-side thread.

    In practice, this model makes the +writing of device drivers easier because the same kernel thread can be used +to process requests from (potentially multiple) user-side clients and DFCs, +thus in effect serialising access to the device driver, and eliminating thread-related +issues, such as the need to know about mutexes, pre-emption, etc. Several +drivers can use the same request/DFC kernel thread to reduce resource usage.

  2. +
  3. Derive your own logical +channel class from DLogicalChannelBase to handle requests. +This allows you to build your own thread model for running DFCs to handle +requests and to handle request completion. This requires that you manage inter-thread +conflicts. However, your design may give you the chance to do some optimisation +by handling some requests in the context of the user-side thread, minimising +context-switching overhead.

  4. +
+

Option 1 lets you get a new driver up and running quickly. Option 2 gives +you greater flexibility if the requirements of your driver demand it.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-FD8634B8-E522-4AC4-8129-ED807A7754A2-GENID-1-2-1-9-1-6-1-9-1-8-1.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-FD8634B8-E522-4AC4-8129-ED807A7754A2-GENID-1-2-1-9-1-6-1-9-1-8-1.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,48 @@ + + + + + +Kernel-side +ImplementationThis document describes kernel-side implementation of requests +to device drivers. +

Requests from the user-side are initially handled by the driver +in the context of the client user-side thread. All requests are passed to +the "gateway" function: DLogicalChannelBase::Request(). +This is defined as pure virtual in DLogicalChannelBase, and +needs to be implemented in a derived class as part of your logical channel +implementation.

+ + Device driver logical channel communication + + + +

There are two options for implementing this:

+
    +
  1. Use the ready-made framework +provided by the DLogicalChannel class, which handles a +request in the context of a single kernel-side thread. This framework uses +the kernel-side messaging mechanism for queuing requests on a DFC that runs +in that single kernel-side thread.

    In practice, this model makes the +writing of device drivers easier because the same kernel thread can be used +to process requests from (potentially multiple) user-side clients and DFCs, +thus in effect serialising access to the device driver, and eliminating thread-related +issues, such as the need to know about mutexes, pre-emption, etc. Several +drivers can use the same request/DFC kernel thread to reduce resource usage.

  2. +
  3. Derive your own logical +channel class from DLogicalChannelBase to handle requests. +This allows you to build your own thread model for running DFCs to handle +requests and to handle request completion. This requires that you manage inter-thread +conflicts. However, your design may give you the chance to do some optimisation +by handling some requests in the context of the user-side thread, minimising +context-switching overhead.

  4. +
+

Option 1 lets you get a new driver up and running quickly. Option 2 gives +you greater flexibility if the requirements of your driver demand it.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-FDAED7A7-3D93-5B57-9879-DF8BDBE8A9BD.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-FDAED7A7-3D93-5B57-9879-DF8BDBE8A9BD.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,14 @@ + + + + + +Load and Open a USB Channel Before configuration the Logical Device Driver (LDD) must be loaded and opened.
Load the USB LDD

Before a channel can be opened the Logical Device Driver (LDD) must be loaded. Load a logical device using User::LoadLogicalDevice() passing it the file name of the LDD you wish to load.

_LIT(KLddName, "eusbcsc.ldd"); +TInt r = User::LoadLogicalDevice(KLddName);
Open a USB Channel

Open your USB channel using the LDD open function RDevUsbcScClient::Open().

RDevUsbcScClient gPort; +TInt r = gPort.Open(0);

After you have loaded and opened the USB LDD you should Set the Configuration Descriptors.

\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-FE36E7DE-7C2C-415B-BB2F-22D9E2BE49A6.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-FE36E7DE-7C2C-415B-BB2F-22D9E2BE49A6.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,41 @@ + + + + + +Configuration StorageThe Hardware Configuration Repository (HCR) can be used +to hold configuration information for DMA. +

There are two places where you may want to consider using a registry +to hold information for DMA.

    +
  1. Chipset configuration

  2. +
  3. Channel configuration +and information.

  4. +

+
Chipset +configuration

On initialization of the chipset you can store +and retrieve settings in the HCR.

In the DMA Implementation +Guide there are links to a sample implementation in which no +chipset configuration is required or specified.

+
Channel +configuration and information

When a client opens a channel, +it specifies a cookie parameter in the DmaChannelMgr::Open() function. This cookie is used by the DMA implementation to identify +a specific channel on a specific DMA controller. This is entirely +chipset and implementation specific and the client will need to know +what cookie values can be used to request a channel.

One way +that the implementation can communicate this information to the client +is by using the Central Repository to hold a table of cookie values +and matching channel identification. An alternative approach may be +to use a Central Repository entry to specify the number of channels +available and then the client knows the highest channel number it +can request.

Again this is entirely implementation specific. +In the implementation mentioned above, the repository is not used.

+
+HCR +Platform Service +
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-FE77CDFC-B66B-485B-A94D-F646894FD330.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Adaptation/GUID-FE77CDFC-B66B-485B-A94D-F646894FD330.dita Fri Oct 15 14:32:18 2010 +0100 @@ -0,0 +1,102 @@ + + + + + +Time Interface GuideProvides a summary of Time platform service interface. +

The Time platform service interface is provided by the MRtcAdaptation class. The class is defined in the os/devicesrv/sysstatemgmt/systemstatemgr/inc/ssmadaptation.h header file.

+
+ Interface classes + + + +Class +Description + + + + +MRtcAdaptation +Provides the interface between the Real Time Clock (RTC) and +the upper layers of the operating system. + + +ASIC +Provides an interface to the Application Specific Integrated +Circuit (ASIC) that is being used. + + + +
+
Time +adaptation functions

The following functions should be implemented +to provide the Time platform service functionality.

+ + + +API +Description + + + + +MRtcAdaptation::ValidateRtc(TDesc8& aValidityPckg, +TRequestStatus aStatus) +Check the real time clock implementation is valid. + + +MRtcAdaptation::SetWakeupAlarm(TDesC8& aAlarmTimePckg, +TRequestStatus& aStat) +Set a device wakeup alarm time in UTC. + + +MRtcAdaptation::UnsetWakeupAlarm(TRequestStatus& +aStatus) +Delete the device wakeup alarm. + + +MRtcAdaptation::Cancel() +Cancel any outstanding request to the real time clock. + + +MRtcAdaptation::Release() +Deletes and release the allocated memory. + + + +

The above function calls will return KErrNotSuported +in an emulator.

+
ASIC +functions

The functions related to the Time platform service +in the ASIC class.

+ + + +API +Description + + + + +ASIC::SetSystemTimeCalibration() +Set the real time clock by specifying the time calibration +in parts per million. + + +ASIC::SystemTimeInSecondsFrom2000(TInt) +Get the system time in seconds from the year 2000. + + +ASIC::SetSystemTimeInSecondsFrom2000(TInt) +Set the system time to 0 from the start the year 2000. + + + +

The header file for the Time platform service can be found here.

+
\ No newline at end of file diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-FF2ABA1D-1F71-5A9C-AFD5-A0CED39BFD86-master.png Binary file Adaptation/GUID-FF2ABA1D-1F71-5A9C-AFD5-A0CED39BFD86-master.png has changed diff -r 578be2adaf3e -r 307f4279f433 Adaptation/GUID-FF2ABA1D-1F71-5A9C-AFD5-A0CED39BFD86_d0e39571_href.png Binary file Adaptation/GUID-FF2ABA1D-1F71-5A9C-AFD5-A0CED39BFD86_d0e39571_href.png has changed