|
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-6DE69F29-45B0-5E62-AA13-DA4041B1BC46" xml:lang="en"><title>Factory |
|
13 Implementation</title><shortdesc>Describes how to implement a factory.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody> |
|
14 <p>The Serial Port Driver PDD must provide a factory class to create channels. |
|
15 The purpose of the PDD factory is to create the physical channel. For the |
|
16 Uart, this is defined by the <codeph>DDriverComm</codeph> class, which is |
|
17 derived from <xref href="GUID-A5484A7F-94B9-34C7-9F88-82B1BF516930.dita"><apiname>DPhysicalDevice</apiname></xref>. The class is defined in the |
|
18 Uart source code: </p> |
|
19 <codeblock id="GUID-15ED5794-BC8A-5CF0-BE5D-8620AFDEDEEA" xml:space="preserve">class DDriverComm : public DPhysicalDevice |
|
20 { |
|
21 public: |
|
22 DDriverComm(); |
|
23 virtual TInt Install(); |
|
24 virtual void GetCaps(TDes8 &aDes) const; |
|
25 virtual TInt Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion &aVer); |
|
26 virtual TInt Validate(TInt aUnit, const TDesC8* anInfo, const TVersion &aVer); |
|
27 }; |
|
28 </codeblock> |
|
29 <p>This implements the four virtual functions that the base class defines, |
|
30 as well as a default constructor. </p> |
|
31 <section id="GUID-5A36A559-CBB6-4495-A1ED-0C4F9289F9B0"><title>Install()</title> <p> <codeph>Install()</codeph> sets |
|
32 the driver name. The name is the way that the physical device is identified. |
|
33 The name is the same as the LDD name, but followed by a dot and a short string |
|
34 to represent the physical device. If you have similar existing source, just |
|
35 copy from there. The function is implemented as: </p> <codeblock id="GUID-6988B583-5060-5CE7-9404-C631C40B188A" xml:space="preserve">TInt DDriverComm::Install() |
|
36 { |
|
37 return SetName(&KPddName); |
|
38 } |
|
39 </codeblock> <p>In the template port, the name is the string <codeph>Comm.Template</codeph>. </p> <p>See |
|
40 also <xref href="GUID-A5484A7F-94B9-34C7-9F88-82B1BF516930.dita#GUID-A5484A7F-94B9-34C7-9F88-82B1BF516930/GUID-0065FAAF-D734-3ED2-816A-CCE9BF607BAB"><apiname>DPhysicalDevice::Install()</apiname></xref> </p> </section> |
|
41 <section id="GUID-CBFB3280-3C16-4F15-A7DB-EDCA278562F6"><title>GetCaps()</title> <p> <codeph>GetCaps()</codeph> returns |
|
42 the capabilities of the physical driver <i>factory</i> (not the driver object). |
|
43 Since driver factories all produce polymorphic objects there is no point in |
|
44 differentiating between them so the function should ignore the passed in descriptor |
|
45 reference. The driver object’s capabilities are returned by the <codeph>DComm</codeph> derived <codeph>Caps()</codeph> function. </p> <p>GetCaps() |
|
46 can be implemented as a stub function, i.e.: </p> <codeblock id="GUID-338ECD13-DD25-55E0-812F-3ED3A49826CD" xml:space="preserve">Void DDriverComm::GetCaps(TDes8& /* aDes */) |
|
47 { |
|
48 }</codeblock> <p>See also <xref href="GUID-A5484A7F-94B9-34C7-9F88-82B1BF516930.dita#GUID-A5484A7F-94B9-34C7-9F88-82B1BF516930/GUID-CA336905-B068-3CFB-80D7-4DF29B92BF4F"><apiname>DPhysicalDevice::GetCaps()</apiname></xref> </p> </section> |
|
49 <section id="GUID-70BBF195-3943-4ABE-9EFB-FCC2BDAC52DD"><title>Validate()</title> <p> <codeph> Validate()</codeph> verifies |
|
50 that the physical driver version is compatible with the caller’s version. |
|
51 This function can be copied in its entirety from any current driver source. |
|
52 It also checks that the unit number used to create a physical channel object |
|
53 is valid, typically checking that the number lies within a valid range. </p> <codeblock id="GUID-03DC2E07-FEBF-5F52-B3A5-7F52C855FC06" xml:space="preserve">TInt DDriverComm::Validate(TInt aUnit, const TDesC8* /*anInfo*/, const TVersion& aVer) |
|
54 { |
|
55 if ( |
|
56 (!Kern::QueryVersionSupported(iVersion,aVer)) || |
|
57 (!Kern::QueryVersionSupported(aVer,TVersion(KMinimumLddMajorVersion,KMinimumLddMinorVersion,KMinimumLddBuild))) |
|
58 ) |
|
59 return KErrNotSupported; |
|
60 if (aUnit<UART_UNIT_OFFSET || aUnit>=(UART_TOTAL_NUMBER_UNITS+UART_UNIT_OFFSET)) |
|
61 return KErrNotSupported; |
|
62 return KErrNone; |
|
63 } |
|
64 </codeblock> <p>Note that <codeph>iVersion</codeph> is a data member in the |
|
65 base class <xref href="GUID-A5484A7F-94B9-34C7-9F88-82B1BF516930.dita"><apiname>DPhysicalDevice</apiname></xref>. </p> <p>See also: </p> <ul> |
|
66 <li id="GUID-0EF9F2F1-EC2A-50E3-9E1B-2D6112FE8623"><p> <xref href="GUID-A5484A7F-94B9-34C7-9F88-82B1BF516930.dita#GUID-A5484A7F-94B9-34C7-9F88-82B1BF516930/GUID-70B6293C-9000-31D9-AE9E-441C9760B92E"><apiname>DPhysicalDevice::Validate()</apiname></xref> </p> </li> |
|
67 <li id="GUID-4ED7473E-D789-5813-9404-0F6BDCB83D3F"><p> <xref href="GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D.dita#GUID-C6946ECB-775F-3EC2-A56F-78F25B9FBE3D/GUID-A28757CC-B89B-3F63-AD39-9955FBE7533B"><apiname>Kern::QueryVersionSupported()</apiname></xref> </p> </li> |
|
68 </ul> </section> |
|
69 <section id="GUID-48EF94F9-ACBC-58DA-9F0E-4034E56C6C74"><title>Create()</title> <p> <codeph>Create()</codeph> creates |
|
70 and returns a pointer to the physical channel object through the <xref href="GUID-4FCB6127-84F3-38F6-8AD2-FC3B94D67DA3.dita"><apiname>DBase</apiname></xref> *& |
|
71 type argument. In the case of serial device drivers, a physical channel is |
|
72 an instance of a class derived from <codeph>DComm</codeph>, which is itself |
|
73 derived from <xref href="GUID-4FCB6127-84F3-38F6-8AD2-FC3B94D67DA3.dita"><apiname>DBase</apiname></xref>. </p> <p>Implementing this function |
|
74 may involve: </p> <ul> |
|
75 <li id="GUID-D6D5111E-22E1-5EA2-B217-EAC3BA5B9599"><p>setting up any port |
|
76 related hardware; for example, defining GPIO pins as UART port I/O </p> </li> |
|
77 <li id="GUID-6769D49B-478C-5282-A918-6D659F823B95"><p>initialising the UART |
|
78 device itself; for example, enabling UART clock sources </p> </li> |
|
79 <li id="GUID-BFEC3036-6F9C-5499-81AF-7A5D01BDD890"><p>binding any interrupt |
|
80 resources to the UART Interrupt Service Routine (ISR). </p> </li> |
|
81 </ul> <p>The function sets a reference argument to point to the newly instantiated |
|
82 physical channel object, but returns an error code if object allocation or |
|
83 initialisation fails, i.e. the call to the physical channel object’s <codeph>DoCreate()</codeph> function |
|
84 fails. Error codes are returned to the caller. </p> <p>This code is typical, |
|
85 and can be copied from any current source. </p> <codeblock id="GUID-E93C6DEA-852D-5B5F-8531-CA4B76B91879" xml:space="preserve">TInt DDriverComm::Create(DBase*& aChannel, TInt aUnit, const TDesC8* anInfo, const TVersion& aVer) |
|
86 { |
|
87 DCommXXX* pD=new DCommXXX; |
|
88 aChannel=pD; |
|
89 TInt r=KErrNoMemory; |
|
90 if (pD) |
|
91 r=pD->DoCreate(aUnit,anInfo); |
|
92 return r; |
|
93 } |
|
94 </codeblock> <p>where <codeph>DCommXXX</codeph> is a <codeph>DComm</codeph> derived |
|
95 class. </p> <p>Customisation depends on the functions in the <codeph>DCommXXX::DoCreate()</codeph> function. </p> </section> |
|
96 </conbody><related-links> |
|
97 <link href="GUID-3C34724F-B476-5329-B0B1-6D5A34294979.dita"><linktext>Interrupt |
|
98 Dispatcher Tutorial</linktext></link> |
|
99 </related-links></concept> |