Symbian3/PDK/Source/GUID-B97BAC2E-04E3-4979-BACE-9C46BADE912E.dita
changeset 1 25a17d01db0c
child 3 46218c8b8afa
equal deleted inserted replaced
0:89d6a7a84779 1:25a17d01db0c
       
     1 <?xml version="1.0" encoding="utf-8"?>
       
     2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
       
     3 <!-- This component and the accompanying materials are made available under the terms of the License 
       
     4 "Eclipse Public License v1.0" which accompanies this distribution, 
       
     5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
       
     6 <!-- Initial Contributors:
       
     7     Nokia Corporation - initial contribution.
       
     8 Contributors: 
       
     9 -->
       
    10 <!DOCTYPE concept
       
    11   PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
       
    12 <concept id="GUID-B97BAC2E-04E3-4979-BACE-9C46BADE912E" xml:lang="en"><title>Deferred
       
    13 Function Calls</title><shortdesc>This document describes how Deferred Function Calls are used to
       
    14 implement asynchronous requests.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
       
    15 <section id="GUID-1F20014A-5F1E-48B3-AEB8-ED1922452A84">   
       
    16    <title>Deferred function calls</title> <p>Asynchronous request processing
       
    17 is normally done in a Deferred Function Call (DFC). The second stage of interrupt
       
    18 handling is deferred to run as a DFC, which runs in a non-critical context. </p> <p>Different
       
    19 asynchronous requests can be handled using a single or multiple DFCs. The
       
    20 number of DFCs to be created must be decided when the driver is designed.
       
    21 For example, a driver that handles at a time an asynchronous receive request
       
    22 and a transmit request would create two DFCs each for receive and transmit. </p> 
       
    23    </section>
       
    24 <section id="GUID-5439E26D-754A-46F3-B607-D229BF5B8A8C"><title>Creation</title> <p>DFCs
       
    25 are created using <xref href="GUID-A14562A5-3E91-3113-AB3C-71DBEA9D58EB.dita"><apiname>TDfc</apiname></xref> objects. </p> <p>The DFC is initialised
       
    26 with a DFC callback function, a pointer to an object to be passed to the callback
       
    27 function, and a priority. It can also provide the DFC queue to be used by
       
    28 this DFC at the time of construction. </p> <codeblock id="GUID-B3918CAB-F168-5992-BFA9-868648D07083" xml:space="preserve">TDfc iRxDfc;
       
    29 iRxDfc(RxDataDfc,this,1); 
       
    30     or
       
    31 iRxDfc(RxDataDfc,this,iDfcQ,1);</codeblock></section>
       
    32 <section id="GUID-886457DF-0DB5-4447-BC9B-EB43060A5C6B"><title>Queuing</title> <p>To
       
    33 initiate the process of DFC functionality, the DFC object must be queued to
       
    34 the DFC queue associated with the Kernel thread. </p> <p>Before adding the
       
    35 DFC to a DFC queue of the thread, it must be associated with the queue (<xref href="GUID-24B2FEDB-9273-351F-A1C6-6F5F91BF83B7.dita"><apiname>TDfcQue</apiname></xref>)
       
    36 object. This can be either done at the time of construction, or can be set
       
    37 later, by calling <xref href="GUID-A14562A5-3E91-3113-AB3C-71DBEA9D58EB.dita#GUID-A14562A5-3E91-3113-AB3C-71DBEA9D58EB/GUID-E3458CD4-7A1C-3FBD-A7FB-488A9C92AE42"><apiname>TDfc::SetDfcQ()</apiname></xref>. </p> <codeblock id="GUID-B57B1C37-A1A5-5C85-AED8-FDD8DBE84280" xml:space="preserve">...
       
    38 // Associate the Tx and Rx DFCs with the same queue set to receive 
       
    39 // the client messages for this driver. SetDfcQ() sets up the DFC 
       
    40 // queue for the DFCs constructed for Tx and Rx
       
    41 //
       
    42 iRxDfc.SetDfcQ(iDfcQ);
       
    43 ...</codeblock> <p> <xref href="GUID-A14562A5-3E91-3113-AB3C-71DBEA9D58EB.dita#GUID-A14562A5-3E91-3113-AB3C-71DBEA9D58EB/GUID-18073EBB-D91B-3AC8-87A2-424AEDD4D7A4"><apiname> TDfc::Add()</apiname></xref> or <xref href="GUID-A14562A5-3E91-3113-AB3C-71DBEA9D58EB.dita#GUID-A14562A5-3E91-3113-AB3C-71DBEA9D58EB/GUID-F6F0C858-8EB2-387B-AE1A-F04B51CE4CED"><apiname>TDfc::Enque()</apiname></xref> is
       
    44 used to add the DFC object to the DFC queue. From an ISR, <xref href="GUID-A14562A5-3E91-3113-AB3C-71DBEA9D58EB.dita#GUID-A14562A5-3E91-3113-AB3C-71DBEA9D58EB/GUID-18073EBB-D91B-3AC8-87A2-424AEDD4D7A4"><apiname>TDfc::Add()</apiname></xref> is
       
    45 used. From a thread, <xref href="GUID-A14562A5-3E91-3113-AB3C-71DBEA9D58EB.dita#GUID-A14562A5-3E91-3113-AB3C-71DBEA9D58EB/GUID-F6F0C858-8EB2-387B-AE1A-F04B51CE4CED"><apiname>TDfc::Enque()</apiname></xref> is used. If preemption
       
    46 is disabled, <codeph>TDfc::Add()</codeph> could also be used. </p> <codeblock id="GUID-9FBB6881-4BA9-534E-86C7-3A0167E9159C" xml:space="preserve">// TDfc::Add() will queue an IDFC or a DFC from an ISR. This function 
       
    47 // is the only way to queue an IDFC and is the only way to queue a 
       
    48 // DFC from an ISR. To queue a DFC from an IDFC or a thread either 
       
    49 // TDfc::Enque() or TDfc::DoEnque() should be used. This function 
       
    50 // does nothing if the IDFC/DFC is already queued.
       
    51 //
       
    52 iRxDfc.Add();
       
    53 </codeblock></section>
       
    54 <section id="GUID-E0B9073A-1554-4085-BE24-E27633B7EDF2"><title>Callback function</title> <p>The
       
    55 DFC callback function is a static function called when a DFC is executed.
       
    56 A pointer to this function is provided at the time of DFC object creation.
       
    57 This function implements the deferred functionality of an asynchronous request,
       
    58 such as reading or writing data from or to an I/O peripheral. It would then
       
    59 either complete the request or start another operation. </p> <codeblock id="GUID-5682EDE1-8397-592D-82CE-78DF11487512" xml:space="preserve">static void RxDataDfc(TAny* aPtr);</codeblock></section>
       
    60 <section id="GUID-A57C3C99-3032-48CD-A800-E9EE7DCDF4E3"><title>Cancellation</title> <p>A
       
    61 DFC function must be cancelled while cleaning up resources, for example, when
       
    62 closing the channel. The function <xref href="GUID-A14562A5-3E91-3113-AB3C-71DBEA9D58EB.dita#GUID-A14562A5-3E91-3113-AB3C-71DBEA9D58EB/GUID-9851B90B-8D05-3C86-B083-44C4564AC140"><apiname>TDfc::Cancel()</apiname></xref> cancels
       
    63 the DFC if it is already queued. It does nothing if a DFC is not queued. It
       
    64 must be called to avoid orphaned DFCs. </p> <codeblock id="GUID-CD926E3D-13E8-51C4-B224-8150FD4D70DB" xml:space="preserve">...
       
    65 // If it is a Transmit request, cancel the Transmit DFC. 
       
    66 // TDfc::Cancel() cancels the DFC if it is already queued. It 
       
    67 // does nothing if DFC is not queued.
       
    68 //
       
    69 iTxDfc.Cancel();
       
    70 ...</codeblock></section>
       
    71 </conbody></concept>