-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmanual.html
4243 lines (3604 loc) · 121 KB
/
manual.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
lang="en" xml:lang="en">
<head>
<title>Riscy Pygness User Manual</title>
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"/>
<meta name="generator" content="Org-mode"/>
<meta name="generated" content="2010-11-10 Wed"/>
<meta name="author" content="Frank Sergeant"/>
<style type="text/css">
<!--/*--><![CDATA[/*><!--*/
html { font-family: Times, serif; font-size: 12pt; }
.title { text-align: center; }
.todo { color: red; }
.done { color: green; }
.tag { background-color:lightblue; font-weight:normal }
.target { }
.timestamp { color: grey }
.timestamp-kwd { color: CadetBlue }
p.verse { margin-left: 3% }
pre {
border: 1pt solid #AEBDCC;
background-color: #F3F5F7;
padding: 5pt;
font-family: courier, monospace;
font-size: 90%;
overflow:auto;
}
table { border-collapse: collapse; }
td, th { vertical-align: top; }
dt { font-weight: bold; }
div.figure { padding: 0.5em; }
div.figure p { text-align: center; }
.linenr { font-size:smaller }
.code-highlighted {background-color:#ffff00;}
.org-info-js_info-navigation { border-style:none; }
#org-info-js_console-label { font-size:10px; font-weight:bold;
white-space:nowrap; }
.org-info-js_search-highlight {background-color:#ffff00; color:#000000;
font-weight:bold; }
/*]]>*/-->
</style>
<script type="text/javascript">
<!--/*--><![CDATA[/*><!--*/
function CodeHighlightOn(elem, id)
{
var target = document.getElementById(id);
if(null != target) {
elem.cacheClassElem = elem.className;
elem.cacheClassTarget = target.className;
target.className = "code-highlighted";
elem.className = "code-highlighted";
}
}
function CodeHighlightOff(elem, id)
{
var target = document.getElementById(id);
if(elem.cacheClassElem)
elem.className = elem.cacheClassElem;
if(elem.cacheClassTarget)
target.className = elem.cacheClassTarget;
}
/*]]>*/-->
</script>
</head><body>
<h1 class="title">Riscy Pygness User Manual</h1>
<div id="table-of-contents">
<h2>Table of Contents</h2>
<div id="text-table-of-contents">
<ul>
<li><a href="#sec-1">1 Introduction </a></li>
<li><a href="#sec-2">2 Installation </a>
<ul>
<li><a href="#sec-2.1">2.1 Choosing a computer for the host </a></li>
<li><a href="#sec-2.2">2.2 Installing the system tools </a></li>
<li><a href="#sec-2.3">2.3 Installing Riscy Pygness </a></li>
</ul>
</li>
<li><a href="#sec-3">3 Getting started using an existing image </a></li>
<li><a href="#sec-4">4 Source code </a>
<ul>
<li><a href="#sec-4.1">4.1 Install Emacs and forthblocks mode </a></li>
<li><a href="#sec-4.2">4.2 Blocks </a></li>
<li><a href="#sec-4.3">4.3 Text files </a></li>
</ul>
</li>
<li><a href="#sec-5">5 Creating a new kernel image </a></li>
<li><a href="#sec-6">6 Multitasking </a>
<ul>
<li><a href="#sec-6.1">6.1 Creating a task </a></li>
<li><a href="#sec-6.2">6.2 Stopping and starting a task </a></li>
</ul>
</li>
<li><a href="#sec-7">7 The Forth model </a>
<ul>
<li><a href="#sec-7.1">7.1 Brief description </a></li>
<li><a href="#sec-7.2">7.2 Additional notes </a></li>
<li><a href="#sec-7.3">7.3 Internals and Design </a></li>
</ul>
</li>
<li><a href="#sec-8">8 Documentation for individual program files </a>
<ul>
<li><a href="#sec-8.1">8.1 makefile </a></li>
<li><a href="#sec-8.2">8.2 riscy.tcl </a></li>
<li><a href="#sec-8.3">8.3 riscy.asm </a></li>
<li><a href="#sec-8.4">8.4 custom include files </a></li>
</ul>
</li>
<li><a href="#sec-9">9 Support Software </a>
<ul>
<li><a href="#sec-9.1">9.1 Binutils (assembler, etc.) </a></li>
<li><a href="#sec-9.2">9.2 Gdb or Insight </a></li>
<li><a href="#sec-9.3">9.3 Tcl </a></li>
<li><a href="#sec-9.4">9.4 Flash Utilities (downloaders) </a></li>
<li><a href="#sec-9.5">9.5 Make </a></li>
<li><a href="#sec-9.6">9.6 Terminal </a></li>
</ul>
</li>
<li><a href="#sec-10">10 Limitations and cautions </a>
<ul>
<li><a href="#sec-10.1">10.1 Switching <b>back</b> to interactive mode with <code>;;</code> </a></li>
<li><a href="#sec-10.2">10.2 Interactive strings </a></li>
<li><a href="#sec-10.3">10.3 C, </a></li>
<li><a href="#sec-10.4">10.4 Constants and LOAD </a></li>
</ul>
</li>
<li><a href="#sec-11">11 Appendix </a>
<ul>
<li><a href="#sec-11.1">11.1 Linux and the command line </a></li>
<li><a href="#sec-11.2">11.2 Putting Ubuntu on a USB stick </a></li>
<li><a href="#sec-11.3">11.3 Board notes </a></li>
<li><a href="#sec-11.4">11.4 Tools summary </a></li>
<li><a href="#sec-11.5">11.5 FAQ </a></li>
<li><a href="#sec-11.6">11.6 JTAG and OpenOCD </a></li>
<li><a href="#sec-11.7">11.7 GDB </a></li>
<li><a href="#sec-11.8">11.8 Emacs </a></li>
<li><a href="#sec-11.9">11.9 Antecedents </a></li>
<li><a href="#sec-11.10">11.10 colorForth </a></li>
<li><a href="#sec-11.11">11.11 GNU Toolchain </a></li>
<li><a href="#sec-11.12">11.12 Makefile automatic variables </a></li>
<li><a href="#sec-11.13">11.13 Troubleshooting </a></li>
<li><a href="#sec-11.14">11.14 Supported Processors </a></li>
</ul>
</li>
<li><a href="#sec-12">12 Contact Information </a></li>
</ul>
</div>
</div>
<div id="outline-container-1" class="outline-2">
<h2 id="sec-1">1 Introduction </h2>
<div id="text-1">
<p>
Riscy Pygness is a 32-bit multitasking Pygmy Forth for the ARM. It
includes full source code for both the <span style="text-decoration:underline;">host</span> (your desktop PC) and
<span style="text-decoration:underline;">target</span> (your ARM development board). The license is BSD/MIT-like so
you can do (nearly) anything you like with it.
</p>
<p>
It is aimed at relatively small embedded ARM systems rather than
desktop ARM systems or large embedded ARM systems running an operating
system (OS). Riscy Pygness is a stand-alone system that is its own
multitasking OS. The current version needs about 4 KB of flash and
1.5 KB RAM. (The size can be reduced further depending on your
needs.) This makes it suitable for use in even the smaller ARM
variants such as these NXP (formerly Philips) chips
</p>
<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
<col align="left"></col><col align="left"></col><col align="left"></col>
<thead>
<tr><th>variant</th><th>flash</th><th>RAM</th></tr>
</thead>
<tbody>
<tr><td>LPC2101</td><td>8 KB</td><td>2 KB</td></tr>
<tr><td>LPC2102</td><td>16 KB</td><td>4 KB</td></tr>
<tr><td>LPC2103</td><td>32 KB</td><td>8 KB</td></tr>
</tbody>
</table>
<p>
It can address the full 4 GB address space, so it can take advantage
of all the flash and RAM available in the larger variants.
</p>
<p>
During development, the host communicates with the target via a serial
port. The host provides the smart terminal and the compiling
services. The host can generate a new, customized Forth image for the
target.
</p>
<p>
The Forth itself runs on the target but you interact with it by typing
commands on the host, much as you would with a Forth running locally
on the host.
</p>
<p>
As you type each line of Forth words (commands) at the terminal, the
line is compiled on the host then transmitted to the target either to
be executed immediately (when "interpreting") or to extend the
dictionary on the target (when "compiling"). (Yes, in either case, it
is compiled on the host.) Numbers typed at the terminal are sent to
the target to be put on the target's data stack. Word headers are
kept on the host, not the target, and all compilation work is done on
the host.
</p>
<p>
The host and the target, by working together this way, provide the
effect of a fully interactive Forth running on the target while
conserving the limited resources of the target.
</p>
<p>
The ideal way to run it is to use Linux or Unix. This can be your
main computer or a spare computer or even (via a live CD or a USB
stick) a temporary computer.
</p>
<p>
There is no particular reason you couldn't use a Microsoft OS, but I
think you will find it easier to use Linux, at least to start with.
If you don't already have a Linux computer, you can boot your computer
temporarily to Linux using one of the Live CDs (either from an actual
CD or from a USB stick), without disturbing your main computer or its
hard drive. Another alternative is to dedicate an old computer to
this purpose. <a href="#sec-2.1">*Choosing a computer for the host</a> describes several
approaches.
</p>
<p>
If you are new to computers, Linux, and the command line, it might
make reading this manual easier to take a quick look at the <a href="#sec-11.1">Linux and the command line</a> section of the <a href="#sec-11">Appendix</a>.
</p>
</div>
</div>
<div id="outline-container-2" class="outline-2">
<h2 id="sec-2">2 Installation </h2>
<div id="text-2">
</div>
<div id="outline-container-2.1" class="outline-3">
<h3 id="sec-2.1">2.1 Choosing a computer for the host </h3>
<div id="text-2.1">
<p>
If you already have an Intel (or AMD) i386 machine (i.e., an ordinary
"PC") running a 32-bit version of Linux, you are all set.
</p>
<p>
If not, and if you would rather not replace the OS on your main
machine with a 32-bit Linux, then there are two main choices to
consider:
</p>
</div>
<div id="outline-container-2.1.1" class="outline-4">
<h4 id="sec-2.1.1">2.1.1 Run Linux temporarily on your main computer </h4>
<div id="text-2.1.1">
<p>
There are several ways to do this, such as
</p>
<ul>
<li>
boot a Linux live CD (such as the Ubuntu 10.04 LTS from
<a href="http://www.ubuntu.com/desktop/get-ubuntu/download">http://www.ubuntu.com/desktop/get-ubuntu/download</a>). Note, I
recommend 10.04, since that is the version I used to compile the
bundle of tools. Still, other versions of Ubuntu, or other live
CDs, might work fine.
<p>
You might tire of installing the bundle of tools everytime you
boot, so I suggest putting the live CD onto a USB stick. See
<a href="#sec-11.2">Putting Ubuntu on a USB stick</a>. That way your the changes you make
will be persistent.
</p>
</li>
<li>
install Linux on an external disk drive (either a flash USB stick
or an external USB disk drive). Then, boot to this external drive
whenever you wish to work with Riscy Pygness.
</li>
</ul>
</div>
</div>
<div id="outline-container-2.1.2" class="outline-4">
<h4 id="sec-2.1.2">2.1.2 Run Linux on a spare computer </h4>
<div id="text-2.1.2">
<p>
Install Linux on some other computer than your main workstation.
Then
</p>
<ul>
<li>
sit at this other computer to work with Riscy Pygness, or
</li>
<li>
sit at your main workstation and connect to the other computer
through your local network. You could think of this other computer
as an <span style="text-decoration:underline;">adaptor</span> that connects your ARM board to your main computer,
even a main computer running a Microsoft OS. You would make this
connection with the <code>ssh</code> program (the modern equivalent of
<code>telnet</code>) or with VNC.
<p>
Once Linux was installed, you wouldn't particularly need to leave a
monitor or keyboard attached to the spare computer.
</p>
</li>
</ul>
<p>This spare computer can be almost any old junk computer you have lying
around. In a pinch, you could get by with 128M of RAM and a small
hard drive and possibly run Linux without a GUI (without the X Window
system). It needs a serial port, but you could use a USB-to-serial
cable.
</p>
</div>
</div>
</div>
<div id="outline-container-2.2" class="outline-3">
<h3 id="sec-2.2">2.2 Installing the system tools </h3>
<div id="text-2.2">
<p>
To run Riscy Pygness, the computer needs to have certain tools
installed, such as Tcl, an ARM cross assembler and linker, make, and a
downloader (to program a binary image into the ARM CPU's flash
memory).
</p>
<p>
This step typically needs to be done just once.
</p>
</div>
<div id="outline-container-2.2.1" class="outline-4">
<h4 id="sec-2.2.1">2.2.1 GNU toolchain for the ARM (and Tclkit) </h4>
<div id="text-2.2.1">
<p>
The easy way is to download
<a href="http://pygmy.utoh.org/riscy/arm-toolchain.tar.bz2">http://pygmy.utoh.org/riscy/arm-toolchain.tar.bz2</a> then uncompress it.
</p>
<pre class="example">
$ wget http://pygmy.utoh.org/riscy/arm-toolchain.tar.bz2
$ sudo tar -xjvf arm-toolchain.tar.bz2 --absolute-names --keep-old-files
</pre>
<p>
The first line above downloads a bundle of tools and the second line
uncompresses the bundle and places the tools where they should go.
</p>
<p>
It installs the following
</p><ul>
<li>
cross-compiling binutils to supply the ARM assembler, linker,
etc.
</li>
<li>
Tclkit to supply Tcl (the assembler pre-processor and the Riscy
Pygness smart terminal/compiler are written in Tcl)
</li>
<li>
lpc21isp (to download code to the ARM CPU's flash memory)
</li>
<li>
GDB (the GNU debugger for the ARM) in case you wish to single-step
through any assembly language code.
</li>
</ul>
<p>Note, this bundle of tools is compiled for a 32-bit version of Linux
running on Intel (AMD, etc.) hardware.
</p>
<p>
The hard way would be to install and/or compile and install those
tools yourself, one by one. In which case, you still might wish to
download the bundle of tools and then run the following command to see
which files and needed and where they go:
</p>
<pre class="example">
$ tar -tf arm-toolchain.tar.bz2
</pre>
</div>
</div>
<div id="outline-container-2.2.2" class="outline-4">
<h4 id="sec-2.2.2">2.2.2 Emacs and Make </h4>
<div id="text-2.2.2">
<p>
You also need to have an editor (I recommend Emacs) and the Make
program. Maybe your version of Linux already has one or both of
these. You can find out if they are installed by running
</p>
<pre class="example">
$ which emacs
$ which make
</pre>
<p>
If not installed, install them with the package manager that your
version of Linux uses. For example, if you are running Debian or
Ubuntu, you could install them with
</p>
<pre class="example">
$ sudo apt-get update
$ sudo apt-get install emacs
$ sudo apt-get install make
</pre>
</div>
</div>
</div>
<div id="outline-container-2.3" class="outline-3">
<h3 id="sec-2.3">2.3 Installing Riscy Pygness </h3>
<div id="text-2.3">
<p>
Download the current version named something like
<code>riscypygness-20101113.tar.bz2</code> from <a href="http://pygmy.utoh.org/riscy/">http://pygmy.utoh.org/riscy/</a> then
uncompress it. Here is an example (but change the file name to use
the current version shown on the web site):
</p>
<pre class="example">
$ cd # move to your home directory
$ wget http://pygmy.utoh.org/riscy/riscypygness-20101113.tar.bz2
$ mkdir riscy # create a directory for your Riscy Pygness work
$ cd riscy # change to that directory
$ tar -xjvf ../riscypygness-20101113.tar.bz2 # uncompress the files
</pre>
<p>
You will need to customize a few variables in <code>makefile</code> to tell it
which ARM CPU variant you are using and which serial port is connected
to the ARM board. See <a href="#sec-8.1.2">*makefile variables</a>.
</p>
<p>
One of the files is named <code>.emacs-example</code>. If you do not already
have a <code>.emacs</code> file in your home directory, you could use it to get
you started:
</p>
<pre class="example">
$ cp ~/riscy/.emacs-example ~/.emacs
</pre>
</div>
</div>
</div>
<div id="outline-container-3" class="outline-2">
<h2 id="sec-3">3 Getting started using an existing image </h2>
<div id="text-3">
<p>
The Riscy Pygness distribution comes with several pre-built,
ready-to-run kernel images. If you have an ARM board that matches one
of these images, burn the <code>*.bin</code> file into the ARM's flash, then run
with the matching <code>*.dictionary</code> file.
</p>
<p>
For example, if you have the Olimex LPC-P2106 board
(<a href="http://olimex.com/dev/lpc-p1.html">http://olimex.com/dev/lpc-p1.html</a>) (also available from Spark Fun
<a href="http://www.sparkfun.com/commerce/product_info.php?products_id=269">http://www.sparkfun.com/commerce/product_info.php?products_id=269</a>),
look for the files
</p>
<dl>
<dt>kernel-lpc2106.bin</dt><dd>
this is the binary image to be burned into
the LPC2106's flash
<p>
Burn <code>kernel-lpc2106.bin</code> into the LPC2106. You can use whatever
method you are already familiar with, or you can use the program
<code>lpc21isp</code>. See the <a href="#sec-9.4">Flash utilities section</a> for examples.
</p>
<p>
This step needs to be done just once (unless/until you generate a
new kernel).
</p>
</dd>
<dt>kernel-lpc2106.dictionary</dt><dd>
this is the matching dictionary file
<p>
Run Riscy Pygness via the <code>riscy.tcl</code> program, passing it the name of
the dictionary file and, optionally, the name of your serial port.
</p>
<pre class="example">
$ ./riscy.tcl -image kernel-lpc2106 -port /dev/ttyS0
</pre>
<p>
Of course, substitute the correct serial port name if you are not
using <code>/dev/ttyS0</code>.
</p>
<p>
This is a fairly long command line to type. You might prefer to
set up a shell script or shell alias to give you a much shorter
command to type. I use a script named <code>r</code> which is short for "run"
to type the command for me – the distribution includes this
example script. So, I start Riscy Pygness interactively by typing
</p>
<pre class="example">
$ ./r
</pre>
<p>
(be sure to edit it for your environment before using it). Or,
create a shell alias with a command such as
</p>
<pre class="example">
$ alias r='./riscy.tcl -image kernel-lpc2106 -port /dev/ttyS0'
</pre>
<p>
and put it in your <code>~/.bashrc</code> file. Then, you can start Riscy
Pygness by typing
</p>
<pre class="example">
$ r
</pre>
</dd>
</dl>
</div>
</div>
<div id="outline-container-4" class="outline-2">
<h2 id="sec-4">4 Source code </h2>
<div id="text-4">
</div>
<div id="outline-container-4.1" class="outline-3">
<h3 id="sec-4.1">4.1 Install Emacs and forthblocks mode </h3>
<div id="text-4.1">
<p>
Of course, you can edit your source code files with any text editor.
If you have a favorite, perhaps you are a <code>vi</code> enthusiast, feel free to
continue to use it. Otherwise you can install Emacs with
</p>
<p>
<code># apt-get install emacs</code>
</p>
<p>
There are some advantages to using the Emacs editor, along with the
<code>forthblocks.el</code> extension (included in Riscy Pygness). Forthblocks
mode allows you to work with plain text Forth code as if (almost as
if) you were working with block files. These are very flexible blocks
in that they can be as large or small as you like. See the <a href="#sec-11.8">Emacs</a>
section. The beginning of the file <code>forthblocks.el</code> contains details
as to how to use and install it.
</p>
<p>
Even if you are a <code>vi</code> enthusiast, you might like to use Emacs to edit
Forth source code, perhaps by installing the Emacs viper package so
you can use your familiar <code>vi</code> keystrokes.
</p>
</div>
</div>
<div id="outline-container-4.2" class="outline-3">
<h3 id="sec-4.2">4.2 Blocks </h3>
<div id="text-4.2">
</div>
<div id="outline-container-4.2.1" class="outline-4">
<h4 id="sec-4.2.1">4.2.1 blocks for source code </h4>
<div id="text-4.2.1">
<p>
Traditionally, Forth code was kept in "screens" or "blocks". Each was
a fixed size of 1024 bytes (characters), presented to the user in an
editor that showed 16 lines of 64 characters.
</p>
<p>
This size is <b>very</b> convenient for source code and encourages modularity
and short definitions.
</p>
<p>
In Riscy Pygness, we fake true 1024-byte blocks by using a text file
divided into logical blocks by special comment lines.
</p>
<p>
Each "block" starts with a special Forth comment in the first line.
The left parenthesis must be in the first column, followed by a space
and either the word "block" or the word "shadow", followed by a space
and a decimal number (the block number). Additional text may follow,
but the comment must end eventually with a right parenthesis.
</p>
<p>
When we <code>LOAD</code> a block, the host program searches for that marker to
know where to extract the text to be interpreted.
</p>
<p>
The procedure <code>filenameFromBlockNumber</code> (near the top of <code>riscy.tcl</code>)
maps block number ranges to file names. Edit it if you wish to add
additional block files or to change the ranges.
</p>
<p>
Block numbers should be in numerical order, else searching might fail.
However, "holes" (missing block numbers) are ok.
</p>
<p>
<code>riscy.tcl</code> reads the entire file into the host's memory, but only when
the file changes.
</p>
<p>
Here are some examples of special comment lines that would mark the
beginning of a block.
</p>
<pre class="example">
( block 0 )
( block 1 ------------------ load block)
( block 2 miscellaneous)
( shadow 2 )
( block 3 )
</pre>
<p>
When you type a Forth command such as <code>22 LOAD</code>, the procedure
<code>filenameFromBlockNumber</code> finds that block 22 belongs to the file
named <code>kernel.fth</code>. If this is the current file, then <code>riscy.tcl</code> has
already read it into memory (on the host), otherwise it becomes the
current file and is read into memory. Then, using the block comment
lines, <code>riscy.tcl</code> finds the range of lines to load.
</p>
<p>
Using the forthblocks mode in <a href="#sec-11.8">Emacs</a>, a single block is displayed at a
time. <code>PgDn</code> (or <code>C-v</code>) moves to the following block. <code>PgUp</code> (or <code>M-v</code>)
moves to the previous block. <code>M-a</code> ("a" for "alternate") toggles
between a block and its corresponding shadow block. Traditionally,
Forth code with short comments goes on the "block" and lengthier
comments go on the "shadow".
</p>
<p>
What I usually do when I start a new Forth file is to write one
comment line for a block and another for a shadow, e.g.,
</p>
<pre class="example">
( block 0 )
( shadow 0 )
</pre>
<p>
Then copy and paste the two a bunch of times, producing something like
</p>
<pre class="example">
( block 0 )
( shadow 0 )
( block 0 )
( shadow 0 )
( block 0 )
( shadow 0 )
( block 0 )
( shadow 0 )
</pre>
<p>
Then run the Emacs forthblocks mode command <code>M-x renumber-blocks</code> to fix
up the numbers automatically, producing
</p>
<pre class="example">
( block 0 )
( shadow 0 )
( block 1 )
( shadow 1 )
( block 2 )
( shadow 2 )
( block 3 )
( shadow 3 )
</pre>
<p>
See the file <code>forthblocks.el</code> for more details on how to set it up and
use it.
</p>
</div>
</div>
<div id="outline-container-4.2.2" class="outline-4">
<h4 id="sec-4.2.2">4.2.2 blocks for data </h4>
<div id="text-4.2.2">
<p>
Another traditional use of 1024-byte blocks is for data storage. This
use is not particularly addressed by the text-file-based block system
described in the previous subsection. Nothing precludes the
possibility of using certain block ranges for text-file-based blocks
for source code storage while using different block ranges for pure
1024-byte data blocks (located perhaps in RAM, flash, or SD cards).
</p>
</div>
</div>
</div>
<div id="outline-container-4.3" class="outline-3">
<h3 id="sec-4.3">4.3 Text files </h3>
<div id="text-4.3">
<p>
Some people apparently <b>really</b> dislike using blocks for source code.
If you are one of those people, you could try the hybrid approach
discussed above (where you use plain text files for source except that
special comments mark the logical blocks) to see if you grow to like
it.
</p>
<p>
Otherwise, for the source for your application, use a plain text file
but start it with a single comment such as
</p>
<pre class="example">
( block 2000 -- this entire file file is block 2000 )
</pre>
<p>
then forget about blocks. The entire text file will be in that single
block. Then
</p>
<pre class="example">
2000 LOAD
</pre>
<p>
will load the entire text file.
</p>
<p>
Note, do not do this with the file <code>kernel.fth</code> as that is used to
generate the kernel.
</p>
</div>
</div>
</div>
<div id="outline-container-5" class="outline-2">
<h2 id="sec-5">5 Creating a new kernel image </h2>
<div id="text-5">
<p>
Why would you wish to create a new kernel? There are serveral
reasons:
</p>
<ul>
<li>
perhaps a pre-built kernel is not available for your ARM board
</li>
<li>
you wish to add, delete, or modify some of the Forth primitives
</li>
<li>
you wish to move more of your application into the kernel (and thus
into flash memory)
</li>
</ul>
<p>The usual procedure is to edit <code>riscy.asm</code> (to change any primitives)
and/or to edit <code>kernel.fth</code> (to change any high-level that will be
part of the kernel), then to use the makefile to generate the new
kernel image binary file (to be burned into flash) and the matching
dictionary file.
</p>
<p>
Be sure to look through <code>makefile</code> and edit any settings that need to be
changed for your environment (such as the serial port name or the CPU
clock speed), then run
</p>
<p>
<code>$ make</code>
</p>
<p>
Which will do any pre-processing and assembly steps and then run
<code>riscy.tcl</code> to create the new binary and dictionary files for all the
supported boards.
</p>
</div>
</div>
<div id="outline-container-6" class="outline-2">
<h2 id="sec-6">6 Multitasking </h2>
<div id="text-6">
<p>
Each task has a TCB (Task Control Block) in RAM. Each task also has
its own data stack area and return stack area. The task's stacks
would not necessarily need to be adjacent to the task's TCB, but that
is where we place them. The address of the task is the start of its
TCB. That is, the task <b>is</b> its TCB or the TCB is the task.
</p>
<p>
The <code>UP</code> register (we use R7 for this) holds the address of the current
task (i.e., the address of the current task's TCB). <code>UP</code> stands for
"User Pointer". It points to task-specific values – values local to
the task.
</p>
<p>
The TCB has 3 named slots plus 5 unnamed slots. Each slot is 32-bits
wide, thus the TCB takes 32 bytes. Traditionally, the TCB would have
even more named slots. Feel free to add them if your application
needs them, but these should do for most applications.
</p>
<ul>
<li>
the 3 named slots are
<dl>
<dt><code>LINK</code></dt><dd>
this slot holds the address of the next task (the task that
will get control when the current task pauses).
</dd>
<dt><code>SP0</code></dt><dd>
this slot holds the starting address (the high address,
because the stack grows toward lower memory) of the data stack.
It is used by the word <code>SP!</code> to reinitialize the task's data stack
pointer.
</dd>
<dt><code>RP0</code></dt><dd>
this slot holds the starting address (the high address,
because the stack grows toward lower memory) of the return stack.
It is used by the word <code>RP!</code> to reinitialize the task's return
stack pointer.
</dd>
</dl>
</li>
<li>
The 5 unnamed slots form a save area for storing a task's state
when it is not running. These slots save the five registers
<dl>
<dt>tos </dt><dd>
the cached top of stack value (register R0 or TOS)
</dd>
<dt>ip </dt><dd>
the instruction pointer register (register R9 or IPTR)
</dd>
<dt>dstk </dt><dd>
the current data stack pointer (register R10)
</dd>
<dt>rstk </dt><dd>
the current return stack pointer (register R11)
</dd>
<dt>rloop </dt><dd>
the current loop counter (register R12)
</dd>
</dl>
</li>
</ul>
<p>Traditionally, <code>PAUSE</code> would first store all the state onto the data
stack and thus need just one slot to store the data stack pointer.
However, to speed up <code>PAUSE</code>, we take advantage of the ARM's store
multiple and load multiple instructions, at the cost of several extra
slots in each TCB.
</p>
<p>
There is always at least one task. This is the "foreground" task. It
and its TCB are configured automatically. The word <code>PAUSE</code> pauses the
current task and turns control over to the next task. Each task, in
its TCB, has a <code>LINK</code> slot that holds the address of the next task to
run. When there is only one task, that task's <code>LINK</code> slot points to
itself. Thus, when <code>PAUSE</code> executes, it saves the state of the
foreground task, then immediately restores the state of the foreground
task, and thus continues running the foreground task. That is, with
only one task, <code>PAUSE</code> jumps back to the foreground task.
</p>
<p>
If you really don't plan to use more than a single task in your
application, you could consider changing <code>PAUSE</code> to a no-op, as it
doesn't really shine until more than one tasks are present.
</p>
<p>
Here is what the TCB looks like, with the offset relative to the start
of the TCB (and thus relative to the value in <code>UP</code>):
</p>
<pre class="example">
+ 0 LINK holds the address of the next task to execute
+ 4 holds saved TOS
+ 8 holds saved IP
+ 0x0C holds saved DSTK
+ 0x10 holds saved RSTK
+ 0x14 holds saved RLOOP
+ 0x18 SP0 holds address of start of data stack
+ 0x1C RP0 holds address of start of return stack
often the data stack will start here (at offset 0x20)
with the return stack starting just above the data stack
</pre>
</div>
<div id="outline-container-6.1" class="outline-3">
<h3 id="sec-6.1">6.1 Creating a task </h3>
<div id="text-6.1">
<p>
There is normally no need to create tasks, as three are created for
you automatically.
</p>
<ul>
<li>
<code>FOREGROUND</code> (also known as <code>TERMINAL</code>)
</li>
<li>
<code>TASK1</code>
</li>
<li>
<code>TASK2</code>
</li>
</ul>
<p>See <code>riscy.asm</code> if you wish to create more or fewer.
</p>
<p>
Until/unless you initialize and wake <code>TASK1</code> and <code>TASK2</code>, only the
<code>FOREGROUND</code> task runs.
</p>
<p>
Suppose we want <code>TASK1</code> to run a Forth word that increments a
variable named <code>TICKS</code> every 1.5 seconds.
</p>
<pre class="example">
VARIABLE TICKS
: TICKER ( -) 0 TICKS ! BEGIN 1500 MS 1 TICKS +! AGAIN ;
' TICKER TASK1 TASK!
TASK1 WAKE
</pre>
<p>