Populating the GUI framebuffer with Rust

Why bother?

I’m on Linux, which means TouchGFX is not ideal. A Linux user can virtualize Windows and run the TouchGFX Designer in there, but from a development workflow perspective it’s painful. In my personal time I try to stick to Rust as much as possible, so that’s the language I’m most comfortable with and wanted to see if I could get working.

What do I get?

Very little, currently. Exclusively populating the screen. Reading sensors, sending them to the UI, all that stuff is the standard SDK. The entire offering of what I’ve done so far is: draw on the watch screen within an app with embedded-graphics.

What’s involved?

UNA almost already supports this, there are some hacks to get what’s offered to actually work. Hopefully these will be upstreamed.

If you’re more than passively interested I can share the repo, but it has a number of things currently that should actively not be copied because I was taking shortcuts to get things to work. In very broad strokes:

  1. Look at una-sdk/Libs/Source/AppSystem/EntryPoint/CustomGUI/main.cpp at main · UNAWatch/una-sdk · GitHub , that’s the contract
  2. Write a shim (in C++) to handle messages
    • C++ owns the framebuffer as well, Rust receives a raw pointer and a length
  3. Make an extremely dull ABI
    • typdef struct { ... everything you need including uint32_t frames ... } poc_gui_state
    • uint32_t poc_gui_screen_count(void)
    • void poc_gui_render(uint8_t* buf, uint16_t width, uint16_t height, uint32_t screen, const poc_gui_state* state);
  4. In Rust, implement DrawTarget over the byte slice
    • this step is glue togetther embedded-graphics and the framebuffer
  5. Build the crate as two types (simulator too!): "staticlib", "lib"
  6. Mash the build together so CMake runs cargo build --release --target thumbv8m.main-none-eabihf then gives the linker the resultant .a.
    • this part is unnecessarily crunchy right now, I anticipate UNA cleaning this up so custom GUIs are easier

There’s an app here you can try that does precisely this:

I’ll try and feed in a real sensor so it’s something a small bit closer to a “real” app, but it is early days.

2 Likes

I spent a little more time with this. There’s a new app here that is a HUGE improvement (/s).

  • shows a “heartbeat” of the render loop with a dot around the outside
  • renders the actual non-faked accelerometer data against a little bullseye
  • shows off a dither

This is very slightly more real. The first screen could be a game if someone had not experienced the last ~50 years of technological advancement.

2 Likes