![]() |
RT-Thread RTOS
An open source embedded real-time operating system
|
**input_uapi.c** exposes each **rt_input_device** as a Linux-compatible character device for POSIX userspace (Smart / LWP + DFS). IOCTLs and **struct input_event** are defined in **drivers/input_uapi.h** (aligned with **include/uapi/linux/input.h**).
DM overview and driver binding: Input device model (DM). In-kernel reporters and handlers: Input subsystem.
Sources: **components/drivers/input/input_uapi.c**, **components/drivers/include/drivers/input_uapi.h**.
| Option | Default | Role |
|---|---|---|
**RT_INPUT_UAPI** | y if **RT_USING_SMART**, else n | Build **input_uapi.c**, attach **dfs_file_ops** in **input_uapi_init** |
**RT_INPUT_UAPI_EVENT_MAX** | 128 | Ring buffer slots (**struct input_event** per device) |
**RT_UAPI_FAKE_BLOCK** | y | **O_NONBLOCK** empty **read** returns synthetic **SYN_REPORT** instead of **-EAGAIN** |
Dependencies: **RT_USING_INPUT**, **RT_USING_KTIME**, **RT_USING_POSIX_DEVIO**.
| Hook | When |
|---|---|
**input_uapi_init** | **rt_input_device_register** — allocates **struct input_uapi**, sets **idev->parent.fops** |
**input_uapi_event** | Every **rt_input_event** while UAPI enabled |
**input_uapi_finit** | **rt_input_device_unregister** — free UAPI state |
Registered device names are **input0**, **input1**, … (**rt_dm_ida** in **input.c**). Open via devfs:
**input_uapi_event** returns without queuing when **idev->parent.ref_count == 0** — userspace must **open** the node before events appear.
| Kernel handler path | UAPI queue | |
|---|---|---|
| Struct | **struct rt_input_event** (drivers/input.h) | **struct input_event** (input_uapi.h) |
| Time | **rt_tick_t tick** | **struct timeval** from **rt_ktime_boottime_get_us** |
| Codes | **dt-bindings/input/event-codes.h** | Same |
**struct input_absinfo** returned by **EVIOCGABS** matches **struct rt_input_absinfo** (**RT_ASSERT** on layout in **input_uapi_init**).
**struct input_uapi** holds:
read_idx**, **write_idx**, **sync_count**events[RT_INPUT_UAPI_EVENT_MAX]**grabbed_file** for **EVIOCGRAB**On each kernel event copy, **write_idx** advances. When **type == EV_SYN** and **code == SYN_REPORT**, **sync_count** increments and **rt_wqueue_wakeup** runs.
**read** drains events until the user buffer is full or a **SYN_REPORT** completes one frame; each consumed frame decrements **sync_count**.
Overflow: if the next write would overwrite unread data, the event is dropped (warning log). Raise **RT_INPUT_UAPI_EVENT_MAX** for high-rate touch streams.
| Behavior | Detail |
|---|---|
| Min size | **count != 0** and **count < sizeof(struct input_event)** → **-EINVAL** |
**count == 0** | Allowed (availability check after wait) |
| Blocking | Waits on **idev->parent.wait_queue** until **sync_count > 0** |
**O_NONBLOCK** | Empty queue → **-EAGAIN**, or fake **SYN_REPORT** if **RT_UAPI_FAKE_BLOCK** |
**poll** | **POLLIN** when **sync_count > 0** (**O_RDONLY** / **O_RDWR** only) |
**write** | **-ENOSYS** |
Grab: if another **dfs_file** holds **EVIOCGRAB**, **read** returns **-EAGAIN**.
| IOCTL | Purpose |
|---|---|
**EVIOCGVERSION** | **EV_VERSION** (0x010001) |
**EVIOCGID** | Virtual ID: bustype **0x06**, vendor **0x5354**, product **0x4556**, version **RT_VER_NUM >> 16** |
**EVIOCGNAME(len)** | Device name (**inputN**) |
**EVIOCGPROP(len)** | Property bitmap (direct-touch bit when buffer large enough) |
**EVIOCGBIT(ev, len)** | Type bitmap (**ev==0**) or **EV_KEY/EV_REL/EV_ABS** maps |
**EVIOCGABS(abs)** | Axis **struct input_absinfo** |
**EVIOCGRAB** | Exclusive grab; non-zero **args** grabs; second grabber **-EBUSY** |
**EVIOCSABS**, force-feedback, and other Linux input IOCTLs → **-EINVAL**.
Use **rt_input_add_handler** in kernel; use UAPI when a POSIX process (e.g. **evtest**) reads the same event stream.
| Issue | Mitigation |
|---|---|
No events before open | **ref_count** gate in **input_uapi_event** |
| Unregister with open fd | **rt_input_device_unregister** checks **ref_count** — close fds first |
| Grab conflicts | Release with **EVIOCGRAB** and zero argument |
| Touch bursts | Increase **RT_INPUT_UAPI_EVENT_MAX** or read faster |
**RT_UAPI_FAKE_BLOCK** | Disable for strict **-EAGAIN** on empty non-blocking reads |
components/drivers/include/drivers/input_uapi.hcomponents/drivers/input/Kconfig