OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [synth/] [arch/] [v2_0/] [doc/] [synth-new-host.html] - Blame information for rev 27

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

Line No. Rev Author Line
1 27 unneback
<!-- Copyright (C) 2002 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 - host</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 Synthetic Target"
20
HREF="hal-synth-arch.html"><LINK
21
REL="PREVIOUS"
22
TITLE="Writing New Devices - target"
23
HREF="synth-new-target.html"><LINK
24
REL="NEXT"
25
TITLE="Porting"
26
HREF="synth-porting.html"></HEAD
27
><BODY
28
CLASS="REFENTRY"
29
BGCOLOR="#FFFFFF"
30
TEXT="#000000"
31
LINK="#0000FF"
32
VLINK="#840084"
33
ALINK="#0000FF"
34
><DIV
35
CLASS="NAVHEADER"
36
><TABLE
37
SUMMARY="Header navigation table"
38
WIDTH="100%"
39
BORDER="0"
40
CELLPADDING="0"
41
CELLSPACING="0"
42
><TR
43
><TH
44
COLSPAN="3"
45
ALIGN="center"
46
>eCos Synthetic Target</TH
47
></TR
48
><TR
49
><TD
50
WIDTH="10%"
51
ALIGN="left"
52
VALIGN="bottom"
53
><A
54
HREF="synth-new-target.html"
55
ACCESSKEY="P"
56
>Prev</A
57
></TD
58
><TD
59
WIDTH="80%"
60
ALIGN="center"
61
VALIGN="bottom"
62
></TD
63
><TD
64
WIDTH="10%"
65
ALIGN="right"
66
VALIGN="bottom"
67
><A
68
HREF="synth-porting.html"
69
ACCESSKEY="N"
70
>Next</A
71
></TD
72
></TR
73
></TABLE
74
><HR
75
ALIGN="LEFT"
76
WIDTH="100%"></DIV
77
><H1
78
><A
79
NAME="SYNTH-NEW-HOST">Writing New Devices - host</H1
80
><DIV
81
CLASS="REFNAMEDIV"
82
><A
83
NAME="AEN726"
84
></A
85
><H2
86
>Name</H2
87
>Writing New Devices&nbsp;--&nbsp;extending the synthetic target, host-side</DIV
88
><DIV
89
CLASS="REFSECT1"
90
><A
91
NAME="SYNTH-NEW-HOST-DESCRIPTION"
92
></A
93
><H2
94
>Description</H2
95
><P
96
>On the host-side adding a new device means writing a Tcl/Tk script
97
that will handle instantiation and subsequent requests from the
98
target-side. These scripts all run in the same full interpreter,
99
extended with various commands provided by the main I/O auxiliary
100
code, and running in an overall GUI framework. Some knowledge of
101
programming with Tcl/Tk is required to implement host-side device
102
support.
103
    </P
104
><P
105
>Some devices can be implemented entirely using a Tcl/Tk script. For
106
example, if the final system will have some buttons then those can be
107
emulated in the synthetic target using a few Tk widgets. A simple
108
emulation could just have the right number of buttons in a row. A more
109
advanced emulation could organize the buttons with the right layout,
110
perhaps even matching the colour scheme, the shapes, and the relative
111
sizes. With other devices it may be necessary for the Tcl script to
112
interact with an external program, because the required functionality
113
cannot easily be accessed from a Tcl script. For example interacting
114
with a raw ethernet device involves some <TT
115
CLASS="FUNCTION"
116
>ioctl</TT
117
>
118
calls, which is easier to do in a C program. Therefore the
119
<TT
120
CLASS="FILENAME"
121
>ethernet.tcl</TT
122
> script which implements the
123
host-side ethernet support spawns a separate program
124
<TT
125
CLASS="FILENAME"
126
>rawether</TT
127
>, written in C, that performs the
128
low-level I/O. Raw ethernet access usually also requires root
129
privileges, and running a small program <TT
130
CLASS="FILENAME"
131
>rawether</TT
132
>
133
with such privileges is somewhat less of a security risk than the
134
whole eCos application, the I/O auxiliary, and various dynamically
135
loaded Tcl scripts.
136
    </P
137
><P
138
>Because all scripts run in a single interpreter, some care has
139
to be taken to avoid accidental sharing of global variables. The best
140
way to avoid problems is to have each script create its own Tcl
141
namespace, so for example the <TT
142
CLASS="FILENAME"
143
>ethernet.tcl</TT
144
> script
145
creates a namespace <TT
146
CLASS="VARNAME"
147
>ethernet::</TT
148
> and all variables
149
and procedures reside in this namespace. Similarly the I/O auxiliary
150
itself makes use of a <TT
151
CLASS="VARNAME"
152
>synth::</TT
153
> namespace.
154
    </P
155
></DIV
156
><DIV
157
CLASS="REFSECT1"
158
><A
159
NAME="SYNTH-NEW-HOST-BUILD"
160
></A
161
><H2
162
>Building and Installation</H2
163
><P
164
>When an eCos device driver or application code instantiates a device,
165
the I/O auxiliary will attempt to load a matching Tcl script. The
166
third argument to <TT
167
CLASS="FUNCTION"
168
>synth_auxiliary_instantiate</TT
169
>
170
specifies the type of device, for example <TT
171
CLASS="LITERAL"
172
>ethernet</TT
173
>,
174
and the I/O auxiliary will append a <TT
175
CLASS="FILENAME"
176
>.tcl</TT
177
> suffix
178
and look for a script <TT
179
CLASS="FILENAME"
180
>ethernet.tcl</TT
181
>.
182
    </P
183
><P
184
>If the device being instantiated is application-specific rather than
185
part of an eCos package, the I/O auxiliary will look first in the
186
current directory, then in <TT
187
CLASS="FILENAME"
188
>~/.ecos/synth</TT
189
>. If it is part of an eCos
190
package then the auxiliary will expect to find the Tcl script and any
191
support files below <TT
192
CLASS="FILENAME"
193
>libexec/ecos</TT
194
> in the install tree - note
195
that the same install tree must be used for the I/O auxiliary itself
196
and for any device driver support. The directory hierarchy below
197
<TT
198
CLASS="FILENAME"
199
>libexec/ecos</TT
200
> matches the
201
structure of the eCos repository, allowing multiple versions of a
202
package to be installed to allow for incompatible protocol changes.
203
    </P
