JorgeGzm opened a new pull request, #3687:
URL: https://github.com/apache/nuttx-apps/pull/3687

   ## Summary
   
   There is no single way to read a keyboard in NuttX today, and it shows in
   the applications.
   
   `examples/hidkbd` reads a USB HID keyboard as a byte stream.
   `examples/keyboard` reads an upper half keyboard as events. Neither works
   with the other, so bringing up a new keyboard means picking the right
   example first, and there is no answer for somebody whose keyboard is
   neither. `examples/lvglterm` went further and had three mutually exclusive
   input sources, with its own help text explaining that the physical keyboard
   options "differ in the data the keyboard device delivers on read(), so pick
   the one that matches the hardware". That is the abstraction leaking: a user
   had to know the keyboard was USB rather than a matrix in order to compile a
   terminal.
   
   This adds `system/kbd`, which reads any keyboard registered with
   `keyboard_register()`, and converts the terminal and the game to the same
   model.
   
   * **`system/kbd`** prints every event a keyboard reports, whatever the
     hardware behind it is. With `-i` it goes the other way and injects into a
     uinput keyboard, either what it reads from its own stdin or every key of
     another keyboard. So an application can be driven from a serial console
     with no keyboard hardware at all, and a real keyboard and an injected one
     can drive it at the same time, which neither can do on its own since an
     application opens a single device.
   
   * **`examples/lvglterm`** has two input sources now, touch and physical, and
     the physical one does not ask what kind of keyboard it is.
   
   * **`games/NXDoom`** handled `KEYBOARD_PRESS` and `KEYBOARD_RELEASE` and
     dropped everything else, so every key reported as `KEYBOARD_SPECPRESS`
     went nowhere. On the simulator that is already every arrow key, since
     `sim_keyboard` reports them that way.
   
     Enter needed handling on both sides, which is worth spelling out because
     it is the whole point of this work: a USB HID keyboard reports it as the
     line feed the key produces, and the simulator reports it as
     `KEYCODE_ENTER`. Two drivers, two conventions for one key. Both have to
     land on `KEY_ENTER`, and validating on a single backend is how you end up
     handling only one of them.
   
   This is the application half of the keyboard work. The keycodes and event
   types it uses came from apache/nuttx#19586, already merged.
   
   ## Companion PR, and why CI is red
   
   This has a companion in the kernel repo, 
