Giter Site home page Giter Site logo

zigembeddedgroup / microzig Goto Github PK

View Code? Open in Web Editor NEW
929.0 28.0 61.0 11.89 MB

Unified abstraction layer and HAL for several microcontrollers

Zig 70.53% Shell 0.06% RobotFramework 0.05% Assembly 5.37% C 20.21% Nix 0.35% Python 3.44%
ziglang zig-package zig embedded hal

microzig's Introduction

MicroZig Logo

Chat Downloads Continuous Integration

NOTE: This is in development; breaks in the API are bound to happen.

What version of Zig to use

0.11.0

Getting Started With MicroZig

I Want To Use MicroZig

IMPORTANT: You don't have to clone this repository to get started!

MicroZig uses a monorepo architecture, but provides a lot of different packages. If you just want to get started, head over to downloads.microzig.tech and download an example for the chip family you desire.

We support several chip families like the RP2 family by RaspberryPi Foundation, STM32 by STMicroelectronics, and many others.

Unpack the example, and run zig build in the resulting example folder gives you zig-out/firmware which contains the resulting files.

Right now, you gotta figure out how to flash the MCU yourself, but as people say: Google is your friend. But you can also ask for help on our Discord server.

I Want To Contribute To MicroZig

IMPORTANT: Developer experience is degraded right now, and not really good. Windows isn't really a supported dev target and you got to expect some friction. There's a project for improving DX, feel free to grab tasks from there!

Please see the project page, it’s used as a place to brainstorm and organize work in ZEG. There will be issues marked as good first issue or drafts for larger ideas that need scoping/breaking ground on.

More words on contribution and development on MicroZig are further down below.

Introduction

This repo contains the infrastructure for getting started in an embedded Zig project; it "gets you to main()". Specifically, it offers:

  • a single easy-to-use builder function that:
    • generates your linker script
    • sets up packages and startup code
  • generalized interfaces for common devices, such as UART.
  • device drivers for interacting with external hardware
  • an uncomplicated method to define xref:interrupts[interrupts]

Design

For MicroZig internals please see the Design Document.

Developing

Right now, the developer experience is not optimal due to 0.11 not really supporting what we're doing at all.

If you want to test your changes, you gotta to the following:

Step 1: Install required python packages, either systemwide or via a virtual environment:

# systemwide:
[user@host] microzig-monorepo/ $ pip install -r tools/requirements.txt
[user@host] microzig-monorepo/ $ 

# using virtual environments:
[user@host] microzig-monorepo/ $ python3 -m venv .venv
[user@host] microzig-monorepo/ $ . .venv/bin/activate # on linux, macos
[user@host] microzig-monorepo/ $ . .venv/Scripts/activate # on windows
[user@host] microzig-monorepo/ $ pip3 install -r tools/requirements.txt
[user@host] microzig-monorepo/ $ 

Step 2: Create a deployment for local usage:

[user@host] microzig-monorepo/ $ python3 ./tools/bundle.py --debug
preparing environment...
validating packages...
loaded packages:
  * microzig-build
  * examples:microchip/avr
  * examples:...
  * microzig-core
  * microchip/avr
  * ...
resolving inner dependencies...
creating packages...
bundling microzig-build...
bundling microzig-core...
bundling microchip/avr...
...
[user@host] microzig-monorepo/ $ 

This command yields output in ./microzig-deploy that is meant to be fetched via http://localhost:8080/.

Step 3: To serve the files on this port, you can start a pre-bundled web server:

[user@host] microzig-monorepo/ $ python3 ./tools/demo-server.py
...

This way, you spawn a local HTTP server that will serve ./microzig-deploy on port 8080 on your machine, and you can then start fetching packages from this.

Now you can use curl to fetch the packages, or you can just create a local development project.

Step 4: Create a local test environment

This is basically done by unpacking an example from the ./microzig-deploy/examples folder, and starting to test changes. As the build.zig.zon has to be updated after running ./tools/bundle.py again, there's a script that helps here: tools/patch-build-zon.py can be used to patch/upgrade your development project inplace based on what it finds in ./microzig-deploy:

