Translated by qhwdw

This commit is contained in:
qhwdw 2019-01-19 17:11:46 +08:00
parent 5e048ce0e6
commit 9e6c89cb1c
No known key found for this signature in database
GPG Key ID: 59DADCB9A1C4B3C0
2 changed files with 70 additions and 68 deletions

View File

@ -1,68 +0,0 @@
[#]: collector: (lujun9972)
[#]: translator: (qhwdw)
[#]: reviewer: ( )
[#]: publisher: ( )
[#]: url: ( )
[#]: subject: (Computer Laboratory Raspberry Pi: Lesson 2 OK02)
[#]: via: (https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/ok02.html)
[#]: author: (Robert Mullins http://www.cl.cam.ac.uk/~rdm34)
Computer Laboratory Raspberry Pi: Lesson 2 OK02
======
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 [Lesson 1: OK01][1] operating system as a basis.
### 1 Waiting
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.
```
mov r2,#0x3F0000
wait1$:
sub r2,#1
cmp r2,#0
bne wait1$
```
```
sub reg,#val subtracts the number val from the value in reg.
cmp reg,#val compares the value in reg with the number val.
Suffix ne causes the command to be executed only if the last comparison determined that the numbers were not equal.
```
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 mov command to put the value 3F000016 into r2, and then subtracting 1 from this value until it is 0. The new commands here are sub, cmp, and bne.
sub is the subtract command, and simply subtracts the second argument from the first.
cmp 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.[1]
bne 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 ne suffix on the b command to mean 'only branch if the last comparison's result was that the values were not equal'. The ne suffix can be used on any command, as can several other (16 in all) conditions such as eq for equal and lt for less than.
### 2 The All Together
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. str r1,[r0,#28]). 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 r1. As with all lessons, a full solution to this can be found on the [download page][2]. Be careful to make sure all of your labels are unique. When you write wait1$: you cannot label another line wait1$.
On my Raspberry Pi it flashes about twice a second. this could easily be altered by changing the value we set r2 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.
In this lesson we've learnt two more assembly commands, sub and cmp, as well as learning about conditional execution in ARM.
In the next lesson, [Lesson 3: OK03][3] 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.
--------------------------------------------------------------------------------
via: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/ok02.html
作者:[Robert Mullins][a]
选题:[lujun9972][b]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: http://www.cl.cam.ac.uk/~rdm34
[b]: https://github.com/lujun9972
[1]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/ok01.html
[2]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/downloads.html
[3]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/ok03.html

View File

@ -0,0 +1,70 @@
[#]: collector: (lujun9972)
[#]: translator: (qhwdw)
[#]: reviewer: ()
[#]: publisher: ()
[#]: url: ()
[#]: subject: (Computer Laboratory Raspberry Pi: Lesson 2 OK02)
[#]: via: (https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/ok02.html)
[#]: author: (Robert Mullins http://www.cl.cam.ac.uk/~rdm34)
计算机实验室 树莓派:课程 2 OK02
======
OK02 课程是在 OK01 课程的基础上构建,通过不停地打开和关闭 `OK``ACT` LED 指示灯来实现闪烁。假设你已经有了 [课程 1OK01][1] 操作系统的代码,它将是这一节课的基础。
### 1、等待
等待是操作系统开发中非常有用的部分。操作系统经常发现自己无事可做,以及必须要延迟。在这个例子中,我们想去做等待,为了能够让这种等待可以看得见,让 LED 灯打开关闭闪烁起来。如果你只是打开和关闭它,你什么都看不到,因为计算机每秒种可以打开和关闭它好几千次。在后面的课程中,我们将看到精确的等待,但是现在,我们只要简单地去消耗时间就足够了。
```
mov r2,#0x3F0000
wait1$:
sub r2,#1
cmp r2,#0
bne wait1$
```
```
sub reg,#val 从寄存器 reg 中的值上减去数字 val
cmp reg,#val 将寄存器中的值与数字 val 进行比较。
如果最后的比较结果是不相等,那么执行后面的 ne 命令。
```
上面是一个很常见的产生延迟的代码片段,由于每个树莓派基本上是相同的,所以产生的延迟大致也是相同的。它的工作原理是,使用一个 `mov` 命令将值 3F0000<sub>16</sub> 推入到寄存器 r2 中,然后将这个值减 1直到这个值减到 0 为止。在这里使用了三个新命令 `sub``cmp``bne`
`sub` 是减法命令,它只是简单地从第一个参数中的值减去第二个参数中的值。
`cmp` 是个很有趣的命令。它将第一个参数与第二个参数进行比较,然后将比较结果记录到一个称为当前处理器状态寄存器的专用寄存器中。你其实不用担心它,它记住的只是两个数谁大或谁小,或是相等而已。[^1]
`bne` 其实是一个伪装的分支命令。在 ARM 汇编语言家族中,任何指令都可以有条件运行。这意味着如果上一个比较结果是某个确定的结果,那个指令才会运行。这是个非常有意思的技巧,我们在后面将大量使用到它,但在本案例中,我们在 `b` 命令后面的 ne 后缀意思是 “只有在上一个比较的结果是值不相等,才去运行分支”。`ne` 后缀可以使用在任何命令上,其它几个(总共 16 个)条件也是如此,比如 `eq` 表示等于,而 `lt` 表示小于。
### 2、组合到一起
上一节讲我提到过,通过将 GPIO 地址偏移量设置为 28str r1,[r0,#28])而不是 40 即可实现 LED 的关闭。因此,你需要去修改课程 OK01 的代码,在打开 LED 后,运行等待代码,然后再关闭 LED再次运行等待代码并包含一个回到开始位置的分支。注意不需要重新启用 GPIO 的 16 号针脚的输出功能,这个操作只需要做一次就可以了。如果你想更高效,我建议你复用 r1 寄存器的值。所有课程都一样,你可以在 [下载页面][2] 找到所有的解决方案。需要注意的是,必须保证你的所有标签都是唯一的。当你写了 wait1\$: 你其它行上的标签就不能再使用 wait1\$ 了。
在我的树莓派上,它大约是每秒闪两次。通过改变我们所设置的 r2 寄存器中的值,可以很轻松地修改它。但是,不幸的是,我不能够精确地预测它的运行速度。如果你的树莓派未按预期正常工作,请查看我们的故障排除页面,如果它正常工作,恭喜你。
在这个课程中,我们学习了另外两个汇编命令:`sub` 和 `cmp`,同时学习了 ARM 中如何实现有条件运行。
在下一个课程,[课程 3OK03][3] 中我们将学习如何编写代码,以及建立一些代码复用的标准,并且如果需要的话,可能会使用 C 或 C++ 来写代码。
[^1]:如果你点了这个链接说明你一定想知道它的具体内容。CPSR 是一个由许多独立的比特位组成的 32 比特寄存器。它有一个位用于表示正数、零和负数。当一个 cmp 指令运行后它从第一个参数上减去第二个参数然后用这个位记下它的结果是正数、零还是负数。如果是零意味着它们相等a-b=0 暗示着 a=b如果为正数意味着 a 大于 ba-b>0 暗示着 a>b如果为负数意味着小于。还有其它比较指令但 cmp 指令最直观。
--------------------------------------------------------------------------------
via: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/ok02.html
作者:[Robert Mullins][a]
选题:[lujun9972][b]
译者:[qhwdw](https://github.com/qhwdw)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]: http://www.cl.cam.ac.uk/~rdm34
[b]: https://github.com/lujun9972
[1]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/ok01.html
[2]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/downloads.html
[3]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/ok03.html