Hubris is a microcontroller operating environment designed for deeply-embedded systems

Overview

Hubris

build

Hubris is a microcontroller operating environment designed for deeply-embedded systems with reliability requirements. Its design was initially proposed in RFD41, but has evolved considerably since then.

Learning

Developer documentation is in Asciidoc in the doc/ directory. It gets rendered via GitHub pages, and is available at https://oxidecomputer.github.io/hubris .

Navigating

The repo is laid out as follows.

  • app/ is where the top-level binary crates for applications live, e.g. app/gimlet contains the firmware crate for Gimlet. Generally speaking, if you want to build an image for something, look here.

  • build/ contains the build system and supporting crates.

  • doc/ contains developer documentation.

  • drv/ contains drivers, a mix of simple driver lib crates and fully-fledged server bin crates. Current convention is that drv/SYSTEM-DEVICE is the driver for DEVICE on SYSTEM (where SYSTEM is usually an SoC name), whereas drv/SYSTEM-DEVICE-server is the server bin crate.

  • lib/ contains assorted utility libraries we've written. If you need to make a reusable crate that doesn't fit into one of the other directories, it probably belongs here.

  • stage0/ is the bootloader/hypovisor, primarily for LPC55.

  • support/ contains some interface and programming support files, like fake certificates and programmer firmware images.

  • sys/ contains the "system" bits of Hubris, namely the kernel (sys/kern), the shared crate defining the ABI (sys/abi), and the user library used by tasks (sys/userlib).

  • task/ contains reusable tasks that aren't drivers. The distinction between things that live in task vs in drv/something-server is fuzzy. Use your judgement.

  • test/ contains the test framework and binary crates for building it for various boards.

Developing

We currently support Linux and Windows as first-tier platforms. The build probably also works on Illumos and Mac; if anyone would like to step up to maintain support and a continuous build for those architectures, we'd love the help.

To submit changes for review, push them to a new branch in this repo (not a separate GitHub fork) and submit a pull request to merge that branch into master. (Pull requests from separate GitHub forks do not currently work. First, the pre-integration checks do not get run automatically in forks, so you'd have to enable Actions in your fork. More importantly, these checks require configuration of a repository secret in order to clone private submodules, so they'll fail when run from a fork.)

Prereqs

You will need:

  • A rustup-based toolchain install. rustup will take care of automatically installing our pinned toolchain version, and the cross-compilation targets, when you first try to build.

  • openocd (ideally 0.11) or (if using the LPC55) pyocd (0.27 or later). Note that the 0.10 release of OpenOCD predates the STLink v3. People are using various post-0.10, pre-0.11 builds provided by system package managers, with some success, but if your system isn't packaging 0.11 yet, pester them. If you're going to use Homebrew on macOS to install OpenOCD, you need to use brew install --head openocd to build the tip of the main branch rather than using the latest binary release.

  • The appropriate Rust toolchain target installed (note: this should happen automatically):

    • rustup target add thumbv7em-none-eabihf (for the STM32)
    • rustup target add thumbv8m.main-none-eabihf (for the LPC55)
  • libusb, typically found from your system's package manager as libusb-1.0.0 or similar.

  • libfdti1, found as libftdi1-dev or similar.

  • arm-none-eabi-objcopy and arm-none-eabi-gdb, typically from your system's package manager using package names like arm-none-eabi-binutils and arm-none-eabi-gdb. macOS users can run brew install --cask gcc-arm-embedded to install the official ARM binaries.

  • The Hubris debugger, Humility:

Windows

If you're on Windows, you can get set up by doing this:

See here for getting the source of openocd or get unofficial binaries. Alternatively, you can install via with chocolatey:

> choco install openocd

You can easily install openocd with scoop:

> scoop bucket add extras
> scoop install openocd

NOTE: openocd installed via scoop has proven problematic for some users. If you experience problems, try installing via choco or from source (see above).

You'll probably need to install this driver.

If your terminal doesn't support serial connections, you'll want to also use PuTTY; this guide does a good job of explaining how.

Finally, the instructions below invoke shell scripts. They're very small, and so for now you can run the commands manually, yourself. We may improve this in the future.

Build

We do not use cargo build or cargo run directly because they are too inflexible for our purposes. We have a complex multi-architecture build, which is a bit beyond them.

Instead, the repo includes a Cargo extension called xtask that namespaces our custom build commands.

  • cargo xtask dist TOMLFILE builds a distribution image for the application described by the TOML file.
    • cargo xtask dist app/demo-stm32f4-discovery/app.toml - stm32f4-discovery
    • cargo xtask dist app/demo-stm32f4-discovery/app-f3.toml - stm32f3-discovery
    • cargo xtask dist app/lpc55xpresso/app.toml - lpcxpresso55s69
    • cargo xtask dist app/demo-stm32h7-nucleo/app-h743.toml - nucleo-ih743zi2
    • cargo xtask dist app/demo-stm32h7-nucleo/app-h753.toml - nucleo-ih753zi
    • cargo xtask dist app/demo-stm32h7-nucleo/app-h7b3.toml - stm32h7b3i-dk
    • cargo xtask dist app/gemini-bu/app.toml - Gemini bringup board
  • cargo xtask build from within a task or kernel directory builds that one component in isolation. The result won't actually run, because it's missing important system context, but this provides a cheaper way to do incremental builds during development. See the Iterating section below.

