Improve the CAN error reporting by also report internal device driver errors.

This commit is contained in:
Frank Benkert 2016-05-11 07:10:17 -06:00 committed by Gregory Nutt
parent 3c594b5ba1
commit 9eeb8634fc
2 changed files with 60 additions and 1 deletions

View File

@ -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 */
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)
{
/* 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);
}
while (ret >= 0 && dev->cd_recv.rx_head == dev->cd_recv.rx_tail);
dev->cd_nrxwaiters--;
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_nrxwaiters = 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_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;
}
#ifdef CONFIG_CAN_ERRORS
else
{
/* Report rx overflow error */
dev->cd_error |= CAN_ERROR5_RXOVERFLOW;
}
#endif
return err;
}

View File

@ -219,7 +219,8 @@
# define CAN_ERROR_BUSOFF (1 << 6) /* Bit 6: Bus off */
# define CAN_ERROR_BUSERROR (1 << 7) /* Bit 7: Bus error */
# 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
* CAN header.
@ -295,6 +296,11 @@
# define CANL_ERROR4_SHORT2GND 0x40
# 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 */
/* CAN filter support ***************************************************************/
@ -494,6 +500,9 @@ struct can_dev_s
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_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 */
struct can_txfifo_s cd_xmit; /* Describes transmit FIFO */
struct can_rxfifo_s cd_recv; /* Describes receive FIFO */