Adaptation/GUID-A87D9280-B61A-49BA-A9AF-178DB9BAECBC.dita
changeset 15 307f4279f433
equal deleted inserted replaced
14:578be2adaf3e 15:307f4279f433
       
     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-A87D9280-B61A-49BA-A9AF-178DB9BAECBC" xml:lang="en"><title>Reading and Writing</title><shortdesc>This document describes how device drivers should open, read from
       
    13 and write to shared chunks.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
       
    14 <p>Both user-side code and drivers can read and write to shared chunks. Once
       
    15 the chunk is created, opened, and memory committed to it, data can be written
       
    16 and read to the shared chunk using the base address. </p>
       
    17 <section id="GUID-4CF7C47A-24D2-4D6D-B577-F0351178CA38"><title>Opening</title> <p>If a shared chunk has already been created
       
    18 by a driver, then another driver can access that shared chunk through its
       
    19 handle by using one of the following functions: </p> <codeblock id="GUID-EB073A6D-5DC3-5572-BD7C-E96F63BB8DCF" xml:space="preserve">DChunk* Kern::OpenSharedChunk(DThread* aThread, TInt aChunkHandle,
       
    20                     TBool aWrite);
       
    21 
       
    22 DChunk* Kern::OpenSharedChunk(DThread *aThread, 
       
    23                     const TAny *aAddress, TBool aWrite, 
       
    24                     TInt &amp;aOffset);
       
    25 </codeblock></section>
       
    26 <section id="GUID-95D166D2-C6BE-45F5-84E7-6F5ACB1BFA38"><title>User-side access</title> <p> <xref href="GUID-326A2F4D-0E99-31C0-A35D-E8BF45913F07.dita"><apiname>RChunk</apiname></xref> is
       
    27 the user side representation of a shared chunk. The user gets a shared chunk
       
    28 handle from a driver, and initialises the <codeph>RChunk</codeph> object with
       
    29 it using <codeph>RChunk::SetHandle(TInt aHandle)</codeph>. </p> <p>The user
       
    30 can now obtain the base address of the chunk by calling <xref href="GUID-326A2F4D-0E99-31C0-A35D-E8BF45913F07.dita#GUID-326A2F4D-0E99-31C0-A35D-E8BF45913F07/GUID-D19E68E8-3C5F-3F97-80F2-B2F80A814A80"><apiname>RChunk::Base()</apiname></xref>.
       
    31 Data can be read or written to this memory location, in same way as any other
       
    32 memory. </p> <codeblock id="GUID-E0F57FBB-1F43-564F-8350-A49B6AFEE3F1" xml:space="preserve">// User side chunk object.     
       
    33  RChunk chunkTx; 
       
    34      
       
    35 // Get the handle to the chunk. A driver creates the chunk and
       
    36 // returns the handle to the user to access it. The handle is  
       
    37 // assigned to the user side chunk object using RChunk::SetHandle(). 
       
    38 // (here done in the GetTxChunkHandle function). The handle has to be a positive 
       
    39 // value. It can be obtained using RChunk::Handle(), if required.
       
    40 //
       
    41 r=ldd.GetTxChunkHandle(chunkTx);     
       
    42 test(r==KErrNone);        
       
    43      
       
    44 // Create a constant descriptor with test data
       
    45 _LIT8(KTestSendData,"&lt;&lt; TEST DATA FOR TUTORIAL DRIVER EXAMPLE &gt;&gt;");
       
    46      
       
    47 TUint8* chunkbase;
       
    48 // Retrieve the base address of the chunk. Using this address, the user 
       
    49 // can access the shared chunk just like any memory pointer. 
       
    50 // RChunk::Base() returns the linear address of the shared chunk.
       
    51 //
       
    52 chunkbase=chunkTx.Base(); 
       
    53     
       
    54 // Write the data to the shared chunk, using the chunk base address.
       
    55 // Note here we do not need to send data to the driver. We just write to 
       
    56 // the buffer and the driver directly accesses the chunk from the kernel side.
       
    57 //
       
    58 TPtr8 inbuf(chunkbase,KTestSendData().Size());
       
    59 inbuf = KTestSendData;
       
    60
       
    61 
       
    62 // Call the LDD interface TransmitData(). There is no need to send the 
       
    63 // data, instead we send only a TRequestStatus object (as it's an  
       
    64 // asynchronous function), and buffer size. If required, an offset in the shared chunk 
       
    65 // can be passed to the driver.
       
    66 r = ldd.TransmitData(txStatus,inbuf.Size());
       
    67  test(r==KErrNone);</codeblock> </section>
       
    68 <section id="GUID-5524489D-37FB-41CF-BC87-540569FF943F"><title>Kernel-side access</title> <p>On the kernel side, a chunk
       
    69 is represented by a <xref href="GUID-85454082-6734-3F1D-983F-734D4C2AB12D.dita"><apiname>DChunk</apiname></xref> object. A chunk is created,
       
    70 mapped, or opened as shown in earlier sections. The linear and physical addresses
       
    71 of the chunk are returned when this is done. At a later stage in the driver,
       
    72 use <xref href="GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D.dita#GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D/GUID-626CCD99-63D8-322A-A807-9DB96523C82D"><apiname>Kern::ChunkAddress()</apiname></xref> and <xref href="GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D.dita#GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D/GUID-79F110C1-2764-34B5-857B-6C0012D2049D"><apiname>Kern::ChunkPhysicalAddress()</apiname></xref> to
       
    73 get the linear and physical addresses respectively. A chunk is read or written
       
    74 to using this address pointer and an offset. </p> <codeblock id="GUID-1E341298-F67A-5A21-8C21-405E1BB97946" xml:space="preserve">// Note: Following lines of code are located in different 
       
    75 // functions and different files. Here they are shown together for 
       
    76 // easy comprehension.
       
    77 
       
    78 // Linear address of the Rx Shared chunk
       
    79 TLinAddr iRxChunkKernAddr;
       
    80 ...
       
    81 
       
    82 // iRxChunkKernAddr returns the linear address of the Rx chunk
       
    83 TInt r=Kern::ChunkCreate(info,chunk,iRxChunkKernAddr, mapAttr);
       
    84 ...
       
    85 
       
    86 // iRxBufPhysAddr returns the physical address of the Rx chunk
       
    87 r=Kern::ChunkCommitContiguous(chunk, bufoffset, size, iRxBufPhysAddr);
       
    88 ...
       
    89 
       
    90 // Here we are directly using the linear address of the shared 
       
    91 // chunk, and so can get rid of any buffer copies. If the DMA 
       
    92 // port supports physical address, then the physical address can be
       
    93 // used instead of a linear address.
       
    94 // 
       
    95 TInt retval = iRxDmaRequest-&gt;Fragment(
       
    96             TUint32)iUartComm-&gt;iPortAddr+KHoUART_RHR,
       
    97             TUint32)(iUartComm-&gt;iRxChunkKernAddr), aCount, 
       
    98             KDmaMemDest|KDmaIncDest, 0 /* no HW Flags*/);</codeblock> <p>Synchronization
       
    99 between user access and kernel access to a shared chunk is handled by the
       
   100 shared chunk API. </p></section>
       
   101 </conbody></concept>