-
Notifications
You must be signed in to change notification settings - Fork 114
/
ok02.html
125 lines (125 loc) · 7.66 KB
/
ok02.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
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Lesson 2 OK02</title>
<link href="stylesheet.css" rel="Stylesheet" type="text/css" />
<script language="javascript" type="text/javascript" src="script.js"></script>
</head>
<body>
<div id="contentAll">
<div id="courseHead">
<h1>
Lesson 2 OK02</h1>
</div>
<div id="pageAll">
<div id="pageBody">
<p>
The OK02 lesson builds on OK01, by causing the 'OK' or 'ACT' LED to turn on and off repeatedly.
It is assumed you have the code for the <a href="ok01.html">Lesson 1: OK01</a> operating
system as a basis.
</p>
<div class="ucampas-toc">
</div>
<h2 id="waiting">
1 Waiting</h2>
<p>
Waiting is a surprisingly useful part of Operating System development. Often Operating
Systems find themselves with nothing to do, and must delay. In this example, we
wish to do so in order to allow the LED flashing off and on to be visible. If you
just turned it off and on, it would not be visible, as the computer would be able
to turn it off and on many thousands of times per second. In later lessons we will
look at accurate waiting, but for now it is sufficient to simply waste time.</p>
<div class="armCodeBlock"><p>
mov r2,#0x3F0000<br />
wait1$:<br />
sub r2,#1<br />
cmp r2,#0<br />
bne wait1$<br />
</p></div>
<div class="commandBox"><p>
<span class="armCodeInline">sub reg,#val</span> subtracts the number <span class="armCodeInline">
val</span> from the value in <span class="armCodeInline">reg</span>.</p></div>
<div class="commandBox"><p>
<span class="armCodeInline">cmp reg,#val</span> compares the value in <span class="armCodeInline">
reg</span> with the number <span class="armCodeInline">val</span>.</p></div>
<div class="commandBox"><p>
Suffix <span class="armCodeInline">ne</span> causes the command to be executed only
if the last comparison determined that the numbers were not equal.</p></div>
<p>
The code above is a generic piece of code that creates a delay, which thanks to
every Raspberry Pi being basically the same, is roughly the same time. How it does
this is using a <span class="armCodeInline">mov</span> command to put the value
3F0000<sub>16</sub> into <span class="armCodeInline">r2</span>, and then subtracting
1 from this value until it is 0. The new commands here are <span class="armCodeInline">
sub</span>, <span class="armCodeInline">cmp</span>, and <span class="armCodeInline">
bne</span>.</p>
<p>
<span class="armCodeInline">sub</span> is the subtract command, and simply subtracts
the second argument from the first.</p>
<p>
<span class="armCodeInline">cmp</span> is a more interesting command. It compares
the first argument with the second, and remembers the result of the comparison in
a special register called the current processor status register. You don't really
need to worry about this, suffice to say it remembers, among other things, which
of the two numbers was bigger or smaller, or if they were equal.<sup><a class="noteLink"
name="note1a" href="#note1" title="Note 1">[1]</a></sup></p>
<p>
<span class="armCodeInline">bne</span> is actually just a branch command in disguise.
In the ARM assembly language family, any instruction can be executed conditionally.
This means that the instruction is only run if the last comparison had a certain
result. We will use this extensively later for interesting tricks, but in this case
we use the <span class="armCodeInline">ne</span> suffix on the <span class="armCodeInline">
b</span> command to mean 'only branch if the last comparison's result was that
the values were not equal'. The <span class="armCodeInline">ne</span> suffix can
be used on any command, as can several other (16 in all) conditions such as <span
class="armCodeInline">eq</span> for equal and <span class="armCodeInline">lt</span>
for less than.</p>
<h2 id="together">
2 The All Together</h2>
<p>
I mentioned briefly last time that the status LED can be turned off again by writing
to an offset of 28 from the GPIO controller instead of 40 (i.e. <span class="armCodeInline">
str r1,[r0,#28]</span>). Thus, you need to modify the code from OK01 to turn
the LED on, run the wait code, turn it off, run the wait code again, and then include
a branch back to the beginning. Note, it is not necessary to re-enable the output
to GPIO 16, we need only do that once. If you're being efficient, which I strongly
encourage, you should be able to reuse the value of <span class="armCodeInline">r1</span>.
As with all lessons, a full solution to this can be found on the <a href="downloads.html">
download page</a>. Be careful to make sure all of your labels are unique. When
you write <span class="armCodeInline">wait1$:</span> you cannot label another line
<span class="armCodeInline">wait1$</span>.
</p>
<p>
On my Raspberry Pi it flashes about twice a second. this could easily be altered
by changing the value we set <span class="armCodeInline">r2</span> to. However,
unfortunately we can't precisely predict the speed this runs at. If you didn't manage
to get this working see our trouble shooting page, otherwise, congratulations.</p>
<p>
In this lesson we've learnt two more assembly commands, <span class="armCodeInline">
sub</span> and <span class="armCodeInline">cmp</span>, as well as learning about
conditional execution in ARM.</p>
<p>
In the next lesson, <a href="ok03.html">Lesson 3: OK03</a> we will evaluate how we're
coding, and establish some standards so that we can reuse code, and if necessary,
work with C or C++ code.</p>
</div>
<div id="pageFooter">
<hr />
<ol>
<li><a name="note1" /><sup>[1]<a class="noteBackLink" href="#note1a">^</a></sup> I suppose
if you've followed the link you really do want to know about it. The CPSR is a 32
bit register consisting of many individual bit fields. It has bit fields for positive,
zero and negative. When a cmp instruction is issued, it subtracts the second argument
from the first, and notes down whether it is positive, zero or negative with these
fields. Zero means the numbers were equal (a-b=0 implies a=b), positive means a
is bigger than b (a-b>0 implies a>b) and negative less than. A variety of
other comparison instructions exist, but cmp is the most intuitive. </li>
</ol>
<p>Spot a mistake? You can help improve this tutorial on <a href="https://github.com/chadderz121/bakingpi-www">GitHub</a>.</p>
<p><a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/deed.en_GB"><img alt="Creative Commons Licence" style="border-width:0" src="http://i.creativecommons.org/l/by-sa/3.0/88x31.png" /></a><br /><span xmlns:dct="http://purl.org/dc/terms/" property="dct:title">Baking Pi: Operating Systems Development</span> by <span xmlns:cc="http://creativecommons.org/ns#" property="cc:attributionName">Alex Chadwick</span> is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/deed.en_GB">Creative Commons Attribution-ShareAlike 3.0 Unported License</a>.</p>
<p>Based on contributions at <a href="https://github.com/chadderz121/bakingpi-www">https://github.com/chadderz121/bakingpi-www</a>.</p>
</div>
</div>
</div>
</body>
</html>