Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rust bindings API review #51

Merged
merged 3 commits into from
Mar 2, 2023
Merged

Rust bindings API review #51

merged 3 commits into from
Mar 2, 2023

Conversation

rafaelcaricio
Copy link
Collaborator

This PR makes the Rust bindings usage more ergonomic and flexible.

// let mut parent = crate::display::DefaultDisplay::get_scr_act()?;
// Ok(Self::create_at(&mut parent)?)
// }
// }
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is used during development, to test the code generation options.

@@ -69,14 +69,33 @@ impl<T> AsMut<T> for Box<T> {
}
}

fn mem_info() -> lvgl_sys::lv_mem_monitor_t {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Probably just need to make safe bindings for this simple function and add to the public API. It's useful for app debugging.

#[cfg(feature = "alloc")]
impl<S: AsRef<str>> From<S> for Label {
fn from(text: S) -> Self {
let text_cstr = CString::new(text.as_ref()).unwrap();
Copy link
Collaborator Author

@rafaelcaricio rafaelcaricio Jun 4, 2021

Choose a reason for hiding this comment

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

This is a test of what is possible with alloc feature enabled. In reality, the From trait implementation should use the TryFrom trait implementation and just call .unwrap() here. People will decide which guarantees they want to have.

use embedded_graphics::pixelcolor::Rgb565;

pub(crate) fn initialize_test() {
init();
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

All tests run in the same LVGL "instance" so the tests might run out of memory at some point. :) Just to keep in mind.

lvgl/src/display.rs Outdated Show resolved Hide resolved

pub struct DrawBuffer<const N: usize> {
initialized: RunOnce,
refresh_buffer: Mutex<RefCell<heapless::Vec<lvgl_sys::lv_color_t, N>>>,
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I use a Mutex here, to satisfy the Rust guarantees. But maybe it is not necessary... some food for thought.

@@ -114,6 +114,7 @@ fn main() {
let bindings = bindgen::Builder::default()
.header(shims_dir.join("lvgl_sys.h").to_str().unwrap())
.generate_comments(false)
.derive_default(true)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Extremely useful feature of bindgen. 💅🏽

// TODO: needs to be 'static somehow
// Cannot be in the DrawBuffer struct because the type `lv_disp_buf_t` contains a raw
// pointer and raw pointers are not Sync and consequently cannot be in `static` variables.
let mut inner: MaybeUninit<lvgl_sys::lv_disp_buf_t> = MaybeUninit::uninit();
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I would like to find a way to make this memory statically allocated. This seems to be a requirement for LVGL v8.


pub struct DrawBuffer<const N: usize> {
initialized: RunOnce,
refresh_buffer: Mutex<RefCell<[MaybeUninit<lvgl_sys::lv_color_t>; N]>>,
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'm using a Mutex here just to make this Sync, not sure if there is a way to remove it but still keep the memory statically allocated.

examples/app.rs Outdated
lvgl::init();

const REFRESH_BUFFER_SIZE: usize = lvgl::DISP_HOR_RES * lvgl::DISP_VER_RES / 10;
static DRAW_BUFFER: DrawBuffer<REFRESH_BUFFER_SIZE> = DrawBuffer::new();
Copy link
Collaborator Author

@rafaelcaricio rafaelcaricio Jun 8, 2021

Choose a reason for hiding this comment

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

Making this statically allocated will avoid dropping this memory address by mistake in an app code.

@nia-e
Copy link
Collaborator

nia-e commented Mar 2, 2023

What's the status on this PR? I was considering attempting to upgrade LVGL to 8.x and it seems like this is necessary. I can rebase on current master and flesh out any missing features if that would be desirable.

@rafaelcaricio
Copy link
Collaborator Author

@nia-e As described in the README of this project. I've moved on from it, since I couldn't find anyone to help me with the development. That means this PR is in its "final" state, as I don't plan to work further on it. I'm pleased that you seem to have interest in this project, and if you think this can or should be merged, please go ahead!

I think this PR has some things that need a second opinion. I've added some comments to things I wanted to highlight. The public API changes here, and we remove explicit dependency on embedded_graphics (it is optional).

There is a part of this PR that I stopped working on before making use of it, which is in the code generation crate. I think we could do much better there. Just keep in mind that I've started this project to help me "learn Rust", so take with a grain of salt the things this library does. If you see something that seems wrong to you, it is because it is probably wrong indeed. 👀

@nia-e
Copy link
Collaborator

nia-e commented Mar 2, 2023

To my utter surprise, a rebase and minimal fixes later, this compiles. I'd rather test more things before I do anything but it seems like my job is easier than expected. Should I open a new PR or push to this branch? I squashed all commits.

@rafaelcaricio
Copy link
Collaborator Author

@nia-e Awesome, Rust is great. lol

You can commit to this branch and continue this PR.

@nia-e nia-e force-pushed the api-review branch 2 times, most recently from fbfd868 to 14054a3 Compare March 2, 2023 11:44
@nia-e nia-e self-assigned this Mar 2, 2023
@nia-e
Copy link
Collaborator

nia-e commented Mar 2, 2023

What were the plans for lvgl_codegen? It has some unused code and behavior is missing. I could try to finish implementing whatever the original idea was.

@nia-e nia-e mentioned this pull request Mar 2, 2023
10 tasks
@nia-e
Copy link
Collaborator

nia-e commented Mar 2, 2023

Also; further digging on the Mutexes revealed that there is Probably No Way (that I could find) to get rid of them short of marking this entire library as non-thread-safe which doesn't feel great. I'd love to be proven wrong, though. parking_lot is a very small crate though and this shouldn't be a huge deal - certainly far better than pulling in all of embedded-graphics at all times like before.

@rafaelcaricio
Copy link
Collaborator Author

@nia-e The idea with the lvgl-codegen crate was to be able to generate the entirety of the LVGL C API instead of manually writing bindings for every single API function LVGL exposes. I wanted to have in the lvgl crate the "core abstractions" that would be used by the codegen. This was a suggestion I got at the begging of this project. That thread might be a good source of what I was thinking at the time too (it has been a while ago 😬 ).

LVGL is not thread-safe itself, so making this crate non-thread-safe shouldn't be a bid deal? 👀 For us to make this crate "thread-safe" we would need to (have and) lock a global Mutex every time we call LVGL C API, not sure if that is a good idea!?

@nia-e
Copy link
Collaborator

nia-e commented Mar 2, 2023

Perfect, okay. I'll drop the Mutexes and read through that thread afterwards.

rafaelcaricio and others added 2 commits March 2, 2023 20:23
Revising the public API for better flexibility

Use old approach, write directly to DrawTarget

Simplified API for display initialization

Possibility to register a shared native display

Fix shared display

Update demo app to use new api

Use ref

Add basic API functions

Add required features

Update examples

Make disp buffer and driver statically allocated

Allow to create statically allocated DrawBuffer

Make DrawBuffer customizable using const generics

Update default features to empty

Allow users to define a display refresh callback closure

Make use of embedded_graphics optional

Update app example

Remove dependency on heapless

Wrap alloc extension in its own module
@nia-e
Copy link
Collaborator

nia-e commented Mar 2, 2023

Seems like extending lvgl-codegen is a can I can safely kick down the road. All in all, I think this is complete and ready for review. Squashed commits.
One more thing I need to fix then it'll be ready.

@nia-e nia-e marked this pull request as ready for review March 2, 2023 19:25
@nia-e nia-e self-requested a review March 2, 2023 19:57
@nia-e
Copy link
Collaborator

nia-e commented Mar 2, 2023

Okay, now it's ready. Give this a look when you have some time @rafaelcaricio. Also this hopefully beings to close #42

get rid of warnings
@nia-e nia-e added the enhancement New feature or request label Mar 2, 2023
@rafaelcaricio
Copy link
Collaborator Author

LGTM. I cannot approve as I originally opened the PR. Feel free to merge ;)

@nia-e nia-e merged commit 0cb1ab4 into master Mar 2, 2023
@rafaelcaricio rafaelcaricio deleted the api-review branch March 2, 2023 23:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants