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