title: How are virtual COM/Serial ports managed by operating system?
body: <p>I'm currenty working on an interface between arduino and raspberry pi. The arduino is connected via usb cable to the Rasbperry Pi. The Arduino has an LED connected to a digital Pin that may be turned on and off by sending specified bytes over the USB serial connection. The Raspberry Pi then runs the following python script:</p>
  <pre class="lang-py prettyprint-override"><code>import serial
  import time
  
  arduino = serial.Serial('/dev/ttyACM0', baudrate=115200, timeout=.1)
  time.sleep(2)
  start = time.time()
  
  for _ in range(10):
      arduino.write(bytes([0x58])) //Turns LED on (on Arduino)
      print(time.time()-start,'on')
      time.sleep(.5)
      arduino.write(bytes([0x18])) //Turns LED off (on Arduino)
      print(time.time()-start,'off')
      time.sleep(.5)
  
  arduino.write(spam_the_COM_port) # will let the arduino start sending 
                                   # infinite amout of bytes
  print('started spamming')
  
  for _ in range(10):
      arduino.write(turn_led_on) #Actual byte is 0x58
      print(time.time()-start,'on')
      time.sleep(.5)
      arduino.write(turn_led_off) #Actual byte is 0x18
      print(time.time()-start,'off')
      time.sleep(.5)
  </code></pre>
  <p>So I'm switching on and off an LED that is connected to an arduino by sending it the specified bytes: 0x58 and 0x18 The Arduino runs code that looks like this:</p>
  <pre class="lang-cpp prettyprint-override"><code>bool spamming = false;
  
  void setup()
  {
    Serial.begin(115200);
    pinMode(24, OUTPUT);
  }
  
  void loop()
  {
     while(Serial.available() &gt; 0)
     {
        unsigned char x = Serial.read();
        if (x == 0x58)
        { 
           digitalWrite(24, HIGH); //Turn on LED
        }
        else if (x == 0x18)
        {
           digitalWrite(24, LOW);  //Turn off LED
        }
        else if (x == 0x00)
        {
            spamming = true;
        }
     }
     if (spamming)
     {
        if (Serial.avialiableForWrite() &gt; 0) Serial.write(0x01);
     }
  }
  </code></pre>
  <p>I get the expected result (which is just the console printing on and off 10 times (on the raspberry side) and the Arduino actually turning the LED on and off 10 times in a row.</p>
  <p>I then send a command that will make the Arduino start sending an infinite amount of bytes to the Raspberry Pi whilst still checking the Serial incoming buffer for new commands. After that I repeat the same process as before and try to send the LED switching command.</p>
  <p>Now the python console output stays the same (runs without any error raising), yet the program blocks at each arduino.write() command for a long time (around 10s or longer) even though there is a timeout specified (0.1s). After blocking, the console prints as usual and the LED on the arduino switches as usual. I just added timesamps to the python console output and the results look like this:</p>
  <pre><code>2.002582311630249 on
  2.502887725830078 off
  3.003848075866699 on
  3.5050783157348633 off
  4.005117177963257 on
  4.5058839321136475 off
  5.006282806396484 on
  5.50661826133728 off
  6.008156776428223 on
  6.509922504425049 off
  7.010948181152344 on
  7.512096166610718 off
  8.012341737747192 on
  8.513236999511719 off
  9.013462543487549 on
  9.514604091644287 off
  10.015231370925903 on
  10.515642404556274 off
  11.01583743095398 on
  11.516374349594116 off
  started spamming
  12.018024444580078 on
  12.518478155136108 off
  13.01881217956543 on
  13.519550085067749 off
  28.621582508087158 on
  44.68230104446411 off
  57.40802550315857 on
  63.064852714538574 off
  65.58953928947449 on
  68.61984610557556 off
  77.50833535194397 on
  96.19384908676147 off
  102.6581130027771 on
  109.2223105430603 off
  132.55511474609375 on
  155.684588432312 off
  171.44103860855103 on
  185.78372859954834 off
  199.51972341537476 on
  216.58949422836304 off
  </code></pre>
  <p>So the problem must be on the raspberry pi. I tried the same code on my windows machine (plugging the arduino in there of course) and the same thing happened, which led to the conclusion that it must have something to do with the virtual COM/Serial port.</p>
  <p>So now to the actual question: Why does it take so long for the serial.write() function to write something to the output buffer (on the pi) when the input buffer (on the pi) is beeing spammed by the arduino?
  As far as I know, a UART Chip has two physically seperate buffers that are completely independent. Does a virtual COM port not have this independence of the two buffers? (Maybe just some allocated memory for both of them in a stack-heap kind of way?) Or is the problem that USB 1.0 and 2.0 are only half-duplex?
  (And then lastly is there a way to fix the fucntion block?)</p>
  <p>[update]
  I managed to stop the function from blocking by adding</p>
  <pre class="lang-py prettyprint-override"><code>if arduino.inWaiting() &gt;  1000: arduino.flushInput()
  </code></pre>
  <p>before every <code>arduino.write()</code> statement. I'm still interested in how the Serial/COM port is managed by the operating system, be it linux/raspbian or windows.</p>