RT-Thread论坛
直播中

徐伟

8年用户 1002经验值
私信 关注
[问答]

rt_can_write内_can_int_tx死循环是怎么回事?

环境:STM32f407 时钟频率168M CAN波特率1M
can配置如下:

  •     drv_can->CanHandle.Init.timeTriggeredMode = DISABLE;
  •     drv_can->CanHandle.Init.AutoBusOff = ENABLE;
  •     drv_can->CanHandle.Init.AutoWakeUp = DISABLE;
  •     drv_can->CanHandle.Init.AutoRetransmission = DISABLE;
  •     drv_can->CanHandle.Init.ReceiveFifoLocked = DISABLE;
  •     drv_can->CanHandle.Init.TransmitFifoPriority = ENABLE;


问题:
接了can设备时,使用正常
开发板拔掉can总线线后,或can设备不通电时,一直在这个函数内死循环。

  • rt_inline int _can_int_tx(struct rt_can_device *can, const struct rt_can_msg *data, int msgs)
  • {
  •     int size;
  •     struct rt_can_tx_fifo *tx_fifo;

  •     RT_ASSERT(can != RT_NULL);

  •     size = msgs;
  •     tx_fifo = (struct rt_can_tx_fifo *) can->can_tx;
  •     RT_ASSERT(tx_fifo != RT_NULL);

  •     while (msgs)
  •     {
  •         rt_base_t level;
  •         rt_uint32_t no;
  •         rt_uint32_t result;
  •         struct rt_can_sndbxinx_list *tx_tosnd = RT_NULL;

  •         rt_sem_take(&(tx_fifo->sem), RT_WAITING_FOREVER);
  •         level = rt_hw_interrupt_disable();
  •         tx_tosnd = rt_list_entry(tx_fifo->freelist.next, struct rt_can_sndbxinx_list, list);
  •         RT_ASSERT(tx_tosnd != RT_NULL);
  •         rt_list_remove(&tx_tosnd->list);
  •         rt_hw_interrupt_enable(level);

  •         no = ((rt_uint32_t)tx_tosnd - (rt_uint32_t)tx_fifo->buffer) / sizeof(struct rt_can_sndbxinx_list);
  •         tx_tosnd->result = RT_CAN_SND_RESULT_WAIT;
  •         if (can->ops->sendmsg(can, data, no) != RT_EOK)
  •         {//一直进入此条件内

  •             /* send failed. */
  •             level = rt_hw_interrupt_disable();
  •             rt_list_insert_after(&tx_fifo->freelist, &tx_tosnd->list);
  •             rt_hw_interrupt_enable(level);
  •             rt_sem_release(&(tx_fifo->sem));

  •             continue;
  •         }

  •         can->status.sndchange = 1;
  •         rt_completion_wait(&(tx_tosnd->completion), RT_WAITING_FOREVER);

  •         level = rt_hw_interrupt_disable();
  •         result = tx_tosnd->result;
  •         if (!rt_list_isempty(&tx_tosnd->list))
  •         {
  •             rt_list_remove(&tx_tosnd->list);
  •         }
  •         rt_list_insert_before(&tx_fifo->freelist, &tx_tosnd->list);
  •         rt_hw_interrupt_enable(level);
  •         rt_sem_release(&(tx_fifo->sem));

  •         if (result == RT_CAN_SND_RESULT_OK)
  •         {
  •             level = rt_hw_interrupt_disable();
  •             can->status.sndpkg++;
  •             rt_hw_interrupt_enable(level);

  •             data ++;
  •             msgs -= sizeof(struct rt_can_msg);
  •             if (!msgs) break;
  •         }
  •         else
  •         {
  •             level = rt_hw_interrupt_disable();
  •             can->status.dropedsndpkg++;
  •             rt_hw_interrupt_enable(level);
  •             break;
  •         }
  •     }

  •     return (size - msgs);
  • }




更多回帖

发帖
×
20
完善资料,
赚取积分