1 of 52

LVGL in WebAssembly: Building NuttX Touchscreen Apps with Zig and testing them in the Web Browser

Lup Yuen LEE

github.com/lupyuen

2 of 52

Our Story Today

  • LVGL Graphics Library +�Zig Programming Language (WebAssembly) +�Apache NuttX Real-Time Operating System (RTOS)
  • Let’s create an LVGL App,�Preview it in a Web Browser
  • By compiling LVGL Library to WebAssembly with Zig Compiler (based on Clang)
  • Browser-based alternative to NuttX Simulator�(Maybe someday NuttX will run in WebAssembly?)
  • Demo Video

2

3 of 52

Why LVGL with WebAssembly?

  • LVGL Apps can get painfully tedious to create:�Recompile, Reflash and Reboot�Again and again and again!
  • Can we preview LVGL Apps in a Web Browser?�Then run the exact same code on a NuttX Gadget?�(Live Reload)
  • LVGL already compiles to WebAssembly with Emscripten and SDL, but let’s explore Zig�(Safer, simpler LVGL Apps)
  • Maybe someday we can Drag-and-Drop to create LVGL Apps in the Web Browser?

3

4 of 52

“NuttX NextGen”?

  • Upsizing from 32-bit MCUs with tiny displays
  • To 64-bit Phones and SBCs with huge displays:�MIPI DSI and HDMI�(720 x 1440 and 1920 x 1080)
  • Large screens need more Design and Collaboration�(Perfect for Education)
  • Open source drivers (non-GPL) are rare�Only GPL Drivers contributed by vendor as BSP�(Missing docs)
  • We seek your contribution!

4

5 of 52

WebAssembly with Zig

WebAssembly

LVGL

Display

Input

UI

6 of 52

Why Zig

  • Works well with C�
  • Runtime Safety�(But not Memory Safe)�
  • Type Inference�
  • Auto-Converts C to Zig

6

7 of 52

Compare C and Zig

7

8 of 52

WebAssembly with Zig

  • Zig compiles to WebAssembly Bytecode�Runs in a Web Browser
  • Zig works both ways with WebAssembly:�JavaScript calling Zig�Zig calling JavaScript
  • Let’s render the Mandelbrot Set in WebAssembly:�Zig computes the Mandelbrot Set�JavaScript calls Zig for every pixel�JavaScript renders pixel to HTML Canvas
  • Source Code

8

9 of 52

9

10 of 52

JavaScript calls Zig WebAssembly

10

11 of 52

JavaScript renders to HTML Canvas

11

12 of 52

Zig Calls JavaScript

  • Now we call out from Zig to JavaScript�
  • We import the JavaScript Function into Zig�
  • Runs slower, but it works!�
  • Source CodeRead the Article

12

13 of 52

LVGL in WebAssembly

WebAssembly

LVGL

Display

Input

UI

14 of 52

LVGL App in Zig

  • LVGL already works with Zig on PinePhone NuttX�
  • Zig Compiler compiles LVGL Apps from Zig to Arm64 Machine Code�
  • “Simpler Safer Touchscreen Apps with Zig”

14

15 of 52

LVGL App in WebAssembly

  • Can the same LVGL App run in a Web Browser? With WebAssembly?�
  • Zig Compiler compiles LVGL Library�from C to WebAssembly�(Via bundled Clang Compiler)�
  • JavaScript will do rendering and mouse input�And call our WebAssembly

15

16 of 52

Compile LVGL to WebAssembly with Zig Compiler

16

17 of 52

LVGL Porting Layer for WebAssembly

  • LVGL expects us to provide Platform-Specific Functions�
  • For Timers, Logging and Assertions�
  • We implement these in Zig

17

18 of 52

WebAssembly Logger for LVGL

  • LVGL Logs sent by Zig to JavaScript, printed in the JavaScript Console�
  • Works OK because Zig can call JavaScript�
  • We’ll see this Common Pattern:�LVGL ↔ Zig ↔ JavaScript�Source CodeRead the Article

18

19 of 52

LVGL Display

WebAssembly

LVGL

Display

Input

UI

20 of 52

20

21 of 52

21

22 of 52

Render LVGL Display in Zig

  • LVGL expects a Callback Function to flush our display�
  • We implement it in Zig and call out to JavaScript to render the HTML Canvas�
  • Zig notifies LVGL that display has been flushed

22

23 of 52

23

24 of 52

Render LVGL Display in JavaScript

  • Zig calls JavaScript to render the display to HTML Canvas�
  • Our JavaScript copies the Canvas Pixels from WebAssembly Memory to HTML Canvas

24

25 of 52

25

26 of 52

Handle LVGL Tasks

  • But LVGL won’t flush our display unless we trigger the LVGL Background Task�
  • Here’s the simple Zig way to trigger the LVGL Background Task�
  • But it won’t work for Mouse Input�
  • Let’s trigger this from a JavaScript Timer…

26

27 of 52

Handle LVGL Tasks: JavaScript Timer calls Zig

27

28 of 52

Initialise LVGL Display

  • Zig Memory Allocator for malloc()
  • Set Custom Logger for LVGL
  • Set LVGL Display Buffer and Display Driver
  • Register the LVGL Display Driver
  • Render the LVGL Widgets
  • Handle the LVGL Tasks
  • Source Code
  • Read the Article

