Skip to content

Commit 6fcabb8

Browse files
committed
doc/guides: Riot Tutorial
examples/guides: Introduce tutorial references doc/guides/tutorial: Introduce code_folder for all tutorials
1 parent a1816a7 commit 6fcabb8

105 files changed

Lines changed: 1277 additions & 4 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
---
2+
title: Creating a Project
3+
description: This tutorial will guide you through creating a new project with a simple hello world program.
4+
code_folder: examples/guides/creating_project/
5+
---
6+
import Contact from '@components/contact.astro';
7+
import GitSetup from '@components/gitsetup.mdx';
8+
9+
Now that we have played around with the examples and have a basic understanding of how to use RIOT, let's create a new project from scratch. We will create a simple hello world program that will print "Hello World!" to the console.
10+
11+
Lets start with the basic git setup, if you already have a git repository set up, you can skip to the next section.
12+
13+
## Step 1: The Basics of Git and Submodules
14+
15+
<GitSetup />
16+
17+
## Step 2: Creating our hello world program
18+
19+
Now that we have added RIOT as a submodule to our project, we can start writing our hello world program. To do this, we create a new file called `main.c` in the `hello_world` directory. You can use any text editor to create this file. We will use Visual Studio Code in this example. To open Visual Studio Code in the directory, you can use the following command:
20+
21+
```bash
22+
code .
23+
```
24+
25+
Now that Visual Studio Code is open, we create a new file called `main.c` and add the following code:
26+
27+
```c title="hello_world/main.c"
28+
/*
29+
* For many printing related things, such as the puts function here
30+
* we import stdio, depending on your board, platform or form of output
31+
* it then includes the right definitions without the need to
32+
* worry about the specific details.
33+
*/
34+
#include <stdio.h>
35+
36+
/*
37+
* This is the main function of the program.
38+
* It serves as the entry point for the program and gets called once your CPU is
39+
* initialized.
40+
*
41+
* The function returns an integer value, which is the exit status
42+
* of the program. A return value of 0 indicates that the program has finished
43+
* successfully.
44+
*/
45+
int main(void) {
46+
puts("Hello World!");
47+
48+
return 0;
49+
}
50+
```
51+
52+
![The hello world program in Visual Studio Code](img/create_project/03_main_c.png)
53+
54+
This program will print "Hello World!" to the console when it is run. The `#include <stdio.h>` line includes the standard input/output library, which allows us to use the `puts` function to print to the console.
55+
56+
## Step 3: Creating the Makefile
57+
58+
Now that we have created our hello world program, we need to create a Makefile to build our program. The Makefile is a build automation tool that allows us to define how our program should be built. We create a new file called `Makefile` in the `hello_world` directory and add the following code:
59+
60+
```makefile title="hello_world/Makefile"
61+
# name of your application
62+
APPLICATION = hello-world
63+
64+
# Change this to your board if you want to build for a different board
65+
BOARD ?= native
66+
67+
# This has to be the absolute path to the RIOT base directory:
68+
RIOTBASE ?= $(CURDIR)/RIOT
69+
70+
# Comment this out to disable code in RIOT that does safety checking
71+
# which is not needed in a production environment but helps in the
72+
# development process:
73+
DEVELHELP ?= 1
74+
75+
# Change this to 0 show compiler invocation lines by default:
76+
QUIET ?= 1
77+
78+
include $(RIOTBASE)/Makefile.include
79+
```
80+
81+
![The Makefile in Visual Studio Code](img/create_project/04_makefile.png)
82+
83+
Congratulations! You have now created a new project with a simple hello world program. In the next step, we will build and run our program just like we did in the "Getting Started" guide.
84+
85+
## Step 4: Building and running the program
86+
87+
<Contact />
88+
89+
To build our program, we use the following command:
90+
91+
```bash
92+
BUILD_IN_DOCKER=1 make all
93+
```
94+
95+
:::note
96+
The `BUILD_IN_DOCKER=1` flag tells the build system to use the docker image provided by RIOT to build our program. This ensures that we have all the necessary dependencies to build our program. If you have already built RIOT on your system, you can omit this flag and the build system will use the toolchain installed on your system.
97+
:::
98+
99+
![Building the program](img/create_project/05_make.png)
100+
101+
After building the program, we can run it using the following command to start the RIOT shell:
102+
103+
```bash
104+
make term
105+
```
106+
107+
If everything went well, you should see our hello world program printing "Hello World!" to the console after a few seconds.
108+
109+
![The hello world program running in the RIOT shell](img/create_project/06_output.png)
110+
111+
Hooraay! You have successfully created a new project with a simple hello world program.
112+
113+
:::tip
114+
Before you push your project to a git hosting service such as Github, make sure to add a `.gitignore` file to your project to exclude unnecessary files from being tracked by git.
115+
116+
For this project, a `.gitignore` file could look like this:
117+
118+
```bash title=".gitignore"
119+
# Ignore build artifacts
120+
bin/
121+
*.bin
122+
*.elf
123+
*.hex
124+
*.map
125+
*.lst
126+
*.o
127+
*.d
128+
*.a
129+
*.out
130+
```
131+
:::
132+
133+
## Conclusion
134+
135+
In this tutorial, we have created a new project with a simple hello world program. We have added RIOT as a submodule to our project, created a hello world program, and built and run the program using the RIOT build system. You can now start building your own applications using RIOT and explore the vast possibilities that RIOT has to offer.
136+
137+
:::note
138+
The source code for this tutorial can be found [HERE](https://github.com/RIOT-OS/RIOT/tree/master/examples/guides/creating_project).
139+
140+
If your project is not working as expected, you can compare your code with the code in this repository to see if you missed anything.
141+
:::

doc/guides/c_tutorials/gpio.mdx

Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
---
2+
title: GPIO & Real Boards
3+
description: This tutorial explains how to use GPIO in RIOT to control LEDs or read button presses.
4+
code_folder: examples/guides/gpio/
5+
---
6+
7+
import Contact from '@components/contact.astro';
8+
import WorkingVideo from './img/gpio/05_working_video.mp4';
9+
import ButtonVideo from './img/gpio/08_buttons.mp4';
10+
11+
So far we have been running all our code using the `arduino-feather-nrf52840-sense` board.
12+
13+
In this tutorial, we will learn how to use the GPIO pins on a real board to control LEDs or read button presses.
14+
15+
For this tutorial I will be using a the `arduino-feather-nrf52840-sense` board with the [Teamagochi PCB](https://github.com/smartuni/teamagochi), but you can use any board that has GPIO pins.
16+
17+
## Step 1: Configuring our Board
18+
19+
<Contact />
20+
21+
First, we need to inform RIOT about the board we are using.
22+
23+
To do this we adapt the `BOARD` variable in our `Makefile` to the board we are using.
24+
25+
```make
26+
BOARD ?= arduino-feather-nrf52840-sense
27+
```
28+
29+
![The board variable in Visual Studio Code](img/gpio/01_define_board.png)
30+
31+
First we want to make sure that we can build the code for the board.
32+
To do this we can simply run `make all` in the terminal,
33+
this will build the code for the board and check if everything is set up correctly.
34+
35+
If everything is set up correctly, we should now be able to move on to flashing the board.
36+
37+
:::tip
38+
It might return something like:
39+
40+
```
41+
/bin/sh: line 1: arm-none-eabi-gcc: command not found
42+
Compiler arm-none-eabi-gcc is required but not found in PATH. Aborting.
43+
```
44+
45+
This means that you need to install the ARM toolchain,
46+
you can do this by running `sudo apt install gcc-arm-none-eabi` on Ubuntu
47+
or `sudo pacman -S arm-none-eabi-gcc` on Arch Linux.
48+
49+
If it still doesn't work, consider running it via the Docker container using `BUILD_IN_DOCKER=1 make flash`.
50+
51+
Please refer to the [Flashing a RIOT Application](/getting-started/flashing) guide for more information.
52+
:::
53+
54+
Try flashing the board with `make flash` and see if it works,
55+
it should still execute the same code as before when running RIOT natively on your
56+
own hardware but now using the actual board.
57+
58+
![Flash output in Visual Studio Code](img/gpio/02_flash_output.png)
59+
60+
Now if we type `make term` we should see the output of the board in the terminal.
61+
Make sure that you have the board connected to your computer via USB and
62+
that your user has the necessary permissions to access the serial port.
63+
64+
:::tip
65+
On Arch Linux, you might need to add your user to the `uucp` group to access the serial port.
66+
67+
```bash
68+
sudo usermod -a -G uucp $USER
69+
```
70+
:::
71+
72+
## Step 2: Controlling LEDs
73+
74+
Now that we have the board working, let's try to control the LEDs on the board.
75+
76+
The exact pins that control the LEDs might vary depending on the board you are using,
77+
but in the case of the `arduino-feather-nrf52840-sense` board, the LED would be connected
78+
on Port 1 Pin 9.
79+
80+
First we need to include the necessary modules in our projects `Makefile`.
81+
82+
```make
83+
# Add the gpio module to the build
84+
USEMODULE += periph_gpio
85+
USEMODULE += periph_gpio_irq
86+
87+
# Enable the milliseconds timer.
88+
USEMODULE += ztimer
89+
USEMODULE += ztimer_msec
90+
```
91+
92+
![The Makefile with the GPIO modules](img/gpio/03_gpio_modules.png)
93+
94+
This allows us to both control the GPIO pins and timers.
95+
96+
Now we need to actually define the pin that we want to control in our code.
97+
To do this include the following lines **before** the `main` function.
98+
{/*<!--skip ci-->*/}
99+
```c
100+
#include "board.h"
101+
#include "periph/gpio.h"
102+
#include "ztimer.h"
103+
104+
/* Define the LED0 pin and mode */
105+
gpio_t led0 = GPIO_PIN(1, 9);
106+
gpio_mode_t led0_mode = GPIO_OUT;
107+
```
108+
109+
Now we can control the LED. First we initialize the pin and afterwards we turn the LED off by clearing the pin
110+
111+
{/*<!--skip ci-->*/}
112+
```c
113+
int main(void) {
114+
/* Initialize the LED0 pin */
115+
gpio_init(led0, led0_mode);
116+
/* Turn off the LED0 pin */
117+
gpio_clear(led0);
118+
119+
/* Loop forever */
120+
while (1) {
121+
122+
}
123+
}
124+
```
125+
126+
Turning the LED off when the board starts is quite boring,
127+
so let's make it blink by adding a delay and toggling the LED.
128+
129+
```c
130+
/* Loop forever */
131+
while (1) {
132+
/* Toggle the LED0 pin every 500 milliseconds */
133+
gpio_toggle(led0);
134+
ztimer_sleep(ZTIMER_MSEC, 500);
135+
}
136+
```
137+
138+
![The Code in Visual Studio Code](img/gpio/04_code.png)
139+
140+
If we now `make flash` and then `make term` we should see the LED blinking.
141+
142+
<video controls>
143+
<source src={WorkingVideo} type="video/mp4" />
144+
Your browser does not support the video tag.
145+
</video>
146+
147+
## Step 3: Reading Button Presses
148+
149+
If you remember what we did in the timers tutorial,
150+
we can use quite similar code to read button presses.
151+
152+
On a constrained device you usually don't want to poll the button state,
153+
which is why we will use an interrupt to detect the button press,
154+
that way we can drastically reduce the power consumption of the device.
155+
156+
157+
First we need to define the callback function that will be called when the button is pressed.
158+
159+
```c title="Define the LED1 pin and mode"
160+
/* Define the LED1 pin and mode */
161+
gpio_t led1 = GPIO_PIN(1, 10);
162+
gpio_mode_t led1_mode = GPIO_OUT;
163+
```
164+
165+
```c title="Define the button callback function"
166+
/* This callback function will be called when the button state changes */
167+
void button_callback(void *arg) {
168+
/* the argument is not used */
169+
(void)arg;
170+
171+
/* Toggle the LED1 pin based on the button state */
172+
if (gpio_read(button)) {
173+
gpio_clear(led1);
174+
} else {
175+
gpio_set(led1);
176+
}
177+
}
178+
```
179+
180+
Now we need to define the button pin and mode and initialize it.
181+
182+
```c {1-2, 26-27}
183+
/* Define the button pin */
184+
gpio_t button = GPIO_PIN(1, 2);
185+
186+
/* This callback function will be called when the button state changes */
187+
void button_callback(void *arg) {
188+
/* the argument is not used */
189+
(void)arg;
190+
191+
/* Toggle the LED1 pin based on the button state */
192+
if (gpio_read(button)) {
193+
gpio_clear(led1);
194+
} else {
195+
gpio_set(led1);
196+
}
197+
}
198+
199+
int main(void) {
200+
/* Initialize the LED0 pin */
201+
gpio_init(led0, led0_mode);
202+
/* Turn off the LED0 pin */
203+
gpio_clear(led0);
204+
205+
/* Initialize the LED1 pin */
206+
gpio_init(led1, led1_mode);
207+
/* Turn off the LED1 pin */
208+
gpio_clear(led1);
209+
210+
/* Initialize the button pin */
211+
gpio_init_int(button, GPIO_IN_PU, GPIO_BOTH, button_callback, NULL);
212+
213+
/* Loop forever */
214+
while (1) {
215+
/* Toggle the LED0 pin every 500 milliseconds */
216+
gpio_toggle(led0);
217+
ztimer_sleep(ZTIMER_MSEC, 500);
218+
}
219+
}
220+
```
221+
222+
This code will initialize the button pin and call the `button_callback` function whenever the button is pressed.
223+
224+
![Full Code in Visual Studio Code](img/gpio/07_full_code.png)
225+
226+
If we now `make flash` and then `make term` we should see the LED turn on when the button is pressed.
227+
228+
:::tip
229+
If you are using the `arduino-feather-nrf52840-sense` board, the button is on the back of the board.
230+
231+
Be careful to not press the reset button by mistake 😉
232+
:::
233+
234+
<video controls>
235+
<source src={ButtonVideo} type="video/mp4" />
236+
Your browser does not support the video tag.
237+
</video>
238+
239+
## Conclusion
240+
241+
In this tutorial we learned how to use the GPIO pins on a real board to control LEDs or read button presses.
242+
243+
This is a very basic example, but it should give you a good starting point to build more complex applications.
244+
245+
<Contact />
246+
247+
:::note
248+
The source code for this tutorial can be found [HERE](https://github.com/RIOT-OS/RIOT/tree/master/examples/guides/gpio).
249+
250+
If your project is not working as expected, you can compare your code with the code in this repository to see if you missed anything.
251+
:::
65.4 KB
Loading
119 KB
Loading
136 KB
Loading
61.8 KB
Loading
57.5 KB
Loading
216 KB
Loading
73.7 KB
Loading
46.4 KB
Loading

0 commit comments

Comments
 (0)