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
    Posts
  • #58814
    Member
    sterretje

      Hello

      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.close()
      else:
        f = open(port)
        attrs = termios.tcgetattr(f)
        attrs[2] = attrs[2] | termios.HUPCL
        termios.tcsetattr(f, termios.TCSAFLUSH, attrs)
        f.close()
      
      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
        ser.open()
      
      # read initial Arduino message
        s = ser.read(20)
        print(s)
      
      # send some data to be echoed
      # b is needed for python3
        ser.write(b'hello world')
        s = ser.read(20)
        print(s)
      
      ser.close()
      

      lsusb

      
      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
      

      dmesg

      
      [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:
      1)
      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?
      2)
      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?
      3)
      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 2 years ago by sterretje.
      #58818
      Member
      Xecure
        Helpful
        Up
        0
        ::

        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).

        antiX Live system enthusiast.
        General Live Boot Parameters for antiX.

        #58953
        Member
        sterretje
          Helpful
          Up
          0
          ::

          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.