Skip to content

Support Embedded Graphics using the screen system call#579

Merged
alevy merged 7 commits intomasterfrom
embedded-graphics
Sep 17, 2025
Merged

Support Embedded Graphics using the screen system call#579
alevy merged 7 commits intomasterfrom
embedded-graphics

Conversation

@bradjc
Copy link
Copy Markdown
Contributor

@bradjc bradjc commented Jul 28, 2025

This uses #568.

It provides basic support for using the embedded graphics library with the Tock screen syscall.

I was able to port the spin demo from libtock-c and verify that it works on the nrf52840dk with the attached monochromatic screen.

@bradjc bradjc force-pushed the embedded-graphics branch from 0a1bb6f to 8bc3eaf Compare August 27, 2025 18:18
@bradjc
Copy link
Copy Markdown
Contributor Author

bradjc commented Sep 2, 2025

Ok this is now updated with both demo apps and the Makefiles in each demo, giving examples of out-of-tree builds.

@bradjc
Copy link
Copy Markdown
Contributor Author

bradjc commented Sep 2, 2025

I don't understand what change is leading to the CI failures. https://github.com/tock/libtock-rs/actions/runs/17407217165/job/49414698382, eg

error[E0277]: the trait bound `TockSyscalls: Syscalls` is not satisfied
  --> runtime/src/startup/mod.rs:62:29
   |
62 |     Termination::complete::<TockSyscalls>(result)
   |                             ^^^^^^^^^^^^ the trait `RawSyscalls` is not implemented for `TockSyscalls`
   |
   = note: required for `TockSyscalls` to implement `Syscalls`
note: required by a bound in `complete`

It requires a Tock runtime, so can't be run using normal host test.
pub struct TockMonochromeScreen {
/// The framebuffer for the max supported screen size (128x64). Each pixel
/// is a bit.
framebuffer: [u8; (128 * 64) / 8],
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this max screen size coming from?

use libtock::display::Screen;
use libtock_platform::ErrorCode;

pub struct TockMonochromeScreen {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this monochrome-specific? The Screen isn't, is it?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something has to be responsible for the pixel format, and the intent is this screen struct is for 128x64 pixel monochrome screens with the Mono_8BitPage pixel format (because, well, that is what I need).

Would it be ok to keep the static buffer, fixed use case, and single size with an updated struct name?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the kernel screen driver at least partially handles this and the userspace is meant to either set the pixel format explicitly (command 26) or get the current pixel format (command 25) and adapt to it. The kernel, then, does a conversion from whatever the driver's pixel format is to the screen's native pixel format (some screens hardware does this, but for some it needs to be done in software). There is no specified default, it's just whatever the underlying screen uses as a default.

I guess this is fine if you explicitly set the pixel format somewhere. But it's not "good" and I don't think we should keep this long term.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this is fine if you explicitly set the pixel format somewhere. But it's not "good" and I don't think we should keep this long term.

I completely agree, but, it's a lot of pretty unglamarous work.

A reasonable step now would be to at least check that the kernel is providing a screen with the expected pixel format.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just call set_pixel_format somewhere for now.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.

let (width, height) = Screen::get_resolution().unwrap_or((0, 0));

Self {
framebuffer: [0; 1024],
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the C version, this is dynamically allocated. I understand why it might be better to statically allocate, especially with good support in Rust, but a fixed 1024-byte array kinda sucks.

Can it be parameterized by a const type parameter (perhaps with a default?) instead? At least as far as the kernel is concerned, the framebuffer can be arbitrarily smaller than the screen resolution (or larger technically, it's just a buffer). It would perhaps complicate draw_iter not to assume framebuffer size == resolution but...

Current implementation is tied to a monochrome, 128x64, 8bitpage screen.
Make that explicit.

Add some comments.
@alevy alevy added this pull request to the merge queue Sep 17, 2025
Merged via the queue into master with commit 5544210 Sep 17, 2025
3 checks passed
@alevy alevy deleted the embedded-graphics branch September 17, 2025 19:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants