1 |
1026 |
ivang |
@c
|
2 |
|
|
@c COPYRIGHT (c) 1988-2002.
|
3 |
|
|
@c On-Line Applications Research Corporation (OAR).
|
4 |
|
|
@c All rights reserved.
|
5 |
|
|
@c
|
6 |
|
|
@c dpmem.t,v 1.11 2002/01/17 21:47:47 joel Exp
|
7 |
|
|
@c
|
8 |
|
|
|
9 |
|
|
@chapter Dual-Ported Memory Manager
|
10 |
|
|
|
11 |
|
|
@cindex ports
|
12 |
|
|
@cindex dual ported memory
|
13 |
|
|
|
14 |
|
|
@section Introduction
|
15 |
|
|
|
16 |
|
|
The dual-ported memory manager provides a mechanism
|
17 |
|
|
for converting addresses between internal and external
|
18 |
|
|
representations for multiple dual-ported memory areas (DPMA).
|
19 |
|
|
The directives provided by the dual-ported memory manager are:
|
20 |
|
|
|
21 |
|
|
@itemize @bullet
|
22 |
|
|
@item @code{@value{DIRPREFIX}port_create} - Create a port
|
23 |
|
|
@item @code{@value{DIRPREFIX}port_ident} - Get ID of a port
|
24 |
|
|
@item @code{@value{DIRPREFIX}port_delete} - Delete a port
|
25 |
|
|
@item @code{@value{DIRPREFIX}port_external_to_internal} - Convert external to internal address
|
26 |
|
|
@item @code{@value{DIRPREFIX}port_internal_to_external} - Convert internal to external address
|
27 |
|
|
@end itemize
|
28 |
|
|
|
29 |
|
|
@section Background
|
30 |
|
|
|
31 |
|
|
@cindex dual ported memory, definition
|
32 |
|
|
@cindex external addresses, definition
|
33 |
|
|
@cindex internal addresses, definition
|
34 |
|
|
|
35 |
|
|
A dual-ported memory area (DPMA) is an contiguous
|
36 |
|
|
block of RAM owned by a particular processor but which can be
|
37 |
|
|
accessed by other processors in the system. The owner accesses
|
38 |
|
|
the memory using internal addresses, while other processors must
|
39 |
|
|
use external addresses. RTEMS defines a port as a particular
|
40 |
|
|
mapping of internal and external addresses.
|
41 |
|
|
|
42 |
|
|
There are two system configurations in which
|
43 |
|
|
dual-ported memory is commonly found. The first is
|
44 |
|
|
tightly-coupled multiprocessor computer systems where the
|
45 |
|
|
dual-ported memory is shared between all nodes and is used for
|
46 |
|
|
inter-node communication. The second configuration is computer
|
47 |
|
|
systems with intelligent peripheral controllers. These
|
48 |
|
|
controllers typically utilize the DPMA for high-performance data
|
49 |
|
|
transfers.
|
50 |
|
|
|
51 |
|
|
@section Operations
|
52 |
|
|
|
53 |
|
|
@subsection Creating a Port
|
54 |
|
|
|
55 |
|
|
The @code{@value{DIRPREFIX}port_create} directive creates a port into a DPMA
|
56 |
|
|
with the user-defined name. The user specifies the association
|
57 |
|
|
between internal and external representations for the port being
|
58 |
|
|
created. RTEMS allocates a Dual-Ported Memory Control Block
|
59 |
|
|
(DPCB) from the DPCB free list to maintain the newly created
|
60 |
|
|
DPMA. RTEMS also generates a unique dual-ported memory port ID
|
61 |
|
|
which is returned to the calling task. RTEMS does not
|
62 |
|
|
initialize the dual-ported memory area or access any memory
|
63 |
|
|
within it.
|
64 |
|
|
|
65 |
|
|
@subsection Obtaining Port IDs
|
66 |
|
|
|
67 |
|
|
When a port is created, RTEMS generates a unique port
|
68 |
|
|
ID and assigns it to the created port until it is deleted. The
|
69 |
|
|
port ID may be obtained by either of two methods. First, as the
|
70 |
|
|
result of an invocation of the
|
71 |
|
|
@code{@value{DIRPREFIX}port_create} directive, the task
|
72 |
|
|
ID is stored in a user provided location. Second, the port ID
|
73 |
|
|
may be obtained later using the
|
74 |
|
|
@code{@value{DIRPREFIX}port_ident} directive. The port
|
75 |
|
|
ID is used by other dual-ported memory manager directives to
|
76 |
|
|
access this port.
|
77 |
|
|
|
78 |
|
|
@subsection Converting an Address
|
79 |
|
|
|
80 |
|
|
The @code{@value{DIRPREFIX}port_external_to_internal} directive is used to
|
81 |
|
|
convert an address from external to internal representation for
|
82 |
|
|
the specified port.
|
83 |
|
|
The @code{@value{DIRPREFIX}port_internal_to_external} directive is
|
84 |
|
|
used to convert an address from internal to external
|
85 |
|
|
representation for the specified port. If an attempt is made to
|
86 |
|
|
convert an address which lies outside the specified DPMA, then
|
87 |
|
|
the address to be converted will be returned.
|
88 |
|
|
|
89 |
|
|
@subsection Deleting a DPMA Port
|
90 |
|
|
|
91 |
|
|
A port can be removed from the system and returned to
|
92 |
|
|
RTEMS with the @code{@value{DIRPREFIX}port_delete} directive. When a port is deleted,
|
93 |
|
|
its control block is returned to the DPCB free list.
|
94 |
|
|
|
95 |
|
|
@section Directives
|
96 |
|
|
|
97 |
|
|
This section details the dual-ported memory manager's
|
98 |
|
|
directives. A subsection is dedicated to each of this manager's
|
99 |
|
|
directives and describes the calling sequence, related
|
100 |
|
|
constants, usage, and status codes.
|
101 |
|
|
|
102 |
|
|
@c
|
103 |
|
|
@c
|
104 |
|
|
@c
|
105 |
|
|
@page
|
106 |
|
|
@subsection PORT_CREATE - Create a port
|
107 |
|
|
|
108 |
|
|
@cindex create a port
|
109 |
|
|
|
110 |
|
|
@subheading CALLING SEQUENCE:
|
111 |
|
|
|
112 |
|
|
@ifset is-C
|
113 |
|
|
@findex rtems_port_create
|
114 |
|
|
@example
|
115 |
|
|
rtems_status_code rtems_port_create(
|
116 |
|
|
rtems_name name,
|
117 |
|
|
void *internal_start,
|
118 |
|
|
void *external_start,
|
119 |
|
|
rtems_unsigned32 length,
|
120 |
|
|
rtems_id *id
|
121 |
|
|
);
|
122 |
|
|
@end example
|
123 |
|
|
@end ifset
|
124 |
|
|
|
125 |
|
|
@ifset is-Ada
|
126 |
|
|
@example
|
127 |
|
|
procedure Port_Create (
|
128 |
|
|
Name : in RTEMS.Name;
|
129 |
|
|
Internal_Start : in RTEMS.Address;
|
130 |
|
|
External_Start : in RTEMS.Address;
|
131 |
|
|
Length : in RTEMS.Unsigned32;
|
132 |
|
|
ID : out RTEMS.ID;
|
133 |
|
|
Result : out RTEMS.Status_Codes
|
134 |
|
|
);
|
135 |
|
|
@end example
|
136 |
|
|
@end ifset
|
137 |
|
|
|
138 |
|
|
@subheading DIRECTIVE STATUS CODES:
|
139 |
|
|
@code{@value{RPREFIX}SUCCESSFUL} - port created successfully@*
|
140 |
|
|
@code{@value{RPREFIX}INVALID_NAME} - invalid task name@*
|
141 |
|
|
@code{@value{RPREFIX}INVALID_ADDRESS} - address not on four byte boundary@*
|
142 |
|
|
@code{@value{RPREFIX}TOO_MANY} - too many DP memory areas created
|
143 |
|
|
|
144 |
|
|
@subheading DESCRIPTION:
|
145 |
|
|
|
146 |
|
|
This directive creates a port which resides on the
|
147 |
|
|
local node for the specified DPMA. The assigned port id is
|
148 |
|
|
returned in id. This port id is used as an argument to other
|
149 |
|
|
dual-ported memory manager directives to convert addresses
|
150 |
|
|
within this DPMA.
|
151 |
|
|
|
152 |
|
|
For control and maintenance of the port, RTEMS
|
153 |
|
|
allocates and initializes an DPCB from the DPCB free pool. Thus
|
154 |
|
|
memory from the dual-ported memory area is not used to store the
|
155 |
|
|
DPCB.
|
156 |
|
|
|
157 |
|
|
@subheading NOTES:
|
158 |
|
|
|
159 |
|
|
The internal_address and external_address parameters
|
160 |
|
|
must be on a four byte boundary.
|
161 |
|
|
|
162 |
|
|
This directive will not cause the calling task to be
|
163 |
|
|
preempted.
|
164 |
|
|
|
165 |
|
|
@c
|
166 |
|
|
@c
|
167 |
|
|
@c
|
168 |
|
|
@page
|
169 |
|
|
@subsection PORT_IDENT - Get ID of a port
|
170 |
|
|
|
171 |
|
|
@cindex get ID of a port
|
172 |
|
|
@cindex obtain ID of a port
|
173 |
|
|
|
174 |
|
|
@subheading CALLING SEQUENCE:
|
175 |
|
|
|
176 |
|
|
@ifset is-C
|
177 |
|
|
@findex rtems_port_ident
|
178 |
|
|
@example
|
179 |
|
|
rtems_status_code rtems_port_ident(
|
180 |
|
|
rtems_name name,
|
181 |
|
|
rtems_id *id
|
182 |
|
|
);
|
183 |
|
|
@end example
|
184 |
|
|
@end ifset
|
185 |
|
|
|
186 |
|
|
@ifset is-Ada
|
187 |
|
|
@example
|
188 |
|
|
procedure Port_Ident (
|
189 |
|
|
Name : in RTEMS.Name;
|
190 |
|
|
ID : out RTEMS.ID;
|
191 |
|
|
Result : out RTEMS.Status_Codes
|
192 |
|
|
);
|
193 |
|
|
@end example
|
194 |
|
|
@end ifset
|
195 |
|
|
|
196 |
|
|
@subheading DIRECTIVE STATUS CODES:
|
197 |
|
|
@code{@value{RPREFIX}SUCCESSFUL} - port identified successfully@*
|
198 |
|
|
@code{@value{RPREFIX}INVALID_NAME} - port name not found
|
199 |
|
|
|
200 |
|
|
@subheading DESCRIPTION:
|
201 |
|
|
|
202 |
|
|
This directive obtains the port id associated with
|
203 |
|
|
the specified name to be acquired. If the port name is not
|
204 |
|
|
unique, then the port id will match one of the DPMAs with that
|
205 |
|
|
name. However, this port id is not guaranteed to correspond to
|
206 |
|
|
the desired DPMA. The port id is used to access this DPMA in
|
207 |
|
|
other dual-ported memory area related directives.
|
208 |
|
|
|
209 |
|
|
@subheading NOTES:
|
210 |
|
|
|
211 |
|
|
This directive will not cause the running task to be
|
212 |
|
|
preempted.
|
213 |
|
|
|
214 |
|
|
@c
|
215 |
|
|
@c
|
216 |
|
|
@c
|
217 |
|
|
@page
|
218 |
|
|
@subsection PORT_DELETE - Delete a port
|
219 |
|
|
|
220 |
|
|
@cindex delete a port
|
221 |
|
|
|
222 |
|
|
@subheading CALLING SEQUENCE:
|
223 |
|
|
|
224 |
|
|
@ifset is-C
|
225 |
|
|
@findex rtems_port_delete
|
226 |
|
|
@example
|
227 |
|
|
rtems_status_code rtems_port_delete(
|
228 |
|
|
rtems_id id
|
229 |
|
|
);
|
230 |
|
|
@end example
|
231 |
|
|
@end ifset
|
232 |
|
|
|
233 |
|
|
@ifset is-Ada
|
234 |
|
|
@example
|
235 |
|
|
procedure Port_Delete (
|
236 |
|
|
ID : in RTEMS.ID;
|
237 |
|
|
Result : out RTEMS.Status_Codes
|
238 |
|
|
);
|
239 |
|
|
@end example
|
240 |
|
|
@end ifset
|
241 |
|
|
|
242 |
|
|
@subheading DIRECTIVE STATUS CODES:
|
243 |
|
|
@code{@value{RPREFIX}SUCCESSFUL} - port deleted successfully@*
|
244 |
|
|
@code{@value{RPREFIX}INVALID_ID} - invalid port id
|
245 |
|
|
|
246 |
|
|
@subheading DESCRIPTION:
|
247 |
|
|
|
248 |
|
|
This directive deletes the dual-ported memory area
|
249 |
|
|
specified by id. The DPCB for the deleted dual-ported memory
|
250 |
|
|
area is reclaimed by RTEMS.
|
251 |
|
|
|
252 |
|
|
@subheading NOTES:
|
253 |
|
|
|
254 |
|
|
This directive will not cause the calling task to be
|
255 |
|
|
preempted.
|
256 |
|
|
|
257 |
|
|
The calling task does not have to be the task that
|
258 |
|
|
created the port. Any local task that knows the port id can
|
259 |
|
|
delete the port.
|
260 |
|
|
|
261 |
|
|
@c
|
262 |
|
|
@c
|
263 |
|
|
@c
|
264 |
|
|
@page
|
265 |
|
|
@subsection PORT_EXTERNAL_TO_INTERNAL - Convert external to internal address
|
266 |
|
|
|
267 |
|
|
@cindex convert external to internal address
|
268 |
|
|
|
269 |
|
|
@subheading CALLING SEQUENCE:
|
270 |
|
|
|
271 |
|
|
@ifset is-C
|
272 |
|
|
@findex rtems_port_external_to_internal
|
273 |
|
|
@example
|
274 |
|
|
rtems_status_code rtems_port_external_to_internal(
|
275 |
|
|
rtems_id id,
|
276 |
|
|
void *external,
|
277 |
|
|
void **internal
|
278 |
|
|
);
|
279 |
|
|
@end example
|
280 |
|
|
@end ifset
|
281 |
|
|
|
282 |
|
|
@ifset is-Ada
|
283 |
|
|
@example
|
284 |
|
|
procedure Port_External_To_Internal (
|
285 |
|
|
ID : in RTEMS.ID;
|
286 |
|
|
External : in RTEMS.Address;
|
287 |
|
|
Internal : out RTEMS.Address;
|
288 |
|
|
Result : out RTEMS.Status_Codes
|
289 |
|
|
);
|
290 |
|
|
@end example
|
291 |
|
|
@end ifset
|
292 |
|
|
|
293 |
|
|
@subheading DIRECTIVE STATUS CODES:
|
294 |
|
|
@code{@value{RPREFIX}SUCCESSFUL} - always successful
|
295 |
|
|
|
296 |
|
|
@subheading DESCRIPTION:
|
297 |
|
|
|
298 |
|
|
This directive converts a dual-ported memory address
|
299 |
|
|
from external to internal representation for the specified port.
|
300 |
|
|
If the given external address is invalid for the specified
|
301 |
|
|
port, then the internal address is set to the given external
|
302 |
|
|
address.
|
303 |
|
|
|
304 |
|
|
@subheading NOTES:
|
305 |
|
|
|
306 |
|
|
This directive is callable from an ISR.
|
307 |
|
|
|
308 |
|
|
This directive will not cause the calling task to be
|
309 |
|
|
preempted.
|
310 |
|
|
|
311 |
|
|
@c
|
312 |
|
|
@c
|
313 |
|
|
@c
|
314 |
|
|
@page
|
315 |
|
|
@subsection PORT_INTERNAL_TO_EXTERNAL - Convert internal to external address
|
316 |
|
|
|
317 |
|
|
@cindex convert internal to external address
|
318 |
|
|
|
319 |
|
|
@subheading CALLING SEQUENCE:
|
320 |
|
|
|
321 |
|
|
@ifset is-C
|
322 |
|
|
@findex rtems_port_internal_to_external
|
323 |
|
|
@example
|
324 |
|
|
rtems_status_code rtems_port_internal_to_external(
|
325 |
|
|
rtems_id id,
|
326 |
|
|
void *internal,
|
327 |
|
|
void **external
|
328 |
|
|
);
|
329 |
|
|
@end example
|
330 |
|
|
@end ifset
|
331 |
|
|
|
332 |
|
|
@ifset is-Ada
|
333 |
|
|
@example
|
334 |
|
|
procedure Port_Internal_To_External (
|
335 |
|
|
ID : in RTEMS.ID;
|
336 |
|
|
Internal : in RTEMS.Address;
|
337 |
|
|
External : out RTEMS.Address;
|
338 |
|
|
Result : out RTEMS.Status_Codes
|
339 |
|
|
);
|
340 |
|
|
@end example
|
341 |
|
|
@end ifset
|
342 |
|
|
|
343 |
|
|
@subheading DIRECTIVE STATUS CODES:
|
344 |
|
|
@code{@value{RPREFIX}SUCCESSFUL} - always successful
|
345 |
|
|
|
346 |
|
|
@subheading DESCRIPTION:
|
347 |
|
|
|
348 |
|
|
This directive converts a dual-ported memory address
|
349 |
|
|
from internal to external representation so that it can be
|
350 |
|
|
passed to owner of the DPMA represented by the specified port.
|
351 |
|
|
If the given internal address is an invalid dual-ported address,
|
352 |
|
|
then the external address is set to the given internal address.
|
353 |
|
|
|
354 |
|
|
@subheading NOTES:
|
355 |
|
|
|
356 |
|
|
This directive is callable from an ISR.
|
357 |
|
|
|
358 |
|
|
This directive will not cause the calling task to be
|
359 |
|
|
preempted.
|
360 |
|
|
|