Note: Because the Hubris repository contains submodules, before building, you must update submodules, either via git clone --recursive, or git submodule update --init or similar.

Run

Details depend on your target board. Here are some common evaluation boards we support.

Gemini bringup board

See the Gemini Bringup Getting Started docs.

STM32F3 & STM32F4 Discovery boards

Connect board via USB.

From one terminal, launch openocd with the corresponding config file:

$ openocd -f app/demo-stm32f4-discovery/openocd.cfg       # STM32F4 Discovery boards OR
$ openocd -f app/demo-stm32f4-discovery/openocd-f3.cfg    # STM32F3 Discovery boards

From another terminal:

$ cargo xtask gdb app/demo-stm32f4-discovery/app.toml openocd.gdb         # STM32F4 Discovery boards OR
$ cargo xtask gdb app/demo-stm32f4-discovery/app-f3.toml openocd-f3.gdb   # STM32F3 Discovery boards

If this works, you'll see gdb mumble some things about flashing, openocd will scroll by some updates, and you will eventually be unceremoniously deposited at a (gdb) prompt halted on the first instruction. Type c / continue to run.

Note that for the STM32F3 Discovery, SB10 must be soldered closed for ITM to work! This solder bridge defaults to being open, which leaves SWO disconnected. See the STM32F3 Discovery User Manual (UM1570) for schematic and details.

LPCXpresso55S69 board

To use the LPCXpresso55S69, you will need pyOCD, version 0.27.0 or later.

The LPCXpresso55S69 is somewhat of a mess because the built-on on-chip debugger, LPC-Link2, does not correctly support SWO/SWV

If you have the stock LPC-Link2, it will report itself this way via pyocd list:

$ pyocd list
  #   Probe                                           Unique ID
-----------------------------------------------------------------
  0   NXP Semiconductors LPC-LINK2 CMSIS-DAP V5.361   JSAQCQIQ

It's also possible that you have the Segger J-Link firmware -- firmware that will make its odious presence known by prompting for you to accept license terms whenever running pyocd list!

$ pyocd list
  #   Probe                                                       Unique ID
-----------------------------------------------------------------------------
  0   Segger J-Link LPCXpresso V2 compiled Apr  4 2019 16:54:03   726424936

In either of these cases you must -- as a one-time step -- install new firmware on the LPC-Link2. The new firmware is a build of the (open source) DAPLink, which we affectionally call RickLink after the engineer who managed to get it all built -- no small feat!

There are two files that you will need, both contained in the Hubris repository:

You will additionally need the LPCScrypt program from NXP.

Here are the steps to install RickLink:

  1. Install the DFU jumper. This can be found next to the SWD header on the left side of the board; it is labelled "DFU".

  2. Run scripts/boot_lpcscrypt from the installed LPCScrypt software:

$ /usr/local/lpcscrypt/scripts/boot_lpcscrypt 
Looking for DFU devices with VID 1fc9 PID 000c ...
dfu-util -d 1fc9:000c -c 1 -i 0 -t 2048 -R  -D /usr/local/lpcscrypt/scripts/../bin/LPCScrypt_228.bin.hdr
Booted LPCScrypt target (1fc9:000c) with /usr/local/lpcscrypt/scripts/../bin/LPCScrypt_228.bin.hdr
$
  1. Run lpcscrypt clockslow:
$ /usr/local/lpcscrypt/bin/lpcscrypt clockslow
$
  1. Run lpcscrypt program +c BankA :
$ /usr/local/lpcscrypt/bin/lpcscrypt program +c ~/hubris/support/lpc4322_bl_crc.bin BankA
..
Programmed 57344 bytes to 0x1a000000 in 0.827s (67.717KB/sec)
$
  1. Assuming it is successful, remove the DFU jumper and disconnect/reconnect USB

  2. There should now be a USB mass storage device named MAINTENANCE

# fdisk -l
Disk /dev/nvme0n1: 477 GiB, 512110190592 bytes, 1000215216 sectors
Disk model: Micron 2200S NVMe 512GB
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: A8653F99-39AB-4F67-A9C9-524A2864856E

Device             Start        End   Sectors   Size Type
/dev/nvme0n1p1      2048    1050623   1048576   512M EFI System
/dev/nvme0n1p2   1050624  967393279 966342656 460.8G Linux filesystem
/dev/nvme0n1p3 967393280 1000214527  32821248  15.7G Linux swap


