Overview
Running code on two cores requires the segmentation of the memory space. At a bare minimum, each core requires its own stack memory, with shared heap and vector table, but memory management is easier if we also dedicate specific memory areas for heap and vector table to each core.
With the RP2350, further segmentation will be required to run both Secure and Non-Secure code, but that’s a topic for another day. For now, we need configurations for the RP2040, and for the RP2350 in Secure, privileged mode to get off the ground.
The Astrobe IDEs don’t have support for dual-core programs. The configuration dialog allows to specify the data and code address parameters for core 0. These values can be accessed by a program via module LinkOptions
. The Astrobe linker uses the specified addresses to build an executable image, where the code is allocated in the flash memory code range, and the variables in the SRAM data range. The data memory space is sub-divided into vector table, heap, stack, and module variables.
See module Config for a depiction of the different address ranges (memory map).
Memory Configuration
Module Config
extends the specifications via Astrobe’s configuration dialog for core 1. The code range does not require any core-specific values, since it is shared among the cores. The module variables are always allocated in the data memory space of core 0, also shared among the cores. Hence, module Config
provides address range values for the stack, the heap, and the vector table for core 1.
In Astrobe, we allocate some of the SRAM to core 0. About half is a good starting point, but depending on the tasks allocated to each core, we may want to adapt this setting, creating a different SRAM distribution among the cores. Core 1 gets all the remaining SRAM “above” the memory allocated to core 0, hence the upper data address value (data end) for core 0 marks the delineation between the cores.1 The amount of vector memory space for core 1 is the same as specified for core 0, at the bottom of the data space of core 1.
Memory Management
The heaps and stacks of both cores are managed through module Memory
. Using NEW
on core 0 allocates memory in the heap of core 0, on core 1 in the heap of core 1. Module Exceptions
sets the vector table address for core 0 at the start (bottom) of the data for core 0, while for core 1 this setting is done when the program for core 1 is started from core 0 via a utility in module MultiCore
.
Module Search Path Configuration
Apart from the directories containing the modules of the Oberon RTK framework itself, our library search path for the compiler and linker also needs to include entries to find Astrobe’s modules MUA
, LinkOptions
, ResData
, Error
, and FPU
, plus the file boot2.bin
for Astrobe for RP2040.
Configuration Files
The two main components discussed above, ie. the different memory settings as well as the search path, are stored in Astrobe’s config.ini
files, of which there can be many different ones to accommodate different needs, situations, and requirements.
Oberon RTK repository contains the current versions of different config files. Unless you happen to use the same directory structure for the installation of Astrobe and the Oberon RTK framework (see below), you’ll need to adjust the settings to your set-up. Also, projects may require their specific configuration files, eg. regarding the SRAM-split among the cores as outlined above.
We can build programs for the two RP MCUs using different Astrobe IDEs, using these config files:
-
Target RP2040/Pico:
- with Astrobe for RP2040
- with Astrobe for M0
-
Target RP2350/Pico2:
- with Astrobe for RP2350
- with Astrobe for RP2040
- with Astrobe for Cortex-M0
- with Astrobe for Cortex-M3
- with Astrobe for Cortex-M4
Tools.ini
The directories with the config files also contain the current Astrobe Tools.ini
files used.
Directory Structure
The above config .ini
files are based on the installation and work directory structure described below. I never put any own code into the Astrobe library installation directories, which I keep pristine and only ever change with new releases of Astrobe.2
(...)/astrobe-mx/m0: Astrobe for Cortex-M0
+ Configs
+ Examples
+ Lib
(...)/astrobe-mx/m3: Astrobe for Cortex-M3
+ Configs
+ Examples
+ Lib
(...)/astrobe-mx/m4: Astrobe for Cortex-M4
+ Configs
+ Examples
+ Lib
(...)/astrobe-mx/rp2040: Astrobe for RP2040
+ Configs
+ Examples
+ Lib
(...)/astrobe-mx/rp2350: Astrobe for RP2350
+ Configs
+ Examples
+ Lib
(...)/oberon-rtk
+ config
+ examples
+ lib
+ libv2
+ tools
%AstrobeM0%
, %AstrobeM3%
, %AstrobeM4%
, %AstrobeRP2040%
, and %AstrobeRP2350%
point to (...)
in the above outline.
Documented Limitations
- Astrobe forums: Bug Reports
- Astrobe release notes, section Known Problems (or similar, if any)
Known Limitations
If you use several Astrobe IDEs, and have modules that are shared between targets and maybe open in different IDEs, be aware that the Astrobe editor does not detect any changes made in a different tool. It’s easy to overwrite and lose changes if not careful. Same in case you use a different editor, eg. for a side-by-side display of modules (I often use VisualStudio Code for this purpose, even though it’s an Electron abomination). I certainly have lost work this way, which, yes, is a layer eight problem, or less euphemistically, my stupidity. Just be aware.
-
The two 4k blocks above the main SRAM remain reserved for the use by module
MemoryExt
. See: RP2040: MCU2.SRAM4_BASE, MCU2.SRAM5_BASE; RP2350: MCU.SRAM8_BASE, MCU.SRAM9_BASE ↩︎ -
I also keep the Astrobe libraries in a (local) git repository, so any changes are easily “browsable” after upgrading to a new Astrobe release. And former versions can be recalled if needed, eg. to build older program versions. ↩︎