204
><P
205
>The preferred way to build host-side software is to use
206
<B
207
CLASS="COMMAND"
208
>autoconf</B
209
> and <B
210
CLASS="COMMAND"
211
>automake</B
212
>. Usually
213
this involves little more than copying the
214
<TT
215
CLASS="FILENAME"
216
>acinclude.m4</TT
217
>, <TT
218
CLASS="FILENAME"
219
>configure.in</TT
220
>
221
and <TT
222
CLASS="FILENAME"
223
>Makefile.am</TT
224
> files from an existing package,
225
for example the synthetic target ethernet driver, and then making
226
minor edits. In <TT
227
CLASS="FILENAME"
228
>acinclude.m4</TT
229
> it may be necessary
230
to adjust the path to the root of the repository.
231
<TT
232
CLASS="FILENAME"
233
>configure.in</TT
234
> may require a similar change, and
235
the <TT
236
CLASS="FUNCTION"
237
>AC_INIT</TT
238
> macro invocation will have to be
239
changed to match one of the files in the new package. A critical macro
240
in this file is <TT
241
CLASS="FILENAME"
242
>ECOS_PACKAGE_DIRS</TT
243
> which will set
244
up the correct install directory. <TT
245
CLASS="FILENAME"
246
>Makefile.am</TT
247
> may
248
require some more changes, for example to specify the data files that
249
should be installed (including the Tcl script). These files should
250
then be processed using <B
251
CLASS="COMMAND"
252
>aclocal</B
253
>,
254
<B
255
CLASS="COMMAND"
256
>autoconf</B
257
> and <B
258
CLASS="COMMAND"
259
>automake</B
260
> in that
261
order. Actually building the software then just involves
262
<B
263
CLASS="COMMAND"
264
>configure</B
265
>, <B
266
CLASS="COMMAND"
267
>make</B
268
> and
269
<B
270
CLASS="COMMAND"
271
>make install</B
272
>, as per the instructions in the
273
toplevel <TT
274
CLASS="FILENAME"
275
>README.host</TT
276
> file.
277
    </P
278
><P
279
>To assist developers, if the environment variable
280
<TT
281
CLASS="ENVAR"
282
>ECOSYNTH_DEVEL</TT
283
> is set then a slightly different
284
algorithm is used for locating device Tcl scripts. Instead of looking
285
only in the install tree the I/O auxiliary will also look in the
286
source tree, and if the script there is more recent than the installed
287
version it will be used in preference. This allows developers to
288
modify the master copy without having to run <B
289
CLASS="COMMAND"
290
>make
291
install</B
292
> all the time.
293
    </P
294
><P
295
>If a script needs to know where it has been installed it can examine
296
the Tcl variable <TT
297
CLASS="VARNAME"
298
>synth::device_install_dir</TT
299
> . This
300
variable gets updated whenever a  script is loaded, so if the
301
value may be needed later it should be saved away in a device-specific
302
variable.
303
    </P
304
></DIV
305
><DIV
306
CLASS="REFSECT1"
307
><A
308
NAME="SYNTH-NEW-HOST-INSTANTIATION"
309
></A
310
><H2
311
>Instantiation</H2
312
><P
313
>The I/O auxiliary will <B
314
CLASS="COMMAND"
315
>source</B
316
> the device-specific
317
Tcl script when the eCos application first attempts to instantiate a
318
device of that type. The script should return a procedure that will be
319
invoked to instantiate a device.
320
    </P
321
><TABLE
322
BORDER="5"
323
BGCOLOR="#E0E0F0"
324
WIDTH="70%"
325
><TR
326
><TD
327
><PRE
328
CLASS="PROGRAMLISTING"
329
>namespace eval ethernet {
330
    &#8230;
331
    proc instantiate { id instance data } {
332
        &#8230;
333
        return ethernet::handle_request
334
    }
335
}
336
return ethernet::instantiate</PRE
337
></TD
338
></TR
339
></TABLE
340
><P
341
>The <TT
342
CLASS="VARNAME"
343
>id</TT
344
> argument is a unique identifier for this
345
device instance. It will also be supplied on subsequent calls to the
346
request handler, and will match the return value of
347
<TT
348
CLASS="FUNCTION"
349
>synth_auxiliary_instantiate</TT
350
> on the target side. A
351
common use for this value is as an array index to support multiple
352
instances of this types of device. The <TT
353
CLASS="VARNAME"
354
>instance</TT
355
> and
356
<TT
357
CLASS="VARNAME"
358
>data</TT
359
> arguments match the corresponding arguments to
360
<TT
361
CLASS="FUNCTION"
362
>synth_auxiliary_instantiate</TT
363
> on the target side, so
364
a typical value for <TT
365
CLASS="VARNAME"
366
>instance</TT
367
> would be
368
<TT
369
CLASS="LITERAL"
370
>eth0</TT
371
>, and <TT
372
CLASS="VARNAME"
373
>data</TT
374
> is used to pass
375
arbitrary initialization parameters from target to host.
376
    </P
377
><P
378
>The actual work done by the instantiation procedure is obviously
379
device-specific. It may involve allocating an <A
380
HREF="synth-new-host.html#SYNTH-NEW-HOST-INTERRUPTS"
381
>interrupt vector</A
382
>, adding a
383
device-specific subwindow to the display, opening a real Linux device,
384
establishing a socket connection to some server, spawning a separate
385
process to handle the actual I/O, or a combination of some or all of
386
the above.
387
    </P
388
><P
389
>If the device is successfully instantiated then the return value
390
should be a handler for subsequent I/O requests. Otherwise the return
391
value should be an empty string, and on the target-side the
392
<TT
393
CLASS="FUNCTION"
394
>synth_auxiliary_instantiate</TT
395
> call will return
396
<TT
397
CLASS="LITERAL"
398
>-1</TT
399
>. The script is responsible for providing
400
<A
401
HREF="synth-new-host.html#SYNTH-NEW-HOST-OUTPUT"
402
>diagnostics</A
403
> explaining
404
why the device could not be instantiated.
405
    </P
406
></DIV
407
><DIV
408
CLASS="REFSECT1"
409
><A
410
NAME="SYNTH-NEW-HOST-REQUESTS"
411
></A
412
><H2
413
>Handling Requests</H2
414
><P
415
>When the target-side calls
416
<TT
417
CLASS="FUNCTION"
418
>synth_auxiliary_xchgmsg</TT
419
>, the I/O auxiliary will
420
end up calling the request handler for the appropriate device instance
421
returned during instantiation:
422
    </P
