-
Notifications
You must be signed in to change notification settings - Fork 0
/
StringBufOut.mod
106 lines (91 loc) · 2.76 KB
/
StringBufOut.mod
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
MODULE StringBufOut;
(**
Oberon RTK Framework
--
Example program, multi-threaded, one core
Description: https://oberon-rtk.org/examples/stringbufout/
--
MCU: Cortex-M0+ RP2040
Board: Pico
--
Copyright (c) 2024 Gray, gray@grayraven.org
https://oberon-rtk.org/licences/
**)
IMPORT Main, Kernel, Terminals, StringDev, StringBuffers, MultiCore, Out, Errors, GPIO, LEDext;
CONST
MillisecsPerTick = 10;
ThreadStackSize = 1024;
TestString = "0123456789";
VAR
t0, t1: Kernel.Thread;
tid0, tid1: INTEGER;
PROCEDURE writeThreadInfo(tid, cid: INTEGER);
BEGIN
Out.String("c"); Out.Int(cid, 0);
Out.String("-t"); Out.Int(tid, 0);
END writeThreadInfo;
PROCEDURE t0c;
VAR ledNo: INTEGER;
BEGIN
GPIO.Set({LEDext.LEDpico});
ledNo := 0;
REPEAT
LEDext.SetLedBits(ledNo, 7, 4);
LEDext.SetLedBits(ledNo, 3, 0);
INC(ledNo);
GPIO.Toggle({LEDext.LEDpico});
Kernel.Next
UNTIL FALSE
END t0c;
PROCEDURE t1c;
CONST NumStr = 3; (* 4 will overflow the output buffer *)
VAR tid, cid, cnt, i: INTEGER;
BEGIN
cid := MultiCore.CPUid();
tid := Kernel.Tid();
cnt := 0;
REPEAT
writeThreadInfo(tid, cid);
Out.Int(cnt, 8); INC(cnt);
Out.String(" ");
Out.String(TestString);
Out.String(" ");
Out.Flush;
i := 0;
WHILE i < NumStr DO
Out.String(TestString); INC(i)
END;
Out.Ln;
Out.Flush;
IF NumStr > 3 THEN (* buffer overflow: previous Out.Ln gets lost *)
Out.Ln; Out.Flush
END;
Kernel.Next
UNTIL FALSE
END t1c;
PROCEDURE run;
VAR res: INTEGER; strDev0, strDev1: StringDev.Device;
BEGIN
(**
Re-wire the text output pipeline, as set up my Main, to use the string buffers
between Out and the terminals.
This block can be commented out, and the program will work unchanged, but
writing directly to the UART.
**)
StringBuffers.InitStrDev(strDev0, Terminals.W[Terminals.TERM0]);
StringBuffers.Open(StringBuffers.BUF0, strDev0, StringDev.PutString, StringDev.FlushOut);
StringBuffers.InitStrDev(strDev1, Terminals.W[Terminals.TERM1]);
StringBuffers.Open(StringBuffers.BUF1, strDev1, StringDev.PutString, StringDev.FlushOut);
Out.Open(StringBuffers.W[0], StringBuffers.W[1]);
(* end potential comment-out *)
Kernel.Install(MillisecsPerTick);
Kernel.Allocate(t0c, ThreadStackSize, t0, tid0, res); ASSERT(res = Kernel.OK, Errors.ProgError);
Kernel.SetPeriod(t0, 250, 0); Kernel.Enable(t0);
Kernel.Allocate(t1c, ThreadStackSize, t1, tid1, res); ASSERT(res = Kernel.OK, Errors.ProgError);
Kernel.SetPeriod(t1, 1000, 0); Kernel.Enable(t1);
Kernel.Run
(* we'll not return here *)
END run;
BEGIN
run
END StringBufOut.