User Tools

Site Tools


projects:qtusb

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revisionBoth sides next revision
projects:qtusb [2013/06/04 16:42] – [udev Rules] mkuciaprojects:qtusb [2013/06/04 23:10] – [udev Rules] mkucia
Line 209: Line 209:
 TODO TODO
  
-==== udev Rules ====+==== udev rules ====
  
 Create a rule for device by making a new file: Create a rule for device by making a new file:
Line 224: Line 224:
  
 There are more actions that udev rules can implement. For example launching application when device is connected. There are more actions that udev rules can implement. For example launching application when device is connected.
 +
 +
 +==== Detecting device mount/remove ====
 +
 +udev allow user applications to receive messages on changes in devices filesystem. 
 +One can filter messages by subsystem and type. 
 +In our case we want to receive USB device notifications from USB subsystem (it also emits USB interface messages).
 +Finally monitor is activated and file descriptor ([[wp>Unix_file_types#Socket|socket file]]) retrieved. 
 +
 +<code=c>
 +// Create the udev object
 +if (!(udev = udev_new()))
 +[..]
 +
 +// Set up a monitor to monitor usb devices
 +mon = udev_monitor_new_from_netlink(udev, "udev");
 +// We want only to receive information about usb devices
 +udev_monitor_filter_add_match_subsystem_devtype(mon, "usb", "usb_device");
 +udev_monitor_enable_receiving(mon);
 +fd = udev_monitor_get_fd(mon);
 +</code>
 +
 +The messages need to be pooled periodically. I created timer that fires every 250 [ms].
 +<code=c>
 +// Start timer that will periodicaly check if hardware is connected
 +monitorTimer = new QTimer(this);
 +connect(monitorTimer, &QTimer::timeout, this, &MainWindow::monitorTimerTick );
 +monitorTimer->start(250);
 +</code>
 +
 +Timer code checks if there is a new message. select() returns amount of messages. In this case function is non-blocking but one can implement timeout easy here.
 +<code=c>
 +void MainWindow::monitorTimerTick()
 +{
 +    // Set up select
 +    fd_set fds;
 +    struct timeval tv;
 +    int ret;
 +    FD_ZERO(&fds);
 +    FD_SET(fd, &fds);
 +    tv.tv_sec = 0;
 +    tv.tv_usec = 0;
 +
 +    ret = select(fd+1, &fds, NULL, NULL, &tv);
 +
 +    // Check if our file descriptor has received data.
 +    if (ret > 0 && FD_ISSET(fd, &fds))
 +    {
 +</code>
 +
 +When new message is confirmed code check if it from our hardware by looking into vendor id and product id.
 +If device matches, code checks type of event and emits appropriate Qt signal.
 +
 +<code=c>
 +// Get the device
 +if ( (dev = udev_monitor_receive_device(mon)) == NULL)
 +[...]
 +// Now check if the device is our rgb_led launchpad
 +
 +const char* str_action = udev_device_get_action(dev);
 +const char* str_PID = udev_device_get_property_value(dev, "ID_MODEL_ID");
 +const char* str_VID = udev_device_get_property_value(dev, "ID_VENDOR_ID");
 +
 +[...]
 +// Compare strings and send signals
 +if ( (strcmp(STR_PRODUCT_ID,str_PID) == 0) && (strcmp(STR_VENDOR_ID,str_VID) == 0) )
 +{
 +   if (strcmp("add",str_action) == 0)
 +   {
 +      emit signal_DeviceConnected();
 +   }
 +   else if (strcmp("remove",str_action) == 0)
 +   {
 +      emit signal_DeviceDisconnected();
 +   }
 +[...]
 +
 +    // If there are more events to process, do not wait for next tick!
 +    if (ret-1 > 0)
 +        monitorTimerTick();
 +</code>
 ====== References ====== ====== References ======
   * http://www.signal11.us/oss/udev/   * http://www.signal11.us/oss/udev/
projects/qtusb.txt · Last modified: 2014/07/06 21:34 by mkucia