[user@host] microzig-monorepo/ $ python3 ./tools/patch-build-zon.py /tmp/dev-project/build.zig.zon
Updating hash of http://localhost:8080/packages/microzig-build.tar.gz to 12200040a36bbbb2fe09809861f565fcda9a10ec3064d70357aa40ad0a61596c16fb
Updating hash of http://localhost:8080/packages/microzig-core.tar.gz to 122013a37ce9ac295303f26057c203e722b9ceaefa5b4403fe5a18ab065f03079e7d
Updating hash of http://localhost:8080/packages/board-support/stmicro/stm32.tar.gz to 12207c278b78c5aeb08cd7889647d7d0d9a359cb28fe68105d2e43f85dabb3865981
[user@host] microzig-monorepo/ $

Both compiling the local example and updating the build.zig.zon requires running the local development server.

Repository structure

  • build/ contains the build components of MicroZig.
  • core/ contains the shared components of MicroZig.
  • board-support/ contains all official board support package.
  • examples/ contains examples that can be used with the board support packages.
  • tools/ contains tooling to work on MicroZig itself, so deployment, testing, ...
  • design/ contains images and logos

Versioning Scheme

MicroZig versions are tightly locked with Zig versions.

The general scheme is ${zig_version}-${commit}-${count}, so the MicroZig versions will look really similar to Zigs versions, but with our own commit abbreviations and counters.

As MicroZig sticks to tagged Zig releases, ${zig_version} will show to which Zig version the MicroZig build is compatible.

Consider the version 0.11.0-abcdef-123 means that this MicroZig version has a commit starting with abcdef, which was the 123rd commit of the version that is compatible with Zig 0.11.0.

microzig's People

Contributors

ardelean-calin avatar binarycraft007 avatar burgrp avatar chivay avatar connorrigby avatar deadblackclover avatar fmaggi avatar franciscollobet avatar freiguy1 avatar grazfather avatar hollmmax avatar jacobly0 avatar jimt avatar joelpaulkoch avatar kassane avatar kodesoul avatar kuon avatar l1ucas avatar marnix avatar masterq32 avatar mattnite avatar noxet avatar philippwendel avatar psnszsn avatar r4gus avatar rbino avatar sreehax avatar tobiaskohlbau avatar vesim987 avatar yerlaser avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

microzig's Issues

Please help: with format a string with numbers or allocator instance in microzig.

Hello!
Thank you for your work on that project.

I start to use it in development. I want to write some simple apps to understand if it works.

I want to be able to format a string with numbers.

I need help with the allocator issue. I need help finding a way to use the standard library functions that require an allocator instance.

Example:

  const allocator = os.heap.page_allocator;

   const string1 = try std.fmt.allocPrint(allocator, "{d}", .{count()});
   defer allocator.free(string1);
   microzig.hal.uart.write(0, string1);

Gives me the error:

 error: root struct of file 'start' has no member named 'os'
 root.os.heap.page_allocator

Is there a way to get the allocator in the Microzig? or ESP32C2 environment? Can I resolve those issues without the allocator usage?
Thank you in advance.

Add Support for SparkFun RED-V RISCV Board

I am currently revisiting computer architecture and design for my personal project of building an operating system. In an attempt to tap into my dormant knowledge of the hardware-software concepts, I would like to contribute and add support for the SparkFun RED-V board. It has a RISC-V chip from SiFive, FE310.

Suggestions re: STM32 from a Rust Embedded dev

Hey! Chiming in as someone doing embedded Rust things:

Just wanted to share particularly with respect to STM32 chips, which have an insane number of variants, SVD files that are often wrong, and a lot of challenging details, it might be worth looking at https://github.com/embassy-rs/stm32-data, which https://embassy.rs uses for the unified stm32 HAL. It is typically more actively patched and maintained for correctness than the upstream STM32 SVD data sources.

In general, SVD files often require patching and continued maintenance, https://github.com/embassy-rs/chiptool might be a good inspiration, which uses YAML files to apply patches and groupings, rather than hand-editing SVD files.

Feel free to close, or let me know if y'all would like to share notes on anything. Excited to see what you all build!

