-
Notifications
You must be signed in to change notification settings - Fork 118
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* import all used ports and return them to the user * better cpu interface for ports to fix riscv features issue * add post process function to target * add build formats * port lpc, linker script generation and refactor * remove rp2040 stack end from linker script * copy `MemoryRegion` to generate_linker_script.zig and make `BuildFormat.uf2` a custom enum * replace port_select with microzig_options * Make lazy dependencies work * remove code duplication * port stm32 examples to the new build system * comments and implement the rest of the functionality
- Loading branch information
Showing
49 changed files
with
156,893 additions
and
144,879 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# build-internals | ||
|
||
This package is meant to provide build related type definitions for | ||
internal use in the repo (avoiding circular dependencies). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,285 @@ | ||
const std = @import("std"); | ||
const Build = std.Build; | ||
const LazyPath = Build.LazyPath; | ||
const Module = Build.Module; | ||
|
||
pub fn build(b: *Build) void { | ||
_ = b.addModule("build-internals", .{ | ||
.root_source_file = b.path("build.zig"), | ||
}); | ||
} | ||
|
||
/// A compilation target for MicroZig. Provides information about the chip, | ||
/// hal, board and so on. | ||
/// | ||
/// This is used instead of `std.Target.Query` to define a MicroZig Firmware. | ||
pub const Target = struct { | ||
/// The `*std.Build.Dependency` belonging of the port that created this target. | ||
dep: *Build.Dependency, | ||
|
||
/// The preferred binary format of this MicroZig target, if it has one. | ||
preferred_binary_format: ?BinaryFormat = null, | ||
|
||
/// The chip this target uses. | ||
chip: Chip, | ||
|
||
/// Usually, embedded projects are single-threaded and single-core applications. Platforms that | ||
/// support multiple CPUs should set this to `false`. | ||
single_threaded: bool = true, | ||
|
||
/// Determines whether the compiler_rt package is bundled with the application or not. | ||
/// This should always be true except for platforms where compiler_rt cannot be built right now. | ||
bundle_compiler_rt: bool = true, | ||
|
||
/// (optional) Provides a default hardware abstraction layer that is used. | ||
/// If `null`, no `microzig.hal` will be available. | ||
hal: ?HardwareAbstractionLayer = null, | ||
|
||
/// (optional) Provides description of external hardware and connected devices | ||
/// like oscillators and such. | ||
/// | ||
/// This structure isn't used by MicroZig itself, but can be utilized from the HAL | ||
/// if present. | ||
board: ?Board = null, | ||
|
||
/// (optional) Provide a custom linker script for the hardware or define a custom generation. | ||
linker_script: ?LazyPath = null, | ||
|
||
/// (optional) Post processing step that will patch up and modify the elf file if necessary. | ||
patch_elf: ?*const fn (*Build.Dependency, LazyPath) LazyPath = null, | ||
|
||
/// Things you can change by deriving from an already existing target. | ||
pub const DeriveOptions = struct { | ||
preferred_binary_format: ?BinaryFormat = null, | ||
chip: ?Chip = null, | ||
single_threaded: ?bool = null, | ||
bundle_compiler_rt: ?bool = null, | ||
hal: ?HardwareAbstractionLayer = null, | ||
board: ?Board = null, | ||
linker_script: ?LazyPath = null, | ||
patch_elf: ?*const fn (*Build.Dependency, LazyPath) LazyPath = null, | ||
}; | ||
|
||
/// Creates a new target from an existing one. | ||
pub fn derive(from: *const Target, options: DeriveOptions) *Target { | ||
const ret = from.dep.builder.allocator.create(Target) catch @panic("out of memory"); | ||
ret.* = .{ | ||
.dep = from.dep, | ||
.preferred_binary_format = options.preferred_binary_format orelse from.preferred_binary_format, | ||
.chip = options.chip orelse from.chip, | ||
.single_threaded = options.single_threaded orelse from.single_threaded, | ||
.bundle_compiler_rt = options.bundle_compiler_rt orelse from.bundle_compiler_rt, | ||
.hal = options.hal orelse from.hal, | ||
.board = options.board orelse from.board, | ||
.linker_script = options.linker_script orelse from.linker_script, | ||
.patch_elf = options.patch_elf orelse from.patch_elf, | ||
}; | ||
return ret; | ||
} | ||
}; | ||
|
||
/// Defines a chip. | ||
pub const Chip = struct { | ||
/// The display name of the controller. | ||
name: []const u8, | ||
|
||
/// (optional) link to the documentation/vendor page of the controller. | ||
url: ?[]const u8 = null, | ||
|
||
/// The cpu target this controller uses. | ||
cpu: std.Target.Query, | ||
|
||
/// The provider for register definitions. | ||
register_definition: union(enum) { | ||
/// Use `regz` to create a zig file from a JSON schema. | ||
json: LazyPath, | ||
|
||
/// Use `regz` to create a json file from a SVD schema. | ||
svd: LazyPath, | ||
|
||
/// Use `regz` to create a zig file from an ATDF schema. | ||
atdf: LazyPath, | ||
|
||
/// Use the provided file directly as the chip file. | ||
zig: LazyPath, | ||
}, | ||
|
||
/// The memory regions that are present in this chip. | ||
memory_regions: []const MemoryRegion, | ||
}; | ||
|
||
/// Defines a hardware abstraction layer. | ||
pub const HardwareAbstractionLayer = struct { | ||
/// Provides the root source file for the HAL. | ||
root_source_file: LazyPath, | ||
|
||
/// Provides imports for the HAL. **Need to be heap allocated.** | ||
imports: []const Module.Import = &.{}, | ||
}; | ||
|
||
/// Provides a description of a board. | ||
/// | ||
/// Boards provide additional information to a chip and HAL package. | ||
/// For example, they can list attached peripherials, external crystal frequencies, | ||
/// flash sizes, ... | ||
pub const Board = struct { | ||
/// Display name of the board. | ||
name: []const u8, | ||
|
||
/// (optional) link to the documentation/vendor page of the board. | ||
url: ?[]const u8 = null, | ||
|
||
/// Provides the root source file for the board definition. | ||
root_source_file: LazyPath, | ||
|
||
/// (optional) Provides imports for the board definition. **Need to be heap allocated.** | ||
imports: []const Module.Import = &.{}, | ||
}; | ||
|
||
/// Convenience struct for heap allocated imports. | ||
pub const ModuleImports = struct { | ||
/// List of imports. | ||
list: []const Module.Import = &.{}, | ||
|
||
/// Initializes module imports on the heap. | ||
pub fn init(allocator: std.mem.Allocator, imports: []const Module.Import) ModuleImports { | ||
return .{ | ||
.list = allocator.dupe(imports) catch @panic("out of memory"), | ||
}; | ||
} | ||
}; | ||
|
||
/// The resulting binary format for the firmware file. | ||
/// A lot of embedded systems don't use plain ELF files, thus we provide means | ||
/// to convert the resulting ELF into other common formats. | ||
pub const BinaryFormat = union(enum) { | ||
/// [Executable and Linkable Format](https://en.wikipedia.org/wiki/Executable_and_Linkable_Format), the standard output from the compiler. | ||
elf, | ||
|
||
/// A flat binary, contains only the loaded portions of the firmware with an unspecified base offset. | ||
bin, | ||
|
||
/// The [Intel HEX](https://en.wikipedia.org/wiki/Intel_HEX) format, contains | ||
/// an ASCII description of what memory to load where. | ||
hex, | ||
|
||
/// A [Device Firmware Upgrade](https://www.usb.org/sites/default/files/DFU_1.1.pdf) file. | ||
dfu, | ||
|
||
/// The [USB Flashing Format (UF2)](https://github.com/microsoft/uf2) designed by Microsoft. | ||
uf2: enum { | ||
ATMEGA32, | ||
SAML21, | ||
NRF52, | ||
ESP32, | ||
STM32L1, | ||
STM32L0, | ||
STM32WL, | ||
LPC55, | ||
STM32G0, | ||
GD32F350, | ||
STM32L5, | ||
STM32G4, | ||
MIMXRT10XX, | ||
STM32F7, | ||
SAMD51, | ||
STM32F4, | ||
FX2, | ||
STM32F2, | ||
STM32F1, | ||
NRF52833, | ||
STM32F0, | ||
SAMD21, | ||
STM32F3, | ||
STM32F407, | ||
STM32H7, | ||
STM32WB, | ||
ESP8266, | ||
KL32L2, | ||
STM32F407VG, | ||
NRF52840, | ||
ESP32S2, | ||
ESP32S3, | ||
ESP32C3, | ||
ESP32C2, | ||
ESP32H2, | ||
RP2040, | ||
RP2XXX_ABSOLUTE, | ||
RP2XXX_DATA, | ||
RP2350_ARM_S, | ||
RP2350_RISC_V, | ||
RP2350_ARM_NS, | ||
STM32L4, | ||
GD32VF103, | ||
CSK4, | ||
CSK6, | ||
M0SENSE, | ||
}, | ||
|
||
/// The [firmware format](https://docs.espressif.com/projects/esptool/en/latest/esp32/advanced-topics/firmware-image-format.html) used by the [esptool](https://github.com/espressif/esptool) bootloader. | ||
esp, | ||
|
||
/// Custom option for non-standard formats. | ||
custom: *Custom, | ||
|
||
/// Returns the standard extension for the resulting binary file. | ||
pub fn get_extension(format: BinaryFormat) []const u8 { | ||
return switch (format) { | ||
.elf => ".elf", | ||
.bin => ".bin", | ||
.hex => ".hex", | ||
.dfu => ".dfu", | ||
.uf2 => ".uf2", | ||
.esp => ".bin", | ||
|
||
.custom => |c| c.extension, | ||
}; | ||
} | ||
|
||
pub const Custom = struct { | ||
/// The standard extension of the format. | ||
extension: []const u8, | ||
|
||
/// A function that will convert a given `elf` file into the custom output format. | ||
convert: *const fn (*Build.Dependency, elf: Build.LazyPath) Build.LazyPath, | ||
}; | ||
}; | ||
|
||
/// A descriptor for memory regions in a microcontroller. | ||
pub const MemoryRegion = struct { | ||
/// The type of the memory region for generating a proper linker script. | ||
kind: Kind, | ||
offset: u64, | ||
length: u64, | ||
|
||
pub const Kind = union(enum) { | ||
/// This is a (normally) immutable memory region where the code is stored. | ||
flash, | ||
|
||
/// This is a mutable memory region for data storage. | ||
ram, | ||
|
||
/// This is a memory region that maps MMIO devices. | ||
io, | ||
|
||
/// This is a memory region that exists, but is reserved and must not be used. | ||
reserved, | ||
|
||
/// This is a memory region used for internal linking tasks required by the board support package. | ||
private: PrivateRegion, | ||
}; | ||
|
||
pub const PrivateRegion = struct { | ||
/// The name of the memory region. Will not have an automatic numeric counter and must be unique. | ||
name: []const u8, | ||
|
||
/// Is the memory region executable? | ||
executable: bool, | ||
|
||
/// Is the memory region readable? | ||
readable: bool, | ||
|
||
/// Is the memory region writable? | ||
writeable: bool, | ||
}; | ||
}; |
2 changes: 1 addition & 1 deletion
2
build/definitions/build.zig.zon → build-internals/build.zig.zon
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
.{ | ||
.name = "build/definitions", | ||
.name = "build-internals", | ||
.version = "0.0.0", | ||
.paths = .{ | ||
"LICENSE", | ||
|
Oops, something went wrong.