环境:
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);
- }