Skip to content

Commit

Permalink
Merge pull request #482 from tock/make-all-tab
Browse files Browse the repository at this point in the history
Make: add `make tab` as an approach to build for multiple locations
  • Loading branch information
jrvanwhy authored Aug 14, 2023
2 parents ae66d0a + daa201a commit c2fef04
Show file tree
Hide file tree
Showing 29 changed files with 351 additions and 262 deletions.
1 change: 0 additions & 1 deletion .cargo/config
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,5 @@ rtv7em = "rthumbv7em"
[target.'cfg(any(target_arch = "arm", target_arch = "riscv32"))']
rustflags = [
"-C", "relocation-model=static",
"-C", "link-arg=-Tlayout.ld",
]
runner = ["cargo", "run", "-p", "runner", "--release"]
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ libtock_runtime = { path = "runtime" }
libtock_sound_pressure = {path = "apis/sound_pressure"}
libtock_temperature = { path = "apis/temperature" }

[build-dependencies]
libtock_build_scripts = { path = "build_scripts"}

[profile.dev]
panic = "abort"
lto = true
Expand Down
65 changes: 64 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ EXCLUDE_MIRI := $(EXCLUDE_RUNTIME) --exclude ufmt-macros
# Arguments to pass to cargo to exclude `std` and crates that depend on it. Used
# when we build a crate for an embedded target, as those targets lack `std`.
EXCLUDE_STD := --exclude libtock_unittest --exclude print_sizes \
--exclude runner --exclude syscalls_tests
--exclude runner --exclude syscalls_tests \
--exclude libtock_build_scripts

# Currently, all of our crates should build with a stable toolchain. This
# verifies our crates don't depend on unstable features by using cargo check. We
Expand All @@ -127,6 +128,68 @@ test: examples test-stable
cargo miri test $(EXCLUDE_MIRI) --workspace
echo '[ SUCCESS ] libtock-rs tests pass'

# Helper functions to define make targets to build for specific (flash, ram,
# target) compilation tuples.
#
# Inspiration from these answers:
# - https://stackoverflow.com/a/50357925
# - https://stackoverflow.com/a/9458230
#
# To create a compilation target for a specific architecture with specific flash
# and RAM addresses, use `fixed-target`:
#
# ```
# $(call fixed-target, F=0x00030000 R=0x20008000 T=thumbv7em-none-eabi A=cortex-m4)
# ```
#
# The "arguments" if you will are:
# - F = Flash Address: The address in flash the app is compiled for.
# - R = RAM Address: The address in RAM the app is compiled for.
# - T = Target: The cargo target to compile for.
# - A = Architecture: The Tock architecture name the target corresponds to.
#
# This technique uses two make variables internally to keep track of state:
# - `ELF_TARGETS`: This is the list of unique targets for each compilation
# tuple. Each target invokes `cargo build` with the specified settings.
# - `ELF_LIST`: The is a list of .elf paths of the generated elfs (one per
# compilation tuple). This is passed to `elf2tab` to generate the output .tab
# file.
#
# Internally, what `fixed-target` does is define a new make target named the
# join of all of the F/R/T/A variables (with the `=` characters removed) and
# then assigns target variables to that new target to represent the compilation
# tuple values.
concat = $(subst =,,$(subst $(eval ) ,,$1))
fixed-target = $(foreach A,$1,$(eval $(call concat,$1): $A)) $(eval ELF_TARGETS += $(call concat,$1))

$(call fixed-target, F=0x00030000 R=0x20008000 T=thumbv7em-none-eabi A=cortex-m4)
$(call fixed-target, F=0x00038000 R=0x20010000 T=thumbv7em-none-eabi A=cortex-m4)

$(call fixed-target, F=0x00040000 R=0x10002000 T=thumbv7em-none-eabi A=cortex-m4)
$(call fixed-target, F=0x00048000 R=0x1000a000 T=thumbv7em-none-eabi A=cortex-m4)

$(call fixed-target, F=0x00040000 R=0x20008000 T=thumbv7em-none-eabi A=cortex-m4)
$(call fixed-target, F=0x00042000 R=0x2000a000 T=thumbv7em-none-eabi A=cortex-m4)
$(call fixed-target, F=0x00048000 R=0x20010000 T=thumbv7em-none-eabi A=cortex-m4)

$(call fixed-target, F=0x00080000 R=0x20006000 T=thumbv7em-none-eabi A=cortex-m4)
$(call fixed-target, F=0x00088000 R=0x2000e000 T=thumbv7em-none-eabi A=cortex-m4)

$(call fixed-target, F=0x403b0000 R=0x3fca2000 T=riscv32imc-unknown-none-elf A=riscv32imc)
$(call fixed-target, F=0x40440000 R=0x3fcaa000 T=riscv32imc-unknown-none-elf A=riscv32imc)

