Skip to content

Use OSEK-like OS on bare-metal ARM(R) Cortex(R)-M3 to calculate pi with a spigot algorithm

License

Notifications You must be signed in to change notification settings

ckormanyos/Osek_pi_crunch_cm3

Repository files navigation

Osek_pi_crunch_cm3

Build Status

This repository uses an OSEK-like OS on bare-metal ARM(R) Cortex(R)-M3 to calculate $\pi$ with a spigot algorithm.

Osek_pi_crunch_cm3 is a fascinating, educational and fun project that computes up to $100,001$ decimal digits of $\pi$ on a bare-metal ARM(R) Cortex(R)-M3 system.

The backbone real-time operating system is taken directly from the OSEK-like OS implemented in Chalandi/OSEK

Software Details

To compute $\pi$, we use a (slow) quadratic pi-spigot algorithm of order $N^2$ in this project. The spigot calculation (having quadratic order) is slower than other well-known algorithms such as AGM or fast series.

The required memory grows linearly with the digit count. Approximately $1.4~\text{Mbyte}$ RAM are needed for the full $10^{5}$ decimal-digit calculation. Since this is significantly more RAM than is available on-chip, a slow external serial SPI SRAM is used for storage.

The complicated and tedious $\pi$ calculation has been purposely made even more difficult using this error-intolerant peripheral SRAM and its slow, bit-banging, all-software SPI communication. This simultaneously provides a challenging stress-stest for the underlying hardware as well as the implementation software and its OS.

GNU/GCC gcc-arm-non-eabi is used for target system development on *nix. The build system is based on Standard GNUmake/shell-script.

Building the Application

Build with GNUmake on *nix

Build on *nix* is easy using an installed gcc-arm-none-eabi

cd Osek_pi_crunch_cm3
./Build.sh 1000

The build results including ELF-file, HEX-mask, MAP-file can be found in the Output directory following the GNUmake build.

The number 1000 sets the length of the calculation result of $\pi$ to $1,001$ decimal digits. The length values supported include (and are limited to) 100, 1000, 10000, 100000 for respectively higher digit counts up to $10^{5}$.

Install gcc-arm-none-eabi on *nix if needed

If gcc-arm-none-eabi is not present, then it can be installed (if needed).

sudo apt install gcc-arm-none-eabi

Prototype Project

This repo features a fully-worked-out prototype example project. The prototype runs on an ARM(R) Cortex(R)-M3 controller fitted on the SMT32F100RB-NUCLEO board. The board is driven in OS-less, bare-metal mode.

The $\pi$-spigot calculation runs continuously and successively in the low-priority idle task (Idle). Upon successful calculation completion, pin PB9 is toggled. This provides a measure of success viewable with a digital oscilloscope.

Simultaneously task T1 exercises a perpetual, simple blinky show featuring the two user LEDs (green and blue) toggling at approximately $\frac{1}{2}~\text{Hz}$. This provides clear visual indication of both system-OK as well as numerical correctness of the most-recently finished spigot calculation.

LCD visualization uses the SerLCD 20x4 from SparkFun. The LCD driver software in the C-language has been adopted from imahjoub/STM32L432_FlashMaster.

Hardware Setup

The hardware setup is pictured in the image below.

Additional images show close-ups of the peripheral circuitry and the serial SRAM connections.

Bit banging is used to implement an all-software, SPI-compatible driver which controls the external SRAM memory chip. A significant amount of external SRAM is needed to hold the potentially very large data array used for intermediate storage in the $\pi$ calculation.

The output pin connections from the board to the SRAM chip are shown in the table below.

NUCLEO PIN SRAM PIN SPI Function
PA11 $1$ CE (SRAM-chip-select-not)
PA10 $2$ SO (SRAM-serial-out)
PA09 $6$ CLK (SRAM-serial-clock)
PA08 $5$ SI (SRAM-serial-in)

The output pin connections from the board to the SparkFund SerLCD are shown in the table below. The SerLCD is driven with SPI communication with another instance of the all-software SPI driver.

NUCLEO PIN SPI Function
PB00 SCK (LCD-serial-clock)
PB01 SDI (LCD-serial-in)
PB02 CN (LCD chip-select-not)

Additional Details

Generic Serial SPI SRAM Driver

The serial SRAM driver is a nice, semi-intentional by-product of this project. This driver can be found in the file mcal_memory_sram_generic_spi.h. It has been written in C++14 utilizing a fully generic, multi-chip, variable-page-size, template form.

The serial SRAM driver provides a simple interface having functions read()/write() and read_n()/write_n() for reading and writing single-byte or multiple-byte streams.

Using this SRAM driver requires providing an independent SPI driver having particular interface functions such as send()/send_n() and recv().

Runtime and Computational Complexity

The spigot algorithm for $\pi$ has quadratic computional complexity. This means that the runtime of the calculation grows quadratically with increasing output digit size. The table below summarizes the runtime of the algorithm on the embedded target for various output digit sizes.

Digits-10 Time [s] Ratio (to $1,001$ digits)
$101$ $0.51^{*}$ $0.01$
$1,001$ $50$ $1$
$10,001$ $5,000$ $100$
$100,001$ $490,000$ $9,800$

$^{*}$ Deactivate LCD printing for this shorter time measurement.

The runtime increases by a factor of approximately $100$ for every tenfold increase in the output digit size, clearly exhibiting quadratic computational complexity.

Licensing

The operating system OSEK and timer files in the MCAL are licensed under GPL. This is consistent with the licensing found in and adopted from Chalandi/OSEK.

The supporting files in ref_app and the pi_spigot application itself are licensed under BSL.

Win*-ported *nix tools in wbin originate from UnxTools and include their own distribution statements.

The Win*-ported GNUmake is taken from ckormanyos/make-4.2.1-msvc-build.

About

Use OSEK-like OS on bare-metal ARM(R) Cortex(R)-M3 to calculate pi with a spigot algorithm

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published