From f6c34a23039510505b55b93a501dbd06203ece62 Mon Sep 17 00:00:00 2001 From: Martin Kojtal <0xc0170@gmail.com> Date: Tue, 5 Sep 2017 12:41:18 +0100 Subject: [PATCH] SerialBase and CAN: fix Callbacks comparision As Callback currently does not have fully functional comparision (see #5017), we workaround by doing null check. --- drivers/CAN.cpp | 16 ++++++++-------- drivers/SerialBase.cpp | 28 +++++++++++++--------------- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/drivers/CAN.cpp b/drivers/CAN.cpp index 226a546e94..e49b7adfcb 100644 --- a/drivers/CAN.cpp +++ b/drivers/CAN.cpp @@ -22,13 +22,11 @@ namespace mbed { -static void donothing() {} - CAN::CAN(PinName rd, PinName td) : _can(), _irq() { // No lock needed in constructor for (size_t i = 0; i < sizeof _irq / sizeof _irq[0]; i++) { - _irq[i] = callback(donothing); + _irq[i] = NULL; } can_init(&_can, rd, td); @@ -39,7 +37,7 @@ CAN::CAN(PinName rd, PinName td, int hz) : _can(), _irq() { // No lock needed in constructor for (size_t i = 0; i < sizeof _irq / sizeof _irq[0]; i++) { - _irq[i] = callback(donothing); + _irq[i] = NULL; } can_init_freq(&_can, rd, td, hz); @@ -117,17 +115,17 @@ void CAN::attach(Callback<void()> func, IrqType type) { lock(); if (func) { // lock deep sleep only the first time - if (_irq[(CanIrqType)type] == callback(donothing)) { + if (!_irq[(CanIrqType)type]) { sleep_manager_lock_deep_sleep(); } _irq[(CanIrqType)type] = func; can_irq_set(&_can, (CanIrqType)type, 1); } else { // unlock deep sleep only the first time - if (_irq[(CanIrqType)type] != callback(donothing)) { + if (_irq[(CanIrqType)type]) { sleep_manager_unlock_deep_sleep(); } - _irq[(CanIrqType)type] = callback(donothing); + _irq[(CanIrqType)type] = NULL; can_irq_set(&_can, (CanIrqType)type, 0); } unlock(); @@ -135,7 +133,9 @@ void CAN::attach(Callback<void()> func, IrqType type) { void CAN::_irq_handler(uint32_t id, CanIrqType type) { CAN *handler = (CAN*)id; - handler->_irq[type].call(); + if (handler->_irq[type]) { + handler->_irq[type].call(); + } } void CAN::lock() { diff --git a/drivers/SerialBase.cpp b/drivers/SerialBase.cpp index c171d1487b..e07a44149d 100644 --- a/drivers/SerialBase.cpp +++ b/drivers/SerialBase.cpp @@ -22,21 +22,17 @@ namespace mbed { -static void donothing() {}; -static void donothing2(int arg) {}; - - SerialBase::SerialBase(PinName tx, PinName rx, int baud) : #if DEVICE_SERIAL_ASYNCH _thunk_irq(this), _tx_usage(DMA_USAGE_NEVER), - _rx_usage(DMA_USAGE_NEVER), _tx_callback(donothing2), - _rx_callback(donothing2), + _rx_usage(DMA_USAGE_NEVER), _tx_callback(NULL), + _rx_callback(NULL), #endif _serial(), _baud(baud) { // No lock needed in the constructor for (size_t i = 0; i < sizeof _irq / sizeof _irq[0]; i++) { - _irq[i] = donothing; + _irq[i] = NULL; } serial_init(&_serial, tx, rx); @@ -78,17 +74,17 @@ void SerialBase::attach(Callback<void()> func, IrqType type) { core_util_critical_section_enter(); if (func) { // lock deep sleep only the first time - if (_irq[type] == donothing) { + if (!_irq[type]) { sleep_manager_lock_deep_sleep(); } _irq[type] = func; serial_irq_set(&_serial, (SerialIrq)type, 1); } else { // unlock deep sleep only the first time - if (_irq[type] != donothing) { + if (_irq[type]) { sleep_manager_unlock_deep_sleep(); } - _irq[type] = donothing; + _irq[type] = NULL; serial_irq_set(&_serial, (SerialIrq)type, 0); } core_util_critical_section_exit(); @@ -97,7 +93,9 @@ void SerialBase::attach(Callback<void()> func, IrqType type) { void SerialBase::_irq_handler(uint32_t id, SerialIrq irq_type) { SerialBase *handler = (SerialBase*)id; - handler->_irq[irq_type](); + if (handler->_irq[irq_type]) { + handler->_irq[irq_type](); + } } int SerialBase::_base_getc() { @@ -192,20 +190,20 @@ void SerialBase::start_write(const void *buffer, int buffer_size, char buffer_wi void SerialBase::abort_write(void) { // rx might still be active - if (_rx_callback == &donothing2) { + if (_rx_callback) { sleep_manager_unlock_deep_sleep(); } - _tx_callback = donothing2; + _tx_callback = NULL; serial_tx_abort_asynch(&_serial); } void SerialBase::abort_read(void) { // tx might still be active - if (_tx_callback == &donothing2) { + if (_tx_callback) { sleep_manager_unlock_deep_sleep(); } - _rx_callback = donothing2; + _rx_callback = NULL; serial_rx_abort_asynch(&_serial); }