Просмотр исходного кода

nrf5x: Fix EP OUT race conditions in OS build

When two tasks entered dcd_edpt_xfer() it was possible that
first disabled interrupt to setup total_len and actual_len
but second task for another endpoint enabled interrupt
between total_len and actual_len resulting in race
condition with interrupt, hence mutex is added on top of interrupt being blocked.
Jerzy Kasenberg 4 лет назад
Родитель
Сommit
36b6ed8ff9
1 измененных файлов с 8 добавлено и 2 удалено
  1. 8 2
      src/portable/nordic/nrf5x/dcd_nrf5x.c

+ 8 - 2
src/portable/nordic/nrf5x/dcd_nrf5x.c

@@ -463,11 +463,17 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
 
 
   xfer_td_t* xfer = get_td(epnum, dir);
   xfer_td_t* xfer = get_td(epnum, dir);
 
 
-  dcd_int_disable(rhport);
+  if (!is_in_isr()) {
+    osal_mutex_lock(dcd_mutex, OSAL_TIMEOUT_WAIT_FOREVER);
+    dcd_int_disable(rhport);
+  }
   xfer->buffer     = buffer;
   xfer->buffer     = buffer;
   xfer->total_len  = total_bytes;
   xfer->total_len  = total_bytes;
   xfer->actual_len = 0;
   xfer->actual_len = 0;
-  dcd_int_enable(rhport);
+  if (!is_in_isr()) {
+    dcd_int_enable(rhport);
+    osal_mutex_unlock(dcd_mutex);
+  }
 
 
   // Control endpoint with zero-length packet and opposite direction to 1st request byte --> status stage
   // Control endpoint with zero-length packet and opposite direction to 1st request byte --> status stage
   bool const control_status = (epnum == 0 && total_bytes == 0 && dir != tu_edpt_dir(NRF_USBD->BMREQUESTTYPE));
   bool const control_status = (epnum == 0 && total_bytes == 0 && dir != tu_edpt_dir(NRF_USBD->BMREQUESTTYPE));