Getting Started with Raspberry Pi: Course 2 OK02

Getting Started with Raspberry Pi: Course 2 OK02

Course OK02 is built on the foundation of Course OK01, achieving blinking by continuously turning the OK or ACT LED indicators on and off.

— Robert Mullins

Course OK02 is built on the foundation of Course OK01, achieving blinking by continuously turning the OK or ACT LED indicators on and off. Assuming you already have the code for Course 1: OK01[1] operating system, it will serve as the basis for this lesson.

1. Waiting

Waiting is a very useful part of operating system development. Operating systems often find themselves with nothing to do and must delay. In this example, we want to allow the LED light to blink visibly by waiting. If you simply turn it on and off, you will see this visual effect because the computer can turn it on and off several thousand times per second (LCTT Note: The persistence of vision effect will make it difficult for you to notice its blinking). In later lessons, we will see precise waiting, but for now, it is sufficient to simply consume time.

mov r2,#0x3F0000
wait1$:
sub r2,#1
cmp r2,#0
bne wait1$

sub reg,#val subtracts the number val from the value in register reg

cmp reg,#val compares the value in the register with the number val.

If the final comparison result is not equal, the b instruction with the ne suffix is executed.

The above is a very common code snippet for generating delays. Since each Raspberry Pi is basically the same, the generated delay is roughly the same. It works by using a mov command to push the value 3F000016 into register r2, then subtracting 1 from this value until it reaches 0. Three new commands are used here: sub, cmp, and bne.

sub is the subtraction command, which simply subtracts the value in the second parameter from the value in the first parameter.

cmp is an interesting command. It compares the first parameter with the second parameter and records the comparison result in a special register called the current processor status register. You actually don’t need to worry about it; it just remembers which of the two numbers is larger, smaller, or equal.

bne is actually a disguised branch command. In the ARM assembly language family, any instruction can be conditionally executed. This means that if the previous comparison result is a specific result, that instruction will run. This is a very interesting trick that we will use extensively later, but in this case, the ne suffix after the b command means “only execute this branch if the previous comparison result is not equal”. The ne suffix can be used on any command, and several others (a total of 16) conditions can also be used, such as eq for equal, and lt for less than.

2. Putting it Together

In the previous section, I mentioned that by setting the GPIO address offset to 28 (i.e.: str r1,[r0,#28]) instead of 40, you can turn off the LED. Therefore, you need to modify the code from Course OK01 to turn on the LED, run the waiting code, then turn off the LED, run the waiting code again, and include a branch back to the starting position. Note that you do not need to re-enable GPIO pin 16’s output function; this operation only needs to be done once. If you want to be more efficient, I suggest you reuse the value in register r1. All courses are the same, and you can find all the solutions on the download page[2]. It is important to ensure that all your labels are unique. Once you have written wait1$:, you cannot use wait1$ on any other line.

On my Raspberry Pi, it flashes about twice per second. By changing the value we set in the r2 register, it can be easily modified. However, unfortunately, I cannot precisely predict its running speed. If your Raspberry Pi does not work as expected, please check our troubleshooting page, and if it works correctly, congratulations.

In this course, we learned two additional assembly commands: sub and cmp, while also learning how to implement conditional execution in ARM.

In the next course, Course 3: OK03[3], we will learn how to write code and establish some standards for code reuse, and if necessary, we may use C or C++ to write code.

1.

If you clicked this link, it means you must want to know its specific content. CPSR is a 32-bit register consisting of many independent bits. It has a bit to represent positive, zero, and negative numbers. When a cmp instruction runs, it subtracts the second parameter from the first parameter and uses this bit to record whether its result is positive, zero, or negative. If it is zero, it means they are equal (a-b=0 implies a=b), if positive, it means a is greater than b (a-b>0 implies a>b), and if negative, it means less than. There are other comparison instructions, but the cmp instruction is the most intuitive. ↩

via: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/ok02.html

Author: Robert Mullins[5] Editor: lujun9972 Translator: qhwdw Proofreader: wxy

This article is originally compiled by LCTT and proudly presented by Linux China

Getting Started with Raspberry Pi: Course 2 OK02

Leave a Comment