px4io_serial: always perform full abort DMA on error

- enable DMA error perf count
This commit is contained in:
Daniel Agar 2021-12-22 17:12:16 -05:00
parent f68ae39840
commit a4040f7afd
4 changed files with 13 additions and 42 deletions

View File

@ -114,7 +114,7 @@ public:
ArchPX4IOSerial(); ArchPX4IOSerial();
ArchPX4IOSerial(ArchPX4IOSerial &) = delete; ArchPX4IOSerial(ArchPX4IOSerial &) = delete;
ArchPX4IOSerial &operator = (const ArchPX4IOSerial &) = delete; ArchPX4IOSerial &operator = (const ArchPX4IOSerial &) = delete;
~ArchPX4IOSerial(); virtual ~ArchPX4IOSerial();
virtual int init(); virtual int init();
virtual int ioctl(unsigned operation, unsigned &arg); virtual int ioctl(unsigned operation, unsigned &arg);
@ -159,7 +159,6 @@ private:
/** /**
* Performance counters. * Performance counters.
*/ */
perf_counter_t _pc_dmasetup;
perf_counter_t _pc_dmaerrs; perf_counter_t _pc_dmaerrs;
/** /**

View File

@ -58,13 +58,7 @@ ArchPX4IOSerial::ArchPX4IOSerial() :
_current_packet(nullptr), _current_packet(nullptr),
_rx_dma_status(_dma_status_inactive), _rx_dma_status(_dma_status_inactive),
_completion_semaphore(SEM_INITIALIZER(0)), _completion_semaphore(SEM_INITIALIZER(0)),
#if 0 _pc_dmaerrs(perf_alloc(PC_COUNT, MODULE_NAME": DMA errors"))
_pc_dmasetup(perf_alloc(PC_ELAPSED, "io_dmasetup ")),
_pc_dmaerrs(perf_alloc(PC_COUNT, "io_dmaerrs "))
#else
_pc_dmasetup(nullptr),
_pc_dmaerrs(nullptr)
#endif
{ {
} }
@ -99,7 +93,6 @@ ArchPX4IOSerial::~ArchPX4IOSerial()
/* and kill our semaphores */ /* and kill our semaphores */
px4_sem_destroy(&_completion_semaphore); px4_sem_destroy(&_completion_semaphore);
perf_free(_pc_dmasetup);
perf_free(_pc_dmaerrs); perf_free(_pc_dmaerrs);
} }
@ -202,7 +195,6 @@ ArchPX4IOSerial::ioctl(unsigned operation, unsigned &arg)
if (count >= 5000) { if (count >= 5000) {
syslog(LOG_INFO, "==== test 1 : %u failures ====\n", fails); syslog(LOG_INFO, "==== test 1 : %u failures ====\n", fails);
perf_print_counter(_pc_txns); perf_print_counter(_pc_txns);
perf_print_counter(_pc_dmasetup);
perf_print_counter(_pc_retries); perf_print_counter(_pc_retries);
perf_print_counter(_pc_timeouts); perf_print_counter(_pc_timeouts);
perf_print_counter(_pc_crcerrs); perf_print_counter(_pc_crcerrs);
@ -241,7 +233,6 @@ ArchPX4IOSerial::_bus_exchange(IOPacket *_packet)
/* start RX DMA */ /* start RX DMA */
perf_begin(_pc_txns); perf_begin(_pc_txns);
perf_begin(_pc_dmasetup);
/* DMA setup time ~3µs */ /* DMA setup time ~3µs */
_rx_dma_status = _dma_status_waiting; _rx_dma_status = _dma_status_waiting;
@ -288,8 +279,6 @@ ArchPX4IOSerial::_bus_exchange(IOPacket *_packet)
//rCR1 |= USART_CR1_TE; //rCR1 |= USART_CR1_TE;
rCR3 |= USART_CR3_DMAT; rCR3 |= USART_CR3_DMAT;
perf_end(_pc_dmasetup);
/* compute the deadline for a 10ms timeout */ /* compute the deadline for a 10ms timeout */
struct timespec abstime; struct timespec abstime;
clock_gettime(CLOCK_REALTIME, &abstime); clock_gettime(CLOCK_REALTIME, &abstime);
@ -309,6 +298,8 @@ ArchPX4IOSerial::_bus_exchange(IOPacket *_packet)
if (ret == OK) { if (ret == OK) {
/* check for DMA errors */ /* check for DMA errors */
if (_rx_dma_status & DMA_STATUS_TEIF) { if (_rx_dma_status & DMA_STATUS_TEIF) {
// stream transfer error, ensure all DMA is also stopped before exiting early
_abort_dma();
perf_count(_pc_dmaerrs); perf_count(_pc_dmaerrs);
ret = -EIO; ret = -EIO;
break; break;
@ -319,6 +310,7 @@ ArchPX4IOSerial::_bus_exchange(IOPacket *_packet)
_current_packet->crc = 0; _current_packet->crc = 0;
if ((crc != crc_packet(_current_packet)) || (PKT_CODE(*_current_packet) == PKT_CODE_CORRUPT)) { if ((crc != crc_packet(_current_packet)) || (PKT_CODE(*_current_packet) == PKT_CODE_CORRUPT)) {
_abort_dma();
perf_count(_pc_crcerrs); perf_count(_pc_crcerrs);
ret = -EIO; ret = -EIO;
break; break;

View File

@ -68,13 +68,7 @@ ArchPX4IOSerial::ArchPX4IOSerial() :
_current_packet(nullptr), _current_packet(nullptr),
_rx_dma_status(_dma_status_inactive), _rx_dma_status(_dma_status_inactive),
_completion_semaphore(SEM_INITIALIZER(0)), _completion_semaphore(SEM_INITIALIZER(0)),
#if 0 _pc_dmaerrs(perf_alloc(PC_COUNT, MODULE_NAME": DMA errors"))
_pc_dmasetup(perf_alloc(PC_ELAPSED, "io_dmasetup ")),
_pc_dmaerrs(perf_alloc(PC_COUNT, "io_dmaerrs "))
#else
_pc_dmasetup(nullptr),
_pc_dmaerrs(nullptr)
#endif
{ {
} }
@ -109,7 +103,6 @@ ArchPX4IOSerial::~ArchPX4IOSerial()
/* and kill our semaphores */ /* and kill our semaphores */
px4_sem_destroy(&_completion_semaphore); px4_sem_destroy(&_completion_semaphore);
perf_free(_pc_dmasetup);
perf_free(_pc_dmaerrs); perf_free(_pc_dmaerrs);
} }
@ -214,7 +207,6 @@ ArchPX4IOSerial::ioctl(unsigned operation, unsigned &arg)
if (count >= 5000) { if (count >= 5000) {
syslog(LOG_INFO, "==== test 1 : %u failures ====\n", fails); syslog(LOG_INFO, "==== test 1 : %u failures ====\n", fails);
perf_print_counter(_pc_txns); perf_print_counter(_pc_txns);
perf_print_counter(_pc_dmasetup);
perf_print_counter(_pc_retries); perf_print_counter(_pc_retries);
perf_print_counter(_pc_timeouts); perf_print_counter(_pc_timeouts);
perf_print_counter(_pc_crcerrs); perf_print_counter(_pc_crcerrs);
@ -256,7 +248,6 @@ ArchPX4IOSerial::_bus_exchange(IOPacket *_packet)
/* start RX DMA */ /* start RX DMA */
perf_begin(_pc_txns); perf_begin(_pc_txns);
perf_begin(_pc_dmasetup);
/* DMA setup time ~3µs */ /* DMA setup time ~3µs */
_rx_dma_status = _dma_status_waiting; _rx_dma_status = _dma_status_waiting;
@ -307,8 +298,6 @@ ArchPX4IOSerial::_bus_exchange(IOPacket *_packet)
//rCR1 &= ~USART_CR1_TE; //rCR1 &= ~USART_CR1_TE;
//rCR1 |= USART_CR1_TE; //rCR1 |= USART_CR1_TE;
perf_end(_pc_dmasetup);
/* compute the deadline for a 10ms timeout */ /* compute the deadline for a 10ms timeout */
struct timespec abstime; struct timespec abstime;
clock_gettime(CLOCK_REALTIME, &abstime); clock_gettime(CLOCK_REALTIME, &abstime);
@ -328,8 +317,8 @@ ArchPX4IOSerial::_bus_exchange(IOPacket *_packet)
if (ret == OK) { if (ret == OK) {
/* check for DMA errors */ /* check for DMA errors */
if (_rx_dma_status & DMA_STATUS_TEIF) { if (_rx_dma_status & DMA_STATUS_TEIF) {
// stream transfer error, ensure TX DMA is also stopped before exiting early // stream transfer error, ensure all DMA is also stopped before exiting early
stm32_dmastop(_tx_dma); _abort_dma();
perf_count(_pc_dmaerrs); perf_count(_pc_dmaerrs);
ret = -EIO; ret = -EIO;
break; break;
@ -340,6 +329,7 @@ ArchPX4IOSerial::_bus_exchange(IOPacket *_packet)
_current_packet->crc = 0; _current_packet->crc = 0;
if ((crc != crc_packet(_current_packet)) || (PKT_CODE(*_current_packet) == PKT_CODE_CORRUPT)) { if ((crc != crc_packet(_current_packet)) || (PKT_CODE(*_current_packet) == PKT_CODE_CORRUPT)) {
_abort_dma();
perf_count(_pc_crcerrs); perf_count(_pc_crcerrs);
ret = -EIO; ret = -EIO;
break; break;

View File

@ -106,13 +106,7 @@ ArchPX4IOSerial::ArchPX4IOSerial() :
_current_packet(nullptr), _current_packet(nullptr),
_rx_dma_status(_dma_status_inactive), _rx_dma_status(_dma_status_inactive),
_completion_semaphore(SEM_INITIALIZER(0)), _completion_semaphore(SEM_INITIALIZER(0)),
#if 0 _pc_dmaerrs(perf_alloc(PC_COUNT, MODULE_NAME": DMA errors"))
_pc_dmasetup(perf_alloc(PC_ELAPSED, "io_dmasetup ")),
_pc_dmaerrs(perf_alloc(PC_COUNT, "io_dmaerrs "))
#else
_pc_dmasetup(nullptr),
_pc_dmaerrs(nullptr)
#endif
{ {
} }
@ -147,7 +141,6 @@ ArchPX4IOSerial::~ArchPX4IOSerial()
/* and kill our semaphores */ /* and kill our semaphores */
px4_sem_destroy(&_completion_semaphore); px4_sem_destroy(&_completion_semaphore);
perf_free(_pc_dmasetup);
perf_free(_pc_dmaerrs); perf_free(_pc_dmaerrs);
} }
@ -252,7 +245,6 @@ ArchPX4IOSerial::ioctl(unsigned operation, unsigned &arg)
if (count >= 5000) { if (count >= 5000) {
syslog(LOG_INFO, "==== test 1 : %u failures ====\n", fails); syslog(LOG_INFO, "==== test 1 : %u failures ====\n", fails);
perf_print_counter(_pc_txns); perf_print_counter(_pc_txns);
perf_print_counter(_pc_dmasetup);
perf_print_counter(_pc_retries); perf_print_counter(_pc_retries);
perf_print_counter(_pc_timeouts); perf_print_counter(_pc_timeouts);
perf_print_counter(_pc_crcerrs); perf_print_counter(_pc_crcerrs);
@ -294,7 +286,6 @@ ArchPX4IOSerial::_bus_exchange(IOPacket *_packet)
/* start RX DMA */ /* start RX DMA */
perf_begin(_pc_txns); perf_begin(_pc_txns);
perf_begin(_pc_dmasetup);
/* DMA setup time ~3µs */ /* DMA setup time ~3µs */
_rx_dma_status = _dma_status_waiting; _rx_dma_status = _dma_status_waiting;
@ -354,8 +345,6 @@ ArchPX4IOSerial::_bus_exchange(IOPacket *_packet)
//rCR1 &= ~USART_CR1_TE; //rCR1 &= ~USART_CR1_TE;
//rCR1 |= USART_CR1_TE; //rCR1 |= USART_CR1_TE;
perf_end(_pc_dmasetup);
/* compute the deadline for a 10ms timeout */ /* compute the deadline for a 10ms timeout */
struct timespec abstime; struct timespec abstime;
clock_gettime(CLOCK_REALTIME, &abstime); clock_gettime(CLOCK_REALTIME, &abstime);
@ -375,8 +364,8 @@ ArchPX4IOSerial::_bus_exchange(IOPacket *_packet)
if (ret == OK) { if (ret == OK) {
/* check for DMA errors */ /* check for DMA errors */
if (_rx_dma_status & DMA_STATUS_TEIF) { if (_rx_dma_status & DMA_STATUS_TEIF) {
// stream transfer error, ensure TX DMA is also stopped before exiting early // stream transfer error, ensure all DMA is also stopped before exiting early
stm32_dmastop(_tx_dma); _abort_dma();
perf_count(_pc_dmaerrs); perf_count(_pc_dmaerrs);
ret = -EIO; ret = -EIO;
break; break;
@ -387,6 +376,7 @@ ArchPX4IOSerial::_bus_exchange(IOPacket *_packet)
_current_packet->crc = 0; _current_packet->crc = 0;
if ((crc != crc_packet(_current_packet)) || (PKT_CODE(*_current_packet) == PKT_CODE_CORRUPT)) { if ((crc != crc_packet(_current_packet)) || (PKT_CODE(*_current_packet) == PKT_CODE_CORRUPT)) {
_abort_dma();
perf_count(_pc_crcerrs); perf_count(_pc_crcerrs);
ret = -EIO; ret = -EIO;
break; break;