diff --git a/Documentation/applications/examples/hidkbd/index.rst b/Documentation/applications/examples/hidkbd/index.rst index a95266e57be..0ffb131bbf4 100644 --- a/Documentation/applications/examples/hidkbd/index.rst +++ b/Documentation/applications/examples/hidkbd/index.rst @@ -14,5 +14,13 @@ This is a simple test to ``debug/verify`` the USB host HID keyboard class driver in ``include/nuttx/input/kbd_codec.h`` to decode the returned keyboard data. These special keys include such things as up/down arrows, home and end keys, etc. If this not defined, only 7-bit printable and control ASCII characters - will be provided to the user. Requires ``CONFIG_HIDKBD_ENCODED`` and - ``CONFIG_LIBC_KBDCODEC``. + will be provided to the user. Requires + ``CONFIG_INPUT_KEYBOARD_BYTESTREAM`` and ``CONFIG_LIBC_KBDCODEC``. + +.. note:: + + This example reads the byte stream that the USB HID keyboard driver used + to deliver on its own, which now comes from + ``CONFIG_INPUT_KEYBOARD_BYTESTREAM``. New work should use ``kbd`` + instead: it reads any keyboard, in either format, and reports key + releases as well. diff --git a/Documentation/applications/examples/lvglterm/index.rst b/Documentation/applications/examples/lvglterm/index.rst index 18e93d34b86..5ca60f2b8e8 100644 --- a/Documentation/applications/examples/lvglterm/index.rst +++ b/Documentation/applications/examples/lvglterm/index.rst @@ -4,8 +4,8 @@ LVGL application that runs an interactive NuttShell (NSH) on the display. NSH is started with its standard streams redirected through pipes, its output is -rendered in an LVGL text area, and the input comes from one of three sources -selected at build time. +rendered in an LVGL text area, and the input comes from either a touchscreen +or a keyboard, selected at build time. The shared code lives in ``lvglterm.c`` (NSH startup, output rendering, main loop); ``lvglterm_touch.c`` and ``lvglterm_kbd.c`` implement the input @@ -15,9 +15,7 @@ Input variants ============== The input source is chosen with the *LVGL Terminal input source* Kconfig -choice (only one is built at a time). The physical-keyboard options differ in -the data the keyboard device returns on ``read()``, so the one that matches the -hardware must be selected. +choice (only one is built at a time). On-screen keyboard (touch) ``CONFIG_EXAMPLES_LVGLTERM_INPUT_TOUCH`` (default). An LVGL keyboard @@ -31,39 +29,60 @@ On-screen keyboard (touch) On-screen keyboard (touch) variant -Matrix / upper-half keyboard - ``CONFIG_EXAMPLES_LVGLTERM_INPUT_KBD_MATRIX``. ``struct - keyboard_event_s`` events are read from a keyboard registered through the - ``CONFIG_INPUT_KEYBOARD`` upper half (for example the M5Stack Cardputer - matrix keyboard on ``/dev/kbd0``) and streamed to the shell; the output - fills the whole screen. The Fn Up/Down cursor keys scroll the output. +Physical keyboard + ``CONFIG_EXAMPLES_LVGLTERM_INPUT_KBD``. Keys are read from a keyboard + registered with ``keyboard_register()`` and streamed to the shell; the + output fills the whole screen. The Up and Down cursor keys scroll the + output. Any keyboard works, and the terminal does not need to know which + kind it is: USB HID, a matrix, the simulator, virtio. .. figure:: lvglterm-kbd.png :align: center :width: 500px :alt: LVGL Terminal driven by a matrix keyboard - Matrix / upper-half keyboard variant - -USB HID keyboard - ``CONFIG_EXAMPLES_LVGLTERM_INPUT_KBD_USB``. A USB HID keyboard (for - example on ``/dev/kbda`` with ``CONFIG_USBHOST_HIDKBD``) delivers a byte - stream that is decoded with the keyboard codec and streamed to the shell. - When the driver is built with ``CONFIG_HIDKBD_ENCODED`` the Up/Down cursor - keys scroll the terminal. + Physical keyboard variant, driven by a matrix keyboard .. figure:: lvglterm-usb.png :align: center :width: 500px :alt: LVGL Terminal driven by a USB HID keyboard - USB HID keyboard variant + The same variant, driven by a USB HID keyboard -Both keyboard variants default the device to -``CONFIG_EXAMPLES_LVGLTERM_KBD_DEV`` (``/dev/kbd0`` for the matrix keyboard, -``/dev/kbda`` for USB) and can be overridden at run time by passing the path -as the first argument (``lvglterm /dev/kbd1``) when more than one keyboard is -present. +The keyboard defaults to ``CONFIG_EXAMPLES_LVGLTERM_KBD_DEV`` and can be +overridden at run time by passing the path as the first argument +(``lvglterm /dev/kbd1``) when more than one keyboard is present. Note that +the USB HID driver names its devices ``/dev/kbda`` onwards, since they come +and go as keyboards are plugged in, while the option defaults to +``/dev/kbd0``. + +The terminal reads ``struct keyboard_event_s`` events unless the kernel was +built with ``CONFIG_INPUT_KEYBOARD_BYTESTREAM``, in which case it reads the +byte stream that the keyboard codec defines. That is a property of the build +rather than of the hardware, so it is not something to configure here. + +Driving the terminal without a keyboard +--------------------------------------- + +Because the terminal reads a keyboard device and does not care which one, it +can be driven from the serial console with nothing plugged in. Enable +``CONFIG_UINPUT_KEYBOARD``, which registers a virtual keyboard on +``/dev/ukeyboard``, and ``CONFIG_SYSTEM_KBD``, which injects into it:: + + nsh> lvglterm /dev/ukeyboard & + nsh> kbd -i /dev/ukeyboard + +Everything typed on the console appears on the display from that point on. +Forwarding a real keyboard into the same virtual one lets both drive the +terminal at once, which it cannot do by itself since it opens a single +device:: + + nsh> kbd -i /dev/ukeyboard /dev/kbda & + +Raise ``CONFIG_UINPUT_KEYBOARD_BUFNUMBER`` when doing this. It counts events +rather than keys, so the default of eight holds four keystrokes, and a +console hands over a whole line at once. Font ==== @@ -81,13 +100,12 @@ Configuration - ``CONFIG_SYSTEM_NSH=y`` -- the NSH library must be enabled. - ``CONFIG_GRAPHICS_LVGL=y`` and ``CONFIG_LV_USE_NUTTX=y`` -- LVGL with its NuttX integration. -- A display (``CONFIG_LV_USE_NUTTX_LCD`` or a framebuffer). Each input variant +- A display (``CONFIG_LV_USE_NUTTX_LCD`` or a framebuffer). Each input variant also needs its own driver: a touchscreen - (``CONFIG_LV_USE_NUTTX_TOUCHSCREEN``) for the touch variant, - ``CONFIG_INPUT_KEYBOARD`` for the matrix variant, or - ``CONFIG_USBHOST_HIDKBD`` for the USB variant. The USB variant selects - ``CONFIG_LIBC_KBDCODEC`` automatically and, for the cursor keys, the driver - should be built with ``CONFIG_HIDKBD_ENCODED``. + (``CONFIG_LV_USE_NUTTX_TOUCHSCREEN``) for the touch variant, or + ``CONFIG_INPUT_KEYBOARD`` and a keyboard driver for the physical variant. + ``CONFIG_LIBC_KBDCODEC`` is selected automatically when the build delivers + the byte stream. - The selected font (``CONFIG_LV_FONT_UNSCII_8`` or ``CONFIG_LV_FONT_UNSCII_16``) is enabled automatically by the font choice. diff --git a/Documentation/applications/system/kbd/index.rst b/Documentation/applications/system/kbd/index.rst new file mode 100644 index 00000000000..0fd6698081b --- /dev/null +++ b/Documentation/applications/system/kbd/index.rst @@ -0,0 +1,99 @@ +=================================== +``kbd`` Keyboard dump and injection +=================================== + +Description +----------- + +The ``kbd`` application prints every event that a keyboard reports. Any +keyboard registered with ``keyboard_register()`` is read the same way, +whatever the hardware behind it is, so this works with a USB HID keyboard, +a matrix, the simulator, virtio or VNC without being told which. + +It is the first thing to run when bringing up a keyboard on a new board: +if the events look right here, every application that reads a keyboard +will see the same thing. + +It replaces the ``hidkbd`` and ``keyboard`` examples, which did this for +one kind of keyboard each and could not read the other. + +Usage +----- + +.. code-block:: bash + + kbd [] [] + kbd -i [] + +Without ``-i`` it reads ```` and prints what arrives, stopping +after ```` keys if one is given. The device defaults to +``CONFIG_SYSTEM_KBD_DEVPATH``. It waits for the device to appear rather +than failing, since a USB keyboard shows up when it is plugged in. + +With ``-i`` it writes instead of reading. See `Injecting keys`_ below. + +Output +------ + +A key that produces a character is reported with the character, and a key +that does not, such as an arrow or a modifier, with a value from +``enum kbd_keycode_e``. The two ranges overlap, so the event type is what +tells them apart:: + + nsh> kbd /dev/kbd0 + kbd: reading /dev/kbd0, keyboard events + press code 97 'a' + release code 97 'a' + specpress keycode 7 + specrel keycode 7 + +The four types are ``press`` and ``release`` for characters, ``specpress`` +and ``specrel`` for keycodes. A driver that reports its arrow keys as +plain presses is not following the contract, and its arrows will be +dropped by applications that do. + +The device delivers ``struct keyboard_event_s`` events unless the kernel +was built with ``CONFIG_INPUT_KEYBOARD_BYTESTREAM``, in which case it +delivers the byte stream that the keyboard codec defines. This follows +that setting rather than having a switch of its own, and says which one it +is on the first line. + +Injecting keys +-------------- + +With ``-i`` the tool goes the other way and writes into a virtual keyboard, +so that an application can be driven with no keyboard hardware at all. +This needs ``CONFIG_UINPUT_KEYBOARD``, which registers ``/dev/ukeyboard``. + +Given no source it injects what it reads from its own stdin, which is the +serial console:: + + nsh> kbd -i /dev/ukeyboard + kbd: injecting into /dev/ukeyboard, type to send, Ctrl-D to stop + +Given a source it forwards every key of one keyboard onto another:: + + nsh> kbd -i /dev/ukeyboard /dev/kbda & + kbd: forwarding /dev/kbda into /dev/ukeyboard + +Point an application at ``/dev/ukeyboard`` and both reach it at once, +which the application cannot do by itself since it opens a single device. + +.. note:: + + Raise ``CONFIG_UINPUT_KEYBOARD_BUFNUMBER`` before injecting. It counts + events rather than keys, so the default of eight holds four keystrokes, + and a console hands over a whole line at once. The keyboard upper half + overwrites the oldest event when the buffer is full, so a typed line + arrives with its beginning missing and nothing says so. + +Configuration +------------- + +- ``CONFIG_SYSTEM_KBD`` enables the application. +- ``CONFIG_SYSTEM_KBD_DEVPATH`` is the keyboard to read when none is named + on the command line. Default ``/dev/kbd0``. Note that the USB HID driver + names its devices ``/dev/kbda`` onwards, since they come and go as + keyboards are plugged in. +- ``CONFIG_SYSTEM_KBD_PROGNAME``, ``CONFIG_SYSTEM_KBD_PRIORITY`` and + ``CONFIG_SYSTEM_KBD_STACKSIZE`` are the usual task settings. diff --git a/Documentation/platforms/arm/stm32h7/boards/linum-stm32h753bi/index.rst b/Documentation/platforms/arm/stm32h7/boards/linum-stm32h753bi/index.rst index 3e2c85d0d9c..65d38f22a9a 100644 --- a/Documentation/platforms/arm/stm32h7/boards/linum-stm32h753bi/index.rst +++ b/Documentation/platforms/arm/stm32h7/boards/linum-stm32h753bi/index.rst @@ -1087,6 +1087,37 @@ that the USB host and the SDMMC peripheral coexist:: nsh> mount -t vfat /dev/mmcsd0 /data nsh> ls /data +**Typing from the serial console instead.** The terminal reads a keyboard +device, and it does not care which one, so it can be driven from the serial +console with no keyboard plugged in at all. This configuration enables +``UINPUT_KEYBOARD``, which registers a virtual keyboard on +``/dev/ukeyboard``, and ``system/kbd``, which injects into it. + +Point the terminal at the virtual keyboard and bridge the console into it:: + + nsh> lvglterm /dev/ukeyboard & + nsh> kbd -i /dev/ukeyboard + +Everything typed on the serial console from that point on appears on the +display. This is how to work on the terminal without the keyboard at hand, +and how to reach the board over a serial link from another machine. + +To use both at once, forward the USB keyboard into the same virtual +keyboard before starting the terminal:: + + nsh> kbd -i /dev/ukeyboard /dev/kbda & + nsh> lvglterm /dev/ukeyboard & + nsh> kbd -i /dev/ukeyboard + +The USB keyboard and the serial console now feed the same terminal, which +an application cannot do on its own since it opens a single device. + +``UINPUT_KEYBOARD_BUFNUMBER`` is raised to 128 here. It counts events +rather than keys, so the default of eight holds four keystrokes, and a +console hands over a whole line at once. The keyboard upper half overwrites +the oldest event when the buffer is full, so a line typed at the console +would arrive with its beginning silently missing. + tone ---- diff --git a/boards/arm/stm32h7/linum-stm32h753bi/configs/lvglterm_kbda/defconfig b/boards/arm/stm32h7/linum-stm32h753bi/configs/lvglterm_kbda/defconfig index 490dc686d07..60c8ff2e28e 100644 --- a/boards/arm/stm32h7/linum-stm32h753bi/configs/lvglterm_kbda/defconfig +++ b/boards/arm/stm32h7/linum-stm32h753bi/configs/lvglterm_kbda/defconfig @@ -30,7 +30,8 @@ CONFIG_DEBUG_FEATURES=y CONFIG_DEBUG_SYMBOLS=y CONFIG_DRIVERS_VIDEO=y CONFIG_EXAMPLES_LVGLTERM=y -CONFIG_EXAMPLES_LVGLTERM_INPUT_KBD_USB=y +CONFIG_EXAMPLES_LVGLTERM_INPUT_KBD=y +CONFIG_EXAMPLES_LVGLTERM_KBD_DEV="/dev/kbda" CONFIG_FAT_DMAMEMORY=y CONFIG_FAT_LCNAMES=y CONFIG_FAT_LFN=y @@ -40,6 +41,7 @@ CONFIG_FS_PROCFS=y CONFIG_GRAN=y CONFIG_GRAN_INTR=y CONFIG_GRAPHICS_LVGL=y +CONFIG_HIDKBD_NOGETREPORT=y CONFIG_INIT_ENTRYPOINT="nsh_main" CONFIG_INTELHEX_BINARY=y CONFIG_LIBC_EXECFUNCS=y @@ -81,11 +83,15 @@ CONFIG_STM32_PWR=y CONFIG_STM32_RTC=y CONFIG_STM32_SDMMC1=y CONFIG_STM32_USART1=y +CONFIG_SYSTEM_KBD=y CONFIG_SYSTEM_NSH=y CONFIG_TASK_NAME_SIZE=0 CONFIG_TESTING_RAMTEST=y +CONFIG_UINPUT_KEYBOARD=y +CONFIG_UINPUT_KEYBOARD_BUFNUMBER=128 CONFIG_USART1_SERIAL_CONSOLE=y CONFIG_USBHOST=y +CONFIG_USBHOST_ASYNCH=y CONFIG_USBHOST_HIDKBD=y CONFIG_USEC_PER_TICK=1000 CONFIG_VIDEO_FB=y diff --git a/boards/xtensa/esp32s3/esp32s3-m5-cardputer/configs/lvglterm/defconfig b/boards/xtensa/esp32s3/esp32s3-m5-cardputer/configs/lvglterm/defconfig index 5bb9c031f09..349e37a7e95 100644 --- a/boards/xtensa/esp32s3/esp32s3-m5-cardputer/configs/lvglterm/defconfig +++ b/boards/xtensa/esp32s3/esp32s3-m5-cardputer/configs/lvglterm/defconfig @@ -47,7 +47,7 @@ CONFIG_ESP32S3_USBSERIAL=y CONFIG_ESPRESSIF_WIFI=y CONFIG_EXAMPLES_LVGLTERM=y CONFIG_EXAMPLES_LVGLTERM_FONT_UNSCII_8=y -CONFIG_EXAMPLES_LVGLTERM_INPUT_KBD_MATRIX=y +CONFIG_EXAMPLES_LVGLTERM_INPUT_KBD=y CONFIG_FAT_LCNAMES=y CONFIG_FAT_LFN=y CONFIG_FS_FAT=y