Hacking ttyACM and ttyUSB

Forum Forums General Software Hacking ttyACM and ttyUSB

  • This topic has 2 replies, 2 voices, and was last updated May 8-6:18 pm by sterretje.
Viewing 3 posts - 1 through 3 (of 3 total)
  • Author
  • #58814


    I work with Arduinos (embedded computers) and (hence) I seem to be in need of hacking ttyACM and ttyUSB. The problem is that if a serial port is opened on one of those, the DTR line is asserted which will reset the Arduinos. I’ve done some research and came up with a python script that partially prevents this from happening.

    import sys
    import serial
    import termios
    # print some python info for fun
    print("Python version")
    print (sys.version)
    print("Version info.")
    print (sys.version_info)
    # define the port
    port = '/dev/ttyUSB0'
    #port = '/dev/ttyACM0'
    resetPort = False
    if resetPort == False:
    # to be able to suppress DTR, we need this
      f = open(port)
      attrs = termios.tcgetattr(f)
      attrs[2] = attrs[2] & ~termios.HUPCL
      termios.tcsetattr(f, termios.TCSAFLUSH, attrs)
      f = open(port)
      attrs = termios.tcgetattr(f)
      attrs[2] = attrs[2] | termios.HUPCL
      termios.tcsetattr(f, termios.TCSAFLUSH, attrs)
    with serial.Serial() as ser:
    # setup serial port
      ser.baudrate = 57600
      ser.port = port
      ser.rtscts = False            # not setting to false prevents communication
      ser.dsrdtr = resetPort        # determines if Arduino resets or not
      ser.timeout = 2
    # print settings
      print (ser.name)
      print (ser)
    # open serial port
    # read initial Arduino message
      s = ser.read(20)
    # send some data to be echoed
    # b is needed for python3
      ser.write(b'hello world')
      s = ser.read(20)


    Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
    Bus 004 Device 008: ID 0403:6001 Future Technology Devices International, Ltd FT232 Serial (UART) IC
    Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
    Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
    Bus 002 Device 011: ID 2a03:0043 dog hunter AG Arduino Uno Rev3
    Bus 002 Device 010: ID 1a86:7523 QinHeng Electronics HL-340 USB-Serial adapter
    Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub


    [45908.623134] usb 2-1: new full-speed USB device number 10 using uhci_hcd
    [45908.778166] usb 2-1: New USB device found, idVendor=1a86, idProduct=7523
    [45908.778171] usb 2-1: New USB device strings: Mfr=0, Product=2, SerialNumber=0
    [45908.778174] usb 2-1: Product: USB2.0-Serial
    [45908.780329] ch341 2-1:1.0: ch341-uart converter detected
    [45908.793302] usb 2-1: ch341-uart converter now attached to ttyUSB0
    [45912.847140] usb 4-1: new full-speed USB device number 8 using uhci_hcd
    [45913.034166] usb 4-1: New USB device found, idVendor=0403, idProduct=6001
    [45913.034172] usb 4-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
    [45913.034177] usb 4-1: Product: FT232R USB UART
    [45913.034180] usb 4-1: Manufacturer: FTDI
    [45913.034184] usb 4-1: SerialNumber: A5025WMS
    [45913.041298] ftdi_sio 4-1:1.0: FTDI USB Serial Device converter detected
    [45913.041412] usb 4-1: Detected FT232RL
    [45913.043313] usb 4-1: FTDI USB Serial Device converter now attached to ttyUSB1
    [45915.607101] usb 2-2: new full-speed USB device number 11 using uhci_hcd
    [45915.795100] usb 2-2: New USB device found, idVendor=2a03, idProduct=0043
    [45915.795107] usb 2-2: New USB device strings: Mfr=1, Product=2, SerialNumber=220
    [45915.795111] usb 2-2: Product: Arduino Uno
    [45915.795115] usb 2-2: Manufacturer: Arduino Srl
    [45915.795118] usb 2-2: SerialNumber: 754393332353518081A1
    [45915.798332] cdc_acm 2-2:1.0: ttyACM0: USB ACM device

    With the earlier given python script, the FTDI and the dog hunter only assert DTR the very first time that the serial port is opened after the boards are connected; successive opening/closing does not result in assertion of DTR. The behaviour of the CH340 did not seem to change with the above script.

    I found https://unix.stackexchange.com/questions/446088/how-to-prevent-dtr-on-open-for-cdc-acm which describes how to hack cdc-acm and have questions:
    Is https://github.com/torvalds/linux/tree/7876320f88802b22d4e2daf7eb027dd14175a0f8/drivers/usb/class still the correct source code for ttyACM? Or does Antix have it’s own version somewhere?
    I will follow https://tldp.org/LDP/lkmpg/2.6/html/x181.html to created the module. Do I need to do rmmod before running insmod?
    And lastly I’m looking for a similar hack for ttyUSB; where can I find the source code?

    Sorry for the long story, tried to be as complete as possible but might have gotten carried away.
    Thanks in advance.

    • This topic was modified 1 month, 2 weeks ago by sterretje.

    antiX’ kernel is compiled directly from the official linux kernel, with some variations (but for your case it should be the same).
    All sources are available on the antiX repo or any other mirror to the repo.
    An example for all kernels in antiX 19: https://repo.antixlinux.com/buster/pool/main/l/
    And more specifically for the latest 4.9.0-264 (64 bits), the source is inside the linux-4.9.0-264-antix.1-amd64-smp_4.9.0-264-antix.1-amd64-smp.orig.tar.gz file.

    I have never created my own module, but I have compiled a custom kernel (with modifications) before, so it is doable. I download and uncompressed the source, edit the files, edit the config to create a new name for the kernel (to not confuse with antiX kernel name), build the .debs and then install the .debs for linux-image and linux-header. Probably creating and compiling a module as you have pointed out should be easier.

    There seems to be a lot of discussion on the arduino forums, for example here: https://forum.arduino.cc/t/the-linux-ttyacm0-drama-more-details-after-a-lot-of-experimenting/126927
    Where they also mention uninstalling modemmanager (installed in antiX).


    Thanks Xecure

    I had forgotten about modemmanager; but that will result in blocked ports.

    I’ve now upgraded the kernel as I could not straight away find the source code for the .235 kernel. Not really prepared to download the full kernel source; but it might be easier to find what I’m looking for if I do so.

    Anyway, question not answered was if I had to do a rmmod before an insmod?

    Thanks again.

Viewing 3 posts - 1 through 3 (of 3 total)
  • You must be logged in to reply to this topic.