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 revision
Previous revision
projects:qtusb [2013/06/02 15:44] – [Linux] mkuciaprojects:qtusb [2014/07/06 21:34] (current) – [Developing multi-platform USB applications with Qt] mkucia
Line 1: Line 1:
 ====== Developing multi-platform USB applications with Qt ====== ====== Developing multi-platform USB applications with Qt ======
  
-//24.05.2013 Freising, Germany// +//Germany 24.05.2013//
- +
-<WRAP center todo> +
-This page is under construction +
-</WRAP> +
  
 <WRAP column 60px> <WRAP column 60px>
 <html> <html>
-<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- Created with Inkscape (http://www.inkscape.org/) --> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.0" width="59.696404" height="117.03584" id="svg2"> <metadata id="metadata10"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:title></dc:title> </cc:Work> </rdf:RDF> </metadata> <defs id="defs4" /> <g transform="translate(-113.88396,-59.934988)" id="layer1"> <g transform="translate(432,-133)" id="g2396"> <g transform="matrix(0.5,0,0,0.5,-144.13392,125.72645)" id="g3855"> <path d="m -286.94644,276.07647 c 2.25641,0 2.375,-0.32456 2.375,-6.5 0,-5.78113 -0.21599,-6.5 -1.95295,-6.5 -3.70388,0 -6.85214,-2.24136 -8.60347,-6.12513 -0.96609,-2.14239 -1.57361,-4.03559 -1.35005,-4.2071 0.22356,-0.17151 2.53288,-1.52939 5.13182,-3.01751 12.90306,-7.38812 18.68728,-23.96169 18.72409,-53.65026 0.0443,-35.70973 -8.94704,-52.63835 -30.26591,-56.98381 -6.70354,-1.3664 -14.30708,-0.63312 -20.27292,1.95511 -8.91148,3.86617 -15.69871,14.21474 -19.03883,29.0287 -2.37545,10.5355 -2.34662,39.37509 0.0505,50.5 3.51644,16.31976 11.81536,28.41254 21.77764,31.7333 3.68933,1.22977 4.20364,1.83831 5.7544,6.80859 2.41185,7.73016 4.56676,11.48088 8.00116,13.92639 3.43513,2.44602 10.23575,4.07656 14.41955,3.45728 C -290.61516,276.26797 -288.25266,276.07647 -286.94641,276.07647 z m -22.60906,-37.30473 c -3.04896,-1.52007 -6.70937,-6.83665 -7.98395,-11.59631 -4.16759,-15.56307 -3.81851,-54.0943 0.58989,-65.11198 2.00113,-5.00129 6.62237,-8.98698 10.42005,-8.98698 4.20244,0 9.48751,5.06719 11.45111,10.97905 3.47238,10.45434 4.05746,45.54877 1.00529,60.29934 C -296.49997,236.08345 -302.93276,242.07353 -309.5555,238.77174 z m 66.98406,7.25641 c 9.46242,-2.10155 10,-2.56605 10,-8.64039 0,-4.71812 -0.23391,-5.37657 -1.75,-4.92617 -5.99778,1.78186 -7.39498,1.79365 -9.29029,0.0784 -1.84998,-1.6742 -1.95971,-3.22064 -1.95971,-27.61852 l 0,-25.84501 6,0 6,0 0,-5.87083 0,-5.87084 -6,-0.67882 -6,-0.67882 0,-9.39133 c 0,-5.16523 -0.3375,-9.59681 -0.75,-9.84796 -0.4125,-0.25114 -2.9657,-0.6152 -5.67377,-0.80901 l -4.92378,-0.35239 -1.71558,7 c -0.94357,3.85 -1.99895,8.2375 -2.34528,9.75 -0.53873,2.35272 -1.13256,2.75 -4.11064,2.75 l -3.48095,0 0,6.5 0,6.5 3,0 3,0 0,29.03984 c 0,35.48318 0.3987,36.84529 11.5,39.28807 C -247.87899,247.10685 -247.31626,247.08194 -242.57144,246.02814 Z" id="path2400" style="fill:#7cc040" /> <path d="m -302.57962,364.48874 8.94276,-15.48548 -6.37933,0 0,-79.15064 16.2824,15.41153 c 1.05131,1.31158 1.7888,3.02765 1.82965,4.79292 0,7.14127 0.002,11.38209 0.005,12.94311 -3.01465,1.05811 -5.19061,3.90039 -5.19061,7.2793 0,4.27454 3.46866,7.74351 7.74476,7.74351 4.27795,0 7.74537,-3.46866 7.74537,-7.74351 0,-3.37891 -2.17472,-6.22119 -5.18689,-7.2793 l 0.002,-12.79146 c 0,-3.4668 -1.90207,-7.09949 -4.13187,-9.41162 0.0662,0.0631 0.13679,0.12874 -10e-4,-0.004 -0.0551,-0.0489 -17.27336,-16.35111 -17.27336,-16.35111 -1.04976,-1.30879 -1.78261,-3.02394 -1.8247,-4.78798 l 0,-8.95389 -5.1151,0.001 0,8.79699 c 0,0.0226 -10e-4,0.0452 0,0.0681 l 0,19.45737 c -0.0449,1.76063 -0.77865,3.47361 -1.82965,4.78116 0,0 -17.21703,16.2985 -17.27274,16.34894 -0.13834,0.1306 -0.0662,0.0656 -10e-4,10e-4 -2.2295,2.31213 -4.13033,5.94636 -4.13033,9.41379 l 0.003,12.32723 -5.19216,0 0,15.48952 15.48796,0 0,-15.48952 -5.18535,0 c 0,0 0.006,-3.24676 0.006,-12.47826 0.0405,-1.76559 0.77711,-3.48352 1.82842,-4.79448 l 16.28549,-15.41492 0,59.79447 L -311.52044,349.00275 Z" id="path1334" style="fill:#7cc040;fill-opacity:1" /> </g> </g> </g> </svg> +<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.0" width="59.696404" height="117.03584" id="svg2"> <metadata id="metadata10"> <rdf:RDF> <cc:Work rdf:about=""> <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> <dc:title></dc:title> </cc:Work> </rdf:RDF> </metadata> <defs id="defs4" /> <g transform="translate(-113.88396,-59.934988)" id="layer1"> <g transform="translate(432,-133)" id="g2396"> <g transform="matrix(0.5,0,0,0.5,-144.13392,125.72645)" id="g3855"> <path d="m -286.94644,276.07647 c 2.25641,0 2.375,-0.32456 2.375,-6.5 0,-5.78113 -0.21599,-6.5 -1.95295,-6.5 -3.70388,0 -6.85214,-2.24136 -8.60347,-6.12513 -0.96609,-2.14239 -1.57361,-4.03559 -1.35005,-4.2071 0.22356,-0.17151 2.53288,-1.52939 5.13182,-3.01751 12.90306,-7.38812 18.68728,-23.96169 18.72409,-53.65026 0.0443,-35.70973 -8.94704,-52.63835 -30.26591,-56.98381 -6.70354,-1.3664 -14.30708,-0.63312 -20.27292,1.95511 -8.91148,3.86617 -15.69871,14.21474 -19.03883,29.0287 -2.37545,10.5355 -2.34662,39.37509 0.0505,50.5 3.51644,16.31976 11.81536,28.41254 21.77764,31.7333 3.68933,1.22977 4.20364,1.83831 5.7544,6.80859 2.41185,7.73016 4.56676,11.48088 8.00116,13.92639 3.43513,2.44602 10.23575,4.07656 14.41955,3.45728 C -290.61516,276.26797 -288.25266,276.07647 -286.94641,276.07647 z m -22.60906,-37.30473 c -3.04896,-1.52007 -6.70937,-6.83665 -7.98395,-11.59631 -4.16759,-15.56307 -3.81851,-54.0943 0.58989,-65.11198 2.00113,-5.00129 6.62237,-8.98698 10.42005,-8.98698 4.20244,0 9.48751,5.06719 11.45111,10.97905 3.47238,10.45434 4.05746,45.54877 1.00529,60.29934 C -296.49997,236.08345 -302.93276,242.07353 -309.5555,238.77174 z m 66.98406,7.25641 c 9.46242,-2.10155 10,-2.56605 10,-8.64039 0,-4.71812 -0.23391,-5.37657 -1.75,-4.92617 -5.99778,1.78186 -7.39498,1.79365 -9.29029,0.0784 -1.84998,-1.6742 -1.95971,-3.22064 -1.95971,-27.61852 l 0,-25.84501 6,0 6,0 0,-5.87083 0,-5.87084 -6,-0.67882 -6,-0.67882 0,-9.39133 c 0,-5.16523 -0.3375,-9.59681 -0.75,-9.84796 -0.4125,-0.25114 -2.9657,-0.6152 -5.67377,-0.80901 l -4.92378,-0.35239 -1.71558,7 c -0.94357,3.85 -1.99895,8.2375 -2.34528,9.75 -0.53873,2.35272 -1.13256,2.75 -4.11064,2.75 l -3.48095,0 0,6.5 0,6.5 3,0 3,0 0,29.03984 c 0,35.48318 0.3987,36.84529 11.5,39.28807 C -247.87899,247.10685 -247.31626,247.08194 -242.57144,246.02814 Z" id="path2400" style="fill:#7cc040" /> <path d="m -302.57962,364.48874 8.94276,-15.48548 -6.37933,0 0,-79.15064 16.2824,15.41153 c 1.05131,1.31158 1.7888,3.02765 1.82965,4.79292 0,7.14127 0.002,11.38209 0.005,12.94311 -3.01465,1.05811 -5.19061,3.90039 -5.19061,7.2793 0,4.27454 3.46866,7.74351 7.74476,7.74351 4.27795,0 7.74537,-3.46866 7.74537,-7.74351 0,-3.37891 -2.17472,-6.22119 -5.18689,-7.2793 l 0.002,-12.79146 c 0,-3.4668 -1.90207,-7.09949 -4.13187,-9.41162 0.0662,0.0631 0.13679,0.12874 -10e-4,-0.004 -0.0551,-0.0489 -17.27336,-16.35111 -17.27336,-16.35111 -1.04976,-1.30879 -1.78261,-3.02394 -1.8247,-4.78798 l 0,-8.95389 -5.1151,0.001 0,8.79699 c 0,0.0226 -10e-4,0.0452 0,0.0681 l 0,19.45737 c -0.0449,1.76063 -0.77865,3.47361 -1.82965,4.78116 0,0 -17.21703,16.2985 -17.27274,16.34894 -0.13834,0.1306 -0.0662,0.0656 -10e-4,10e-4 -2.2295,2.31213 -4.13033,5.94636 -4.13033,9.41379 l 0.003,12.32723 -5.19216,0 0,15.48952 15.48796,0 0,-15.48952 -5.18535,0 c 0,0 0.006,-3.24676 0.006,-12.47826 0.0405,-1.76559 0.77711,-3.48352 1.82842,-4.79448 l 16.28549,-15.41492 0,59.79447 L -311.52044,349.00275 Z" id="path1334" style="fill:#7cc040;fill-opacity:1" /> </g> </g> </g> </svg> 
 </html> </html>
 </WRAP> </WRAP>
Line 44: Line 39:
  
 libusbx supports Windows, Linux, MacOS X, OpenBSD and NetBSD. Multiple language bindings exist including Python and C<sup>#</sup>. libusbx supports Windows, Linux, MacOS X, OpenBSD and NetBSD. Multiple language bindings exist including Python and C<sup>#</sup>.
 +
 +<WRAP center important>
 +2014-07-06: libusbx was merged back to libusb project. See [[http://libusbx.1081486.n5.nabble.com/Libusbx-devel-Announcing-libusb-1-0-18-as-well-as-libusbx-1-0-18-FINAL-td2375.html| this post]].
 +</WRAP>
 +
  
 === What about VID/PID? === === What about VID/PID? ===
Line 50: Line 50:
   * [[http://www.usb.org/developers/usbfaq#12| USB.org How do I get a USB VID, TID and PID?]]   * [[http://www.usb.org/developers/usbfaq#12| USB.org How do I get a USB VID, TID and PID?]]
   * [[http://www.ti.com/mcu/docs/mcuorphan.tsp?contentId=72713&DCMP=STELLARIS&| TI Stellaris USB VID/PID Sublicense Application]]   * [[http://www.ti.com/mcu/docs/mcuorphan.tsp?contentId=72713&DCMP=STELLARIS&| TI Stellaris USB VID/PID Sublicense Application]]
- 
 ====== Software ====== ====== Software ======
  
Line 183: Line 182:
 If true plug-and-play is required it is better to use standard USB class (for example CDC). If true plug-and-play is required it is better to use standard USB class (for example CDC).
  
-Qt Linux source code [TODO]+ {{:projects:usb_gui.zip|Qt Linux source code}}
  
-==== Building libusbx ====+==== Linking libraries ==== 
 +If your system is up-to-date you will most likely have both libraries installed. You can link them using following qmake code: 
 +<code> 
 +LIBS += -L/usr/local/lib/ -lusb-1.0 
 +LIBS += -L/usr/lib/ -ludev 
 +</code> 
 +==== udev rules ====
  
 +Create a rule for device by making a new file:
  
-  - Download the code from libusbx source forge download page +  nano /etc/udev/rules.d/usb_led_bulk.rules
-  - Extract files +
-  - Run standard sequence: +
-    - ''./configure'' +
-    - ''make'' +
-    - ''make install''+
  
-After that user should find ''libusb-1.0.a'' in local libraries catalog ''/usr/local/lib''+with following content:
  
-It might be necessary to install required packagessee README.+  SUBSYSTEMS=="usb"ATTRS{idVendor}=="1cbe", ATTRS{idProduct}=="0003", GROUP="users", MODE="0666", SYMLINK+="rgb_led"
  
 +This will allow non-root users to access the device. Also device will be accessible through path ''/dev/rgb_led''
  
-==== Building systemd (libudev) ==== +Restart udev service for changes to take effect ''/etc/init.d/udev restart''
-  - Download most recent source from http://www.freedesktop.org/software/systemd/ +
-  - Extract +
-  - Go to project directory +
-  - Build library (additional packages might be required I had to build libdbus, see README): +
-    - ''./configure'' +
-    - ''make'' +
-    - ''make install'' +
-TODO+
  
-==== udev Rules ====+There are more actions that udev rules can implement. For example launching application when device is connected.
  
-TODO 
  
-Start with creating a rule for device +==== Detecting device mount/remove ====
-  nano /etc/udev/rules.d/usb_led_bulk.rules+
  
-  SUBSYSTEMS=="usb", ATTRS{idVendor}=="1cbe", ATTRS{idProduct}=="0003", GROUP="users", MODE="0666", SYMLINK+="rgb_led"+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. 
  
-This will allow non-root users to access the device. Also device will be accessible through path ''/dev/rgb_led''+<code=c> 
 +// Create the udev object 
 +if (!(udev = udev_new())) 
 +[..]
  
-Restart udev service for changes to take effect ''/etc/init.d/udev restart''+// 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 messageselect() 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://libusbx.sourceforge.net/api-1.0/
 +
   * http://www.signal11.us/oss/udev/   * http://www.signal11.us/oss/udev/
   * http://www.freedesktop.org/software/systemd/libudev/   * http://www.freedesktop.org/software/systemd/libudev/
 +  * http://linux.die.net/man/8/udevadm
 +
   * http://www.linuxforu.com/2012/06/some-nifty-udev-rules-and-examples/   * http://www.linuxforu.com/2012/06/some-nifty-udev-rules-and-examples/
   * http://www.reactivated.net/writing_udev_rules.html   * http://www.reactivated.net/writing_udev_rules.html
-  * http://linux.die.net/man/8/udevadm 
   * http://hackaday.com/2009/09/18/how-to-write-udev-rules/   * http://hackaday.com/2009/09/18/how-to-write-udev-rules/
 +
 +  * http://msdn.microsoft.com/en-us/library/windows/hardware/gg463179.aspx
  
 <WRAP todo> <WRAP todo>
   * Build single software package for MCU, Win and Linux   * Build single software package for MCU, Win and Linux
-  * add more references 
 </WRAP> </WRAP>
projects/qtusb.1370180687.txt.gz · Last modified: 2013/06/02 15:44 by mkucia