Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
179 changes: 90 additions & 89 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,15 @@ In this way the project exhibits a high level of portability.

## Supported Targets in the Reference Application

The reference application supports the following targets:
The reference application supports the following targets (in alpha-numeric order):

| Target name (as used in build command) | Target Description | *(breadboard) |
| -------------------------------------- | ----------------------------------------------------------- | ------------- |
| `avr` | MICROCHIP(R) [former ATMEL(R)] AVR(R) ATmega328P | X |
| `am335x` | BeagleBone with Texas Instruments(R) AM335x ARM(R) A8 | |
| `atmega2560` | MICROCHIP(R) [former ATMEL(R)] AVR(R) ATmega2560 | |
| `atmega4809` | MICROCHIP(R) [former ATMEL(R)] AVR(R) ATmegax4809 | X |
| `am335x` | BeagleBone with Texas Instruments(R) AM335x ARM(R) A8 | |
| `bcm2835_raspi_b` | RaspberryPi(R) Zero with ARM1176-JZFS(TM) | |
| `avr` (as used in the book) | MICROCHIP(R) [former ATMEL(R)] AVR(R) ATmega328P | X |
| `bcm2835_raspi_b` | RaspberryPi(R) Zero with ARM1176-JZFS(TM) | X |
| `Debug`/`Release` | PC on `Win*` via MSVC x64 compiler `Debug`/`Release` | |
| `host` | PC/Workstation on `Win*`/`mingw64`/`*nix` via host compiler | |
| `lpc11c24` | NXP(R) OM13093 LPC11C24 board ARM(R) Cortex(R)-M0+ | |
Expand Down Expand Up @@ -359,17 +359,23 @@ any additional libraries for these projects
(other than those that are ordinarily installed
during the standard installation of ATMEL Studio).

## Target Details
## Details on Selected Target

Target details including startup code and linker definition files can
be found in the [ref_app/target](./ref_app/target) directory
and its subdirectories. There are individual subdirectories for
each supported target microcontroller system.

The MICROCHIP(R) [former ATMEL(R)] AVR(R) configuration
called `target avr` runs
on a classic ARDUINO(R) compatible board.
The program toggles the yellow LED on `portb.5`.
The ARM(R) A8 configuration (called `target am335x`) runs on the BeagleBone
board (black edition). For the white edition, the CPU clock needs to be reduced
from $900~\text{MHz}$ to something like $600~\text{MHz}$. This project creates a bare-metal program
for the BeagleBone that runs independently from any kind of `*nix` distro on
the board. Our program is designed to boot the BeagleBone from a raw binary file
called _MLO_ stored on a FAT32 SDHC microcard. The binary file includes a
special boot header comprised of two 32-bit integers. The program is loaded
from SD-card into RAM memory and subsequently executed. When switching on
the BeagleBone black, the boot button (S2) must be pressed while powering
up the board. The program toggles the first user LED (LED1 on `port1.21`).

The MICROCHIP(R) [former ATMEL(R)] AVR(R) configuration
called `target atmega2560` runs
Expand All @@ -389,70 +395,10 @@ on an ARDUINO(R) EVERY compatible board clocked
with the internal resonator at $20~\text{MHz}$.
The program toggles the yellow LED on `porte.2` (i.e., `D5`).

