lvgl / lv_binding_rust

LVGL bindings for Rust. A powerful and easy-to-use embedded GUI with many widgets, advanced visual effects (opacity, antialiasing, animations) and low memory requirements (16K RAM, 64K Flash).
MIT License
668 stars 69 forks source link

Isolate build display from update (DrawBuffer ???) #148

Closed fulup-bzh closed 1 year ago

fulup-bzh commented 1 year ago

I run an asynchronous application, where display construction if done at init time and update from an independant asynchronous timer. I started from arc sample implementing the construction in one routine and display update in an other. When trying to update the window I get a core dump, I suspect DrawBuffer or an other holding handle to be wipe out when returning from init routine.

Question: which are the handle I should keep track of to make sure that my display does not get wipe out from stack when returning from my init routine ? (using arc sample as base)

Note: In order to keep different display handles from being wipe out at return my routine returns.

       return DisplayHandle {
           sim_display,
            window,
            arc,
            display,
        }

I cannot return buffer coming from DrawBuffer because it of its type that depends in the definition.

My timer async routine fail in lvgl::task_handler()

  pub fn tick_update(&mut self, tick: Duration) {

        // update internal lvgl tick timer
        lvgl::tick_inc(tick);

        // exec any lvgl pending task/action
        lvgl::task_handler();
}
fulup-bzh commented 1 year ago

For information debugger trace. image

nia-e commented 1 year ago

Are you moving the actual display between threads? If so, handling this case is still an open question; see https://github.com/lvgl/lv_binding_rust/issues/140. I was trying to partially fix this in https://github.com/lvgl/lv_binding_rust/pull/144/ but I haven't had time to work on this project recently

fulup-bzh commented 1 year ago

Potential display widgets may may change value/status from a different thread. Nevertheless the update action handle from a timer always come from the same thread. The issue seems more to be that when returning from my create function, some LVGL handle are free. I'm expecially afrby Drawbuffer could reserve memory in stack and not in a Box::leak

fulup-bzh commented 1 year ago

Digging further, I found a warning that alarm me.

        // Safety: The variable `draw_buffer` is statically allocated, no need to worry about this being dropped.
        disp_drv.draw_buf = Box::<_lv_disp_draw_buf_t>::into_raw(
            draw_buffer
                .get_ptr()
                .ok_or(DisplayError::FailedToRegister)?,
        ) as *mut _;

When I do not get the impression that the way drawbuffer is created garantie that it is static. (The size is static, but I do not see what garanty the memory allocation to be static.

let buffer = DrawBuffer::<{ (1920 * 1200)/10 as usize }>::default();

Did I miss something ?

nia-e commented 1 year ago

I believe that has since been patched, it should be fine on latest git master?

fulup-bzh commented 1 year ago

I updated to master without more success. To make this clearer to follow I propose to close this thread and reopen a new cleaner one on "updating display from an independent context"