423
><TABLE
424
BORDER="5"
425
BGCOLOR="#E0E0F0"
426
WIDTH="70%"
427
><TR
428
><TD
429
><PRE
430
CLASS="PROGRAMLISTING"
431
>namespace eval ethernet {
432
    &#8230;
433
    proc handle_request { id request arg1 arg2 txdata txlen max_rxlen } {
434
        &#8230;
435
        if { &lt;some condition&gt; } {
436
            synth::send_reply &lt;error code&gt; 0 ""
437
            return
438
        }
439
        &#8230;
440
        synth::send_reply &lt;reply code&gt; $packet_len $packet
441
    }
442
    &#8230;
443
}</PRE
444
></TD
445
></TR
446
></TABLE
447
><P
448
>The <TT
449
CLASS="VARNAME"
450
>id</TT
451
> argument is the same device id that was
452
passed to the instantiate function, and is typically used as an array
453
index to access per-device data. The <TT
454
CLASS="VARNAME"
455
>request</TT
456
>,
457
<TT
458
CLASS="VARNAME"
459
>arg1</TT
460
>, <TT
461
CLASS="VARNAME"
462
>arg2</TT
463
>, and
464
<TT
465
CLASS="VARNAME"
466
>max_rxlen</TT
467
> are the same values that were passed to
468
<TT
469
CLASS="FUNCTION"
470
>synth_auxiliary_xchgmsg</TT
471
> on the target-side,
472
although since this is a Tcl script obviously the numbers have been
473
converted to strings. The <TT
474
CLASS="VARNAME"
475
>txdata</TT
476
> buffer is raw data
477
as transmitted by the target, or an empty string if the I/O operation
478
does not involve any additional data. The Tcl procedures
479
<B
480
CLASS="COMMAND"
481
>binary scan</B
482
>, <B
483
CLASS="COMMAND"
484
>string index</B
485
> and
486
<B
487
CLASS="COMMAND"
488
>string range</B
489
> may be found especially useful when
490
manipulating this buffer. <TT
491
CLASS="VARNAME"
492
>txlen</TT
493
> is provided for
494
convenience, although <B
495
CLASS="COMMAND"
496
>string length $txdata</B
497
> would
498
give the same information.
499
    </P
500
><P
501
>The code for actually processing the request is of course device
502
specific. If the target does not expect a reply then the request
503
handler should just return when finished. If a reply is expected then
504
there should be a call to <B
505
CLASS="COMMAND"
506
>synth::send_reply</B
507
>. The
508
first argument is the reply code, and will be turned into a 32-bit
509
integer on the target side. The second argument specifies the length
510
of the reply data, and the third argument is the reply data itself.
511
For some devices the Tcl procedure <B
512
CLASS="COMMAND"
513
>binary format</B
514
>
515
may prove useful. If the reply involves just a code and no additional
516
data, the second and third arguments should be <TT
517
CLASS="LITERAL"
518
>0</TT
519
>
520
and an empty string respectively.
521
    </P
522
><P
523
>Attempts to send a reply when none is expected, fail to send a reply
524
when one is expected, or send a reply that is larger than the
525
target-side expects, will all be detected by the I/O auxiliary and
526
result in run-time error messages.
527
    </P
528
><P
529
>It is not possible for the host-side code to send unsolicited messages
530
to the target. If host-side code needs attention from the target, for
531
example because some I/O operation has completed, then an interrupt
532
should be raised.
533
    </P
534
></DIV
535
><DIV
536
CLASS="REFSECT1"
537
><A
538
NAME="SYNTH-NEW-HOST-INTERRUPTS"
539
></A
540
><H2
541
>Interrupts</H2
542
><P
543
>The I/O auxiliary provides a number of procedures for interrupt
544
handling.
545
    </P
546
><TABLE
547
BORDER="5"
548
BGCOLOR="#E0E0F0"
549
WIDTH="70%"
550
><TR
551
><TD
552
><PRE
553
CLASS="PROGRAMLISTING"
554
>synth::interrupt_allocate &lt;name&gt;
555
synth::interrupt_get_max
556
synth::interrupt_get_devicename &lt;vector&gt;
557
synth::interrupt_raise &lt;vector&gt;</PRE
558
></TD
559
></TR
560
></TABLE
561
><P
562
><B
563
CLASS="COMMAND"
564
>synth::interrupt_allocate</B
565
> is normally called during
566
device instantiation, and returns the next free interrupt vector. This
567
can be passed on to the target-side device driver in response to a
568
suitable request, and it can then install an interrupt handler on that
569
vector. Interrupt vector <TT
570
CLASS="LITERAL"
571
>0</TT
572
> is used within the
573
target-side code for the real-time clock, so the allocated vectors
574
will start at <TT
575
CLASS="LITERAL"
576
>1</TT
577
>. The argument identifies the
578
device, for example <TT
579
CLASS="LITERAL"
580
>eth0</TT
581
>. This is not actually used
582
internally, but can be accessed by user-initialization scripts that
583
provide some sort of interrupt monitoring facility (typically via the
584
<TT
585
CLASS="LITERAL"
586
>interrupt</TT
587
> <A
588
HREF="synth-new-host.html#SYNTH-NEW-HOST-HOOKS"
589
>hook</A
590
>). It is possible for a
591
single device to allocate multiple interrupt vectors, but the
592
synthetic target supports a maximum of 32 such vectors.
593
    </P
594
><P
595
><B
596
CLASS="COMMAND"
597
>synth::interrupt_get_max</B
598
> returns the highest
599
interrupt vector that has been allocated, or <TT
600
CLASS="LITERAL"
601
>0</TT
602
> if
603
there have been no calls to
604
<B
605
CLASS="COMMAND"
606
>synth::interrupt_allocate</B
607
>.
608
<B
609
CLASS="COMMAND"
610
>synth::interrupt_get_devicename</B
611
> returns the string
612
that was passed to <B
613
CLASS="COMMAND"
614
>synth::interrupt_allocate</B
615
> when
616
the vector was allocated.
617
    </P
618
><P
619
><B
620
CLASS="COMMAND"
621
>synth::interrupt_raise</B
622
> can be called any time after
623
initialization. The argument should be the vector returned by
624
<B
625
CLASS="COMMAND"
626
>synth::interrupt_allocate</B
627
> for this device. It will
628
activate the normal eCos interrupt handling mechanism so, subject to
629
interrupts being enabled and this particular interrupt not being
630
masked out, the appropriate ISR will run.
631
    </P
632
><DIV
633
CLASS="NOTE"
634
><BLOCKQUOTE
635
CLASS="NOTE"
636
><P
637
><B
638
>Note: </B
639
>At this time it is not possible for a device to allocate a specific
640
interrupt vector. The order in which interrupt vectors are assigned to
641
devices effectively depends on the order in which the eCos devices get
642
initialized, and that may change if the eCos application is rebuilt. A
643
future extension may allow devices to allocate specific vectors, thus
644
making things more deterministic. However that will introduce new
645
problems, in particular the code will have to start worrying about
646
requests for vectors that have already been allocated.
647
    </P
