This is a collection of scripts and auxiliary files that I wrote since I wanted to do the Praktikum Systemprogrammierung on Linux (like a normal person). 5-10 hours of extra work and configuration are way better than having to touch W*ndows. I'm uploading everything in case it helps someone else down the line.
- Dependencies
- Manually building SPOS
- Build/Test script
3.1 Examples
3.2 QoL Tip - Using clangd
4.1 Configuration
4.2 Updating project files - VSCode
- Docker/CI
- License
To build SPOS for the ATMega644, you need the following dependencies:
- avr8-gnu-toolchain (3.6.2.1778)
- ATMega644 Device Family Pack (2.0.401)
Since the toolchain used in the course is ancient, you probably won't find it in your distro's package manager. To
install everything needed under /opt/avr
, you can use scripts/setupAvrLibs.sh
. Make sure you have curl
,
tar
and unzip
installed.
$ sudo ./scripts/setupAvrLibs.sh
Note that other scripts rely on everything being under /opt/avr
, so you should not change the installation path.
$ cd /path/to/SPOS
$ sed -e 's:avr-gcc:/opt/avr/gcc/bin/avr-gcc:g' \
-e 's:\(CFLAGS =\):\1 -I"/opt/avr/dfp/include":g' \
Makefile | make -B -f -
The scripts/build_test.sh
script can be used to build and test the project. It runs under Linux and Windows
(via git-bash
, which is preinstalled on the VMs and on the lab computers). It uses the following environment
variables:
WIN
: Set to1
if you are running on Windows. This is used to determine the path to theavr-gcc
binaries.STOP
: Set to1
if you want to stop the script after compiling each test (useful to flash the test to the device without waiting).PUB
: Set to1
if you want to pull the tests from a public network location (useful if you are on the lab computers). You can change the location inside the script (WIN_PUB_TESTS
). The default is
WIN_PUB_TESTS="/p/public/Versuch\ $VERSUCH/Testtasks"
# Note that this is a UNIX path, since we're using git-bash.
# It corresponds to the following Windows path:
\\p\public\Versuch $VERSUCH\Testtasks
# or
P:\public\Versuch $VERSUCH\Testtasks
The script automatically reads the VERSUCH
number from ${SCRIPT_DIRECTORY}/../SPOS/SPOS/defines.h
and uses the Makefile from ${SCRIPT_DIRECTORY}/../SPOS/Makefile
. This means that it expects the
following directory structure:
PROJECT_ROOT
├── scripts
│ ├── build_test.sh
│ ├── ...
├── SPOS
│ ├── Makefile
│ ├── ...
│ ├── SPOS
│ │ ├── defines.h
│ │ ├── ...
When PUB!=1
, the script expects the tests to be in ${SCRIPT_DIRECTORY}/../SPOS/Tests/V$VERSUCH/
, e. g.
${SCRIPT_DIRECTORY}/../SPOS/Tests/V4/3 Heap Cleanup
. The directory structure with tests would look
as follows:
PROJECT_ROOT
├── scripts
│ ├── build_test.sh
│ ├── ...
├── SPOS
│ ├── Makefile
│ ├── SPOS
│ │ ├── defines.h
│ │ ├── ...
│ ├── Tests
│ │ ├── V1
│ │ │ ├── 1 Hello World
│ │ │ │ ├── progs.c
│ │ │ ├── 2 Hello World
│ │ │ │ ├── progs.c
│ │ │ ├── ...
│ │ ├── V2
│ │ │ ├── 1 Hello World
│ │ │ │ ├── progs.c
│ │ │ ├── 2 Hello World
│ │ │ │ ├── progs.c
│ │ │ ├── ...
│ │ ├── ...
- Make sure all tests compile successfully
$ cd PROJECT_ROOT
$ ./scripts/build_test.sh
- On the lab computers, pull the tests from the public network location and stop after compiling each test to flash it to the device (no need to clean-build/rebuild the project, this is handled by the script).
$ cd PROJECT_ROOT
$ WIN=1 PUB=1 STOP=1 ./scripts/build_test.sh
The script doesn't care about the current working directory. You can run git-bash
(from anywhere), write
e.g. WIN=1 PUB=1 STOP=1
and drag-and-drop the build_test.sh
file into the terminal, then hit Return to
run it. All that matters is that the directory structure explained above is present.
To use clangd, you need to install the following dependencies and configure your editor (e.g. neovim) accordingly. This means installing a Language Server Protocol (LSP) client and configuring it to use clangd. For neovim, you can use mason.nvim.
The easiest way to configure clangd after setting up your editor is by using
rizsotto/Bear to generate a compile_commands.json
file.
You'll need to redo this every time you add new *.{c,h}
files to the project.
$ cd PROJECT_ROOT
$ bear -- make -f scripts/Makefile -B
clangd is not happy with some of the things we do. Specifically, it does not like __attribute__((naked))
and PROGMEM
.
To fix this, change the following files:
// Add the following to defines.h
#ifdef __clang__
# undef __ATTR_PROGMEM__
# define __ATTR_PROGMEM__ __attribute__((section(".progmem1.data")))
#endif
// In os_scheduler.c, change
ISR(TIMER2_COMPA_vect) __attribute__((naked));
// to
#ifndef __clang__
ISR(TIMER2_COMPA_vect) __attribute__((naked));
#endif
Note that you still need avr-gcc
to compile SPOS. This is just to use LSP features, e.g. in neovim.
To use VSCode you'll need a few more things.
- AVR Helper extension
- C/C++ Extension Pack
- avrdude (consult your package manager)
After installing everything, type ^P
in VSCode and select "AVR Helper: Perform initial setup". Enter
the following things during setup (assuming you used setupAvrLibs.sh
before).
- 1/4:
/opt/avr/gcc/bin/avr-gcc
- 2/4:
/usr/bin/avrdude
(may vary across distributions) - 3/4: Leave empty
- 4/4:
/opt/avr/dfp/include
You should now be able to use IntelliSense.
scripts/build_test.sh
was written with GitLab CI in mind. It can be used to make sure the project compiles in a
Docker container. An example Dockerfile is provided with the project. You'll need to bring your own
runner for the RWTH GitLab instance.
- Build and tag the image, e.g.
$ cd PROJECT_ROOT/scripts
$ docker build -t avr_builder:latest .
- Update
.gitlab-ci.yml
to use your image.
These files are (un)licensed under The Unlicense. See license for more information.