Using Linux virtual mouse driver - linux

I am trying to implement a virtual mouse driver according to the Essential Linux device Drivers book. There is a user space application, which generates coordinates as well as a kernel module.
See: Virtual mouse driver and userspace application code and also a step by step on how to use this driver.
1.) I compile the code of the user space application and driver.
2.) Next i checked dmesg output and have,
input: Unspecified device as /class/input/input32
Virtual Mouse Driver Initialized
3.) The sysfs node was created properly during initialization (found in /sys/devices/platform/vms/coordinates)
4.) I know that the virtual mouse driver (input32 ) is linked to event5 by checking the following:
$ cat /proc/bus/input/devices
I: Bus=0000 Vendor=0000 Product=0000 Version=0000
N: Name=""
P: Phys=
S: Sysfs=/devices/virtual/input/input32
U: Uniq=
H: Handlers=event5
B: EV=5
B: REL=3
5.) Next i attach a GPM server to the event interface: gpm -m /dev/input/event5 -t evdev
6.) Run the user space application to generate random coordinates for virtual mouse and observe generated coordinates using od -x /dev/input/event5.
And nothing happens. Why?
Also here author mentioned that gdm should be stopped, using /etc/init.d/gdm stop, but i get "no such service" when stopping gdm.
Here is my complete script for building and runing virtual mouse:
make -C /usr/src/kernel/2.6.35.6-45.fc14.i686/ SUBDIRS=$PWD modules
gcc -o app_userspace app_userspace.c
insmod app.ko
gpm -m /dev/input-event5 -t evdev
./app_userspace
Makefile:
obj-m+=app.o
Kernel version: 2.6.35.6
As i said before i can recieve the result through od, but i received it through your program
echo 9 19 > /sys/devices/platform/virmouse/vmevent
gives:
time 1368284298.207654 type 2 code 0 value 9
time 1368284298.207657 type 2 code 1 value 19
time 1368284298.207662 type 0 code 0 value 0
So now the question is: what is wrong with X11? I would like to stress, that i tried this code under two different distributions Ubuntu 11.04 and Fedora 14.
Maybe this will help: in Xorg.0.log i see the following:
[ 21.022] (II) No input driver/identifier specified (ignoring)
[ 272.987] (II) config/udev: Adding input device (/dev/input/event5)
[ 272.987] (II) No input driver/identifier specified (ignoring)
[ 666.521] (II) config/udev: Adding input device (/dev/input/event5)
[ 666.521] (II) No input driver/identifier specified (ignoring)

I spent a huge amount of time, resolving this issue, and i would like to help other people, who run in this problem. I think some outer X11 features interfered my module work. After disabling GDM it now works fine (runlevel 3). Working code you can find here http://fred-zone.blogspot.ru/2010/01/mouse-linux-kernel-driver.html working distro ubuntu 11.04 (gdm disabled)

Try replacing the below lines of code in the input device driver
set_bit(EV_REL, vms_input_dev->evbit);
set_bit(REL_X, vms_input_dev->relbit);
set_bit(REL_Y, vms_input_dev->relbit);
with
vms_input_dev->name = "Virtual Mouse";
vms_input_dev->phys = "vmd/input0"; // "vmd" is the driver's name
vms_input_dev->id.bustype = BUS_VIRTUAL;
vms_input_dev->id.vendor = 0x0000;
vms_input_dev->id.product = 0x0000;
vms_input_dev->id.version = 0x0000;
vms_input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REL);
vms_input_dev->keybit[BIT_WORD(BTN_MOUSE)] = BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
vms_input_dev->relbit[0] = BIT_MASK(REL_X) | BIT_MASK(REL_Y);
vms_input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA);
vms_input_dev->relbit[0] |= BIT_MASK(REL_WHEEL);
It worked for me on ubuntu 12.04

Related

Trouble initializing SDK node using USB-TTL M210 v2

