So I have a UART IRQ handler that is fired for each byte sent over UART, which then writes to a Fifo buffer and once the end of the data is detected, a callback is invoked which parses the data and signals the Main Thread to do stuff based on what's passed.

A few questions:

* If I have two producers that use UART for sending data, how should the situation of the interrupts from each producer occurring at the same time be dealt with? Say, the data is sent from producer A and producer B around the same time, given both are of the same priority, one of the interrupts will take the lead, and when it's done, the second one shall begin. Is this how it actually works?
* If it works as described above, I foresee the FIFO buffer getting "corrupted" in the sense that it could contain alternate characters from each producer assuming interrupts get fired at the same time or in an alternate sequence, as opposed to a whole word from each source separately. I guess the only way around would be to have FIFOs one for each source?

For e.g:

1. Producer A wants to send `"He"`
2. Producer B wants to send `"Hi"`

Both end up sending a byte at the same time

```
UART IRQ -> receives `'H'` from `Producer A`
UART IRQ -> receives `'H'` from `Producer B`
UART IRQ -> receives `'e'` from `Producer A`
UART IRQ -> receives `'i'` from `Producer B`

```

now the FIFO looks like -> `HHei` as opposed to `He` and `Hi` being processed separately.

* If there are multiple producers for the Fifo buffer, and assuming an ISR is triggered for each byte entered/sent, would there really be a need for mutex protection?

**For reference, [here's an example](https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.sdk5.v14.0.0%2Fble_sdk_app_nus_eval.html) of how nordic sends bytes from 2 producers, and each triggering the same IRQ:**

1. via a COM listener
2. via UART BLE Service.

Following is just an example for the context...

```
// main.cpp
Uart uart;

int main(void) {

  SystemTsk systemTsk(&uart);
  vTaskStartScheduler();    
}

// systemTsk.cpp
SystemTsk::SystemTsk(Uart &uart) : uart(uart)
{
    systemTaskQueue = xQueueCreate(queueSize, itemSize);
    if (systemTaskQueue == NULL)
    {
        // error handling
    }

    // create a task
    if (xTaskCreate(SystemTsk::run, "main", 256, this, 0, &taskHandle) != pdPASS)
    {
        // error handling
    }   
}

void SystemTsk::run(void *instance)
{
    auto pInstance = static_cast<SystemTsk*>(instance);
    pInstance->mainThread();
}

void SystemTsk::mainThread()
{   
  int data;
  while(true) 
  { 

     if (xQueueReceive(systemTaskQueue, &data, 0) == pdPASS) {
         // delegate stuff according to data
     }

  }
}
// uart.cpp
void UARTE0_UART0_IRQHandler(void)
{
   uartObj.irq();
}

void Uart::irq(void)
{ 
   // read into buffer etc
   if (endOfData) 
   { 
     uartCb(buffer);
   }
}

// uart_data.cpp
void parse(uint8_t buffer[])
{
  // parse the uart data...
}

void uartCb(uint8_t buffer[])
{ 
   // ...
   parse(buffer);
   // send the data to the queue to unblock the task via xQueueSendFromISR()

}

```