From 1e10299b43e255a4029cacc18bdf248289be7092 Mon Sep 17 00:00:00 2001 From: Gaute Hope Date: Thu, 17 May 2012 18:13:25 +0200 Subject: [PATCH] Avoid race lock up in usart Long external interrupts may cause usart reads to lock up if they prevent usart interrupts to be handled quick enough. This patch increases usart interrupt priority and prevents the usart interrupt from being delayed. --- libmaple/usart.c | 5 +++++ libmaple/usart.h | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/libmaple/usart.c b/libmaple/usart.c index 0bdc37ae8..7d6e7ca57 100644 --- a/libmaple/usart.c +++ b/libmaple/usart.c @@ -102,6 +102,11 @@ void usart_init(usart_dev *dev) { rb_init(dev->rb, USART_RX_BUF_SIZE, dev->rx_buf); rcc_clk_enable(dev->clk_id); nvic_irq_enable(dev->irq_num); + + /* Set to max priority to avoid race condition where register presumably + * might change before it can be picked out by USART interrupt and cause + * it to lock up. */ + nvic_irq_set_priority (dev->irq_num, 0); } /** diff --git a/libmaple/usart.h b/libmaple/usart.h index ed00e16cb..4b55b280f 100644 --- a/libmaple/usart.h +++ b/libmaple/usart.h @@ -309,7 +309,9 @@ static inline void usart_putstr(usart_dev *dev, const char* str) { * @see usart_data_available() */ static inline uint8 usart_getc(usart_dev *dev) { - return rb_remove(dev->rb); + /* Use rb_safe_remove to avoid race in case another interrupt have reset + * or cleared the ringbuffer */ + return rb_safe_remove (dev->rb); } /**