I am trying to connect M210 v2 RTK to a desktop computer with Ubuntu 18.04, ROS Melodic and parallel installation of Opencv 3.3.1 and 4.5.3 using a USB-TTL RS232 to make UART connection and an USB-USB connecting drone and desktop to be able to run Advanced Sensing.
When I call ls -l /dev/ttyACM* && ls -l /dev/ttyUSB* it returns that it is indentified the USB and ACM connection.
crw-rw---- 1 root dialout 166, 0 out 4 13:18 /dev/ttyACM0
crw-rw---- 1 root dialout 188, 0 out 4 13:18 /dev/ttyUSB0
I also set the transfer rate of TTL-USB to 921600 using minicom, and gave persmission to device to read and write with sudo usermod -a -G dialout $USER && sudo chmod 666 /dev/ttyUSB0
Unfortunatelly when I launch roslaunch dji_osdk_ros dji_sdk_node.launch it appears some connection problem presented below and I am not being able to fix it. I have been trying to turn on/off drone and RC several times ass described here, but the problem still stand.
started roslaunch server http://V3D06:43613/
SUMMARY
========
PARAMETERS
* /dji_sdk/acm_name: /dev/ttyACM0
* /dji_sdk/align_time: False
* /dji_sdk/app_id: 1076017
* /dji_sdk/app_version: 1
* /dji_sdk/baud_rate: 921600
* /dji_sdk/dxc: False
* /dji_sdk/enc_key: 6bd1d26f8dd897e4b...
* /dji_sdk/serial_name: /dev/ttyUSB0
* /dji_sdk/use_broadcast: False
* /rosdistro: melodic
* /rosversion: 1.14.12
NODES
/
dji_sdk (dji_osdk_ros/dji_sdk_node)
auto-starting new master
process[master]: started with pid [2436]
ROS_MASTER_URI=http://localhost:11311
setting /run_id to bde7b4d2-252e-11ec-8a59-1831bfb3e154
process[rosout-1]: started with pid [2458]
started core service [/rosout]
process[dji_sdk-2]: started with pid [2464]
[ INFO] [1633364323.534426789]: Advanced Sensing is Enabled on M210.
Read App ID
User Configuration read successfully.
[1276751.089]STATUS/1 # getDroneVersion, L1702: ret = 0
[1276751.089]STATUS/1 # parseDroneVersionInfo, L1122: Device Serial No. = 1DADG3E00100U4
[1276751.089]STATUS/1 # parseDroneVersionInfo, L1124: Firmware = 3.4.3.44
[1276751.089]STATUS/1 # functionalSetUp, L279: Shake hand with drone successfully by getting drone version.
[1276751.089]STATUS/1 # legacyX5SEnableTask, L56: Legacy X5S Enable task created.
[1276752.089]STATUS/1 # sendHeartbeatToFCTask, L1576: OSDK send heart beat to fc task created.
[1276752.289]STATUS/1 # Control, L40: The control class is going to be deprecated.It will be better to use the FlightController class instead!
[1276752.290]STATUS/1 # FileMgrImpl, L253: register download file callback handler successfully.
[1276753.557]STATUS/1 # PSDKModule, L98: MOP only support M300, so mop client will not be initialized here.
[1276753.557]STATUS/1 # PSDKModule, L98: MOP only support M300, so mop client will not be initialized here.
[1276753.557]STATUS/1 # PSDKModule, L98: MOP only support M300, so mop client will not be initialized here.
[1276753.557]STATUS/1 # initDJIHms, L900: DJI HMS is not supported on this platform!
[1276753.567]STATUS/1 # getDroneVersion, L1702: ret = 0
[1276753.567]STATUS/1 # parseDroneVersionInfo, L1122: Device Serial No. = 1DADG3E00100U4
[1276753.567]STATUS/1 # parseDroneVersionInfo, L1124: Firmware = 3.4.3.44
[1276753.567]STATUS/1 # AdvancedSensing, L145: Advanced Sensing init for the M210 drone
[1276753.567]STATUS/1 # init, L49: Looking for USB device...
[1276753.572]STATUS/1 # init, L65: Found 8 USB devices, identifying DJI device...
[1276753.572]STATUS/1 # init, L83: Found a DJI device...
[1276753.572]STATUS/1 # init, L96: Attempting to open DJI USB device...
[1276753.572]ERRORLOG/1 # init, L101: Failed to open DJI USB device...
[1276753.572]ERRORLOG/1 # init, L102: Error code: -3
[1276753.572]ERRORLOG/1 # init, L105: Please make sure you provide a udev file for your system and reboot the computer
[1276753.573]STATUS/1 # LiveViewImpl, L89: Finding if liveview stream is available now.
[1276754.076]STATUS/1 # init, L254: Start advanced sensing initalization
[1276754.076]STATUS/1 # activate, L1329: version 0x304032C
[1276754.076]STATUS/1 # adv_pthread, L46: adv pthread created !!!!!!!!!!!!!!!!!!!!!!!
[1276754.076]STATUS/1 # adv_pthread, L48: adv pthread running !!!!!!!!!!!!!!!!!!!!!!!
[dji_sdk-2] process has died [pid 2464, exit code -11, cmd /home/vant3d/catkin_ws/devel/lib/dji_osdk_ros/dji_sdk_node __name:=dji_sdk __log:=/home/vant3d/.ros/log/bde7b4d2-252e-11ec-8a59-1831bfb3e154/dji_sdk-2.log].
log file: /home/vant3d/.ros/log/bde7b4d2-252e-11ec-8a59-1831bfb3e154/dji_sdk-2*.log
It appears it has some problem providing a udev file, but I don't know how to fix it. Does anyone have some idea to help on this problems?
Thank you!
That's my post. Firstly turn off advanced sensing to try whether a basic FTDI works.
The second which DJI OSDK version are you using? does the OSDK version match the version in OSDK-ROS? I saw you have M300 in. that is usually in OSDK 4+. For M210, I only use 3.8 and 3.9
If basic FTDI works, and you can get all the feedback. there is a higher chance that you have the wrong ACM config. DJI RNDIS thing is nasty and may not be config properly. You need to manually set static IP of 192.168.43.1 (or I remember something like this 42 or 43, you need to check on this static IP) and set it manually