28

29 of 52

LVGL Input

WebAssembly

LVGL

Display

Input

UI

30 of 52

30

31 of 52

31

32 of 52

Handle LVGL Input

  • Capture JavaScript Events:�Mouse Down, Mouse Up,�Touch Down, Touch Up�
  • Pass the Touch Point to Zig�
  • Zig will remember it and pass to LVGL later�
  • LVGL will poll our Zig Input Driver for Mouse and Touch Input

32

33 of 52

LVGL Input Device

  • Implement the LVGL Input Device in Zig�
  • Plus some C code because Zig can’t access LVGL Structs with Bit Fields�
  • Source CodeRead the Article

33

34 of 52

Feature Phone UI

WebAssembly

LVGL

Display

Input

UI

35 of 52

Feature Phone with LVGL, Zig and NuttX

  • Feature Phone UI as an LVGL Touchscreen App
  • That runs in the Web Browser with WebAssembly
  • And on an actual phone: PINE64 PinePhone
  • NuttX RTOS will support Outgoing Calls and Outgoing SMS on PinePhone
  • Though PCM Audio, Incoming Calls and Incoming SMS are still missing
  • Demo Video

35

36 of 52

36

37 of 52

LVGL Containers, Labels and Buttons

  • LVGL Containers for the Display Digits, Call Buttons, Digit Buttons�
  • Inside the LVGL Containers are�LVGL Labels�LVGL Buttons�
  • We handle presses of the LVGL Buttons�and update the LVGL Labels

37

38 of 52

Display Container with Digit Label

38

39 of 52

Call Container with LVGL Buttons

39

40 of 52

40

41 of 52

LVGL Buttons in Zig

  • We create the entire LVGL App in Zig�
  • Create the LVGL Buttons�
  • Set the Event Callback for the Button Press

41

42 of 52

Handle LVGL Buttons

  • Zig handles the Event Callback�
  • Get the Event Code�
  • Fetch the Button Text�
  • Convert the text from C String to Zig Slice

42

43 of 52

Handle Call Button and Digit Buttons

  • Call Button pressed:�Call the Phone Number that �was dialed�
  • Digit Button pressed:�Append the Digit to the Phone Number�
  • But Call Button will work differently:�WebAssembly vs PinePhone NuttX

43

44 of 52

Works on WebAssembly AND PinePhone!

  • Zig allows importing of Target-Specific Functions:�WebAssembly vs NuttX�
  • So our Call Button will work �differently on WebAssembly �vs NuttX�
  • Source CodeRead the Article

44

45 of 52

Feature Phone App in WebAssembly

  • We have created an LVGL App that runs in a Web Browser with WebAssembly�Demo Video
  • And the exact same LVGL App runs on PinePhone NuttX�Demo Video
  • Maybe someday we can Drag-and-Drop to create LVGL Apps in the Web Browser?

45

46 of 52

Phone Calls and SMS over 4G

  • PinePhone has an LTE Modem inside:�Quectel EG25-G�
  • Connected over UART and USB�
  • Outgoing Calls and Outgoing SMS are OK�
  • UART Interface is ready for Voice Call and SMS Commands

46

47 of 52

47

48 of 52

“NuttX NextGen”?

48

PinePhone

Allwinner A64

PinePhone Pro

Rockchip RK3399

i.MX 8QuadMax MEK�NXP i.MX 8

Star64�StarFive JH7110

49 of 52

49

PinePhone

Allwinner A64

PinePhone Pro

Rockchip RK3399

i.MX 8QuadMax MEK�NXP i.MX 8

Star64�StarFive JH7110

Banana Pi M64 /

Olimex A64 /

Pine64 LTS

Retro Pixel Pocket

Pinebook Pro /

Chromebooks

VisionFive2 /

Milk-V Mars

Librem 5

Phone

Mars CM

Orange Pi /

Rock Pi 4 /

RockPro64

PineTab2�(RK3566)

PineTab-V

Powkiddy RGB30 (RK3566)

SOQuartz�(RK3566)

Olimex TERES-I /

Pinebook

Arm64

RISC-V

50 of 52

“NuttX NextGen”?

50

Arm / RISC-V SoC

Allwinner A64

Rockchip RK3399

NXP i.MX 8

StarFive JH7110

Smartphone

PinePhone

PinePhone Pro

Librem 5

SBC

Banana Pi M64 /

Olimex A64 /

Pine64 LTS

Orange Pi /

Rock Pi 4 /

RockPro64

i.MX 8QuadMax MEK

Star64 /

VisionFive2 /

Milk-V Mars

Tablet

PineTab2*

PineTab-V

Laptop

Olimex TERES-I /

Pinebook

Pinebook Pro / Chromebooks

CM4 SoM

SOQuartz*

Mars CM

Gaming Handheld

Retro Pixel Pocket

Powkiddy RGB30*

*RK3566

51 of 52

Articles

51

52 of 52

Thank You

  • Thanks to the NuttX, LVGL and Zig Communities�
  • Let’s experiment and discover new ways of working with LVGL�
  • From Microcontrollers to Smartphones to Single-Board Computers�
  • And create many more cool, useful and sophisticated LVGL Applications!

52