(edited title to make it more clear this is just my opinion, not like an "offical embedded rust position")

documentation not clear and failre when using example

I'm attempting to use microzig, and I'm also very new to zig and the instructions in README.adoc assume that you have a lot of knowledge about zig and how microzig works.

I attempted to use the sample and despite inferring how to make it work, even with modifications, it fails to compile.

run: zig init-exe

undocumented commands (implied via the vague statement: add the hardware support package as a submodule, this is also the "simple way" as zig init-exe doesn't do a git init, so can't do some git submodule command to add it):

mkdir deps
cd deps
git clone --recursive https://github.com/ZigEmbeddedGroup/microchip-atmega
cd ..

replace build.zig (undocumented what file, and need to replace hardware_support_package with microchip-atmega and replace root_source_file with source_file) w/:

const std = @import("std");
const atmega = @import("deps/microchip-atmega/build.zig");

// the hardware support package should have microzig as a dependency
const microzig = @import("deps/microchip-atmega/deps/microzig/build.zig");

pub fn build(b: *std.build.Builder) !void {
    const optimize = b.standardOptimizeOption(.{});
    var exe = microzig.addEmbeddedExecutable( b, .{
        .name = "my-executable",
        .source_file = .{
            .path = "src/main.zig",
        },
        .backing = .{
            .board = atmega.boards.arduino_nano,

            // instead of a board, you can use the raw chip as well
            // .chip = atmega.chips.atmega328p,
        },
        .optimize = optimize,
    });
    exe.install();
}

replace src/main.zig with the next block (undocumented what file to put it in).

run zig build and see the following failure:

$ zig build
zig build-exe my-executable Debug avr-freestanding-eabi: error: the following command terminated unexpectedly:
[xxx]/github/zig/build/zig2 build-exe /private/tmp/mcre/deps/microchip-atmega/deps/microzig/src/start.zig -fno-strip --cache-dir /private/tmp/mcre/zig-cache --global-cache-dir [xxx]/.cache/zig --name my-executable -fno-compiler-rt -fsingle-threaded -target avr-freestanding-eabi -mcpu avr5 --script /private/tmp/mcre/zig-cache/microzig/bad2341405a5fe8c06f6286f91ea1100/ATmega328P_AVR5.ld --mod microzig:config,chip,cpu,hal,board:/private/tmp/mcre/deps/microchip-atmega/deps/microzig/src/microzig.zig --mod chip:microzig:/private/tmp/mcre/deps/microchip-atmega/src/chips/ATmega328P.zig --mod board:microzig:/private/tmp/mcre/deps/microchip-atmega/src/boards/arduino_nano.zig --mod hal:microzig:/private/tmp/mcre/deps/microchip-atmega/src/hals/ATmega328P.zig --mod app:microzig:/private/tmp/mcre/src/main.zig --mod cpu:microzig:/private/tmp/mcre/deps/microchip-atmega/deps/microzig/src/modules/cpus/avr5.zig --mod config::/private/tmp/mcre/zig-cache/microzig/config-6df6165a62f30831cad66fa94379f8d3.zig --deps app,microzig --enable-cache --listen=- 
Build Summary: 1/4 steps succeeded; 1 failed (disable with -fno-summary)
install transitive failure
└─ install my-executable transitive failure
   └─ zig build-exe my-executable Debug avr-freestanding-eabi failure
      └─ linkerscript success
error: the following build command failed with exit code 1:
/private/tmp/mcre/zig-cache/o/b840765e239219fa1562b810d024cd97/build [xxx]/github/zig/build/zig2 /private/tmp/mcre /private/tmp/mcre/zig-cache [xxx]/.cache/zig

environment: MacOS Ventura 13.2

zig version: 0.11.0-dev.2249+dcdb87836

I'm unsure what to do now to make the necessary executable.

Add "hal" packages to microzig

Similar to how an app can have it's own packages, create another option to the build function that adds a "hal" package. This is a package that only depends on microzig and would be used to write drivers for chips with similar peripherals, Eg. an nrf52 hal.