648
></BLOCKQUOTE
649
></DIV
650
></DIV
651
><DIV
652
CLASS="REFSECT1"
653
><A
654
NAME="SYNTH-NEW-HOST-ARGS"
655
></A
656
><H2
657
>Flags and Command Line Arguments</H2
658
><P
659
>The generic I/O auxiliary code will process the standard command line
660
arguments, and will set various flag variables accordingly. Some of
661
these should be checked by device-specific scripts.
662
    </P
663
><P
664
></P
665
><DIV
666
CLASS="VARIABLELIST"
667
><DL
668
><DT
669
><TT
670
CLASS="VARNAME"
671
>synth::flag_gui</TT
672
></DT
673
><DD
674
><P
675
>This is set when the I/O auxiliary is operating in graphical mode
676
rather than text mode. Some functionality such as filters and the GUI
677
layout are only available in graphical mode.
678
        </P
679
><TABLE
680
BORDER="5"
681
BGCOLOR="#E0E0F0"
682
WIDTH="70%"
683
><TR
684
><TD
685
><PRE
686
CLASS="PROGRAMLISTING"
687
>    if { $synth::flag_gui } {
688
        &#8230;
689
    }</PRE
690
></TD
691
></TR
692
></TABLE
693
></DD
694
><DT
695
><TT
696
CLASS="VARNAME"
697
>synth::flag_verbose</TT
698
></DT
699
><DD
700
><P
701
>The user has requested additional information during startup. Each
702
device driver can decide how much additional information, if any,
703
should be produced.
704
         </P
705
></DD
706
><DT
707
><TT
708
CLASS="VARNAME"
709
>synth::flag_keep_going</TT
710
></DT
711
><DD
712
><P
713
>The user has specified <TT
714
CLASS="OPTION"
715
>-k</TT
716
> or
717
<TT
718
CLASS="OPTION"
719
>--keep-going</TT
720
>, so even if an error occurs the I/O
721
auxiliary and the various device driver scripts should continue running
722
if at all possible. Diagnostics should still be generated.
723
        </P
724
></DD
725
></DL
726
></DIV
727
><P
728
>Some scripts may want to support additional command line arguments.
729
This facility should be used with care since there is no way to
730
prevent two different scripts from trying to use the same argument.
731
The following Tcl procedures are available:
732
    </P
733
><TABLE
734
BORDER="5"
735
BGCOLOR="#E0E0F0"
736
WIDTH="70%"
737
><TR
738
><TD
739
><PRE
740
CLASS="PROGRAMLISTING"
741
>synth::argv_defined &lt;name&gt;
742
synth::argv_get_value &lt;name&gt;</PRE
743
></TD
744
></TR
745
></TABLE
746
><P
747
><B
748
CLASS="COMMAND"
749
>synth::argv_defined</B
750
> returns a boolean to indicate
751
whether or not a particular argument is present. If the argument is
752
the name part of a name/value pair, an <TT
753
CLASS="LITERAL"
754
>=</TT
755
> character
756
should be appended. Typical uses might be:
757
    </P
758
><TABLE
759
BORDER="5"
760
BGCOLOR="#E0E0F0"
761
WIDTH="70%"
762
><TR
763
><TD
764
><PRE
765
CLASS="PROGRAMLISTING"
766
>    if { [synth::argv_defined "-o13"] } {
767
        &#8230;
768
    }
769
 
770
    if { [synth::argv_defined "-mark="] } {
771
        &#8230;
772
    }</PRE
773
></TD
774
></TR
775
></TABLE
776
><P
777
>The first call checks for a flag <TT
778
CLASS="LITERAL"
779
>-o13</TT
780
> or
781
<TT
782
CLASS="LITERAL"
783
>--o13</TT
784
> - the code treats options with single and
785
double hyphens interchangeably. The second call checks for an argument
786
of the form <TT
787
CLASS="LITERAL"
788
>-mark=&lt;value&gt;</TT
789
> or a pair of
790
arguments <TT
791
CLASS="LITERAL"
792
>-mark &lt;value&gt;</TT
793
>. The value part of a
794
name/value pair can be obtained using
795
<B
796
CLASS="COMMAND"
797
>synth::argv_get_value</B
798
>;
799
    </P