Raspberry Pi: IR LED works, but irsend does not transmit any IR code

I installed the current lirc package (0.9.0~pre1-1.2) on a Raspian jessie (no pixel) (everything updated and upgraded) and connected to the (lirc default) GPIO ports:
to gpio port 17 - an IR LED via transistor etc
to gpio port 18 - an IR receiver nodule
The receiver part works perfectly:
mode2 command receiving raw data from transmitter
the IR code recognition of previously recorded keys works
However, the IR LED only works only while lirc is not involved:
a shell script can switch the IR LED on and off with no problem
The only thing that doesn't work:
irsend does not make the IR transmitter emit anything, however no error message is shown
So the hardware, especially the IR LED is definitely working, while lirc cannot make the LED emit any configured IR code.
Please note that this seems to be a duplicate of
stackoverflow: irsend is not giving errors, but does not send signal on Raspbian
Unfortunately it is not. The "solution" provided there was placing the data for /etc/modules into the file /etc/modules-load.d/lirc_rpi.conf. I tried that as well, but it makes no difference.
Any help is greatly appreciated!
Configuration data follows - if any other data is required, I'd be happy to add it! TIA!
System and lirc Configuration
Extract fom: /boot/config.txt
dtoverlay=lirc-rpi,gpio_in_pin=18,gpio_out_pin=17,debug=on
Extract of: /etc/modules
lirc_dev
lirc_rpi gpio_in_pin=18 gpio_out_pin=17
(not sure if that is necessary at all, does not make a difference if this is not configured!? Any hint apppreciated)
All active entries in: /etc/lirc/hardware.conf
LIRCD_ARGS="--uinput"
DRIVER="default"
DEVICE="/dev/lirc0"
MODULES="lirc_rpi"
LIRCD_CONF=""
LIRCMD_CONF=""
Some system output
1) The driver is loaded, output of following command right after boot, output of: dmesg | grep lirc
lirc_dev: IR Remote Control driver registered, major 245
lirc_rpi: module is from the staging directory, the quality is unknown, you have been warned.
lirc_rpi: to_irq 178
lirc_rpi: auto-detected active low receiver on GPIO pin 18
lirc_rpi lirc_rpi: lirc_dev: driver lirc_rpi registered at minor = 0
lirc_rpi: driver registered!
input: lircd as /devices/virtual/input/input0
lirc_rpi: Interrupt 178 obtained
2) the service is started and running, output of: systemctl status lirc
? lirc.service - LSB: Starts LIRC daemon.
Loaded: loaded (/etc/init.d/lirc)
Active: active (running) since Mo 2017-06-12 20:04:03 CEST; 2h 58min ago
Process: 377 ExecStart=/etc/init.d/lirc start (code=exited, status=0/SUCCESS)
CGroup: /system.slice/lirc.service
+-437 /usr/sbin/lircd --driver=default --device=/dev/lirc0 --uinput
3) the modules are loaded, output of: lsmod | grep Module;lsmod | grep lirc
Module Size Used by
lirc_rpi 8453 3
lirc_dev 10211 1 lirc_rpi
rc_core 23776 1 lirc_dev
I followed the troubleshooting steps in the (outdated) manual at http://aron.ws/projects/lirc_rpi/
to get some more information.
Output of: cat /sys/kernel/debug/gpio
gpiochip0: GPIOs 0-53, parent: platform/20200000.gpio, pinctrl-bcm2835:
gpio-35 ( |? ) in hi
gpio-47 ( |? ) out lo
I have seen that output also in this case:
raspberrypi.stcakexchange: LIRC won't transmit (irsend: hardware does not support sending)
This user is as irritated by that output as I am - can somebody please tell why gpio-35 and gpio-47 are listed here? shouldn't it be gpio-17 and gpio-18?
Output of: cat /proc/interrupts | grep lirc
178: 875 pinctrl-bcm2835 18 Edge lirc_rpi
This matches the dmesg output on having obtained interrupt 178
Any other dmesg output of lircd, no matter what action, is repeatedly (most likely due to the debug option set) only
lirc_rpi: SET_SEND_CARRIER
lirc_rpi: in init_timing_params, freq=38000 pulse=13157, space=13158
lirc_rpi: SET_SEND_DUTY_CYCLE
lirc_rpi: in init_timing_params, freq=38000 pulse=13157, space=13158
Having restarted testing again after some time for to build up a test copy of the circuit, the problem occurred again. And now, after some more month of much testing, having asked lots of people for help (no one could help), even having purchased and built up a cheap mini USB oscilloscope kit for to examine the hardware further, I finally found the solution.
Long story short: everything in the configuration was correct, and all of the attached hardware was fine. The problem was the testing script - see my remark on
"a shell script can switch the IR LED on and off with no problem"
and as I did not put it in the above description, nobody could have found the solution myself....
The script uses the pseudo files in /sys/class/gpio, see an example here:
raspberry-projects.com: IO pin control from the command line
At the end of the script a command writes to /sys/class/gpio/unexport for cleanup purposes, and this step seems to reset a GPIO port to always end up in the state of being configured for input. As a result LIRC is not longer able to control this GPIO port, since it seems to configure the GPIO port for output only during system boot, and after that always expecting the port to be in that state.
I tracked the problem down to this point by using the gpio utility from the wirinpi package (install with sudo apt-get wiringpi), executing gpio readall and checking for differences.
The time when everything suddenly worked again, I simply may have fogotten about to run my testscript before testing LIRC, which I otherwise always did...
Luckily the problem with the port configuration can easily be fixed without having to reboot the system. Again I use the gpio utility to reset reset the used port for output, where in the below example
the default output port 17 for LIRC is used and
the parameter -g lets the utility use the ordinary GPIO port numbering and not that very different one of the wiringpi package and library
Here is the command, after having executed this last in my test script, LIRC can properly send IR codes again:
gpio -g mode 17 out