https://github.com/apache/nuttx/pull/19592, which updates
   the two board configurations that name the option this renames. The two
   cannot be green at the same time: CI builds each repo against the other's
   master, so this one sees configurations that still name
   `EXAMPLES_LVGLTERM_INPUT_KBD_USB` and `_KBD_MATRIX`, and the companion sees
   an apps master that does not have `EXAMPLES_LVGLTERM_INPUT_KBD` yet. Both
   turn green once both are in.
   
   The failures are limited to the normalisation step of those two
   configurations, one line each:
   
   ```
     [1/1] Normalize linum-stm32h753bi/lvglterm_kbda
        modified:   
boards/arm/stm32h7/linum-stm32h753bi/configs/lvglterm_kbda/defconfig
           -CONFIG_EXAMPLES_LVGLTERM_INPUT_KBD_USB=y
     [1/1] Normalize esp32s3-m5-cardputer/lvglterm
        modified:   
boards/xtensa/esp32s3/esp32s3-m5-cardputer/configs/lvglterm/defconfig
           -CONFIG_EXAMPLES_LVGLTERM_INPUT_KBD_MATRIX=y
   ```
   
   Worth flagging for review: no in-tree configuration enables `SYSTEM_KBD`
   yet, so CI never compiles the new application here. The companion PR turns
   it on in `linum-stm32h753bi:lvglterm_kbda`. Until then it was built locally
   with the two branches paired, see Testing.
   
   ## Impact
   
   `examples/hidkbd` and `examples/keyboard` stay for now. They are what the
   in-tree configurations still name, and removing them has to wait until those
   configurations have been moved to `system/kbd`.
   
   `EXAMPLES_LVGLTERM_INPUT_KBD_MATRIX` and `EXAMPLES_LVGLTERM_INPUT_KBD_USB`
   are replaced by a single `EXAMPLES_LVGLTERM_INPUT_KBD`. The two in-tree
   configurations that selected either one, on the Linum and on the M5Stack
   Cardputer, are updated in the kernel PR. The device path has to be spelled
   out for a USB keyboard, since that driver names its devices `/dev/kbda`
   onwards while the option defaults to `/dev/kbd0`.
   
   `EXAMPLES_HIDKBD_ENCODED`, `NSH_USBKBD` and `MICROWINDOWS_KBD_RAW` all read
   a stream of characters rather than events, which now comes from
   `INPUT_KEYBOARD_BYTESTREAM` rather than from the USB HID driver itself. All
   three depend on it now, so Kconfig refuses a combination that cannot work
   instead of letting the application read events and treat them as text. No
   in-tree configuration selects the last two.
   
   The terminal no longer honours cursor keys reported out of band as
   ordinary presses of 0x80 to 0x83. The M5Stack Cardputer was the only
   driver that did that, and it is converted in the kernel PR, which merges
   first.
   
   Nothing else changes for an application that was already reading events.
   
   ## Testing
   
   Validated on hardware in two independent backends: a USB HID keyboard on a
   Linum STM32H753BI, and X11 on the simulator.
   
   `system/kbd`, reading a real keyboard, event model:
   
       kbd: reading /dev/kbda, keyboard events
       press     code  97 'a'
       release   code  97 'a'
       specpress keycode 7
       specrel   keycode 7
   
   Counted rather than eyeballed. Typing normally produced 40 presses and 40
   releases, perfectly paired, with no key pressed twice while held, no orphan
   release, nothing stuck down at the end, and four keys held at once reported
   in the right order. The special keys gave 29 press and release pairs on the
   same terms, including two arrows held together.
   
   `system/kbd -i`, driving a keyboard that does not exist, with a second
   instance dumping the same device:
   
       nsh> kbd /dev/ukeyboard &
       nsh> kbd -i /dev/ukeyboard
       kbd: injecting into /dev/ukeyboard, type to send, Ctrl-D to stop
       abc
       press     code  97 'a'
       release   code  97 'a'
       press     code  98 'b'
       release   code  98 'b'
       press     code  99 'c'
       release   code  99 'c'
   
   `system/kbd -i` with a source, forwarding the USB keyboard into the virtual
   one, gave 24 press and release pairs across the crossing with no duplicate,
   no orphan and three keys held at once.
   
   `examples/lvglterm` was driven on the board's LCD from a real USB keyboard,
   from the serial console through the uinput bridge, and from both at once
   with the USB keyboard forwarded into the same virtual keyboard. The terminal
   is the same binary in all three cases and reads a single device.
   
   `games/NXDoom` was played on the simulator: the menu responds to Enter, the
   arrows move, Ctrl fires, Shift runs, Tab opens the map and Escape returns to
   the menu. Instrumenting the event handler confirmed the translation, with
   Enter arriving as `KEYCODE_ENTER` and leaving as 13, and the arrows as 5 to
   8 leaving as 173 to 176.
   
   Built every configuration in the tree that touches a keyboard, inside the CI
   container, with this branch paired against the companion kernel branch so
   that the renamed option and `SYSTEM_KBD` are actually exercised:
   
   ```
   ### Normalisation
     clean linum-stm32h753bi:lvglterm_kbda     clean olimex-lpc1766stk:hidkbd
     clean esp32s3-m5-cardputer:lvglterm       clean nucleo-h753zi:jumbo
     clean sama5d4-ek:nsh                      clean qemu-intel64:jumbo
   ### Build
     PASS linum-stm32h753bi:lvglterm_kbda      PASS olimex-lpc1766stk:hidkbd
     PASS esp32s3-m5-cardputer:lvglterm        PASS sim:nxdoom
   ```
   
   The CI test lists that cover these boards were also run in full against the
   kernel master: `arm-08`, `arm-07` and `arm-03`, 240 configurations, no
   failure.
   
   Two failures seen in the container are environmental and reproduce on an
   untouched master: the Xtensa lists fail when the `esp-hal-3rdparty`
   download is truncated, which breaks the `.context` target for every ESP32-S3
   configuration, and `ci20` fails to link because the PINGUINOL `p32-ld` in
   the image does not know the target the board asks for:
   
   ```
   p32-ld: target elf32-tradlittlemips not found
   p32-ld: supported targets: elf32-bigmips elf32-littlemips ...
   ```
   
   `nxstyle` is clean on every file touched.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to