Disk /dev/sda: 64.1 MiB, 67174400 bytes, 131200 sectors
Disk model: VFS
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000
# mount /dev/sda /mnt
# ls /mnt
DETAILS.TXT  PRODINFO.HTM
# cat /mnt/DETAILS.TXT
# DAPLink Firmware - see https://mbed.com/daplink
Unique ID: 02360b000d96e4fc00000000000000000000000097969905
HIC ID: 97969905
Auto Reset: 1
Automation allowed: 1
Overflow detection: 1
Daplink Mode: Interface
Interface Version: 0254
Bootloader Version: 0254
Git SHA: f499eb6ec4a847a2b78831fe1acc856fd8eb2f28
Local Mods: 1
USB Interfaces: MSD, CDC, HID, WebUSB
Bootloader CRC: 0x09974fb3
Interface CRC: 0x7174ab4c
Remount count: 0
URL: https://os.mbed.com/platforms/LPCXpresso55S69/
  1. Copy lpc4322_lpc55s69xpresso_if_rla_swo_hacks.bin to the USB drive
$ sudo cp ~/hubris/support/lpc4322_lpc55s69xpresso_if_rla_swo_hacks.bin /mnt
$
  1. Unmount (or otherwise sync) the USB drive:
# umount /mnt
#
  1. Unplug and replug the USB cable.

Verify that you are on the new firmware by running pyocd list:

$ pyocd list
  #   Probe                        Unique ID                                         
-------------------------------------------------------------------------------------
  0   LPCXpresso55S69 [lpc55s69]   02360b000d96e4fc00000000000000000000000097969905  

Once RickLink is running:

  • Terminal 1: pyocd gdbserver -t lpc55s69
  • Terminal 2: telnet localhost 4444 (semihosting output)
  • Terminal 3: cargo xtask gdb app/lpc55xpresso/app.toml openocd.gdb

LPC55S28 on Gemini carrier board

Note that the RickLink running on the LPCXpresso55S69 can also be used as the debugger for the LPC55S28 on the Gemini carrier board. To do this, first, follow all of the instructions above to get RickLink onto your LPCXpresso55S69. Then:

  1. Using a soldering iron, solder a two-pin header on J5. J5 can be be found to the left of P1 and below the "Debugger" jumper (J3).

  2. Put a jumper on the new header

  3. Move the "Debugger" jumper (J3) to "Ext".

  4. Use a SWD cable (10-pin 2x5 1.27mm pitch cable) to connect the SWD on the LPCXpresso55S69 to the SWD underneath the carrier board on Gemini (J202)

(To allow your RickLink to once again debug its local LPC55S69, remove the jumper on J5 and move J3 to "Loc".)

ST Nucleo-H743ZI2 board

  • Terminal 1: cd app/demo-stm32h7-nucleo; openocd
  • Terminal 2: cargo xtask gdb app/demo-stm32h7-nucleo/app-h743.toml openocd.gdb

ST Nucleo-H753ZI board

  • Terminal 1: cd app/demo-stm32h7-nucleo; openocd
  • Terminal 2: cargo xtask gdb app/demo-stm32h7-nucleo/app-h753.toml openocd.gdb

ST STM32H7B3I-DK board

  • Terminal 1: cd app/demo-stm32h7-nucleo; openocd
  • Terminal 2: cargo xtask gdb app/demo-stm32h7-nucleo/app-h7b3.toml openocd.gdb

Multiple boards simultaneously

If multiple probes are attached, tools may struggle to find the right one at the right time. In particular, OpenOCD will pick the first one that it finds; to force OpenOCD to pick a particular probe, you can ascertain the serial number of the probe (e.g., from humility probe) and then specify that serial number in the corresponding openocd.cfg by adding, e.g.:

interface hla
hla_serial 271828182845904523536028

(Where 271828182845904523536028 is the serial number of the probe.)

Update ST-Link Firmware if necessary

It is common that debugging dongles, and development boards with embedded debug hardware like the Nucleo series, are delivered with older firmware.

You will not be able to use Humilty with outdated ST-Link firmware.

Follow this "ST-LINK firmware upgrade" link to find software and instructions necessary to install current firmware.

Flash

An image within a Hubris archive can be flashed directly onto a target board by running cargo xtask flash and specifying the appropriate TOML file. This will run cargo xtask dist and then execute the appropriate command (either OpenOCD or pyOCD) to flash the image; the exact invocation depends on the board:

  • LPCXpresso55S69: cargo xtask flash app/lpc55xpresso/app.toml
  • STM32F4 Discovery board: cargo xtask flash app/demo-stm32f4-discovery/app.toml
  • ST Nucleo-H743ZI2 board: cargo xtash flash app/demo-stm32h7-nucleo/app-h743.toml
  • ST Nucleo-H753ZI board: cargo xtash flash app/demo-stm32h7-nucleo/app-h753.toml
  • ST STM32H7B3I-DK board: cargo xtask flash app/demo-stm32h7-nucleo/app-h7b3.toml
  • Gemini bringup board: cargo xtask flash app/gemini-bu/app.toml

Debug

The Hubris debugger, Humility, is run in situ by specifying an archive on a directly connected board, or postmortem by specifying a dump. As a convenience for development, Humility can also be run in situ by specifying the appropriate TOML, e.g. on a machine with an STM32F4 Discovery board directly attached:

