diff -r 89d6a7a84779 -r 25a17d01db0c Symbian3/PDK/Source/GUID-124AC7EE-E227-5358-A755-628FFE257250.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Symbian3/PDK/Source/GUID-124AC7EE-E227-5358-A755-628FFE257250.dita Fri Jan 22 18:26:19 2010 +0000 @@ -0,0 +1,176 @@ + + + + + +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 accessor functions; see the +overall picture.

It's useful to note that a single HAL handler +may end up being called as a result of calls to different accessor functions. +For example, ProcessDisplayCurrentModeInfo() and GetBacklightPresent() are +accessor 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: groups and the location of +their HAL handlers and Cross +reference: attribute --> group/function-id/capabilities for the full +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