mirror of
https://github.com/apache/nuttx.git
synced 2025-12-08 10:55:51 +08:00
drivers/can/kvaser_pci.c: configure number of passes in interrupt handler
Configure number of passes in interrupt handler logic to avoid losing RX frames in QEMU environment. Signed-off-by: p-szafonimateusz <p-szafonimateusz@xiaomi.com>
This commit is contained in:
committed by
Donny(董九柱)
parent
e2cdb7ef34
commit
4ed174a7e0
@@ -273,6 +273,16 @@ config CAN_KVASER
|
||||
|
||||
if CAN_KVASER
|
||||
|
||||
config CAN_KVASER_IRQ_PASSES
|
||||
int "Kvaser PCI interrupt passes"
|
||||
default 16
|
||||
range 1 512
|
||||
---help---
|
||||
This option sets how many times the card status will be checked
|
||||
during one interrupt handler. A value greater than 1 helps avoid
|
||||
data loss when there is a lot of traffic on the CAN bus.
|
||||
The downside is that it increases the interrupt service time.
|
||||
|
||||
choice
|
||||
prompt "Kvaser PCI CAN device type"
|
||||
default CAN_KVASER_CHARDEV if CAN
|
||||
|
||||
@@ -946,36 +946,37 @@ static void kvaser_chardev_interrupt(FAR struct kvaser_driver_s *priv)
|
||||
{
|
||||
uint8_t st = 0;
|
||||
int i = 0;
|
||||
int passes;
|
||||
|
||||
for (i = 0; i < priv->count; i++)
|
||||
for (passes = 0; passes < CONFIG_CAN_KVASER_IRQ_PASSES; passes++)
|
||||
{
|
||||
st = kvaser_getreg_sja(&priv->sja[i], SJA1000_INT_RAW_REG);
|
||||
if (st == 0)
|
||||
for (i = 0; i < priv->count; i++)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
st = kvaser_getreg_sja(&priv->sja[i], SJA1000_INT_RAW_REG);
|
||||
if (st == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Receive interrupt */
|
||||
/* Handle RX frames */
|
||||
|
||||
if (st & SJA1000_RX_INT_ST)
|
||||
{
|
||||
kvaser_chardev_receive(&priv->sja[i]);
|
||||
}
|
||||
|
||||
/* Transmit interrupt */
|
||||
/* Transmit interrupt */
|
||||
|
||||
if (st & SJA1000_TX_INT_ST)
|
||||
{
|
||||
/* Tell the upper half that the transfer is finished. */
|
||||
if (st & SJA1000_TX_INT_ST)
|
||||
{
|
||||
/* Tell the upper half that the transfer is finished. */
|
||||
|
||||
can_txdone(&priv->sja[i].dev);
|
||||
}
|
||||
can_txdone(&priv->sja[i].dev);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CAN_ERRORS
|
||||
/* Handle errors */
|
||||
/* Handle errors */
|
||||
|
||||
kvaser_chardev_error(&priv->sja[i], st);
|
||||
kvaser_chardev_error(&priv->sja[i], st);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_CAN_KVASER_CHARDEV */
|
||||
@@ -1487,42 +1488,43 @@ static void kvaser_sock_interrupt_work(FAR void *arg)
|
||||
FAR struct kvaser_driver_s *priv = arg;
|
||||
uint8_t st = 0;
|
||||
uint8_t i = 0;
|
||||
int passes;
|
||||
|
||||
for (i = 0; i < priv->count; i++)
|
||||
for (passes = 0; passes < CONFIG_CAN_KVASER_IRQ_PASSES; passes++)
|
||||
{
|
||||
st = kvaser_getreg_sja(&priv->sja[i], SJA1000_INT_RAW_REG);
|
||||
if (st == 0)
|
||||
for (i = 0; i < priv->count; i++)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
st = kvaser_getreg_sja(&priv->sja[i], SJA1000_INT_RAW_REG);
|
||||
if (st == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Receive interrupt */
|
||||
/* Handle RX frames */
|
||||
|
||||
if (st & SJA1000_RX_INT_ST)
|
||||
{
|
||||
kvaser_sock_receive(&priv->sja[i]);
|
||||
}
|
||||
|
||||
/* Transmit interrupt */
|
||||
/* Transmit interrupt */
|
||||
|
||||
if (st & SJA1000_TX_INT_ST)
|
||||
{
|
||||
NETDEV_TXDONE(&priv->sja[i].dev);
|
||||
if (st & SJA1000_TX_INT_ST)
|
||||
{
|
||||
NETDEV_TXDONE(&priv->sja[i].dev);
|
||||
|
||||
/* There should be space for a new TX in any event.
|
||||
* Poll the network for new XMIT data.
|
||||
*/
|
||||
/* There should be space for a new TX in any event.
|
||||
* Poll the network for new XMIT data.
|
||||
*/
|
||||
|
||||
net_lock();
|
||||
devif_poll(&priv->sja[i].dev, kvaser_sock_txpoll);
|
||||
net_unlock();
|
||||
}
|
||||
net_lock();
|
||||
devif_poll(&priv->sja[i].dev, kvaser_sock_txpoll);
|
||||
net_unlock();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NET_CAN_ERRORS
|
||||
/* Handle errors */
|
||||
/* Handle errors */
|
||||
|
||||
kvaser_sock_error(&priv->sja[i], st);
|
||||
kvaser_sock_error(&priv->sja[i], st);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_CAN_KVASER_SOCKET */
|
||||
|
||||
Reference in New Issue
Block a user