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

[DeviceDriver] Fix can infinite loop when can driver send error

 - in _can_int_tx if can driver sendmsg do not return RT_EOK,
   it will repeat until sendmsg return RT_EOK
 - if error occur on can bus(wire broken or EMI), all threads that
   have lower priority will not be executed
 - we should let application layer to determine if resend is appropriate
   when send fail, besides in data link layer, can already implemented
   auto resend in hardware
gbcwbz 3 лет назад
Родитель
Сommit
84fe80fbf9
1 измененных файлов с 3 добавлено и 2 удалено
  1. 3 2
      components/drivers/can/can.c

+ 3 - 2
components/drivers/can/can.c

@@ -158,10 +158,10 @@ rt_inline int _can_int_tx(struct rt_can_device *can, const struct rt_can_msg *da
         {
         {
             /* send failed. */
             /* send failed. */
             level = rt_hw_interrupt_disable();
             level = rt_hw_interrupt_disable();
-            rt_list_insert_after(&tx_fifo->freelist, &tx_tosnd->list);
+            rt_list_insert_before(&tx_fifo->freelist, &tx_tosnd->list);
             rt_hw_interrupt_enable(level);
             rt_hw_interrupt_enable(level);
             rt_sem_release(&(tx_fifo->sem));
             rt_sem_release(&(tx_fifo->sem));
-            continue;
+            goto err_ret;
         }
         }
 
 
         can->status.sndchange = 1;
         can->status.sndchange = 1;
@@ -189,6 +189,7 @@ rt_inline int _can_int_tx(struct rt_can_device *can, const struct rt_can_msg *da
         }
         }
         else
         else
         {
         {
+err_ret:
             level = rt_hw_interrupt_disable();
             level = rt_hw_interrupt_disable();
             can->status.dropedsndpkg++;
             can->status.dropedsndpkg++;
             rt_hw_interrupt_enable(level);
             rt_hw_interrupt_enable(level);