The Espressif (`target xtensa32`) port for NodeMCU ESP32
uses a subset of the
[Espressif SDK](https://github.com/espressif/esp-idf)
to run the reference application.
This somewhat unconventional implementation configures
$1$ single OS task running exclusively on $1$ CPU core only.
Additional reductions in code/memory size(s) have been accomplished
via selective stubbing of library functions.

The Espressif (`target xtensa_esp32_s3`) port for NodeMCU ESP32-S3
features a bare-metal startup _without_ using any of the SDK.
The bare-metal startup was taken from the work of
[Chalandi/Baremetal_esp32s3_nosdk](https://github.com/Chalandi/Baremetal_esp32s3_nosdk).
The multicore system first boots core0 which subsequently
starts up core1 and also starts up the RISC-V-ULP coprocessor core.
Blinky runs in the standard `ref_app`
on core0 toggling `port7` while an endless timer loop on core1
toggles `port6`. These LED ports togle in near unison
at the normal blinky feequency of $\frac{1}{2}~\text{Hz}$.
The RISC-V-ULP coprocessor performs an LED dimming
show on `port17` at a randomly chosen frequency
that is asynchronous to the regular blinky show.
Self-procured LEDs and resistors need to be fitted externally
on the port pins in order to observe blinking and dimming
on this particular board.

The NXP(R) OM13093 LPC11C24 board ARM(R) Cortex(R)-M0+ configuration
called `target lpc11c24` toggles the LED on `port0.8`.

The ARM(R) Cortex(R)-M3 configuration (called `target stm32f100`) runs on
the STM32VL-DISCOVERY board commercially available from ST Microelectronics(R).
The program toggles the blue LED on `portc.8`.

The second ARM(R) Cortex(R)-M3 configuration (called `target stm32l100c`)
runs on the STM32L100-DISCOVERY board commercially available from
ST Microelectronics(R). The program toggles the blue LED on `portc.8`.

The third ARM(R) Cortex(R)-M3 configuration (called `target stm32l152`)
runs on the STM32L152C-DISCOVERY board commercially available from
ST Microelectronics(R). The program toggles the blue LED on `portb.6`.

The first ARM(R) Cortex(R)-M4F configuration (called `target stm32f407`) runs on
the STM32F4-DISCOVERY board commercially available from ST Microelectronics(R).
The program toggles the blue LED on `portd.15`.

Another ARM(R) Cortex(R)-M4F configuration (called `target stm32f446`) runs on
the STM32F446-NUCLEO-64 board commercially available from ST Microelectronics(R).
The program toggles the green LED on `porta.5`.
An Ozone debug file is supplied for this system for those interested.

The first ARM(R) Cortex(R)-M7 configuration (called `target stm32h7a3`) runs on
the STM32H7A3-NUCLEO-144 board commercially available from ST Microelectronics(R).
The program toggles the green LED on `portb.0`.

The ARM(R) A8 configuration (called `target am335x`) runs on the BeagleBone
board (black edition). For the white edition, the CPU clock needs to be reduced
from $900~\text{MHz}$ to something like $600~\text{MHz}$. This project creates a bare-metal program
for the BeagleBone that runs independently from any kind of `*nix` distro on
the board. Our program is designed to boot the BeagleBone from a raw binary file
called _MLO_ stored on a FAT32 SDHC microcard. The binary file includes a
special boot header comprised of two 32-bit integers. The program is loaded
from SD-card into RAM memory and subsequently executed. When switching on
the BeagleBone black, the boot button (S2) must be pressed while powering
up the board. The program toggles the first user LED (LED1 on `port1.21`).
The MICROCHIP(R) [former ATMEL(R)] AVR(R) configuration
called `target avr` (as used in the book) runs
on a classic ARDUINO(R) compatible board.
The program toggles the yellow LED on `portb.5`.

The ARM(R) 1176-JZF-S configuration (called `target bcm2835_raspi_b`) runs on the
RaspberryPi(R) Zero (PiZero) single core controller.
Expand All @@ -469,33 +415,65 @@ config.txt, all described on internet. A complete set of
running the bare-metal reference application are included in this repo.
The program toggles the GPIO status LED at GPIO index `0x47`.

The NXP(R) OM13093 LPC11C24 board ARM(R) Cortex(R)-M0+ configuration
called `target lpc11c24` toggles the LED on `port0.8`.

Target `nxp_imxrt1062` runs on the Teensy 4.0 board from Spark Fun.
The orange user-LED is toggled.

The `riscvfe310` target utilizes the SiFive RISC-V FE310 SoC
on Spark Fun's commercially available _Red_ _Thing_ _Plus_ Board.
The blue LED on port `GPIO0.5` is toggled.

The `rpi_pico_rp2040` target configuration employs the
RaspberryPi(R) Pico RP2040 with dual-core ARM(R) Cortex(R)-M0+
clocked at $133~\text{MHz}$. The low-level startup boots through
core0. Core0 then starts up core1 (via a specific protocol).
Core1 subsequently carries out the blinky application,
while core0 enters an endless, idle loop.
Ozone debug files are supplied for this system for those interested.
Reverse engineering of the complicated (and scantly documented)
dual-core startup originated in and have been taken from (with many thanks)
from the `Blinky_Pico_dual_core_nosdk`
[repo](https://github.com/Chalandi/Blinky_Pico_dual_core_nosdk).
core0 which then starts up core1 via specific protocol.
Core1 carries out the blinky application while core0 enters an endless,
idle loop. Ozone debug files are supplied for this system
for those interested. Reverse engineering of the complicated
and scantly documented dual-core startup originated in
and have been taken (with many thanks) from the
[`Chalandi/Blinky_Pico_dual_core_nosdk`](https://github.com/Chalandi/Blinky_Pico_dual_core_nosdk).
repository.

The `rpi_pico2_rp2350` target configuration employs the
RaspberryPi(R) Pico2 RP2350 with dual-core ARM(R) Cortex(R)-M33
clocked at $150~\text{MHz}$. It has essentially the same boot
structure as the `2040`. Similarly the dual-core startup was
pioneered by the efforts revealed in the modernized `Blinky_Pico2_dual_core_nosdk`
[repo](https://github.com/Chalandi/Blinky_Pico2_dual_core_nosdk).
pioneered by the efforts revealed in the modernized
[`Chalandi/Blinky_Pico2_dual_core_nosdk`](https://github.com/Chalandi/Blinky_Pico2_dual_core_nosdk).
repository.

The ARM(R) Cortex(R)-M3 configuration (called `target stm32f100`) runs on
the STM32VL-DISCOVERY board commercially available from ST Microelectronics(R).
The program toggles the blue LED on `portc.8`.

The first ARM(R) Cortex(R)-M4F configuration (called `target stm32f407`) runs on
the STM32F4-DISCOVERY board commercially available from ST Microelectronics(R).
The program toggles the blue LED on `portd.15`.

Another ARM(R) Cortex(R)-M4F configuration (called `target stm32f446`) runs on
the STM32F446-NUCLEO-64 board commercially available from ST Microelectronics(R).
The program toggles the green LED on `porta.5`.
An Ozone debug file is supplied for this system for those interested.

The first ARM(R) Cortex(R)-M7 configuration (called `target stm32h7a3`) runs on
the STM32H7A3-NUCLEO-144 board commercially available from ST Microelectronics(R).
The program toggles the green LED on `portb.0`.

The second ARM(R) Cortex(R)-M3 configuration (called `target stm32l100c`)
runs on the STM32L100-DISCOVERY board commercially available from
ST Microelectronics(R). The program toggles the blue LED on `portc.8`.

The third ARM(R) Cortex(R)-M3 configuration (called `target stm32l152`)
runs on the STM32L152C-DISCOVERY board commercially available from
ST Microelectronics(R). The program toggles the blue LED on `portb.6`.

The `target v850es_fx2` implementation uses a classic Renesas(R) V850es/Fx2 core.
The upd703231 microcontroller derivative on an F-Line _Drive_ _It_
starter kit is used.

The `riscvfe310` target utilizes the SiFive RISC-V FE310 SoC
on Spark Fun's commercially available _Red_ _Thing_ _Plus_ Board.
The blue LED on port `GPIO0.5` is toggled.

The adaption for `wch_ch32v307` runs on the WCH CH32v307 board.
It uses the RISC-V CH32v307 microcontroller from
Nanjing Qinheng Microelectronics Co., Ltd.
Expand All @@ -505,8 +483,31 @@ The similar adaption `wch_ch32v307_llvm` is essentially
the same except it uses an LLVM RISC-V toolchain
instead of GCC RISC-V.

Target `nxp_imxrt1062` runs on the Teensy 4.0 board from Spark Fun.
The orange user-LED is toggled.
The Espressif (`target xtensa_esp32_s3`) port for NodeMCU ESP32-S3
features a bare-metal startup _without_ using any of the SDK.
The bare-metal startup was taken from the work of
[Chalandi/Baremetal_esp32s3_nosdk](https://github.com/Chalandi/Baremetal_esp32s3_nosdk).
The multicore system first boots core0 which subsequently
starts up core1 and also starts up the RISC-V-ULP coprocessor core.
Blinky runs in the standard `ref_app`
on core0 toggling `port7` while an endless timer loop on core1
toggles `port6`. These LED ports togle in near unison
at the normal blinky feequency of $\frac{1}{2}~\text{Hz}$.
The RISC-V-ULP coprocessor performs an LED dimming
show on `port17` at a randomly chosen frequency
that is asynchronous to the regular blinky show.
Self-procured LEDs and resistors need to be fitted externally
on the port pins in order to observe blinking and dimming
on this particular board.

The Espressif (`target xtensa32`) port for NodeMCU ESP32
uses a subset of the
[Espressif SDK](https://github.com/espressif/esp-idf)
to run the reference application.
This somewhat unconventional implementation configures
$1$ single OS task running exclusively on $1$ CPU core only.
Additional reductions in code/memory size(s) have been accomplished
via selective stubbing of library functions.

For other compatible boards, feel free contact me directly or submit
an issue requesting support for your desired target system.
Expand Down
30 changes: 15 additions & 15 deletions ref_app/target/micros/xtensa_esp32_s3/startup/Std/StdLib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,26 +29,26 @@

extern "C" {

typedef signed long long DItype __attribute__((mode (DI)));
typedef unsigned long long UDItype __attribute__((mode (DI)));
typedef unsigned int USItype __attribute__((mode (SI)));
using DItype = signed long long;
using UDItype = unsigned long long;
using USItype = unsigned int;

extern int __builtin_clzll(unsigned long long);
extern auto __builtin_clzll(unsigned long long) -> int;

#define DWtype DItype
#define UDWtype UDItype
#define UWtype USItype
using DWtype = DItype;
using UDWtype = UDItype;
using UWtype = USItype;

UDWtype __udivdi3 (UDWtype n, UDWtype d);
UDWtype __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp);
UDWtype __umoddi3 (UDWtype u, UDWtype v);
auto __udivdi3 (UDWtype n, UDWtype d) -> UDWtype;
auto __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp) -> UDWtype;
auto __umoddi3 (UDWtype u, UDWtype v) -> UDWtype;

UDWtype __udivdi3 (UDWtype n, UDWtype d)
auto __udivdi3 (UDWtype n, UDWtype d) -> UDWtype
{
return __udivmoddi4 (n, d, (UDWtype *) 0);
}

UDWtype __umoddi3 (UDWtype u, UDWtype v)
auto __umoddi3 (UDWtype u, UDWtype v) -> UDWtype
{
UDWtype w;

Expand All @@ -57,7 +57,7 @@ UDWtype __umoddi3 (UDWtype u, UDWtype v)
return w;
}

UDWtype __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
auto __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp) -> UDWtype
{
UDWtype q = 0, r = n, y = d;
UWtype lz1, lz2, i, k;
Expand Down Expand Up @@ -136,7 +136,7 @@ UDWtype __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp)
#pragma GCC diagnostic ignored "-Wcast-align"
#endif

void* memset(void* str, int c, size_t n)
auto memset(void* str, int c, size_t n) -> void*
{
std::uint8_t* ptr { reinterpret_cast<std::uint8_t*>(str) };

Expand Down Expand Up @@ -180,7 +180,7 @@ void* memset(void* str, int c, size_t n)
return str;
}

void* memcpy (void* dest, const void* src, size_t n)
auto memcpy (void* dest, const void* src, size_t n) -> void*
{
std::uint8_t* d { reinterpret_cast<std::uint8_t*>(dest) };
const std::uint8_t* s { reinterpret_cast<const uint8_t*>(src) };
Expand Down
6 changes: 6 additions & 0 deletions ref_app/target/micros/xtensa_esp32_s3/startup/Std/core-isa.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
///////////////////////////////////////////////////////////////////////////////
// Copyright Christopher Kormanyos 2025.
// Distributed under the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)
//

// Originally from (but slightly modified from):

Expand Down
18 changes: 13 additions & 5 deletions ref_app/target/micros/xtensa_esp32_s3/startup/Std/ieee754-sf.S
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
/******************************************************************************************
// Copyright Christopher Kormanyos 2025.
// Distributed under the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)
//
******************************************************************************************/

// Originally from:
// Originally from (but slightly modified from):

/* IEEE-754 single-precision functions for Xtensa
Copyright (C) 2006-2025 Free Software Foundation, Inc.
Expand Down Expand Up @@ -272,7 +279,8 @@ __addsf3:

/* Subtraction */
__subsf3_aux:

.align 4

/* Handle NaNs and Infinities. (This code is placed before the
start of the function just to keep it in range of the limited
branch displacements.) */
Expand Down Expand Up @@ -438,7 +446,7 @@ __subsf3:
movi a2, 0
leaf_return

.Lsub_borrow:
.Lsub_borrow:
/* The subtraction has underflowed into the exponent field, so the
value needs to be renormalized. Shift the mantissa left as
needed to remove any leading zeros and adjust the exponent
Expand Down Expand Up @@ -502,12 +510,12 @@ __subsf3:

#ifdef L_mulsf3

/* Multiplication */
/* Multiplication */
#if !XCHAL_HAVE_MUL16 && !XCHAL_HAVE_MUL32 && !XCHAL_HAVE_MAC16
#define XCHAL_NO_MUL 1
#endif

.literal_position
.literal_position
__mulsf3_aux:

/* Handle unusual cases (zeros, subnormals, NaNs and Infinities).
Expand Down
11 changes: 9 additions & 2 deletions ref_app/target/micros/xtensa_esp32_s3/startup/Std/lib1funcs.S
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@

// Originally from:
/******************************************************************************************
// Copyright Christopher Kormanyos 2025.
// Distributed under the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)
//
******************************************************************************************/

// Originally from (but slightly modified from):

/* Assembly functions for the Xtensa version of libgcc1.
Copyright (C) 2001-2025 Free Software Foundation, Inc.
Expand Down
2 changes: 1 addition & 1 deletion ref_app/target/micros/xtensa_esp32_s3/startup/boot.S
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//
******************************************************************************************/

/* Originally from: */
/* Originally from (but slightly modified from): */
/******************************************************************************************
Filename : boot.S

Expand Down
Loading