{"id":13423254,"url":"https://github.com/oxidecomputer/hubris","last_synced_at":"2026-02-20T22:19:42.303Z","repository":{"id":37084860,"uuid":"252314296","full_name":"oxidecomputer/hubris","owner":"oxidecomputer","description":"A lightweight, memory-protected, message-passing kernel for deeply embedded systems.","archived":false,"fork":false,"pushed_at":"2026-02-13T22:29:20.000Z","size":68532,"stargazers_count":3427,"open_issues_count":298,"forks_count":218,"subscribers_count":50,"default_branch":"master","last_synced_at":"2026-02-14T02:34:15.611Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/oxidecomputer.png","metadata":{"files":{"readme":"README.mkdn","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":"support/fake_certs/fake_certificate.der.crt","governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2020-04-02T00:06:32.000Z","updated_at":"2026-02-13T20:29:13.000Z","dependencies_parsed_at":"2024-02-16T19:26:24.008Z","dependency_job_id":"743d1152-0fb3-47cb-be6f-cd5b76a50021","html_url":"https://github.com/oxidecomputer/hubris","commit_stats":null,"previous_names":[],"tags_count":173,"template":false,"template_full_name":null,"purl":"pkg:github/oxidecomputer/hubris","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oxidecomputer%2Fhubris","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oxidecomputer%2Fhubris/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oxidecomputer%2Fhubris/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oxidecomputer%2Fhubris/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oxidecomputer","download_url":"https://codeload.github.com/oxidecomputer/hubris/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oxidecomputer%2Fhubris/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29667088,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-20T19:49:36.704Z","status":"ssl_error","status_checked_at":"2026-02-20T19:44:05.372Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T00:00:26.208Z","updated_at":"2026-02-20T22:19:42.275Z","avatar_url":"https://github.com/oxidecomputer.png","language":"Rust","readme":"# Hubris\n\n![dist](https://github.com/oxidecomputer/hubris/actions/workflows/dist.yml/badge.svg)\n\nHubris is a microcontroller operating environment designed for deeply-embedded\nsystems with reliability requirements. Its design was initially proposed in\nRFD41, but has evolved considerably since then.\n\n# Learning\n\nDeveloper documentation is in Asciidoc in the `doc/` directory. It gets rendered\nvia GitHub pages, and is available at https://oxidecomputer.github.io/hubris .\n\n# Navigating\n\nThe repo is laid out as follows.\n\n- `app/` is where the top-level binary crates for applications live, e.g.\n  `app/gimlet` contains the firmware crate for Gimlet. Generally speaking, if\n  you want to build an image for something, look here.\n\n- `build/` contains the build system and supporting crates.\n\n- `chips/` contains peripheral definitions and debugging support files for\n  individual microcontrollers.\n\n- `doc/` contains developer documentation.\n\n- `drv/` contains drivers, a mix of simple driver lib crates and fully-fledged\n  server bin crates. Current convention is that `drv/SYSTEM-DEVICE` is the\n  driver for `DEVICE` on `SYSTEM` (where `SYSTEM` is usually an SoC name),\n  whereas `drv/SYSTEM-DEVICE-server` is the server bin crate.\n\n- `idl/` contains interface definitions written in\n  [Idol](https://github.com/oxidecomputer/idolatry)\n\n- `lib/` contains assorted utility libraries we've written. If you need to make\n  a reusable crate that doesn't fit into one of the other directories, it\n  probably belongs here.\n\n- `support/` contains some interface and programming support files, like fake\n  certificates and programmer firmware images.\n\n- `sys/` contains the \"system\" bits of Hubris, namely the kernel (`sys/kern`),\n  the shared crate defining the ABI (`sys/abi`), and the user library used by\n  tasks (`sys/userlib`).\n\n- `task/` contains reusable tasks that aren't drivers. The distinction between\n  things that live in `task` vs in `drv/something-server` is fuzzy. Use your\n  judgement.\n\n- `test/` contains the test framework and binary crates for building it for\n  various boards.\n\n- `website/` contains the source code for the\n  [hubris website](https://hubris.oxide.computer/)\n\n# Developing\n\nWe currently support Linux and Windows as first-tier platforms. Because of some\ninconsistency in linker behavior across platforms, images may not match across\nplatforms, so we recommend choosing one as your \"official\" build platform for\nproducing blessed images. macOS and Illumos are both used as informal build\nplatforms by Oxide employees, though they are not currently tested in CI. (Oxide\nblessed images are produced on Linux.)\n\nTo submit changes for review, push them to a branch in a fork and submit a pull\nrequest to merge that branch into `master`. For details, see\n[`CONTRIBUTING.md`](CONTRIBUTING.md).\n\n## Prereqs\n\nYou will need:\n\n- A `rustup`-based toolchain install. `rustup` will take care of automatically\n  installing our pinned toolchain version, and the cross-compilation targets,\n  when you first try to build.\n\n- [libusb](https://libusb.info/), typically found from your system's package\n  manager as `libusb-1.0.0` or similar.\n\n- [libfdti1](https://www.intra2net.com/en/developer/libftdi/), found\n  as `libftdi1-dev` or similar.\n\n- If you will be running GDB, you should install `arm-none-eabi-gdb`.  This is\n  typically from your system's package manager with a package name like\n  `arm-none-eabi-gdb` or `gdb-multiarch`.  macOS users can run\n  `brew install --cask gcc-arm-embedded` to install the\n  [official ARM binaries](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm).\n\n- The Hubris debugger, [Humility](https://github.com/oxidecomputer/humility).\n  Note that `cargo install` interacts strangely with the `rust-toolchain.toml`\n  file present in the root of this repository; if you run the following command\n  verbatim to install Humility, do so from a different directory:\n  - `cargo install --git https://github.com/oxidecomputer/humility.git --locked humility-bin`\n    - Requires `cargo-readme` as a dependency: `cargo install cargo-readme`\n\n### Windows\n\nThere are three alternative ways to install OpenOCD:\n\nSee [here](https://openocd.org/pages/getting-openocd.html) for getting the source of `openocd`\nor get unofficial binaries.\n\nAlternatively, you can install with [chocolatey](https://chocolatey.org/install):\n\n```console\n\u003e choco install openocd\n```\n\nLastly, you could install `openocd` with [scoop](https://scoop.sh/):\n\n```console\n\u003e scoop bucket add extras\n\u003e scoop install openocd\n```\n**Note:** `openocd` installed via `scoop` has proven problematic for some\nusers. If you experience problems, try installing via `choco` or from source\n(see above).\n\nTo use the ST-Link programmer, you'll probably need to install\n[this driver](https://www.st.com/en/development-tools/stsw-link009.html).\n\nIt's not necessary to build and run Hubris, but if you want to communicate\nover a serial link (and that's not supported by your terminal), you'll want to\nuse PuTTY; [this guide](https://pbxbook.com/voip/sputty.html)\ndoes a good job of explaining how.\n\n## Build\n\n**We do not use `cargo build` or `cargo run` directly because they are too\ninflexible for our purposes.** We have a complex multi-architecture build, which\nis a bit beyond them.\n\nInstead, the repo includes a Cargo extension called `xtask` that namespaces our\ncustom build commands.\n\n`cargo xtask dist TOMLFILE` builds a distribution image for the\napplication described by the TOML file.\n\n- `cargo xtask dist app/demo-stm32f4-discovery/app.toml` - stm32f4-discovery\n- `cargo xtask dist app/demo-stm32f4-discovery/app-f3.toml` - stm32f3-discovery\n- `cargo xtask dist app/lpc55xpresso/app.toml` - lpcxpresso55s69\n- `cargo xtask dist app/demo-stm32g0-nucleo/app-g031.toml` - stm32g031-nucleo\n- `cargo xtask dist app/demo-stm32g0-nucleo/app-g070.toml` - stm32g070-nucleo\n- `cargo xtask dist app/demo-stm32h7-nucleo/app-h743.toml` - nucleo-ih743zi2\n- `cargo xtask dist app/demo-stm32h7-nucleo/app-h753.toml` - nucleo-ih753zi\n- `cargo xtask dist app/gemini-bu/app.toml` - Gemini bringup board\n\n## Iterating\n\nBecause a full image build can take 10 seconds or more, depending on what you've\nchanged, when you're iterating on a task or kernel you'll probably want to build\nit separately. This is what `cargo xtask build` is for.\n\nFor instance, to build `task-ping` as it would be built in one of the images, but\nwithout building the rest of the demo, run:\n\n```console\n$ cargo xtask build app/gimletlet/app.toml ping\n```\n\n## Running `clippy`\nThe `cargo xtask clippy` subcommand can be used to run `clippy` against one or\nmore tasks in the context of a particular image:\n\n```console\n$ cargo xtask clippy app/gimletlet/app.toml ping pong\n```\n\n## Integrating with `rust-analyzer`\nThe Hubris build system will not work with `rust-analyzer` out of the box.\n\nHowever, `cargo xtask lsp` is here to help: it takes as its argument a Rust\nfile, and returns JSON-encoded configuration for how to set up `rust-analyzer`.\n\nTo use this data, some editor configuration is required!\n\n(we haven't made plugins yet, but it would certainly be possible)\n\nUsing Neovim and [`rust-tools`](https://github.com/simrat39/rust-tools.nvim),\nhere's an example configuration:\n\n```lua\n-- monkeypatch rust-tools to correctly detect our custom rust-analyzer\nrequire'rust-tools.utils.utils'.is_ra_server = function (client)\n  local name = client.name\n  local target = \"rust_analyzer\"\n  return string.sub(client.name, 1, string.len(target)) == target\n    or client.name == \"rust_analyzer-standalone\"\nend\n\n-- Configure LSP through rust-tools.nvim plugin, with lots of bonus\n-- content for Hubris compatibility\nlocal cache = {}\nlocal clients = {}\nrequire'rust-tools'.setup{\n  tools = { -- rust-tools options\n    autoSetHints = true,\n    inlay_hints = {\n      show_parameter_hints = false,\n      parameter_hints_prefix = \"\",\n      other_hints_prefix = \"\",\n      -- do other configuration here as desired\n    },\n  },\n\n  server = {\n    on_new_config = function(new_config, new_root_dir)\n      local bufnr = vim.api.nvim_get_current_buf()\n      local bufname = vim.api.nvim_buf_get_name(bufnr)\n      local dir = new_config.root_dir()\n      if string.find(dir, \"hubris\") then\n        -- Run `xtask lsp` for the target file, which gives us a JSON\n        -- dictionary with bonus configuration.\n        local prev_cwd = vim.fn.getcwd()\n        vim.cmd(\"cd \" .. dir)\n        local cmd = dir .. \"/target/debug/xtask lsp \"\n        -- Notify `xtask lsp` of existing clients in the CLI invocation,\n        -- so it can check against them first (which would mean a faster\n        -- attach)\n        for _,v in pairs(clients) do\n          local c = vim.fn.escape(vim.json.encode(v), '\"')\n          cmd = cmd .. '-c\"' .. c .. '\" '\n        end\n        local handle = io.popen(cmd .. bufname)\n        handle:flush()\n        local result = handle:read(\"*a\")\n        handle:close()\n        vim.cmd(\"cd \" .. prev_cwd)\n\n        -- If `xtask` doesn't know about `lsp`, then it will print an error to\n        -- stderr and return nothing on stdout.\n        if result == \"\" then\n          vim.notify(\"recompile `xtask` for `lsp` support\", vim.log.levels.WARN)\n        end\n\n        -- If the given file should be handled with special care, then\n        -- we give the rust-analyzer client a custom name (to prevent\n        -- multiple buffers from attaching to it), then cache the JSON in\n        -- a local variable for use in `on_attach`\n        local json = vim.json.decode(result)\n        if json[\"Ok\"] ~= nil then\n          new_config.name = \"rust_analyzer_\" .. json.Ok.hash\n          cache[bufnr] = json\n          table.insert(clients, {toml = json.Ok.app, task = json.Ok.task})\n        else\n          -- TODO:\n          -- vim.notify(vim.inspect(json.Err), vim.log.levels.ERROR)\n        end\n      end\n    end,\n\n    on_attach = function(client, bufnr)\n      local json = cache[bufnr]\n      if json ~= nil then\n        local config = vim.deepcopy(client.config)\n        local ra = config.settings[\"rust-analyzer\"]\n        -- Do rust-analyzer builds in a separate folder to avoid blocking\n        -- the main build with a file lock.\n        table.insert(json.Ok.buildOverrideCommand, \"--target-dir\")\n        table.insert(json.Ok.buildOverrideCommand, \"target/rust-analyzer\")\n        ra.cargo = {\n          extraEnv = json.Ok.extraEnv,\n          features = json.Ok.features,\n          noDefaultFeatures = true,\n          target = json.Ok.target,\n          buildScripts = {\n            overrideCommand = json.Ok.buildOverrideCommand,\n          },\n        }\n        ra.check = {\n          overrideCommand = json.Ok.buildOverrideCommand,\n        }\n        config.lspinfo = function()\n          return { \"Hubris app:      \" .. json.Ok.app,\n                   \"Hubris task:     \" .. json.Ok.task }\n        end\n        client.config = config\n      end\n    end,\n\n    settings = {\n      [\"rust-analyzer\"] = {\n        -- enable clippy on save\n        checkOnSave = {\n          command = \"clippy\",\n          extraArgs = { '--target-dir', 'target/rust-analyzer' },\n        },\n        diagnostics = {\n          disabled = {\"inactive-code\"},\n        },\n      }\n    }\n  },\n}\nend\n```\n\n### What's going on here?\nWhen a new LSP configuration is created (`on_new_config`), we run `cargo\nxtask lsp` on the target file.  The JSON configuration includes a hash of\nthe configuration; we use that hash to modify the name of the client from\n`rust_analyzer` to `rust_analyzer_$HASH`.  This prevents Neovim from\nattempting to reuse an existing client, which are normally deduplicated by\nclient name and workspace root directory; in Hubris, we want multiple clients\ncoexisting with same workspace root, so they need different names.  Then, we\nstash the rest of the configuration in a local variable (`cache`), and record\nthe existence of this client in `clients`.\n\nWhen attaching to the LSP, we try to pull the configuration out of `cache`.  If\none exists, then we know we're dealing with a Hubris buffer; copy over relevant\nportions of the configuration.\n\nNote that this does not compile `xtask` for you; it assumes it already exists\nin `target/debug/xtask`.  This should be true if you're using Hubris regularly,\nand saves significant amounts of time when opening a new file.\n\n## Adding a task\n\nTo create your own task, the easiest method is:\n\n- Copy `task/template` to a new name.\n- Edit its `Cargo.toml` with your name and a new package name.\n- Add it to the list of workspace members in the root `Cargo.toml`.\n- Add it to a system image by editing an `app.toml` file.\n- Run `cargo xtask build` to compile it.\n\nA typical `app.toml` entry for a small task that uses no memory-mapped\nperipherals would read\n\n```toml\n[tasks.name_for_task_in_this_image]\nname = \"my-task-target-name\"\npriority = 1\nrequires = {flash = 1024, ram = 1024}\nstart = true\n```\n\n## Graphing task relationships and priorities\n\nA graph can be generated that show the relationships of the various tasks\nand their priorities. The resulting file is in [Graphviz](https://graphviz.org/)'s\n`dot` format. `Dot` source [can be included](https://docs.asciidoctor.org/diagram-extension/latest/) in [Asciidoctor](https://asciidoctor.org) source\nor rendered to a variety of formats.\n\nTo create and view an SVG graph for `gimletlet` on Ubuntu, ensure that the `graphviz` package is installed. Then generate the graph:\n\n```console\n$ cargo xtask graph -o gimletlet.dot app/gimletlet/app.toml\n$ dot -Tsvg gimletlet.dot \u003e gimletlet.svg\n$ xdg-open gimletlet.svg\n```\n\n### Generating all graphs under Linux\n\nBash commands to generate all graphs:\n\n```console\n  APPS=( $(find app -name '*.toml' ! -name Cargo.toml) )\n  for app in \"${APPS[@]}\"\n  do\n    out=$(basename ${app//\\//_} .toml).dot\n    svg=$(basename $out .dot).svg\n    cargo xtask graph -o $out $app\n    dot -Tsvg $out \u003e $svg\n  done\n  first=\"${APPS[0]}\"\n  out=\"$(basename ${first//\\//_} .toml).dot\"\n  svg=\"$(basename $out .dot).svg\"\n  xdg-open \"${svg}\"\n```\n\nIf `eog` is the default viewer, opening the first SVG in a directory will\nallow cycling through all of the available graphs using the same window.\n\n# Using Hubris\nHubris is tightly coupled to its debugger,\n[Humility](https://github.com/oxidecomputer/humility),\nwhich is used for the commands below either implicitly\n(in `cargo xtask flash`) or explicitly (in `cargo xtask humility`).\n\nIf the `humility` binary is not available on your `$PATH`, the `HUBRIS_HUMILITY_PATH`\nenvironment variable may be used to provide the path to the binary.\n\n## Flash\n\nAn image within a Hubris archive can be flashed directly onto a target board\nby running `cargo xtask flash` and specifying the appropriate\nTOML file.  This will run `cargo xtask dist` and then pass the resulting\nbuild archive to `humility flash`. `humility` will invoke either OpenOCD or\npyOCD to flash the image; the exact invocation depends on the board\nand is encoded in the build archive.\n\n- LPCXpresso55S69: `cargo xtask flash app/lpc55xpresso/app.toml`\n- STM32F4 Discovery board: `cargo xtask flash app/demo-stm32f4-discovery/app.toml`\n- ST Nucleo-H743ZI2 board: `cargo xtask flash app/demo-stm32h7-nucleo/app-h743.toml`\n- ST Nucleo-H753ZI board: `cargo xtask flash app/demo-stm32h7-nucleo/app-h753.toml`\n- Gemini bringup board: `cargo xtask flash app/gemini-bu/app.toml`\n\n## Running Humility\n\nHumility is run _in situ_ by specifying an archive on a directly connected\nboard, or postmortem by specifying a dump.  As a convenience for development,\nHumility can also be run _in situ_ by specifying the appropriate TOML, e.g.\non a machine with an STM32F4 Discovery board directly attached:\n\n```console\n$ cargo xtask humility app/demo-stm32f4-discovery/app.toml -- tasks\n    Finished dev [optimized + debuginfo] target(s) in 0.17s\n     Running `target/debug/xtask humility demo/app.toml -- tasks`\nhumility: attached via ST-Link\nID ADDR     TASK               GEN STATE    \n 0 20000108 jefe                 0 Healthy(InRecv(None))     \n 1 20000178 rcc_driver           0 Healthy(InRecv(None))     \n 2 200001e8 usart_driver         0 Healthy(InRecv(None))     \n 3 20000258 user_leds            0 Healthy(Runnable)          \u003c-\n 4 200002c8 ping                48 Healthy(Runnable)         \n 5 20000338 pong                 0 Healthy(InRecv(None))     \n 6 200003a8 idle                 0 Healthy(Runnable)         \n```\n\n### Debugging with GDB\n`humility` includes a `gdb` subcommand which attaches to a running system\nusing `arm-none-eabi-gdb`, optionally running its own `openocd` instance based\non configuration data in the build archive.\n\nFor convenience, there's also a `cargo xtask gdb` façade which calls `humility`\nwith the appropriate build archive:\n\n```console\n$ cargo xtask gdb app/demo-stm32f4-discovery/app.toml -- --run-openocd\n# ... lots of output elided ...\ntask_idle::main () at task/idle/src/main.rs:14\n14          loop {\nBreakpoint 1 at 0x800434c: file /crates.io/cortex-m-rt-0.6.15/src/lib.rs, line 560.\nNote: automatically using hardware breakpoints for read-only addresses.\nsemihosting is enabled\n\nsemihosting is enabled\n\n(gdb)\n```\n\nNote that `cargo xtask gdb` will (by default) also run `dist` and `flash`, to\nensure that the image on the chip is up to date.  The `-n`/`--noflash` option\nskips these steps.\n\n# Testing Hubris\n\nThe Hubris kernel is tested with a dedicated _test image_ that includes a test\nrunner, assistant and test suite.  The test image emits its results via ITM.\nWhile these results can be interpreted manually, `humility test` automates\nthis.  `humility test` itself is most easily run via `cargo xtask test`, which\nruns the equivalent of `cargo xtask dist`, `cargo xtask flash`\nand `cargo xtask humility test`.  The exact invocation depends on the board:\n\n- LPCXpresso55S69: `cargo xtask test test/tests-lpc55xpresso/app.toml`\n- STM32F3 Discovery board: `cargo xtask test test/tests-stm32fx/app-f3.toml`  \n  **Note: for this board, SB10 must be soldered closed for ITM to work**\n- STM32F4 Discovery board: `cargo xtask test test/tests-stm32fx/app.toml`\n- ST Nucleo-H743ZI2 board: `cargo xtask test test/tests-stm32h7/app-h743.toml`\n- ST Nucleo-H753ZI board: `cargo xtask test test/tests-stm32h7/app-h753.toml`\n\nNote: `cargo xtask humility test` runs OpenOCD to connect to the device.\nYou must exit any other instances of OpenOCD that you have connected to the device\nbefore running tests.\n\nSee the [documentation for `humility\ntest`](https://github.com/oxidecomputer/humility#humility-test) for details\non test results.\n\n## Debugging tests\n\nOutput from tests is captured by `humility test`; `sys_log!()` calls to\ntests can be added and then captured in a `humility test` dump.  To capture\na dump from tests that are otherwise passing, use `cargo xtask humility`\ndirectly and pass the `-d` flag, e.g.:\n\n```console\n$ cargo xtask humility test/tests-stm32fx/app.toml -- test -d\n...\nhumility: attached via ST-Link\nhumility: TPIU sync packet found at offset 1\nhumility: ITM synchronization packet found at offset 12\nhumility: expecting 22 cases\nhumility: running test_send ... ok\n...\nhumility: running test_timer_notify ... ok\nhumility: running test_timer_notify_past ... ok\nhumility: tests completed: pass\nhumility: test output dumped to hubris.testout.2\n```\n\nif one needs to both run GDB and the test suite, use `cargo xtask gdb`\nwith the test image's TOML and the appropriate GDB file, and then place\nbreakpoints at the test of interest.\n\n# Special cases\n## Gemini bringup board\n\nSee the Gemini Bringup\n[Getting Started](https://github.com/oxidecomputer/gemini-bringup/tree/master/gemini-bringup)\ndocs (internal Oxide repo)\n\n## STM32F3 Discovery boards\n**For the STM32F3 Discovery board, SB10 must be soldered closed for ITM\nto work!** This solder bridge defaults to being open, which leaves SWO\ndisconnected.  See the STM32F3 Discovery User Manual (UM1570) for schematic\nand details.\n\n## LPCXpresso55S69 board\n\nThe LPCXpresso55S69 is somewhat of a mess because the built-on on-chip\ndebugger, LPC-Link2, [does not correctly support SWO/SWV](https://community.nxp.com/t5/LPC-Microcontrollers/SWO-SWV-on-LPC-Link2-with-CMSIS-DAP/m-p/1079442)\n\nIf you have the stock LPC-Link2, it will report itself this way via \n[`probe-rs list`](https://probe.rs/docs/tools/probe-rs/) or `humility lsusb`:\n\n\n```console\n$ probe-rs list\nThe following debug probes were found:\n[0]: MCU-LINK (r0FF) CMSIS-DAP V3.153 -- 1fc9:0143:U2VLC0GBANWF1 (CMSIS-DAP)\n```\n\nIt's also possible that you have the Segger J-Link firmware -- firmware\nthat will make its odious presence known by prompting for you to accept license\nterms whenever running `pyocd list`!\n\n```console\n$ pyocd list\n  #   Probe                                                       Unique ID\n-----------------------------------------------------------------------------\n  0   Segger J-Link LPCXpresso V2 compiled Apr  4 2019 16:54:03   726424936\n```\n\nIn either of these cases you must -- as a one-time step -- install new\nfirmware on the LPC-Link2.  The new firmware is a build of the (open source) \n[DAPLink](https://github.com/oxidecomputer/DAPLink), which\nwe affectionally call **RickLink** after\nthe engineer who managed to get it all built -- no small feat!\n\nThere are two files that you will need, both contained in the Hubris repository:\n\n- [lpc4322_bl_crc.bin](./support/lpc4322_bl_crc.bin)\n- [lpc4322_lpc55s69xpresso_if_rla_swo_hacks.bin](./support/lpc4322_lpc55s69xpresso_if_rla_swo_hacks.bin)\n\nYou will additionally need the [LPCScrypt program](https://www.nxp.com/design/microcontrollers-developer-resources/lpc-microcontroller-utilities/lpcscrypt-v2-1-1:LPCSCRYPT)\nfrom NXP.\n\nHere are the steps to install RickLink:\n\n1. Install the DFU jumper. This can be found next to the SWD header on the\nleft side of the board; it is labelled \"DFU\".\n\n2. Run `scripts/boot_lpcscrypt` from the installed LPCScrypt software:\n\n```console\n$ /usr/local/lpcscrypt/scripts/boot_lpcscrypt \nLooking for DFU devices with VID 1fc9 PID 000c ...\ndfu-util -d 1fc9:000c -c 1 -i 0 -t 2048 -R  -D /usr/local/lpcscrypt/scripts/../bin/LPCScrypt_228.bin.hdr\nBooted LPCScrypt target (1fc9:000c) with /usr/local/lpcscrypt/scripts/../bin/LPCScrypt_228.bin.hdr\n$\n```\n\n3. Run `lpcscrypt clockslow`:\n\n```console\n$ /usr/local/lpcscrypt/bin/lpcscrypt clockslow\n$\n```\n\n4. Run `lpcscrypt program +w1 0x0 BankA` to overwrite existing firmware\n\n```console\n$ /usr/local/lpcscrypt/bin/lpcscrypt program +w1 0x0 BankA\n................\nProgrammed 524288 bytes to 0x1a000000 in 2.610s (196.165KB/sec)\n$\n```\n\n5. Run `lpcscrypt program +c \u003cpath-to-lpc4322_bl_crc.bin\u003e BankA`:\n\n```console\n$ /usr/local/lpcscrypt/bin/lpcscrypt program +c ~/hubris/support/lpc4322_bl_crc.bin BankA\n..\nProgrammed 57344 bytes to 0x1a000000 in 0.827s (67.717KB/sec)\n$\n```\n\n6. Assuming it is successful, remove the DFU jumper and disconnect/reconnect USB\n\n7. There should now be a USB mass storage device named `MAINTENANCE`\n\n```console\n# fdisk -l\nDisk /dev/nvme0n1: 477 GiB, 512110190592 bytes, 1000215216 sectors\nDisk model: Micron 2200S NVMe 512GB\nUnits: sectors of 1 * 512 = 512 bytes\nSector size (logical/physical): 512 bytes / 512 bytes\nI/O size (minimum/optimal): 512 bytes / 512 bytes\nDisklabel type: gpt\nDisk identifier: A8653F99-39AB-4F67-A9C9-524A2864856E\n\nDevice             Start        End   Sectors   Size Type\n/dev/nvme0n1p1      2048    1050623   1048576   512M EFI System\n/dev/nvme0n1p2   1050624  967393279 966342656 460.8G Linux filesystem\n/dev/nvme0n1p3 967393280 1000214527  32821248  15.7G Linux swap\n\n\nDisk /dev/sda: 64.1 MiB, 67174400 bytes, 131200 sectors\nDisk model: VFS\nUnits: sectors of 1 * 512 = 512 bytes\nSector size (logical/physical): 512 bytes / 512 bytes\nI/O size (minimum/optimal): 512 bytes / 512 bytes\nDisklabel type: dos\nDisk identifier: 0x00000000\n# mount /dev/sda /mnt\n# ls /mnt\nDETAILS.TXT  PRODINFO.HTM\n# cat /mnt/DETAILS.TXT\n# DAPLink Firmware - see https://mbed.com/daplink\nUnique ID: 02360b000d96e4fc00000000000000000000000097969905\nHIC ID: 97969905\nAuto Reset: 1\nAutomation allowed: 1\nOverflow detection: 1\nDaplink Mode: Interface\nInterface Version: 0254\nBootloader Version: 0254\nGit SHA: f499eb6ec4a847a2b78831fe1acc856fd8eb2f28\nLocal Mods: 1\nUSB Interfaces: MSD, CDC, HID, WebUSB\nBootloader CRC: 0x09974fb3\nInterface CRC: 0x7174ab4c\nRemount count: 0\nURL: https://os.mbed.com/platforms/LPCXpresso55S69/\n```\n\n8. Copy `lpc4322_lpc55s69xpresso_if_rla_swo_hacks.bin` to the USB drive\n\n```console\n$ sudo cp ~/hubris/support/lpc4322_lpc55s69xpresso_if_rla_swo_hacks.bin /mnt\n$\n```\n\n9. Unmount (or otherwise sync) the USB drive:\n\n```console\n# umount /mnt\n#\n```\n\n10. Unplug and replug the USB cable.\n\nVerify that you are on the new firmware by running `pyocd list` or \n`probe-rs list`:\n\n```console\n$ pyocd list\n  #   Probe                        Unique ID                                         \n-------------------------------------------------------------------------------------\n  0   LPCXpresso55S69 [lpc55s69]   02360b000d96e4fc00000000000000000000000097969905\n```\n\n## LPC55S28 on Gemini carrier board\n\nNote that the RickLink running on the LPCXpresso55S69 can *also* be used \nas the debugger for the LPC55S28 on the Gemini carrier board.  To do this,\nfirst, follow all of the instructions above to get RickLink onto your\nLPCXpresso55S69.  Then:\n\n1. Using a soldering iron, solder a two-pin header on J5. J5 can be\n   be found to the left of P1 and below the \"Debugger\" jumper (J3).\n\n2. Put a jumper on the new header\n\n3. Move the \"Debugger\" jumper (J3) to \"Ext\".\n\n4. Use a SWD cable (10-pin 2x5 1.27mm pitch cable) to connect the SWD on the\n   LPCXpresso55S69 to the SWD underneath the carrier board on Gemini (J202)\n\n(To allow your RickLink to once again debug its local LPC55S69,\nremove the jumper on J5 and move J3 to \"Loc\".)\n\n## Multiple boards simultaneously\n\nIf multiple probes are attached, tools may struggle to find the right one at\nthe right time.  In particular, OpenOCD will pick the first one that it finds;\nto force OpenOCD to pick a *particular* probe,\nyou can ascertain the serial number of the probe (e.g., from `humility probe`)\nand then specify that serial number in the corresponding `openocd.cfg` by\nadding, e.g.:\n\n```\ninterface hla\nhla_serial 271828182845904523536028\n```\n\n(Where `271828182845904523536028` is the serial number of the probe.)\n\n## Updating ST-Link Firmware if necessary\n\nIt is common that debugging dongles, and development boards with embedded\ndebug hardware like the Nucleo series, are delivered with older firmware.\n\nYou will not be able to use Humilty with outdated ST-Link firmware. Humility\nwill tell you this is the case, for example when attempting to use `humility test`:\n\n```\n...\nWarn : Adding extra erase range, 0x08020060 .. 0x0803ffff\n** Programming Finished **\n** Verify Started **\n** Verified OK **\n** Resetting Target **\nhumility: test failed: The firmware on the probe is outdated\nError: test failed\n```\n\nFollow this \"[ST-LINK firmware upgrade](https://www.st.com/en/development-tools/stsw-link007.html)\" link to find\nsoftware and instructions necessary to install current firmware.\n","funding_links":[],"categories":["Real-time","Rust","others","Packages, Libraries and RTOSes"],"sub_categories":["Real-time Operating System (RTOS)","Alternative Languages (Not C/C++)"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foxidecomputer%2Fhubris","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foxidecomputer%2Fhubris","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foxidecomputer%2Fhubris/lists"}