rotary encoder driver does not create device node /dev/input/eventN

I use a board running with Linux 3.0.8.
I follow the instructions from Documentation/input/rotary-encoder.txt and call the following in driver module:
platform_device_register(&rotary_encoder_device);
The kernel prints the following when boots up:
[5.629682] input: rotary-encoder as /devices/platform/rotary-encoder.0/input/input1
and I can get this:
# ls /sys/devices/platform/rotary-encoder.0/input/input1/
capabilities id name properties uevent
device modalias phys subsystem uniq
However there is no device node /dev/input/eventN created.
How to fix this? Thanks for any help.

why does the i2cdetect always gives UU on my RTC in embedded Linux

I'd like to communicate read from my RTC in C code rather than the "hwclock" shell command.
However, when I use i2cdetect, it shows 0x68(which is my RTC slave address) is having the status "UU", which means "Probing was skipped, because this address is currently in use by a driver". And after I tried the i2cget, its givng "could bot set address to 0x68: Device or resource busy".
So I'm thinking if there are some problem in my Linux kernel that will force to read from my RTC all the time, or some other reason.
Thanks
I am assuming that you are using DS-1307 RTC, or one of its variants (because of 0x68 slave address). Check if its driver is loaded by:
$ lsmod | grep rtc
If you seen an entry of rtc_ds1307, (like this -> rtc_ds1307 17394 0 ) in the output of above command then this driver might be in hold of that address.
If the driver is loaded in system then unload it using
$ rmmod rtc-ds1307
EDIT:
(In light of OP's feedback,) Please do the following
1) cat /sys/bus/i2c/devices/3-0068/modalias. This will give you the name of the kernel driver that is keeping this device busy. Copy the driver-name after the colon(:)
OP's output of the command tells us that its ds1337
2) Check if ds1337 is an alias for a driver, using
grep ds1337 /lib/modules/`uname -r`/modules.alias
Hopefully you will get the following output
alias i2c:ds1337 rtc_ds1307
This confirms our presumption that rtc_ds1307 is infact the driver in hold of the I2C address 0x68.
3) use rmmod rtc_ds1307 to unload the driver.
Note: This will only work if the driver is a Loadable Kernel Module, otherwise you will see the following error:
ERROR: Module rtc_ds1307 does not exist in /proc/modules
In that case you will have to recompile the kernel again with that driver disabled/modularized.
0x68 is being used by some driver,
Disable that driver in kernel source code and recompile source code.