$ cargo xtask humility app/demo-stm32f4-discovery/app.toml tasks
    Finished dev [optimized + debuginfo] target(s) in 0.17s
     Running `target/debug/xtask humility demo/app.toml tasks`
humility: attached via ST-Link
ID ADDR     TASK               GEN STATE    
 0 20000108 jefe                 0 Healthy(InRecv(None))     
 1 20000178 rcc_driver           0 Healthy(InRecv(None))     
 2 200001e8 usart_driver         0 Healthy(InRecv(None))     
 3 20000258 user_leds            0 Healthy(Runnable)          <-
 4 200002c8 ping                48 Healthy(Runnable)         
 5 20000338 pong                 0 Healthy(InRecv(None))     
 6 200003a8 idle                 0 Healthy(Runnable)         

Testing

The Hubris kernel is tested with a dedicated test image that includes a test runner, assistant and test suite. The test image emits its results via ITM. While these results can be interpreted manually, humility test automates this. humility test itself is most easily run via cargo xtask test, which runs the equivalent of cargo xtask dist, cargo xtask flash and cargo xtask humility test. The exact invocation depends on the board:

  • LPCXpresso55S69: cargo xtask test test test/tests-lpc55/app.toml
  • STM32F3 Discovery board: cargo xtask test test/tests-stm32fx/app-f3.toml
    Note: for this board, SB10 must be soldered closed for ITM to work
  • STM32F4 Discovery board: cargo xtask test test/tests-stm32fx/app.toml
  • ST Nucleo-H743ZI2 board: cargo xtask test test/tests-stm32h7/app-h743.toml
  • ST Nucleo-H753ZI board: cargo xtask test test/tests-stm32h7/app-h753.toml
  • ST STM32H7B3I-DK board: cargo xtask test test/tests-stm32h7/app-h7b3.toml

See the documentation for humility test for details on test results.

Debugging tests

Output from tests is captured by humility test; sys_log!() calls to tests can be added and then captured in a humility test dump. To capture a dump from tests that are otherwise passing, use cargo xtask humility directly and pass the -d flag, e.g.:

$ cargo xtask humility test/tests-stm32fx/app.toml -- test -d
...
humility: attached via ST-Link
humility: TPIU sync packet found at offset 1
humility: ITM synchronization packet found at offset 12
humility: expecting 22 cases
humility: running test_send ... ok
...
humility: running test_timer_notify ... ok
humility: running test_timer_notify_past ... ok
humility: tests completed: pass
humility: test output dumped to hubris.testout.2

if one needs to both run GDB and the test suite, use cargo xtask gdb with the test image's TOML and the appropriate GDB file, and then place breakpoints at the test of interest.

Adding a task

To create your own task, the easiest method is:

  • Copy task-template to a new name.
  • Edit its Cargo.toml with your name and a new package name.
  • Add it to the list of workspace members in the root Cargo.toml.

You can now run cargo xtask build in the task's directory to run a standalone build. (See below for details.)

To actually test the task, you need to add it to a system image by editing an app.toml file. A typical entry for a small task that uses no memory-mapped peripherals would read

[tasks.name_for_task_in_this_image]
path = "../my-task-directory"
name = "my-task-target-name"
priority = 1
requires = {flash = 1024, ram = 1024}
start = true

Iterating

Because a full image build can take 10 seconds or more, depending on what you've changed, when you're iterating on a task or kernel you'll probably want to build it outside the context of an image. We have a thing called a "standalone build" for this.

For instance, to run a standalone build of task-ping, run:

$ cd task-ping
$ cargo xtask build

This magic happens in three parts:

  1. Packages that support standalone build have a package.metadata.build.target key giving the default target architecture for standalone builds.
  2. Our build.rs files that receive information from the dist xtask will do reasonable defaulty things if that information is missing, e.g. in this case.
  3. By convention, we set a default feature "standalone" for standalone builds, and switch it off in the app.toml used by the package xtask. You can use this feature to conditionally compile stuff.

Note: most tasks pick up their build.rs behavior implicitly by depending on userlib. You generally do not need a build.rs in your task unless you need to detect compiler/architecture features or depend on board rev.

