OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [doc/] [html/] [ref/] [synth-new-target.html] - Blame information for rev 482

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 28 unneback
<!-- Copyright (C) 2003 Red Hat, Inc.                                -->
2
<!-- This material may be distributed only subject to the terms      -->
3
<!-- and conditions set forth in the Open Publication License, v1.0  -->
4
<!-- or later (the latest version is presently available at          -->
5
<!-- http://www.opencontent.org/openpub/).                           -->
6
<!-- Distribution of the work or derivative of the work in any       -->
7
<!-- standard (paper) book form is prohibited unless prior           -->
8
<!-- permission is obtained from the copyright holder.               -->
9
<HTML
10
><HEAD
11
><TITLE
12
>Writing New Devices - target</TITLE
13
><meta name="MSSmartTagsPreventParsing" content="TRUE">
14
<META
15
NAME="GENERATOR"
16
CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+
17
"><LINK
18
REL="HOME"
19
TITLE="eCos Reference Manual"
20
HREF="ecos-ref.html"><LINK
21
REL="UP"
22
TITLE="eCos Synthetic Target"
23
HREF="hal-synth-arch.html"><LINK
24
REL="PREVIOUS"
25
TITLE="System Calls"
26
HREF="synth-syscalls.html"><LINK
27
REL="NEXT"
28
TITLE="Writing New Devices - host"
29
HREF="synth-new-host.html"></HEAD
30
><BODY
31
CLASS="REFENTRY"
32
BGCOLOR="#FFFFFF"
33
TEXT="#000000"
34
LINK="#0000FF"
35
VLINK="#840084"
36
ALINK="#0000FF"
37
><DIV
38
CLASS="NAVHEADER"
39
><TABLE
40
SUMMARY="Header navigation table"
41
WIDTH="100%"
42
BORDER="0"
43
CELLPADDING="0"
44
CELLSPACING="0"
45
><TR
46
><TH
47
COLSPAN="3"
48
ALIGN="center"
49
>eCos Reference Manual</TH
50
></TR
51
><TR
52
><TD
53
WIDTH="10%"
54
ALIGN="left"
55
VALIGN="bottom"
56
><A
57
HREF="synth-syscalls.html"
58
ACCESSKEY="P"
59
>Prev</A
60
></TD
61
><TD
62
WIDTH="80%"
63
ALIGN="center"
64
VALIGN="bottom"
65
></TD
66
><TD
67
WIDTH="10%"
68
ALIGN="right"
69
VALIGN="bottom"
70
><A
71
HREF="synth-new-host.html"
72
ACCESSKEY="N"
73
>Next</A
74
></TD
75
></TR
76
></TABLE
77
><HR
78
ALIGN="LEFT"
79
WIDTH="100%"></DIV
80
><H1
81
><A
82
NAME="SYNTH-NEW-TARGET">Writing New Devices - target</H1
83
><DIV
84
CLASS="REFNAMEDIV"
85
><A
86
NAME="AEN18180"
87
></A
88
><H2
89
>Name</H2
90
>Writing New Devices&nbsp;--&nbsp;extending the synthetic target, target-side</DIV
91
><DIV
92
CLASS="REFSYNOPSISDIV"
93
><A
94
NAME="AEN18183"><H2
95
>Synopsis</H2
96
><DIV
97
CLASS="FUNCSYNOPSIS"
98
><A
99
NAME="AEN18184"><P
100
></P
101
><TABLE
102
BORDER="5"
103
BGCOLOR="#E0E0F0"
104
WIDTH="70%"
105
><TR
106
><TD
107
><PRE
108
CLASS="FUNCSYNOPSISINFO"
109
>#include &lt;cyg/hal/hal_io.h&gt;
110
      </PRE
111
></TD
112
></TR
113
></TABLE
114
><P
115
><CODE
116
><CODE
117
CLASS="FUNCDEF"
118
>int synth_auxiliary_instantiate</CODE
119
>(const char* package, const char* version, const char* device, const char* instance, const char* data);</CODE
120
></P
121
><P
122
><CODE
123
><CODE
124
CLASS="FUNCDEF"
125
>void synth_auxiliary_xchgmsg</CODE
126
>(int device_id, int request, int arg1, int arg2, const unsigned char* txdata, int txlen, int* reply, unsigned char* rxdata, int* rxlen, int max_rxlen);</CODE
127
></P
128
><P
129
></P
130
></DIV
131
></DIV
132
><DIV
133
CLASS="REFSECT1"
134
><A
135
NAME="SYNTH-NEW-TARGET-DESCRIPTION"
136
></A
137
><H2
138
>Description</H2
139
><P
140
>In some ways writing a device driver for the synthetic target is very
141
similar to writing one for a real target. Obviously it has to provide
142
the standard interface for that class of device, so for example an
143
ethernet device has to provide <TT
144
CLASS="FUNCTION"
145
>can_send</TT
146
>,
147
<TT
148
CLASS="FUNCTION"
149
>send</TT
150
>, <TT
151
CLASS="FUNCTION"
152
>recv</TT
153
> and similar
154
functions. Many devices will involve interrupts, so the driver
155
contains ISR and DSR functions and will call
156
<TT
157
CLASS="FUNCTION"
158
>cyg_drv_interrupt_create</TT
159
>,
160
<TT
161
CLASS="FUNCTION"
162
>cyg_drv_interrupt_acknowledge</TT
163
>, and related
164
functions.
165
    </P
166
><P
167
>In other ways writing a device driver for the synthetic target is very
168
different. Usually the driver will not have any direct access to the
169
underlying hardware. In fact for some devices the I/O may not involve
170
real hardware, instead everything is emulated by widgets on the
171
graphical display. Therefore the driver cannot just peek and poke
172
device registers, instead it must interact with host-side code by
173
exchanging message. The synthetic target HAL provides a function
174
<TT
175
CLASS="FUNCTION"
176
>synth_auxiliary_xchgmsg</TT
177
> for this purpose.
178
    </P
179
><P
180
>Initialization of a synthetic target device driver is also very
181
different. On real targets the device hardware already exists when the
182
driver's initialization routine runs. On the synthetic target it is
183
first necessary to instantiate the device inside the I/O auxiliary, by
184
a call to <TT
185
CLASS="FUNCTION"
186
>synth_auxiliary_instantiate</TT
187
>. That
188
function performs a special message exchange with the I/O auxiliary,
189
causing it to load a Tcl script for the desired type of device and run
190
an instantiation procedure within that script.
191
    </P
192
><P
193
>Use of the I/O auxiliary is optional: if the user does not specify
194
<TT
195
CLASS="OPTION"
196
>--io</TT
197
> on the command line then the auxiliary will not
198
be started and hence most I/O operations will not be possible. Device
199
drivers should allow for this possibility, for example by just
200
discarding any data that gets written. The HAL exports a flag
201
<TT
202
CLASS="VARNAME"
203
>synth_auxiliary_running</TT
204
> which should be checked.
205
    </P
206
></DIV
207
><DIV
208
CLASS="REFSECT1"
209
><A
210
NAME="SYNTH-NEW-TARGET-INSTANTIATE"
211
></A
212
><H2
213
>Instantiating a Device</H2
214
><P
215
>Device instantiation should happen during the C++ prioritized static
216
constructor phase of system initialization, before control switches to
217
<TT
218
CLASS="FUNCTION"
219
>cyg_user_start</TT
220
> and general application code. This
221
ensures that there is a clearly defined point at which the I/O
222
auxiliary knows that all required devices have been loaded. It can
223
then perform various consistency checks and clean-ups, run the user's
224
<TT
225
CLASS="FILENAME"
226
>mainrc.tcl</TT
227
> script, and make the main window
228
visible.
229
    </P
230
><P
231
>For standard devices generic eCos I/O code will call the device
232
initialization routines at the right time, iterating through the
233
<TT
234
CLASS="VARNAME"
235
>DEVTAB</TT
236
> table in a static constructor. The same
237
holds for network devices and file systems. For more custom devices
238
code like the following can be used:
239
    </P
240
><TABLE
241
BORDER="5"
242
BGCOLOR="#E0E0F0"
243
WIDTH="70%"
244
><TR
245
><TD
246
><PRE
247
CLASS="PROGRAMLISTING"
248
>#include &lt;cyg/infra/cyg_type.h&gt;
249
class mydev_init {
250
  public:
251
    mydev_init() {
252
        &#8230;
253
    }
254
};
255
static mydev_init mydev_init_object CYGBLD_ATTRIB_INIT_PRI(CYG_INIT_IO);</PRE
256
></TD
257
></TR
258
></TABLE
259
><P
260
>Some care has to be taken because the object
261
<TT
262
CLASS="VARNAME"
263
>mydev_init_object</TT
264
> will typically not be referenced
265
by other code, and hence may get eliminated at link-time. If the code
266
is part of an eCos package then problems can be avoided by putting the
267
relevant file in <TT
268
CLASS="FILENAME"
269
>libextras.a</TT
270
>:
271
    </P
272
><TABLE
273
BORDER="5"
274
BGCOLOR="#E0E0F0"
275
WIDTH="70%"
276
><TR
277
><TD
278
><PRE
279
CLASS="PROGRAMLISTING"
280
>cdl_package CYGPKG_DEVS_MINE {
281
    &#8230;
282
    compile -library=libextras.a init.cxx
283
}</PRE
284
></TD
285
></TR
286
></TABLE
287
><P
288
>For devices inside application code the same can be achieved by
289
linking the relevant module as a <TT
290
CLASS="FILENAME"
291
>.o</TT
292
> file rather
293
than putting it in a <TT
294
CLASS="FILENAME"
295
>.a</TT
296
> library.
297
    </P
298
><P
299
>In the device initialization routine the main operation is a call to
300
<TT
301
CLASS="FUNCTION"
302
>synth_auxiliary_instantiate</TT
303
>. This takes five
304
arguments, all of which should be strings:
305
    </P
306
><P
307
></P
308
><DIV
309
CLASS="VARIABLELIST"
310
><DL
311
><DT
312
><TT
313
CLASS="VARNAME"
314
>package</TT
315
></DT
316
><DD
317
><P
318
>For device drivers which are eCos packages this should be a directory
319
path relative to the eCos repository, for example
320
<TT
321
CLASS="LITERAL"
322
>devs/eth/synth/ecosynth</TT
323
>. This will allow the I/O
324
auxiliary to find the various host-side support files for this package
325
within the install tree. If the device is application-specific and not
326
part of an eCos package then a NULL pointer can be used, causing the
327
I/O auxiliary to search for the support files in the current directory
328
and then in <TT
329
CLASS="FILENAME"
330
>~/.ecos/synth</TT
331
>
332
instead.
333
        </P
334
></DD
335
><DT
336
><TT
337
CLASS="VARNAME"
338
>version</TT
339
></DT
340
><DD
341
><P
342
>For eCos packages this argument should be the version of the package
343
that is being used, for example <TT
344
CLASS="LITERAL"
345
>current</TT
346
>. A simple
347
way to get this version is to use the
348
<TT
349
CLASS="FUNCTION"
350
>SYNTH_MAKESTRING</TT
351
> macro on the package name.
352
If the device is application-specific then a NULL pointer should be
353
used.
354
        </P
355
></DD
356
><DT
357
><TT
358
CLASS="VARNAME"
359
>device</TT
360
></DT
361
><DD
362
><P
363
>This argument specifies the type of device being instantiated, for
364
example <TT
365
CLASS="LITERAL"
366
>ethernet</TT
367
>. More specifically the I/O
368
auxiliary will append a <TT
369
CLASS="FILENAME"
370
>.tcl</TT
371
> suffix, giving
372
the name of a Tcl script that will handle all I/O requests for the
373
device. If the application requires several instances of a type
374
of device then the script will only be loaded once, but the script
375
will contain an instantiation procedure that will be called for each
376
device instance.
377
        </P
378
></DD
379
><DT
380
><TT
381
CLASS="VARNAME"
382
>instance</TT
383
></DT
384
><DD
385
><P
386
>If it is possible to have multiple instances of a device then this
387
argument identifies the particular instance, for example
388
<TT
389
CLASS="LITERAL"
390
>eth0</TT
391
> or <TT
392
CLASS="LITERAL"
393
>eth1</TT
394
>. Otherwise a NULL
395
pointer can be used.
396
        </P
397
></DD
398
><DT
399
><TT
400
CLASS="VARNAME"
401
>data</TT
402
></DT
403
><DD
404
><P
405
>This argument can be used to pass additional initialization data from
406
eCos to the host-side support. This is useful for devices where eCos
407
configury must control certain aspects of the device, rather than
408
host-side configury such as the target definition file, because eCos
409
has compile-time dependencies on some or all of the relevant options.
410
An example might be an emulated frame buffer where eCos has been
411
statically configured for a particular screen size, orientation and
412
depth. There is no fixed format for this string, it will be
413
interpreted only by the device-specific host-side Tcl script. However
414
the string length should be limited to a couple of hundred bytes to
415
avoid possible buffer overflow problems.
416
        </P
417
></DD
418
></DL
419
></DIV
420
><P
421
>Typical usage would look like:
422
    </P
423
><TABLE
424
BORDER="5"
425
BGCOLOR="#E0E0F0"
426
WIDTH="70%"
427
><TR
428
><TD
429
><PRE
430
CLASS="PROGRAMLISTING"
431
>    if (!synth_auxiliary_running) {
432
      return;
433
    }
434
    id = synth_auxiliary_instantiate("devs/eth/synth/ecosynth",
435
             SYNTH_MAKESTRING(CYGPKG_DEVS_ETH_ECOSYNTH),
436
             "ethernet",
437
             "eth0",
438
             (const char*) 0);</PRE
439
></TD
440
></TR
441
></TABLE
442
><P
443
>The return value will be a device identifier which can be used for
444
subsequent calls to <TT
445
CLASS="FUNCTION"
446
>synth_auxiliary_xchgmsg</TT
447
>. If
448
the device could not be instantiated then <TT
449
CLASS="LITERAL"
450
>-1</TT
451
> will
452
be returned. It is the responsibility of the host-side software to
453
issue suitable diagnostics explaining what went wrong, so normally the
454
target-side code should fail silently.
455
    </P
456
><P
457
>Once the desired device has been instantiated, often it will be
458
necessary to do some additional initialization by a message exchange.
459
For example an ethernet device might need information from the
460
host-side about the MAC address, the <A
461
HREF="synth-new-target.html#SYNTH-NEW-TARGET-INTERRUPTS"
462
>interrupt vector</A
463
>, and
464
whether or not multicasting is supported.
465
    </P
466
></DIV
467
><DIV
468
CLASS="REFSECT1"
469
><A
470
NAME="SYNTH-NEW-TARGET-XCHGMSG"
471
></A
472
><H2
473
>Communicating with a Device</H2
474
><P
475
>Once a device has been instantiated it is possible to perform I/O by
476
sending messages to the appropriate Tcl script running inside the
477
auxiliary, and optionally getting back replies. I/O operations are
478
always initiated by the eCos target-side, it is not possible for the
479
host-side software to initiate data transfers. However the host-side
480
can raise interrupts, and the interrupt handler inside the target can
481
then exchange one or more messages with the host.
482
    </P
483
><P
484
>There is a single function to perform I/O operations,
485
<TT
486
CLASS="FUNCTION"
487
>synth_auxiliary_xchgmsg</TT
488
>. This takes the following
489
arguments:
490
    </P
491
><P
492
></P
493
><DIV
494
CLASS="VARIABLELIST"
495
><DL
496
><DT
497
><TT
498
CLASS="VARNAME"
499
>device_id</TT
500
></DT
501
><DD
502
><P
503
>This should be one of the identifiers returned by a previous
504
call to <TT
505
CLASS="FUNCTION"
506
>synth_auxiliary_instantiate</TT
507
>, specifying the
508
particular device which should perform some I/O.
509
         </P
510
></DD
511
><DT
512
><TT
513
CLASS="VARNAME"
514
>request</TT
515
></DT
516
><DD
517
><P
518
>Request are just signed 32-bit integers that identify the particular
519
I/O operation being requested. There is no fixed set of codes, instead
520
each type of device can define its own.
521
         </P
522
></DD
523
><DT
524
><TT
525
CLASS="VARNAME"
526
>arg1</TT
527
>, <TT
528
CLASS="VARNAME"
529
>arg2</TT
530
></DT
531
><DD
532
><P
533
>For some requests it is convenient to pass one or two additional
534
parameters alongside the request code. For example an ethernet device
535
could define a multicast-all request, with <TT
536
CLASS="VARNAME"
537
>arg1</TT
538
>
539
controlling whether this mode should be enabled or disabled. Both
540
<TT
541
CLASS="VARNAME"
542
>arg1</TT
543
> and <TT
544
CLASS="VARNAME"
545
>arg2</TT
546
> should be signed
547
32-bit integers, and their values are interpreted only by the
548
device-specific Tcl script.
549
         </P
550
></DD
551
><DT
552
><TT
553
CLASS="VARNAME"
554
>txdata</TT
555
>, <TT
556
CLASS="VARNAME"
557
>txlen</TT
558
></DT
559
><DD
560
><P
561
>Some I/O operations may involve sending additional data, for example
562
an ethernet packet. Alternatively a control operation may require many
563
more parameters than can easily be encoded in <TT
564
CLASS="VARNAME"
565
>arg1</TT
566
>
567
and <TT
568
CLASS="VARNAME"
569
>arg2</TT
570
>, so those parameters have to be placed in
571
a suitable buffer and extracted at the other end.
572
<TT
573
CLASS="VARNAME"
574
>txdata</TT
575
> is an arbitrary buffer of
576
<TT
577
CLASS="VARNAME"
578
>txlen</TT
579
> bytes that should be sent to the host-side.
580
There is no specific upper bound on the number of bytes that can be
581
sent, but usually it is a good idea to allocate the transmit buffer
582
statically and keep transfers down to at most several kilobytes.
583
         </P
584
></DD
585
><DT
586
><TT
587
CLASS="VARNAME"
588
>reply</TT
589
></DT
590
><DD
591
><P
592
>If the host-side is expected to send a reply message then
593
<TT
594
CLASS="VARNAME"
595
>reply</TT
596
> should be a pointer to an integer variable
597
and will be updated with a reply code, a simple 32-bit integer. The
598
synthetic target HAL code assumes that the host-side and target-side
599
agree on the protocol being used: if the host-side will not send a
600
reply to this message then the <TT
601
CLASS="VARNAME"
602
>reply</TT
603
> argument
604
should be a NULL pointer; otherwise the host-side must always send
605
a reply code and the <TT
606
CLASS="VARNAME"
607
>reply</TT
608
> argument must be valid.
609
         </P
610
></DD
611
><DT
612
><TT
613
CLASS="VARNAME"
614
>rxdata</TT
615
>, <TT
616
CLASS="VARNAME"
617
>rxlen</TT
618
></DT
619
><DD
620
><P
621
>Some operations may involve additional data coming from the host-side,
622
for example an incoming ethernet packet. <TT
623
CLASS="VARNAME"
624
>rxdata</TT
625
>
626
should be a suitably-sized buffer, and <TT
627
CLASS="VARNAME"
628
>rxlen</TT
629
> a
630
pointer to an integer variable that will end up containing the number
631
of bytes that were actually received. These arguments will only be
632
used if the host-side is expected to send a reply and hence the
633
<TT
634
CLASS="VARNAME"
635
>reply</TT
636
> argument was not NULL.
637
         </P
638
></DD
639
><DT
640
><TT
641
CLASS="VARNAME"
642
>max_rxlen</TT
643
></DT
644
><DD
645
><P
646
>If a reply to this message is expected and that reply may involve
647
additional data, <TT
648
CLASS="VARNAME"
649
>max_rxlen</TT
650
> limits the size of that
651
reply. In other words, it corresponds to the size of the
652
<TT
653
CLASS="VARNAME"
654
>rxdata</TT
655
> buffer.
656
         </P
657
></DD
658
></DL
659
></DIV
660
><P
661
>Most I/O operations involve only some of the arguments. For example
662
transmitting an ethernet packet would use the
663
<TT
664
CLASS="VARNAME"
665
>request</TT
666
>, <TT
667
CLASS="VARNAME"
668
>txdata</TT
669
> and
670
<TT
671
CLASS="VARNAME"
672
>txlen</TT
673
> fields (in addition to
674
<TT
675
CLASS="VARNAME"
676
>device_id</TT
677
> which is always required), but would not
678
involve <TT
679
CLASS="VARNAME"
680
>arg1</TT
681
> or <TT
682
CLASS="VARNAME"
683
>arg2</TT
684
> and no
685
reply would be expected. Receiving an ethernet packet would involve
686
<TT
687
CLASS="VARNAME"
688
>request</TT
689
>, <TT
690
CLASS="VARNAME"
691
>rxdata</TT
692
>,
693
<TT
694
CLASS="VARNAME"
695
>rxlen</TT
696
> and <TT
697
CLASS="VARNAME"
698
>max_rxlen</TT
699
>; in addition
700
<TT
701
CLASS="VARNAME"
702
>reply</TT
703
> is needed to get any reply from the host-side
704
at all, and could be used to indicate whether or not any more packets
705
are buffered up. A control operation such as enabling multicast mode
706
would involve <TT
707
CLASS="VARNAME"
708
>request</TT
709
> and <TT
710
CLASS="VARNAME"
711
>arg1</TT
712
>,
713
but none of the remaining arguments.
714
    </P
715
></DIV
716
><DIV
717
CLASS="REFSECT1"
718
><A
719
NAME="SYNTH-NEW-TARGET-INTERRUPTS"
720
></A
721
><H2
722
>Interrupt Handling</H2
723
><P
724
>Interrupt handling in the synthetic target is much the same as on a
725
real target. An interrupt object is created using
726
<TT
727
CLASS="FUNCTION"
728
>cyg_drv_interrupt_create</TT
729
>, attached, and unmasked.
730
The emulated device - in other words the Tcl script running inside the
731
I/O auxiliary - can raise an interrupt. Subject to interrupts being
732
disabled and the appropriate vector being masked, the system will
733
invoke the specified ISR function. The synthetic target HAL
734
implementation does have some limitations: there is no support for
735
nested interrupts, interrupt priorities, or a separate interrupt
736
stack. Supporting those might be appropriate when targetting a
737
simulator that attempts to model real hardware accurately, but not for
738
the simple emulation provided by the synthetic target.
739
    </P
740
><P
741
>Of course the actual implementation of the ISR and DSR functions will
742
be rather different for a synthetic target device driver. For real
743
hardware the device driver will interact with the device by reading
744
and writing device registers, managing DMA engines, and the like. A
745
synthetic target driver will instead call
746
<TT
747
CLASS="FUNCTION"
748
>synth_auxiliary_xchgmsg</TT
749
> to perform the I/O
750
operations.
751
    </P
752
><P
753
>There is one other significant difference between interrupt handling
754
on the synthetic target and on real hardware. Usually the eCos code
755
will know which interrupt vectors are used for which devices. That
756
information is fixed when the target hardware is designed. With the
757
synthetic target interrupt vectors are assigned to devices on the host
758
side, either via the target definition file or dynamically when the
759
device is instantiated. Therefore the initialization code for a
760
target-side device driver will need to request interrupt vector
761
information from the host-side, via a message exchange. Such interrupt
762
vectors will be in the range 1 to 31 inclusive, with interrupt 0 being
763
reserved for the real-time clock.
764
    </P
765
></DIV
766
><DIV
767
CLASS="NAVFOOTER"
768
><HR
769
ALIGN="LEFT"
770
WIDTH="100%"><TABLE
771
SUMMARY="Footer navigation table"
772
WIDTH="100%"
773
BORDER="0"
774
CELLPADDING="0"
775
CELLSPACING="0"
776
><TR
777
><TD
778
WIDTH="33%"
779
ALIGN="left"
780
VALIGN="top"
781
><A
782
HREF="synth-syscalls.html"
783
ACCESSKEY="P"
784
>Prev</A
785
></TD
786
><TD
787
WIDTH="34%"
788
ALIGN="center"
789
VALIGN="top"
790
><A
791
HREF="ecos-ref.html"
792
ACCESSKEY="H"
793
>Home</A
794
></TD
795
><TD
796
WIDTH="33%"
797
ALIGN="right"
798
VALIGN="top"
799
><A
800
HREF="synth-new-host.html"
801
ACCESSKEY="N"
802
>Next</A
803
></TD
804
></TR
805
><TR
806
><TD
807
WIDTH="33%"
808
ALIGN="left"
809
VALIGN="top"
810
>System Calls</TD
811
><TD
812
WIDTH="34%"
813
ALIGN="center"
814
VALIGN="top"
815
><A
816
HREF="hal-synth-arch.html"
817
ACCESSKEY="U"
818
>Up</A
819
></TD
820
><TD
821
WIDTH="33%"
822
ALIGN="right"
823
VALIGN="top"
824
>Writing New Devices - host</TD
825
></TR
826
></TABLE
827
></DIV
828
></BODY
829
></HTML
830
>

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.