Register(/bind/match) a device with a driver

I am writing a usb driver (for a gamepad) on linux, and when I plug it in, ti loads usbhid. How can I make it so it loads my driver (gp_driver)?
I did the unbind usbhid and bind to my driver trick, but I don't want to do it every single time.
Should I have my driver already loaded?
Should I code something in my driver?
I have the vendor and product id in my driver..
thanks
You will want to create a udev rule for your device, which can take care of creating your device file, setting permissions on the device file, and loading relevant drivers.
Resources
http://reactivated.net/writing_udev_rules.html
http://www.redhat.com/magazine/002dec04/features/udev/
Example
Taken from: http://plugcomputer.org/plugwiki/index.php/Load_Serial_Drivers_Automatically_Using_udev
# if no driver has claimed the interface yet, load ftdi_sio
ACTION=="add", SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_interface", \
ATTRS{idVendor}=="9e88", ATTRS{idProduct}=="9e8f", \
DRIVER=="", \
RUN+="/sbin/modprobe -b ftdi_sio"
Binding a (in your case HID-) device to a specific driver is not a trivial task and depends on the kernel version you are using:
Kernel < 4.16
Before kernel 4.16 you had to edit and recompile drivers/hid/hid-core.c since this file contained a list of devices which should not be not handled by hid-generic (hid_have_special_driver struct), you can see an example of how this was done here:
https://github.com/atar-axis/xpadneo/blob/master/misc/kernel_patches/0002-hid_generic_claims_devices.patch
Kernel >= 4.16
Starting with Kernel 4.16 the list was removed and hid-generic checks if any of the other drivers wants the device, if so - then hid-generic steps back and does not claim the device.
The related patch is: https://github.com/torvalds/linux/commit/e04a0442d33b8cf183bba38646447b891bb02123#diff-88d50bd989bbdf3bbd2f3c5dcd4edcb9
Workaround (works always)
You can always use an udev-rule (e.g. /etc/udev/rules.d/99-xpadneo.rules), either before 4.16 or whenever there is more than one specialized driver in your system:
# unbind the device from hid-generic on kernel < 4.16
# and bind it to the specialized driver (xpadneo in this case)
ACTION=="add", KERNEL=="0005:045E:02FD.*|0005:045E:02E0.*", SUBSYSTEM=="hid",\
RUN+="/bin/bash -c 'echo $kernel > /sys/bus/hid/drivers/hid-generic/unbind'", \
RUN+="/bin/bash -c 'echo $kernel > /sys/bus/hid/drivers/xpadneo/bind'"
# unbind the device from another specialized driver which came first
# and bind it to xpadneo
ACTION=="add", KERNEL=="0005:045E:02FD.*|0005:045E:02E0.*", SUBSYSTEM=="hid",\
RUN+="/bin/bash -c 'echo $kernel > /sys/bus/hid/drivers/microsoft/unbind'", \
RUN+="/bin/bash -c 'echo $kernel > /sys/bus/hid/drivers/xpadneo/bind'"
Notes
Instead of bash you should maybe use sh
I don't remember when bind and unbind where added, but it quite a while ago.
You can read a bit more about loading, binding and registration of (HID-) drivers here:
http://0x0001.de/linux-driver-loading-registration-and-binding/
https://github.com/atar-axis/xpadneo/issues/33
According to this Linux Journal article, you need to have:
A pointer to the module owner of your driver
The name of the USB driver
A list of the USB IDs this driver should provide
A probe() function
A disconnect() function
Now, I suspect, because it is loading the standard driver, you may not have either 3, 4, or maybe you haven't registered the driver with the USB subsystem at all.
I've never written a USB driver before (only hacked char/mem.c), but this info might come in handy.

Resources