Comments
  • Notification/interrupt latency: resetting IRQ notification mask takes hundreds of cycles

    Notification/interrupt latency: resetting IRQ notification mask takes hundreds of cycles

    Greetings!

    I'm ~~on an incredibly misguided misadventure~~ experimenting with using Hubris in a BLDC application. Given the high currents and potential for copious amounts of magic smoke, the, erm... "pucker factor" is pretty high, but so far so good! 😅

    I've gotten Hubris's codebase to the point where I can depend on it as if it were an external crate (lots of env variable overriding and explicit path setting, but that's for another bug), and am now working through the intricacies of how Hubris handles interrupts as notifications. It appears that there's a Not Small™️ amount of overhead associated with interrupt/notification handling, at least in terms of a 40KHz control loop. I'm building this on an H723 where I've confirmed I can boost the SYSCLK to 520MHz (!), with an AHBx bus speed of 270MHz, which means I've got just about 13k instructions to do the full commutation + FoC computation, including overhead.

    I've been benchmarking the interrupt latency using an Idolatry server via idol_runtime::dispatch_n and the handle_notitication section of the NotificationHandler trait. For the benchmark setup I've got a timer going at full tilt, have the OC1 channel drive a pin high, and catch the update interrupt. The moment we enter DefaultHandler from arm_m.rs I drive a GPIO pin high via the BSRR register so I can tell exactly when we enter the interrupt handler. Hubris then detects the task that needed the interrupt, context switches into PendSV, and resumes the task. Since this is an idol server, the sys_recv call in dispatch_n returns and in turn calls the handle_notification method on the server.

    Apologies, this is kinda wordy; here's a probe of what's going on here (this is done at opt-level = 3, which is both different than the stock Hubris config and also much larger in terms of flash):

    latency

    1. First, the timer goes off, driving the yellow trace and firing off the interrupt. This is the start of the 40KHz commutation handler.
    2. I hacked in a single instruction in DefaultHandler to drive the cyan trace high, indicating the first moment we get into Hubris.
    3. Inside of handle_notification, I first drive the magenta pin high, do some "work" inside my custom interrupt handler (200x core::asm::nop() calls just for this example), then drive it low when I'm effectively done with what I need to do in my interrupt handler.
    4. Now that I've handled the notification (née interrupt), I need to update Hubris that we want to handle it again. This is done via a sys_irq_control call, which I've wrapped with a call to drive the blue tracehigh and low before/after the call:
      unsafe { core::ptr::write_volatile(0x58021018 as *mut u32, 1 << 8); }
      sys_irq_control(TIM1_UPD_MASK, true);
      unsafe { core::ptr::write_volatile(0x58021018 as *mut u32, 1 << (8 + 16)); }
      
    5. Finally, when we leave the handle_notification I set the cyan trace low.

    Side note: I need to re-confirm this is at 520MHz... I had previously done so via probing MCO, but the 40ns delay between the magenta drop and the blue raise - two consecutive writes to BSRR - admittedly is a bit concerning, considering that translates to ~10 instructions instead of just a single one. Will look at the disassembly after filing this...

    If I'm reading this correctly, this takes about 1.3us to get into the handle_notification call, or ~680 instructions (!). I know there's a decent amount of overhead in context switching, finding the right handling task, checking masks. setting up the MPU, etc. It still takes quite a while even on O3, though judging by the use cases I can find in the repo I suspect interrupt latency has not been a target for optimization. That said the more surprising part is that simply notifying Hubris that I want to reset and listen again for the interrupt (sys_irq_control) takes over 3x as long as the actual interrupt itself (!!!), which translates to multiple hundreds of cycles at 520MHz. This seems... inefficient? Looking through the code it seems to need to call into the kernel to do so, and I haven't been able to trace beyond the kernel context switch in sys_irq_control_stub. Any ideas on how to handle notifications like this faster? Am I just missing an optimization flag or three?

    As a workaround: how does one go about overriding interrupt handlers to use 'em outside of the Hubris framework? The reference manual suggests they're declared weak, but I tried using cortex-m-rt's #[interrupt] decorator around a fn TIM1_UP and it didn't seem to override the DefaultHandler Hubris handler. I don't see any instances of overriding the default interrupt handler within the Hubris codebase, though there's a pretty good chance I just plain missed it :)

    opened by timblakely 16
  • Build fail on MacOS: feature(asm) may not be used on the stable release channel

    Build fail on MacOS: feature(asm) may not be used on the stable release channel

    This is probably a local config problem but...

    ➜  hubris git:(master) rustup show
    Default host: x86_64-apple-darwin
    rustup home:  /Users/georgn/.rustup
    
    installed toolchains
    --------------------
    
    stable-x86_64-apple-darwin
    nightly-2019-01-19-x86_64-apple-darwin
    nightly-2020-04-07-x86_64-apple-darwin
    nightly-2021-09-22-x86_64-apple-darwin
    nightly-x86_64-apple-darwin
    
    installed targets for active toolchain
    --------------------------------------
    
    thumbv7em-none-eabihf
    thumbv8m.main-none-eabihf
    x86_64-apple-darwin
    
    active toolchain
    ----------------
    
    nightly-2021-09-22-x86_64-apple-darwin (overridden by '/Users/georgn/git/hubris/rust-toolchain.toml')
    rustc 1.57.0-nightly (ac2d9fc50 2021-09-21)
    
    ➜  hubris git:(master) cargo xtask dist app/demo-stm32h7-nucleo/app-h7b3.toml
        Finished dev [optimized + debuginfo] target(s) in 0.64s
         Running `target/debug/xtask dist app/demo-stm32h7-nucleo/app-h7b3.toml`
    flash = 8000000..8100000
    ram = 20000000..20020000
    Used:
    flash: 0x24100
    ram: 0x8000
    building path app/demo-stm32h7-nucleo/../../task/jefe
       Compiling cortex-m v0.7.3
       Compiling userlib v0.1.0 (/Users/georgn/git/hubris/sys/userlib)
    error[E0554]: `#![feature]` may not be used on the stable release channel
      --> sys/userlib/src/lib.rs:28:1
       |
    28 | #![feature(asm)]
       | ^^^^^^^^^^^^^^^^
    
    error[E0554]: `#![feature]` may not be used on the stable release channel
      --> sys/userlib/src/lib.rs:29:1
       |
    29 | #![feature(naked_functions)]
       | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    
    For more information about this error, try `rustc --explain E0554`.
    error: could not compile `userlib` due to 2 previous errors
    warning: build failed, waiting for other jobs to finish...
    error[E0554]: `#![feature]` may not be used on the stable release channel
      --> /Users/georgn/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-0.7.3/src/lib.rs:58:45
       |
    58 | #![cfg_attr(feature = "inline-asm", feature(asm))]
       |                                             ^^^
    
    error: build failed
    Error: failed to build jefe
    
    Caused by:
        command failed, see output for details
    

    Any hints or suggestions welcome.

    opened by MMI 14
  • Build system cleanup

    Build system cleanup

    On Friday, @cbiffle and I talked about me maybe cleaning up the build system a bit. I thought about it over the weekend, and I'd like to take a stab at it.

    This PR is going to be where I'm going to be doing my work. I'm basing a lot of it on xtasks: https://github.com/matklad/cargo-xtask Basically, xtask is a pattern for a polyfill for a future cargo feature that lets you do this kind of thing, and so by reorganizing around it, we reasonably future-proof work.

    Rough plan:

    • [x] convert packager to an xtask
    • [x] follow xtask conventions
      • [x] packager -> dist
      • [x] introduce ci task and clean up CI, maybe? needs more investigation first
    • [x] fold package.sh /package_lspc55 into dist xtask
    • [x] fold run.sh into a new debugger xtask (willing to bikeshed this name)

    thoughts on the above plan?

    opened by steveklabnik 12
  • bump toolchain to last night's nightly

    bump toolchain to last night's nightly

    The decision to re-purpose the asm feature flag was changed, which is great. Let's get us on a version of the toolchain that uses the new flags.

    ~~This won't be quite ready just yet; I tested using the f4 demo; gonna use one CI run to show me what else breaks so I can fix it up.~~ Now ready!

    opened by steveklabnik 11
  • Update toolchain

    Update toolchain

    This PR is a WIP; I built the demo project and it works, but not sure about the others just yet.

    This PR takes us up to today's nightly, 2021-10-12. This doesn't require any real changes, just updates to fix various warnings. I've separated each into their own commits.

    Some questions:

    • is ULease being dead code actually correct here? A cursory search didn't see it actually being used yet anywhere, that is, rustc is right.
    • lpc55_support has some more warnings; these come from a dependency, packed_struct. We're on 0.3, the latest version is 0.10. I haven't explored that codebase yet and so I don't feel as confident in updating. Happy to give it a shot, but figure I'd tackle it last, and it's in another repo anyway which we'd have to get merged and then get it updated over here.
    opened by steveklabnik 9
  • Error: environment variable not found

    Error: environment variable not found

    Hi,

    I got the following error? Any hints? Any document to add a new board (or CPU) to hubris?

    Thanks, Sheng-Liang PS:

    Setup: Surface-laptop 4 load with ubuntu 21.10: Linux Surface-Laptop-4 5.13.0-35-generic #40-Ubuntu SMP Mon Mar 7 08:03:10 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

    cargo xtask dist app/demo-stm32h7-nucleo/app-h743.toml Finished dev [optimized + debuginfo] target(s) in 0.16s Running target/debug/xtask dist app/demo-stm32h7-nucleo/app-h743.toml flash = 0x08000000..0x08100000 ram = 0x20000000..0x20020000 sram1 = 0x30000000..0x30020000 Used: flash: 0x32000 (19%) ram: 0x10000 (50%) sram1: 0x8000 (25%) Error: environment variable not found

    opened by Shengliang 7
  • xtask: Include textaddress for each symbol file.

    xtask: Include textaddress for each symbol file.

    I don't know if it's just that I'm using an older gdb than everyone else, but on my system the default script.gdb generated by xtask doesn't work as gdb cannot match up the files against their corresponding addresses:

    Reading symbols from target/demo-stm32g0b1-nucleo/dist/final.elf...(no debugging symbols found)...done.
    target/demo-stm32g0b1-nucleo/dist/script.gdb:1: Error in sourced command file:
    The address where target/demo-stm32g0b1-nucleo/dist/kernel has been loaded is missing
    0x08004eca in ?? ()
    No symbol table is loaded.  Use the "file" command.
    

    By specifying the correct textaddress for each symbol file they are loaded correctly:

    Reading symbols from target/demo-stm32g0b1-nucleo/dist/final.elf...(no debugging symbols found)...done.
    add symbol table from file "target/demo-stm32g0b1-nucleo/dist/kernel" at
            .text_addr = 0x8000000
    add symbol table from file "target/demo-stm32g0b1-nucleo/dist/jefe" at
            .text_addr = 0x8008000
    add symbol table from file "target/demo-stm32g0b1-nucleo/dist/rcc_driver" at
            .text_addr = 0x800c000
    add symbol table from file "target/demo-stm32g0b1-nucleo/dist/idle" at
            .text_addr = 0x800e000
    0x08004eca in __aeabi_memset4 ()
        at /cargo/registry/src/github.com-1ecc6299db9ec823/compiler_builtins-0.1.49/src/arm.rs:219
    
    opened by jperkin 6
  • Improve caching via Swatinem/rust-cache

    Improve caching via Swatinem/rust-cache

    We were trying to do this ourselves, but it has always been a bit... suboptimal. https://matklad.github.io/2021/09/04/fast-rust-builds.html recently points towards this Action, and it should do a better job than we were doing, and is easier to use, to boot!

    This is not ready to merge yet, I would like to verify that it actually works, which of course means running the jobs which means opening a PR.

    opened by steveklabnik 6
  • Change the openocd.cfg

    Change the openocd.cfg

    I had to make this change to get my board to connect. The real question is, why? I'm opening this PR not so much because I think this should be merged, but I want to get to the bottom of it.

    opened by steveklabnik 6
  • Error: environment variable not found

    Error: environment variable not found

    I'm getting this error as well but it doesn't even seem to be getting as far as your thing got.

    Using rutsc 1.64.0 and cargo 1.64.0

    [nix-shell:~/hubris]$ cargo xtask dist app/demo-stm32f4-discovery/app-f3.toml
        Finished dev [optimized + debuginfo] target(s) in 0.24s
         Running `target/debug/xtask dist app/demo-stm32f4-discovery/app-f3.toml`
    Error: environment variable not found
    
    opened by therishidesai 5
  • Cortex-M0+ port

    Cortex-M0+ port

    It would be nice to have Cortex-M0+ support for situations in the future where we need a low-cost micro.

    @jperkin has a prototype port.

    We should talk. :-)

    kernel 
    opened by cbiffle 5
  • Round image size up to the next multiple of 32 before calculating hash.

    Round image size up to the next multiple of 32 before calculating hash.

    The image produced by the build is padded out to the next multiple of 32 with 0xff. This change gets us a FWID identical to the hash value of the final.bin image.

    opened by flihp 0
  • Update RoT memory map to reserve RAM for updates

    Update RoT memory map to reserve RAM for updates

    Due to system constraints there is no alternate image for the stage0 bootloader. This makes updating it a riskier proposition than Hubris since a broken stage0 may be equivalent to a bricked board. To reduce risk, we can reserve a region of RAM for staging an update before committing to flash.

    Section 2.1.8 of the LPC55 manual gives a table of RAM layouts. The final product will use the 320 KB layout. We have a size limit of 64K for stage0. We've been testing with the 256KB layout which lacks RAM3 and we aren't running into any limitations so reserving RAM3 looks plausible.

    lpc55 
    opened by labbott 0
  • Enums from RDL generated in generator

    Enums from RDL generated in generator

    There are a lot changes to the upstream tools etc to get this in place, so I'd like to review the changes here and iterate if necessary.

    This uses num-derive per @cbiffle's suggestion and removes the hand-written enum for state decoding now that it is generated. We can change most everything here, so feedback appreciated! This works fine with the legacy maps too, since the encoding is optional.

    I've also not been a serious consumer of the FPGA registers API so feedback from those that have would be appreciated.

    opened by nathanaelhuffman 3
  • SP can come up with a self-assigned MAC address

    SP can come up with a self-assigned MAC address

    While debugging a presumably-unrelated issue on a gimlet in the compliance rack, we used faux-mgs to reset the SP over the management network via

    faux-mgs \
        --listen-addr '[::]:0' \
        --interface axf1 \
        --discovery-addr '[fe80::aa40:25ff:fe04:10c]:11111' \
        reset
    

    The reset took effect immediately (as evidenced by the fans ceasing their screaming), but faux-mgs did not see the SP come back online, and subsequent attempts to talk to it all timed out. After some frantic hair-pulling, we learned that the SP had actually come back fine, but had assigned itself a different MAC/IP address. After sending it a second reset (to its new address):

    faux-mgs \
        --listen-addr '[::]:0' \
        --interface axf1 \
        --discovery-addr '[fe80::0c1d:57ff:fe6c:7c38]:11111' \
        reset
    

    it came back with its original, expected MAC / IP address (fe80::aa40:25ff:fe04:10c).

    opened by jgallagher 1
  • control-plane-agent: Include number of errors when reporting sensor readings

    control-plane-agent: Include number of errors when reporting sensor readings

    opened by jgallagher 0
  • control-plane-agent should send VPD-based identity information

    control-plane-agent should send VPD-based identity information

    opened by jgallagher 0
