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
Last revisionBoth sides next revision
projects:qtusb [2013/06/01 23:26] – [Linux] mkuciaprojects:qtusb [2013/06/04 23:23] – [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 50: Line 45:
   * [[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 174: Line 168:
 </code> </code>
 ===== Linux ===== ===== Linux =====
-I am using Debian 6.0.(virtual machine)+{{:projects:qt_usb_linux.png |}} 
 +I am using Debian 7 with LXDE
  
 We cannot use windows-specific routines under Linux. To check if device is connected or not we will pool udev monitor.  We cannot use windows-specific routines under Linux. To check if device is connected or not we will pool udev monitor. 
Line 182: Line 177:
 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", NAME="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.txt · Last modified: 2014/07/06 21:34 by mkucia