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-host.html] - Blame information for rev 314

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

powered by: WebSVN 2.1.0

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