$(call fixed-target, F=0x10020000 R=0x20004000 T=thumbv6m-none-eabi A=cortex-m0)
$(call fixed-target, F=0x10028000 R=0x2000c000 T=thumbv6m-none-eabi A=cortex-m0)

$(ELF_TARGETS):
LIBTOCK_LINKER_FLASH=$(F) LIBTOCK_LINKER_RAM=$(R) cargo build --example $(EXAMPLE) $(features) --target=$(T) $(release) --out-dir target/$(A).$(F).$(R) -Z unstable-options
$(eval ELF_LIST += target/$(A).$(F).$(R)/$(EXAMPLE),$(A).$(F).$(R))

.PHONY: tab
tab: $(ELF_TARGETS)
mkdir -p target/tab
elf2tab --kernel-major 2 --kernel-minor 1 -n $(EXAMPLE) -o target/tab/$(EXAMPLE).tab --stack 1024 --minimum-footer-size 256 $(ELF_LIST)

# Creates the `make <BOARD> EXAMPLE=<EXAMPLE>` targets. Arguments:
# 1) The name of the platform to build for.
#
Expand Down
28 changes: 23 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@ Generally this library was tested with Tock [Release

The library should work on all Tock boards, but currently apps must be compiled
for the flash and RAM address they are executed at. See [Fix
relocation](https://github.com/tock/libtock-rs/issues/28) for more details.
This means that process binaries must be compiled especially for your board and
that there can only be one application written in rust at a time and it must be
installed as the first application on the board, unless you want to play games
with linker scripts.
relocation](https://github.com/tock/libtock-rs/issues/28) for more details. You
may either compile a process binary especially for your board and use only a
single application written in rust at a time, or use the `make tab` target that
builds examples for a series of likely useful flash and RAM addresses.

## Getting Started

Expand Down Expand Up @@ -44,6 +43,8 @@ The easiest way to start using libtock-rs is adding an example to the
`examples/` folder. We recommend starting by copying the `console` example, as
it is a simple example that shows you how to perform normal debug prints.

### Building for a specific board

To build your example for your board you can use

```shell
Expand All @@ -62,6 +63,23 @@ This script does the following steps for you:
- create a TAB (tock application bundle)
- if you have a J-Link compatible board connected: flash this TAB to your board (using tockloader)

### Building a generic TAB (Tock Application Bundle) file

To build your example for a variety of boards you can use

```shell
make tab EXAMPLE=<example>
```

To install the tab use tockloader

```shell
tockloader install target/tab/<example.tab>
```

Tockloader will determine which compiled version with the correct flash and RAM
addresses to use.


## License

Expand Down
3 changes: 3 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
libtock_build_scripts::auto_layout();
}
9 changes: 9 additions & 0 deletions build_scripts/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
authors = ["Tock Project Developers <tock-dev@googlegroups.com>"]
categories = ["embedded", "no-std", "os"]
description = """Helper functions for compiling libtock-rs apps."""
edition = "2021"
license = "Apache-2.0 OR MIT"
name = "libtock_build_scripts"
repository = "https://www.github.com/tock/libtock-rs"
version = "0.1.0"
60 changes: 60 additions & 0 deletions build_scripts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
Libtock Build Scripts Support Crate
===================================

This crate provides helpers for building libtock-rs apps.

Usage
-----

There are three general steps to use this crate.

1. This crate should be included as a build dependency in the app's Cargo.toml
file:

```toml
# Cargo.toml
...

[build-dependencies]
libtock_build_scripts = { git = "https://github.com/tock/libtock-rs"}
```

This will ensure the crate and the contained linker scripts are available for
the app build.

2. This crate provides a helper function which can used from the libtock-rs
app's build.rs file. In the common case, you just call the provided function
from the build.rs file in your crate's root:

```rs
// build.rs

fn main() {
libtock_build_scripts::auto_layout();
}
```

This will allow cargo to setup linker scripts and paths for the linker when
your app is built.

3. When calling `cargo build` you need to instruct the build.rs on where in
memory to compile your app for. This crate supports two mechanisms to do
this. You can only use one.

1. Set the `LIBTOCK_PLATFORM` environment variable which specifies the name
of the linker script in `/layouts` to be used. So for example, if you are
using the microbit_v2 you might run:

```bash
$ LIBTOCK_PLATFORM=microbit_v2 cargo build --target thumbv7em-none-eabi --release
```

2. Set the `LIBTOCK_LINKER_FLASH` and `LIBTOCK_LINKER_RAM` environment
variables which specify the starting addresses of flash and RAM memory,
respectively. This allows you to customize where exactly the compiled app
must be placed in flash and RAM. For example, to build for common
Cortex-M4 platforms you might run:

```bash
$ LIBTOCK_LINKER_FLASH=0x00040000 LIBTOCK_LINKER_RAM=0x20008000 cargo build --target thumbv7em-none-eabi --release
```
File renamed without changes.
Loading

0 comments on commit c2fef04

Please sign in to comment.