Owner
Oxide Computer Company
Servers as they should be.
Oxide Computer Company
A lightweight microkernel/IPC based operating system built with Rust which is not a clone of any existing operating system

Noble Operating System Noble is a lightweight microkernel and IPC based operating system built with Rust which is not a clone of any existing operatin

Revolution Xenon 3 Jan 10, 2022
A comparison of operating systems written in Rust

Rust OS comparison A comparison of operating systems written in Rust. There are several open source operating systems written in Rust. Most of them ar

Markus Kohlhase 492 Jan 8, 2023
A secure embedded operating system for microcontrollers

Tock is an embedded operating system designed for running multiple concurrent, mutually distrustful applications on Cortex-M and RISC-V based embedded

Tock Embedded OS 4.1k Jan 5, 2023
A secure embedded operating system for microcontrollers

Tock is an embedded operating system designed for running multiple concurrent, mutually distrustful applications on Cortex-M and RISC-V based embedded

Tock Embedded OS 4k Jan 2, 2023
The official kernel for Popcorn OS, and operating system designed for handheld devices.

About Popkern is the kernel for Popcorn OS, an operating system designed for handheld devices. As such, the kernel is (to be) optimised at all levels

Team Scena 3 Sep 19, 2021
An all-environment scripting library for interacting with CosmWasm smart-contracts.