An application would be able to access the hal via microzig.hal, and with it's access to other microzig namespaces it would be able to do conditional compilation for different chips if the need arose.

Implement compiler_rt for AVR

This work requires upstreaming to https://github.com/ziglang/zig

As a repro compile this program with the following build command:

export fn foo(a: i32, b: i32) i32 {
    return a * b;
}
zig build-exe -target avr-freestanding -mcpu=avr5 test.zig -O ReleaseSmall

and you'll see the following output:

LLVM ERROR: Not supported instr: <MCInst 312 <MCOperand Reg:1> <MCOperand Imm:15> <MCOperand Reg:53>>

note: doing this in a basic program that is being built by the microzig build function, it does not bundle compiler_rt, so you'll see a missing definition:

ld.lld: error: undefined symbol: __mulsi3

STM32F4XX does not support SysTick register

I think this may be a bug in regz, not microzig, or maybe whatever svd file that was used to generate the register definitions. afaik All Cortex devices have the same definition of this register. I coppied a samd one and it worked without issue

Getting Started

How do I get started ? The instructions on setting up a new project seem out of date.
I would like to develop for raspberry pi pico.

No output files generated

If I clone the repository and run zig build, zig-out folder isn't generated. Only zig-cache is. Tried with this compiler zig-linux-x86_64-0.11.0-dev.2317+46b2f1f70.

I would expect for test programs to compile.

AVR: Support C backend

Right now, the AVR support is degraded. With using avr-gcc, we can make it work quite well though.

This requires updating the AVR code to use a different logic in the start code, and just implement a extern fn main() c_int, that jumps into the microzig code and is happy about .bss, .data being already set up.

As-is, we cannot implement the whole startup logic ourselves via C backend, as some features are still missing.

Various issues

I am having troubles getting examples building with the monorepo. Reporting my issues as requested.

  1. No mention of need to install requirements.
  2. bundle.py uses pathspec with the negate kwarg in match_tree, but requirements.txt doesn't pin a version. This used 0.11.0 on my machine, but negate shows up in 0.12.0
  3. bundle.py uses the --hard-deference option from tar, which is not a valid option for OSX tar. I suggest using tarlib. I got around this, however, by installing gnutar with brew and symlinking it to tar on my PATH.
  4. No .zon files with the build.zig files for the example. I don't know how to write these to have it point to the server.

Improve customization of linker scripts

Right now in raspberrypi-rp2040 we've had to hardcode the linker script to allow a boot2 section, time_critical section, and have all of sram executable so that some of it may be executed by the processor. Linker scripts can be pretty complex, but maybe we can reduce the feature to only what's typically required in embedded systems. If users are already at the point where they need very specific features or linker script layouts then it's already easy enough for them to write their own.

Compile error on Raspberry Pi

Building a microzig project on a Raspberry Pi 2 fails with this error:

/home/pi/.cache/zig/p/1220af58bdaa721b8189f3a7adfda660517dd354463463388e96d69fe4ceccf80b92/build.zig:161:55: error: expected type 'usize', found 'u64'
                .elf, .bin, .hex, .dfu, .esp => |val| {
                                                      ^
/home/pi/.cache/zig/p/1220af58bdaa721b8189f3a7adfda660517dd354463463388e96d69fe4ceccf80b92/build.zig:161:55: note: unsigned 32-bit int cannot represent all possible unsigned 64-bit values

What could be the reason for this? Maybe because the Pi's CPU is 32 bit, and u64 is hardcoded somewhere?

Support serial over USB (CEC ADC)

I'd like to have a log.zig logFn that I could use to emit debug logs over USB, rather than UART.

Currently Microzig has support for acting as a USB HID device. I believe emitting debug logs over USB would require support for acting as a "serial device", which uses USB CDC/ADC.

[Tracking issue] Platform support/wishlist

Currently, the number of supported platforms is rather minimal. If the owners are alright with it, I'd like to designate this issue as a tracking issue for boards/chips which are not yet implemented in here with the aim of getting a good selection supported.

To start off the list, here's a few chips I have come across:

  • ATMega644/A (chip)
  • ATTiny25/45/85 (chip)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.