800
><TABLE
801
BORDER="5"
802
BGCOLOR="#E0E0F0"
803
WIDTH="70%"
804
><TR
805
><TD
806
><PRE
807
CLASS="PROGRAMLISTING"
808
>    variable speed 1
809
    if { [synth::argv_defined "-mark="] } {
810
        set mark [synth::argv_get_value "-mark="]
811
        if { ![string is integer $mark] || ($mark &#60; 1) || ($mark &#62; 9) } {
812
            &lt;issue diagnostic&gt;
813
        } else {
814
            set speed $mark
815
        }
816
    }</PRE
817
></TD
818
></TR
819
></TABLE
820
><P
821
><B
822
CLASS="COMMAND"
823
>synth::argv_get_value</B
824
> should only be used after a
825
successful call to <B
826
CLASS="COMMAND"
827
>synth::argv_defined</B
828
>.
829
At present there is no support for some advanced forms of command line
830
argument processing. For example it is not possible to repeat a
831
certain option such as <TT
832
CLASS="OPTION"
833
>-v</TT
834
> or
835
<TT
836
CLASS="OPTION"
837
>--verbose</TT
838
>, with each occurrence increasing the level
839
of verbosity.
840
    </P
841
><P
842
>If a script is going to have its own set of command-line arguments
843
then it should give appropriate details if the user specifies
844
<TT
845
CLASS="OPTION"
846
>--help</TT
847
>. This involves a hook function:
848
    </P
849
><TABLE
850
BORDER="5"
851
BGCOLOR="#E0E0F0"
852
WIDTH="70%"
853
><TR
854
><TD
855
><PRE
856
CLASS="PROGRAMLISTING"
857
>namespace eval my_device {
858
    proc help_hook { } {
859
        puts " -o13          : activate the omega 13 device"
860
        puts " -mark &lt;speed&gt; : set speed. Valid values are 1 to 9."
861
    }
862
 
863
    synth::hook_add "help" my_device::help_hook
864
}</PRE
865
></TD
866
></TR
867
></TABLE
868
></DIV
869
><DIV
870
CLASS="REFSECT1"
871
><A
872
NAME="SYNTH-NEW-HOST-TDF"
873
></A
874
><H2
875
>The Target Definition File</H2
876
><P
877
>Most device scripts will want to check entries in the target
878
definition file for run-time configuration information. The Tcl
879
procedures for this are as follows:
880
    </P
881
><TABLE
882
BORDER="5"
883
BGCOLOR="#E0E0F0"
884
WIDTH="70%"
885
><TR
886
><TD
887
><PRE
888
CLASS="PROGRAMLISTING"
889
>synth::tdf_has_device &lt;name&gt;
890
synth::tdf_get_devices
891
synth::tdf_has_option &lt;devname&gt; &lt;option&gt;
892
synth::tdf_get_option &lt;devname&gt; &lt;option&gt;
893
synth::tdf_get_options &lt;devname&gt; &lt;option&gt;
894
synth::tdf_get_all_options &lt;devname&gt;</PRE
895
></TD
896
></TR
897
></TABLE
898
><P
899
><B
900
CLASS="COMMAND"
901
>synth::tdf_has_device</B
902
> can be used to check whether
903
or not the target definition file had an entry
904
<TT
905
CLASS="LITERAL"
906
>synth_device&nbsp;&lt;name&gt;</TT
907
>. Usually the name
908
will match the type of device, so the
909
<TT
910
CLASS="FILENAME"
911
>console.tcl</TT
912
> script will look for a target
913
definition file entry <TT
914
CLASS="LITERAL"
915
>console</TT
916
>.
917
<B
918
CLASS="COMMAND"
919
>synth::tdf_get_devices</B
920
> returns a list of all
921
device entries in the target definition file.
922
    </P
923
><P
924
>Once it is known that the target definition file has an entry for a
925
certain device, it is possible to check for options within the entry.
926
<B
927
CLASS="COMMAND"
928
>synth::tdf_has_option</B
929
> just checks for the presence,
930
returning a boolean:
931
    </P
932
><TABLE
933
BORDER="5"
934
BGCOLOR="#E0E0F0"
935
WIDTH="70%"
936
><TR
937
><TD
938
><PRE
939
CLASS="PROGRAMLISTING"
940
>    if { [synth::tdf_has_option "console" "appearance"] } {
941
        &#8230;
942
    }</PRE
943
></TD
944
></TR
945
></TABLE
946
><P
947
><B
948
CLASS="COMMAND"
949
>synth::tdf_get_option</B
950
> returns a list of all the
951
arguments for a given option. For example, if the target definition
952
file contains an entry:
953
    </P
954
><TABLE
955
BORDER="5"
956
BGCOLOR="#E0E0F0"
957
WIDTH="70%"
958
><TR
959
><TD
960
><PRE
961
CLASS="PROGRAMLISTING"
962
>synth_device console {
963
    appearance -foreground white -background black
964
    filter trace {^TRACE:.*} -foreground HotPink1 -hide 1
965
    filter xyzzy {.*xyzzy.*} -foreground PapayaWhip
966
}</PRE
967
></TD
968
></TR
969
></TABLE
970
><P
971
>A call
972
<B
973
CLASS="COMMAND"
974
>synth::tdf_get_option&nbsp;console&nbsp;appearance</B
975
>
976
will return the list <TT
977
CLASS="LITERAL"
978
>{-foreground white -background
979
black}</TT
980
>. This list can be manipulated using standard Tcl routines
981
such as <B
982
CLASS="COMMAND"
983
>llength</B
984
> and <B
985
CLASS="COMMAND"
986
>lindex</B
987
>. Some
988
options can occur multiple times in one entry, for example
989
<TT
990
CLASS="OPTION"
991
>filter</TT
992
> in the <TT
993
CLASS="LITERAL"
994
>console</TT
995
> entry.
996
<B
997
CLASS="COMMAND"
998
>synth::tdf_get_options</B
999
> returns a list of lists,
1000
with one entry for each option occurrence.
1001
<B
1002
CLASS="COMMAND"
1003
>synth::tdf_get_all_options</B
1004
> returns a list of lists
1005
of all options. This time each entry will include the option name as
1006
well.
1007
    </P
1008
><P
1009
>The I/O auxiliary will not issue warnings about entries in the target
1010
definition file for devices which were not loaded, unless the
1011
<TT
1012
CLASS="OPTION"
1013
>-v</TT
1014
> or <TT
1015
CLASS="OPTION"
1016
>--verbose</TT
1017
> command line
1018
argument was used. This makes it easier to use a single target
1019
definition file for different applications. However the auxiliary will
1020
issue warnings about options within an entry that were ignored,
1021
because often these indicate a typing mistake of some sort. Hence a
1022
script should always call <B
1023
CLASS="COMMAND"
1024
>synth::tdf_has_option</B
1025
>,
1026
<B
1027
CLASS="COMMAND"
1028
>synth:;tdf_get_option</B
1029
> or
1030
<B
1031
CLASS="COMMAND"
1032
>synth::tdf_get_options</B
1033
> for all valid options, even
1034
if some of the options preclude the use of others.
1035
    </P
1036
></DIV
1037
><DIV
1038
CLASS="REFSECT1"
1039
><A
1040
NAME="SYNTH-NEW-HOST-HOOKS"
1041
></A
1042
><H2
1043
>Hooks</H2
1044
><P
1045
>Some scripts may want to take action when particular events occur, for
1046
example when the eCos application has exited and there is no need for
1047
further I/O. This is supported using hooks:
1048
    </P
1049
><TABLE
1050
BORDER="5"
1051
BGCOLOR="#E0E0F0"
1052
WIDTH="70%"
1053
><TR
1054
><TD
1055
><PRE
1056
CLASS="PROGRAMLISTING"
1057
>namespace eval my_device {
1058
    &#8230;
1059
    proc handle_ecos_exit { arg_list } {
1060
        &#8230;
1061
    }
1062
    synth::hook_add "ecos_exit" my_device::handle_ecos_exit
1063
}</PRE
1064
></TD
1065
></TR
1066
></TABLE
1067
><P
1068
>It is possible for device scripts to add their own hooks and call all
1069
functions registered for those hooks. A typical use for this is by
1070
user initialization scripts that want to monitor some types of I/O.
1071
The available Tcl procedures for manipulating hooks are:
1072
    </P
1073
><TABLE
1074
BORDER="5"
1075
BGCOLOR="#E0E0F0"
1076
WIDTH="70%"
1077
><TR
1078
><TD
1079
><PRE
1080
CLASS="PROGRAMLISTING"
1081
>synth::hook_define &lt;name&gt;
1082
synth::hook_defined &lt;name&gt;
1083
synth::hook_add &lt;name&gt; &lt;function&gt;
1084
synth::hook_call &lt;name&gt; &lt;args&gt;</PRE
1085
></TD
1086
></TR
1087
></TABLE
1088
><P
1089
><B
1090
CLASS="COMMAND"
1091
>synth::hook_define</B
1092
> creates a new hook with the
1093
specified name. This hook must not already exist.
1094
<B
1095
CLASS="COMMAND"
1096
>synth::hook_defined</B
1097
> can be used to check for the
1098
existence of a hook. <B
1099
CLASS="COMMAND"
1100
>synth::hook_add</B
1101
> allows other
1102
scripts to register a callback function for this hook, and
1103
<B
1104
CLASS="COMMAND"
1105
>synth::hook_call</B
1106
> allows the owner script to invoke
1107
all such callback functions. A hook must already be defined before a
1108
callback can be attached. Therefore typically device scripts will only
1109
use standard hooks and their own hooks, not hooks created by some
1110
other device, because the order of device initialization is not
1111
sufficiently defined. User scripts run from
1112
<TT
1113
CLASS="FILENAME"
1114
>mainrc.tcl</TT
1115
> can use any hooks that have been
1116
defined.
1117
    </P
1118
><P
1119
><B
1120
CLASS="COMMAND"
1121
>synth::hook_call</B
1122
> takes an arbitrary list of
1123
arguments, for example:
1124
    </P
1125
><TABLE
1126
BORDER="5"
1127
BGCOLOR="#E0E0F0"
1128
WIDTH="70%"
1129
><TR
1130
><TD
1131
><PRE
1132
CLASS="PROGRAMLISTING"
1133
>    synth::hook_call "ethernet_rx" "eth0" $packet</PRE
1134
></TD
1135
></TR
1136
></TABLE
1137
><P
1138
>The callback function will always be invoked with a single argument,
1139
a list of the arguments that were passed to
1140
<B
1141
CLASS="COMMAND"
1142
>synth::hook_call</B
1143
>:
1144
    </P
1145
><TABLE
1146
BORDER="5"
1147
BGCOLOR="#E0E0F0"
1148
WIDTH="70%"
1149
><TR
1150
><TD
1151
><PRE
1152
CLASS="PROGRAMLISTING"
1153
>    proc rx_callback { arg_list } {
1154
        set device [lindex $arg_list 0]
1155
        set packet [lindex $arg_list 1]
1156
    }</PRE
1157
></TD
1158
></TR
1159
></TABLE
1160
><P
1161
>Although it might seem more appropriate to use Tcl's
1162
<B
1163
CLASS="COMMAND"
1164
>eval</B
1165
> procedure and have the callback functions
1166
invoked with the right number of arguments rather than a single list,
1167
that would cause serious problems if any of the data contained special
1168
characters such as <TT
1169
CLASS="LITERAL"
1170
>[</TT
1171
> or <TT
1172
CLASS="LITERAL"
1173
>$</TT
1174
>. The
1175
current implementation of hooks avoids such problems, at the cost of
1176
minor inconvenience when writing callbacks.
1177
    </P
1178
><P
1179
>A number of hooks are defined as standard. Some devices will add
1180
additional hooks, and the device-specific documentation should be
1181
consulted for those. User scripts can add their own hooks if desired.
1182
    </P
1183
><P
1184
></P
1185
><DIV
1186
CLASS="VARIABLELIST"
1187
><DL
1188
><DT
1189
><TT
1190
CLASS="LITERAL"
1191
>exit</TT
1192
></DT
1193
><DD
1194
><P
1195
>This hook is called just before the I/O auxiliary exits. Hence it
1196
provides much the same functionality as <TT
1197
CLASS="FUNCTION"
1198
>atexit</TT
1199
> in
1200
C programs. The argument list passed to the callback function will be
1201
empty.
1202
        </P
1203
></DD
1204
><DT
1205
><TT
1206
CLASS="LITERAL"
1207
>ecos_exit</TT
1208
></DT
1209
><DD
1210
><P
1211
>This hook is called when the eCos application has exited. It is used
1212
mainly to shut down I/O operations: if the application is no longer
1213
running then there is no point in raising interrupts or storing
1214
incoming packets. The callback argument list will be empty.
1215
        </P
1216
></DD
1217
><DT
1218
><TT
1219
CLASS="LITERAL"
1220
>ecos_initialized</TT
1221
></DT
1222
><DD
1223
><P
1224
>The synthetic target HAL will send a request to the I/O auxiliary once
1225
the static constructors have been run. All devices should now have been
1226
instantiated. A script could now check how many instances there are of
1227
a given type of device, for example ethernet devices, and create a
1228
little monitor window showing traffic on all the devices. The
1229
<TT
1230
CLASS="LITERAL"
1231
>ecos_initialized</TT
1232
> callbacks will be run just before
1233
the user's <TT
1234
CLASS="FILENAME"
1235
>mainrc.tcl</TT
1236
> script. The callback
1237
argument list will be empty.
1238
        </P
1239
></DD
1240
><DT
1241
><TT
1242
CLASS="LITERAL"
1243
>help</TT
1244
></DT
1245
><DD
1246
><P
1247
>This hook is also invoked once static constructors have been run, but
1248
only if the user specified <TT
1249
CLASS="OPTION"
1250
>-h</TT
1251
> or
1252
<TT
1253
CLASS="OPTION"
1254
>--help</TT
1255
>. Any scripts that add their own command line
1256
arguments should add a callback to this hook which outputs details of
1257
the additional arguments. The callback argument list will be empty.
1258
        </P
1259
></DD
1260
><DT
1261
><TT
1262
CLASS="LITERAL"
1263
>interrupt</TT
1264
></DT
1265
><DD
1266
><P
1267
>Whenever a device calls <B
1268
CLASS="COMMAND"
1269
>synth::interrupt_raise</B
1270
> the
1271
<TT
1272
CLASS="LITERAL"
1273
>interrupt</TT
1274
> hook will be called with a single
1275
argument, the interrupt vector. The main use for this is to allow
1276
user scripts to monitor interrupt traffic.
1277
        </P
1278
></DD
1279
></DL
1280
></DIV
1281
></DIV
1282
><DIV
1283
CLASS="REFSECT1"
1284
><A
1285
NAME="SYNTH-NEW-HOST-OUTPUT"
1286
></A
1287
><H2
1288
>Output and Filters</H2
1289
><P
1290
>Scripts can use conventional facilities for sending text output to the
1291
user, for example calling <B
1292
CLASS="COMMAND"
1293
>puts</B
1294
> or directly
1295
manipulating the central text widget
1296
<TT
1297
CLASS="VARNAME"
1298
>.main.centre.text</TT
1299
>. However in nearly all cases it
1300
is better to use output facilities provided by the I/O auxiliary
1301
itself:
1302
    </P
1303
><TABLE
1304
BORDER="5"
1305
BGCOLOR="#E0E0F0"
1306
WIDTH="70%"
1307
><TR
1308
><TD
1309
><PRE
1310
CLASS="PROGRAMLISTING"
1311
>synth::report &lt;msg&gt;
1312
synth::report_warning &lt;msg&gt;
1313
synth::report_error &lt;msg&gt;
1314
synth::internal_error &lt;msg&gt;
1315
synth::output &lt;msg&gt; &lt;filter&gt;</PRE
1316
></TD
1317
></TR
1318
></TABLE
1319
><P
1320
><B
1321
CLASS="COMMAND"
1322
>synth::report</B
1323
> is intended for messages related to
1324
the operation of the I/O auxiliary itself, especially additional
1325
output resulting from <TT
1326
CLASS="OPTION"
1327
>-v</TT
1328
> or
1329
<TT
1330
CLASS="OPTION"
1331
>--verbose</TT
1332
>. If running in text mode the output will go
1333
to standard output. If running in graphical mode the output will go to
1334
the central text window. In both modes, use of <TT
1335
CLASS="OPTION"
1336
>-l</TT
1337
> or
1338
<TT
1339
CLASS="OPTION"
1340
>--logfile</TT
1341
> will modify the behaviour.
1342
    </P
1343
><P
1344
><B
1345
CLASS="COMMAND"
1346
>synth::report_warning</B
1347
>,
1348
<B
1349
CLASS="COMMAND"
1350
>synth::report_error</B
1351
> and
1352
<B
1353
CLASS="COMMAND"
1354
>synth::internal_error</B
1355
> have the obvious meaning,
1356
including prepending strings such as <TT
1357
CLASS="LITERAL"
1358
>Warning:</TT
1359
> and
1360
<TT
1361
CLASS="LITERAL"
1362
>Error:</TT
1363
>. When the eCos application informs the I/O
1364
auxiliary that all static constructors have run, if at that point
1365
there have been any calls to <B
1366
CLASS="COMMAND"
1367
>synth::error</B
1368
> then the
1369
I/O auxiliary will exit. This can be suppressed with command line
1370
arguments <TT
1371
CLASS="OPTION"
1372
>-k</TT
1373
> or <TT
1374
CLASS="OPTION"
1375
>--keep-going</TT
1376
>.
1377
<B
1378
CLASS="COMMAND"
1379
>synth::internal_error</B
1380
> will output some information
1381
about the current state of the I/O auxiliary and then exit
1382
immediately. Of course it should never be necessary to call this
1383
function.
1384
    </P
1385
><P
1386
><B
1387
CLASS="COMMAND"
1388
>synth::output</B
1389
> is the main routine for outputting
1390
text. The second argument identifies a filter. If running in text mode
1391
the filter is ignored, but if running in graphical mode the filter can
1392
be used to control the appearance of this output. A typical use would
1393
be:
1394
    </P
1395
><TABLE
1396
BORDER="5"
1397
BGCOLOR="#E0E0F0"
1398
WIDTH="70%"
1399
><TR
1400
><TD
1401
><PRE
1402
CLASS="PROGRAMLISTING"
1403
>    synth::output $line "console"</PRE
1404
></TD
1405
></TR
1406
></TABLE
1407
><P
1408
>This outputs a single line of text using the
1409
<TT
1410
CLASS="LITERAL"
1411
>console</TT
1412
> filter. If running in graphical mode the
1413
default appearance of this text can be modified with the
1414
<TT
1415
CLASS="OPTION"
1416
>appearance</TT
1417
> option in the
1418
<B
1419
CLASS="COMMAND"
1420
>synth_device&nbsp;console</B
1421
> entry of the target
1422
definition file. The <SPAN
1423
CLASS="GUIMENUITEM"
1424
>System filters</SPAN
1425
> menu
1426
option can be used to change the appearance at run-time.
1427
    </P
1428
><P
1429
>Filters should be created before they are used. The procedures
1430
available for this are:
1431
    </P
1432
><TABLE
1433
BORDER="5"
1434
BGCOLOR="#E0E0F0"
1435
WIDTH="70%"
1436
><TR
1437
><TD
1438
><PRE
1439
CLASS="PROGRAMLISTING"
1440
>synth::filter_exists &lt;name&gt;
1441
synth::filter_get_list
1442
synth::filter_add &lt;name&gt; [options]
1443
synth::filter_parse_options &lt;options&gt; &lt;parsed_options&gt; &lt;message&gt;
1444
synth::filter_add_parsed &lt;name&gt; &lt;parsed_options&gt;</PRE
1445
></TD
1446
></TR
1447
></TABLE
1448
><P
1449
><B
1450
CLASS="COMMAND"
1451
>synth::filter_exists</B
1452
> can be used to check whether
1453
or not a particular filter already exists: creating two filters with
1454
the same name is not allowed.
1455
<B
1456
CLASS="COMMAND"
1457
>synth::filter_get_list</B
1458
> returns a list of the
1459
current known filters. <B
1460
CLASS="COMMAND"
1461
>synth::filter_add</B
1462
> can be
1463
used to create a new filter. The first argument names the new filter,
1464
and the remaining arguments control the initial appearance. A typical
1465
use might be:
1466
    </P
1467
><TABLE
1468
BORDER="5"
1469
BGCOLOR="#E0E0F0"
1470
WIDTH="70%"
1471
><TR
1472
><TD
1473
><PRE
1474
CLASS="PROGRAMLISTING"
1475
>    synth::filter_add "my_device_tx" -foreground yellow -hide 1</PRE
1476
></TD
1477
></TR
1478
></TABLE
1479
><P
1480
>It is assumed that the supplied arguments are valid, which typically
1481
means that they are hard-wired in the script. If instead the data
1482
comes out of a configuration file and hence may be invalid, the
1483
I/O auxiliary provides a parsing utility. Typical usage would be:
1484
    </P
1485
><TABLE
1486
BORDER="5"
1487
BGCOLOR="#E0E0F0"
1488
WIDTH="70%"
1489
><TR
1490
><TD
1491
><PRE
1492
CLASS="PROGRAMLISTING"
1493
>    array set parsed_options [list]
1494
    set message ""
1495
    if { ![synth::filter_parse_options $console_appearance parsed_options message] } {
1496
        synth::report_error \
1497
                "Invalid entry in target definition file $synth::target_definition\
1498
                 \n  synth_device \"console\", entry \"appearance\"\n$message"
1499
    } else {
1500
        synth::filter_add_parsed "console" parsed_options
1501
    }</PRE
1502
></TD
1503
></TR
1504
></TABLE
1505
><P
1506
>On success <TT
1507
CLASS="VARNAME"
1508
>parsed_options</TT
1509
> will be updated with an
1510
internal representation of the desired appearance, which can then be
1511
used in a call to <B
1512
CLASS="COMMAND"
1513
>synth::filter_add_parsed</B
1514
>. On
1515
failure <TT
1516
CLASS="VARNAME"
1517
>message</TT
1518
> will be updated with details of the
1519
parsing error that occurred.
1520
    </P
1521
></DIV
1522
><DIV
1523
CLASS="REFSECT1"
1524
><A
1525
NAME="SYNTH-NEW-HOST-GUI"
1526
></A
1527
><H2
1528
>The Graphical Interface</H2
1529
><P
1530
>When the I/O auxiliary is running in graphical mode, many scripts will
1531
want to update the user interface in some way. This may be as simple
1532
as adding another entry to the help menu for the device, or adding a
1533
new button to the toolbar. It may also involve adding new subwindows,
1534
or even creating entire new toplevel windows. These may be simple
1535
monitor windows, displaying additional information about what is going
1536
on in the system in a graphical format. Alternatively they may emulate
1537
actual I/O operations, for example button widgets could be used to
1538
emulate real physical buttons.
1539
    </P
1540
><P
1541
>The I/O auxiliary does not provide many procedures related to the
1542
graphical interface. Instead it is expected that scripts will just
1543
update the widget hierarchy directly.
1544
    </P
1545
><DIV
1546
CLASS="INFORMALFIGURE"
1547
><A
1548
NAME="AEN1018"><P
1549
></P
1550
><DIV
1551
CLASS="MEDIAOBJECT"
1552
><P
1553
><IMG
1554
SRC="layout.gif"
1555
ALIGN="CENTER"></P
1556
></DIV
1557
><P
1558
></P
1559
></DIV
1560
><P
1561
>So adding a new item to the <SPAN
1562
CLASS="GUIMENU"
1563
>Help</SPAN
1564
> menu involves a
1565
<B
1566
CLASS="COMMAND"
1567
>.menubar.help&nbsp;add</B
1568
> operation with suitable
1569
arguments. Adding a new button to the toolbar involves creating a
1570
child window in <TT
1571
CLASS="VARNAME"
1572
>.toolbar</TT
1573
> and packing it
1574
appropriately. Scripts can create their own subwindows and then pack
1575
it into one of <TT
1576
CLASS="VARNAME"
1577
>.main.nw</TT
1578
>,
1579
<TT
1580
CLASS="VARNAME"
1581
>.main.n</TT
1582
>, <TT
1583
CLASS="VARNAME"
1584
>.main.ne</TT
1585
>,
1586
<TT
1587
CLASS="VARNAME"
1588
>.main.w</TT
1589
>, <TT
1590
CLASS="VARNAME"
1591
>.main.e</TT
1592
>,
1593
<TT
1594
CLASS="VARNAME"
1595
>.main.sw</TT
1596
>, <TT
1597
CLASS="VARNAME"
1598
>.main.s</TT
1599
> or
1600
<TT
1601
CLASS="VARNAME"
1602
>.main.se</TT
1603
>. Normally the user should be allowed to
1604
<A
1605
HREF="synth-gui.html#SYNTH-GUI-LAYOUT"
1606
>control</A
1607
> this via the target
1608
definition file. The central window <TT
1609
CLASS="VARNAME"
1610
>.main.centre</TT
1611
>
1612
should normally be left alone by other scripts since it gets used for
1613
text output.
1614
    </P
1615
><P
1616
>The following graphics-related utilities may be found useful:
1617
    </P
1618
><TABLE
1619
BORDER="5"
1620
BGCOLOR="#E0E0F0"
1621
WIDTH="70%"
1622
><TR
1623
><TD
1624
><PRE
1625
CLASS="PROGRAMLISTING"
1626
>synth::load_image &lt;image name&gt; &lt;filename&gt;
1627
synth::register_ballon_help &lt;widget&gt; &lt;message&gt;
1628
synth::handle_help &lt;URL&gt;</PRE
1629
></TD
1630
></TR
1631
></TABLE
1632
><P
1633
><B
1634
CLASS="COMMAND"
1635
>synth::load_image</B
1636
> can be used to add a new image to
1637
the current interpreter. If the specified file has a
1638
<TT
1639
CLASS="FILENAME"
1640
>.xbm</TT
1641
> extension then the image will be a
1642
monochrome bitmap, otherwise it will be a colour image of some sort.
1643
A boolean will be returned to indicate success or failure, and
1644
suitable diagnostics will be generated if necessary.
1645
    </P
1646
><P
1647
><B
1648
CLASS="COMMAND"
1649
>synth::register_balloon_help</B
1650
> provides balloon help
1651
for a specific widget, usually a button on the toolbar.
1652
    </P
1653
><P
1654
><B
1655
CLASS="COMMAND"
1656
>synth::handle_help</B
1657
> is a utility routine that can be
1658
installed as the command for displaying online help, for example:
1659
    </P
1660
><TABLE
1661
BORDER="5"
1662
BGCOLOR="#E0E0F0"
1663
WIDTH="70%"
1664
><TR
1665
><TD
1666
><PRE
1667
CLASS="PROGRAMLISTING"
1668
>    .menubar.help add command -label "my device" -command \
1669
        [list synth::handle_help "file://$path"]</PRE
1670
></TD
1671
></TR
1672
></TABLE
1673
></DIV
1674
><DIV
1675
CLASS="NAVFOOTER"
1676
><HR
1677
ALIGN="LEFT"
1678
WIDTH="100%"><TABLE
1679
SUMMARY="Footer navigation table"
1680
WIDTH="100%"
1681
BORDER="0"
1682
CELLPADDING="0"
1683
CELLSPACING="0"
1684
><TR
1685
><TD
1686
WIDTH="33%"
1687
ALIGN="left"
1688
VALIGN="top"
1689
><A
1690
HREF="synth-new-target.html"
1691
ACCESSKEY="P"
1692
>Prev</A
1693
></TD
1694
><TD
1695
WIDTH="34%"
1696
ALIGN="center"
1697
VALIGN="top"
1698
><A
1699
HREF="hal-synth-arch.html"
1700
ACCESSKEY="H"
1701
>Home</A
1702
></TD
1703
><TD
1704
WIDTH="33%"
1705
ALIGN="right"
1706
VALIGN="top"
1707
><A
1708
HREF="synth-porting.html"
1709
ACCESSKEY="N"
1710
>Next</A
1711
></TD
1712
></TR
1713
><TR
1714
><TD
1715
WIDTH="33%"
1716
ALIGN="left"
1717
VALIGN="top"
1718
>Writing New Devices - target</TD
1719
><TD
1720
WIDTH="34%"
1721
ALIGN="center"
1722
VALIGN="top"
1723
>&nbsp;</TD
1724
><TD
1725
WIDTH="33%"
1726
ALIGN="right"
1727
VALIGN="top"
1728
>Porting</TD
1729
></TR
1730
></TABLE
1731
></DIV
1732
></BODY
1733
></HTML
1734
>

powered by: WebSVN 2.1.0

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