mirror of
https://github.com/apache/nuttx.git
synced 2026-05-27 11:26:12 +08:00
Improve the CAN error reporting by also report internal device driver errors.
This commit is contained in:
committed by
Gregory Nutt
parent
3c594b5ba1
commit
9eeb8634fc
@@ -522,6 +522,44 @@ static ssize_t can_read(FAR struct file *filep, FAR char *buffer,
|
|||||||
/* Interrupts must be disabled while accessing the cd_recv FIFO */
|
/* Interrupts must be disabled while accessing the cd_recv FIFO */
|
||||||
|
|
||||||
flags = enter_critical_section();
|
flags = enter_critical_section();
|
||||||
|
|
||||||
|
#ifdef CONFIG_CAN_ERRORS
|
||||||
|
/* Check for internal errors */
|
||||||
|
|
||||||
|
if (dev->cd_error != 0)
|
||||||
|
{
|
||||||
|
FAR struct can_msg_s *msg;
|
||||||
|
|
||||||
|
/* Detected an internal driver error. Generate a
|
||||||
|
* CAN_ERROR_MESSAGE
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (buflen < CAN_MSGLEN(CAN_ERROR_DLC))
|
||||||
|
{
|
||||||
|
goto return_with_irqdisabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg = (FAR struct can_msg_s *)buffer;
|
||||||
|
msg->cm_hdr.ch_id = CAN_ERROR_INTERNAL;
|
||||||
|
msg->cm_hdr.ch_dlc = CAN_ERROR_DLC;
|
||||||
|
msg->cm_hdr.ch_rtr = 0;
|
||||||
|
msg->cm_hdr.ch_error = 1;
|
||||||
|
#ifdef CONFIG_CAN_EXTID
|
||||||
|
msg->cm_hdr.ch_extid = 0;
|
||||||
|
#endif
|
||||||
|
msg->cm_hdr.ch_unused = 0;
|
||||||
|
memset(&(msg->cm_data), 0, CAN_ERROR_DLC);
|
||||||
|
msg->cm_data[5] = dev->cd_error;
|
||||||
|
|
||||||
|
/* Reset the error flag */
|
||||||
|
|
||||||
|
dev->cd_error = 0;
|
||||||
|
|
||||||
|
ret = CAN_MSGLEN(CAN_ERROR_DLC);
|
||||||
|
goto return_with_irqdisabled;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_CAN_ERRORS */
|
||||||
|
|
||||||
while (dev->cd_recv.rx_head == dev->cd_recv.rx_tail)
|
while (dev->cd_recv.rx_head == dev->cd_recv.rx_tail)
|
||||||
{
|
{
|
||||||
/* The receive FIFO is empty -- was non-blocking mode selected? */
|
/* The receive FIFO is empty -- was non-blocking mode selected? */
|
||||||
@@ -540,6 +578,7 @@ static ssize_t can_read(FAR struct file *filep, FAR char *buffer,
|
|||||||
ret = sem_wait(&dev->cd_recv.rx_sem);
|
ret = sem_wait(&dev->cd_recv.rx_sem);
|
||||||
}
|
}
|
||||||
while (ret >= 0 && dev->cd_recv.rx_head == dev->cd_recv.rx_tail);
|
while (ret >= 0 && dev->cd_recv.rx_head == dev->cd_recv.rx_tail);
|
||||||
|
|
||||||
dev->cd_nrxwaiters--;
|
dev->cd_nrxwaiters--;
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@@ -927,6 +966,9 @@ int can_register(FAR const char *path, FAR struct can_dev_s *dev)
|
|||||||
dev->cd_ntxwaiters = 0;
|
dev->cd_ntxwaiters = 0;
|
||||||
dev->cd_nrxwaiters = 0;
|
dev->cd_nrxwaiters = 0;
|
||||||
dev->cd_npendrtr = 0;
|
dev->cd_npendrtr = 0;
|
||||||
|
#ifdef CONFIG_CAN_ERRORS
|
||||||
|
dev->cd_error = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
sem_init(&dev->cd_xmit.tx_sem, 0, 0);
|
sem_init(&dev->cd_xmit.tx_sem, 0, 0);
|
||||||
sem_init(&dev->cd_recv.rx_sem, 0, 0);
|
sem_init(&dev->cd_recv.rx_sem, 0, 0);
|
||||||
@@ -1073,6 +1115,14 @@ int can_receive(FAR struct can_dev_s *dev, FAR struct can_hdr_s *hdr,
|
|||||||
|
|
||||||
err = OK;
|
err = OK;
|
||||||
}
|
}
|
||||||
|
#ifdef CONFIG_CAN_ERRORS
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Report rx overflow error */
|
||||||
|
|
||||||
|
dev->cd_error |= CAN_ERROR5_RXOVERFLOW;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-1
@@ -219,7 +219,8 @@
|
|||||||
# define CAN_ERROR_BUSOFF (1 << 6) /* Bit 6: Bus off */
|
# define CAN_ERROR_BUSOFF (1 << 6) /* Bit 6: Bus off */
|
||||||
# define CAN_ERROR_BUSERROR (1 << 7) /* Bit 7: Bus error */
|
# define CAN_ERROR_BUSERROR (1 << 7) /* Bit 7: Bus error */
|
||||||
# define CAN_ERROR_RESTARTED (1 << 8) /* Bit 8: Controller restarted */
|
# define CAN_ERROR_RESTARTED (1 << 8) /* Bit 8: Controller restarted */
|
||||||
/* Bits 9-10: Available */
|
# define CAN_ERROR_INTERNAL (1 << 9) /* Bit 9: Stack internal error (See CAN_ERROR5_* definitions) */
|
||||||
|
/* Bit 10: Available */
|
||||||
|
|
||||||
/* The remaining definitions described the error report payload that follows the
|
/* The remaining definitions described the error report payload that follows the
|
||||||
* CAN header.
|
* CAN header.
|
||||||
@@ -295,6 +296,11 @@
|
|||||||
# define CANL_ERROR4_SHORT2GND 0x40
|
# define CANL_ERROR4_SHORT2GND 0x40
|
||||||
# define CANL_ERROR4_SHORT2CANH 0x50
|
# define CANL_ERROR4_SHORT2CANH 0x50
|
||||||
|
|
||||||
|
/* Data[5]: Error status of stack internals */
|
||||||
|
|
||||||
|
# define CAN_ERROR5_UNSPEC 0x00 /* Unspecified error */
|
||||||
|
# define CAN_ERROR5_RXOVERFLOW (1 << 0) /* Bit 0: RX buffer overflow */
|
||||||
|
|
||||||
#endif /* CONFIG_CAN_ERRORS */
|
#endif /* CONFIG_CAN_ERRORS */
|
||||||
|
|
||||||
/* CAN filter support ***************************************************************/
|
/* CAN filter support ***************************************************************/
|
||||||
@@ -494,6 +500,9 @@ struct can_dev_s
|
|||||||
uint8_t cd_npendrtr; /* Number of pending RTR messages */
|
uint8_t cd_npendrtr; /* Number of pending RTR messages */
|
||||||
volatile uint8_t cd_ntxwaiters; /* Number of threads waiting to enqueue a message */
|
volatile uint8_t cd_ntxwaiters; /* Number of threads waiting to enqueue a message */
|
||||||
volatile uint8_t cd_nrxwaiters; /* Number of threads waiting to receive a message */
|
volatile uint8_t cd_nrxwaiters; /* Number of threads waiting to receive a message */
|
||||||
|
#ifdef CONFIG_CAN_ERRORS
|
||||||
|
uint8_t cd_error; /* Flags to indicate internal device errors */
|
||||||
|
#endif
|
||||||
sem_t cd_closesem; /* Locks out new opens while close is in progress */
|
sem_t cd_closesem; /* Locks out new opens while close is in progress */
|
||||||
struct can_txfifo_s cd_xmit; /* Describes transmit FIFO */
|
struct can_txfifo_s cd_xmit; /* Describes transmit FIFO */
|
||||||
struct can_rxfifo_s cd_recv; /* Describes receive FIFO */
|
struct can_rxfifo_s cd_recv; /* Describes receive FIFO */
|
||||||
|
|||||||
Reference in New Issue
Block a user