BOOT Smart contract scripting library to ease CosmWasm smart contract deployment and testing. BOOT is inspired by terra-rust-api and uses cosmos-rust

Abstract 18 Dec 28, 2022
A hobby operating system, in Rust

intermezzOS: kernel intermezzOS is a hobby operating system. This repository is for its kernel. See the website for more. License This project is dual

intermezzOS 1.3k Jan 1, 2023
The Stupid Operating System

Stupid Operating System SOS is a simple, tiny toy OS implemented in Rust. I'm writing this mostly for fun, to learn more about OS design and kernel ha

SOS 241 Dec 15, 2022
Aero is a new modern, unix based operating system. It is being developed for educational purposes.

Areo Aero is a new modern, unix based operating system written in Rust and is being developed for educational purposes. Aero follows the monolithic ke

Anhad Singh 623 Dec 24, 2022
A new operating system kernel with Linux binary compatibility written in Rust.

Kerla Kerla is a monolithic operating system kernel from scratch in Rust which aims to be compatible with the Linux ABI, that is, runs Linux binaries

Seiya Nuta 3.1k Jan 1, 2023
Operating system written in Rust for NumWorks calculator (model n0110)

RustWorks An OS (eventually) for the Numworks calculator (model n0110). Setup First install Rust by following these instuctions then: rustup target ad

