Search code examples
c++serial-communicationlibusb-1.0

C++ send data with libusb (working with RS 232)


I'm sending 199 151 2 3 3 7 63 173 174 block to serial port and got success. But when i do it with libusb nothing happens. No error or nothing happens.

here how i send data to serial (RS 232):

unsigned char data[9];
//filling data
RS232_cputs(comportNumber, &data[0], 9); //success

here how i send data to usb

//endPointAdressIn = 2;
//timeout = 0;

for( int i = 0; i < 9; i++ )
{
     libusb_bulk_transfer(deviceHandle, endPointAdressIn , data, 3, &actual, timeout);
}

Is there a protocol difference between usb and serial RS? If i send same data serial and usb, cant i get success?

I've found something like that:

when they send data to serial, sending char by char. when i sending it serial i also do like that. But they send same data to usb they'are adding two chars for each: for 199 151 2 3 3 7 63 173 174 data, they are sending 2 1 199 2 1 151 2 1 2 2 1 3 2 1 3 2 1 7 2 1 6 2 1 3 2 1 173 2 1 174

They'are i also tried it like that:

transferredData[0]=0x02;
transferredData[1]=0x01;

for( int i = 0; i < 9; i++ )
{
    transferredData[2] = data[i];

    return_value = libusb_bulk_transfer(deviceHandle, endPointAdressIn , transferredData, 3, &actual, 0);        
}

i have added 2, 1 for each my data member and i send it like that. And also nothing happened. No error or nothing in my hardware.

So what am i doing wrong?


Solution

  • USB devices implement USB device classes in their firmware a Virtual COM port ( USB serial ) device implements USB CDC ACM device class ( https://en.wikipedia.org/wiki/USB_communications_device_class ) . the operating system loads drivers / kernel modules that fit the device class(es), i.e. linux loads usb-serial for a virtual com port, the source code is in https://elixir.free-electrons.com/linux/v3.5/source/drivers/usb/serial/usb-serial.c

    so the kernel module internally uses bulk transfers however in a way that is compliant with the device firmware of the USB-to-serial device ( USB CDC ACM device class )

    a usb device does not implement all possible functionalities ( device classes ), some implement multiple device classes ( https://en.wikipedia.org/wiki/USB#Device_classes ), in this case can be switched between the functionalities via usb interfaces i.e. a smartphone implements mass storage, PTP, MTP, CDC ( RNDIS (tethering ) ),...

    when you try to write bulk transfers over a CDC ACM device you 1. get problems with the os driver /kernel module that is automatically loaded ( you have at least to unload it ) 2. get problems with the device firmware, because your bulk transfers have to be compliant with the device firmware

    you can choose endpoints on the device and write bulk transfers to them however if you do not know what the device firmware does with your bulk trnasfers this is not very reasonable, this is why the standardized USB device classes exist

    or for short, it is very difficult to use a bare USB device reasonably ( bare means without a kernel module, or at least without knowledge about the device firmware )

    USB is a complicated protocol ( RS-232 / serial is relatively easy ) because USB is very variable, universal ( can connect all sorts of devices : cameras, smartphones, printers, mass storage, ... ) and this variability brings complexity

    there is NO usb device without a microcontroller running a firmware on it because the complexity of the USB protocol requires this ...

    a good summary of USB protocol is in http://www.beyondlogic.org/usbnutshell/usb1.shtml