null 30 Nov 10, 2022
Geng wanzheng ([a] more complete) asynchronous operating system

更完整系统(GWZOS) 更完整系统的目的是编写一个异步功能完整的异步操作系统。我们希望尽可能完整地实现异步内核的核心概念,提供相应的驱动、软件生态系统,为未来内核的设计探索可能的实现方案。对比不同解决方案的性能开销,得到较详细的内核验证结论。 感谢大家对项目的支持!接龙链接 设计文档请参考: 无相

Luo Jia 10 Aug 26, 2021
SteinsOS is an operating system written in Rust

SteinsOS is an operating system featuring non-preemptive kernel targeting on single-core armv8 architecture.

Sheng 84 Dec 15, 2022
Xrs is a POSIX-subset operating system kernel written in Rust.

XRS-OS ( ?? WIP) Xrs is a POSIX-subset operating system kernel written in Rust. Current project team members 0x5459 core developer (he/him) 0x5457 cor

null 7 Nov 16, 2022
A simples rust operating system that prints hello world.

rust-os-helloworld A simples rust operating system that prints hello world. Just run: cargo install bootimage and: cargo bootimage Install QEMU and: q

null 3 Nov 24, 2021
An attempt at an operating system written in Rust

Rust Operating System An attempt at a simple operating system in Rust and a semester project for the Operating Systems course at CS@UCU. Documentation

Andriy Sultanov 10 Jan 15, 2022
A small operating system, for my own learning

taos This project is the result of following Philipp Oppermann's series of tutorials in building a small operating system kernel targeting x86-64, alo

null 0 Nov 7, 2021
Cute tiny operating system for RISC-V. ฅ•ω•ฅ

MoeOS ⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄ ٩(^ᴗ^)۶欢迎参观MoeOS的仓库,MoeOS是一个小巧可爱(并不)的操作系统,目前全力支持RISC-V中。 (*≧▽≦)因为还只是一个玩具操作系统,就别要求她能做太多事情啦!现在功能还不完善,会慢慢加的! 编译 呐,你想给我找个家么? 目前MoeOS

Rui Li 30 Nov 11, 2022
Rux - An x86_64 toy operating system kernel written in Rust

Rux - An x86_64 toy operating system kernel written in Rust. Rux is a port of the Hux kernel, my x86 32-bit single-CPU toy kernel written in C, following the OSTEP book structure and terminology.

Guanzhou Jose Hu 6 Feb 26, 2022