From b174d6a31405006fb02d7852127a001a60881f97 Mon Sep 17 00:00:00 2001 From: Russ Butler Date: Fri, 10 Jun 2016 17:54:00 +0100 Subject: [PATCH] Add virtual lock for thread safe classes Add a virtual lock for the classes which are thread safe. This allows the use of a mutex to be overridden. --- hal/api/AnalogIn.h | 21 ++++++++++----- hal/api/AnalogOut.h | 21 ++++++++++----- hal/api/BusIn.h | 2 ++ hal/api/BusInOut.h | 2 ++ hal/api/BusOut.h | 2 ++ hal/api/CAN.h | 2 ++ hal/api/I2C.h | 4 +-- hal/api/InterruptManager.h | 4 +++ hal/api/SPI.h | 4 +-- hal/common/BusIn.cpp | 14 +++++++--- hal/common/BusInOut.cpp | 28 ++++++++++++------- hal/common/BusOut.cpp | 16 ++++++++--- hal/common/CAN.cpp | 48 +++++++++++++++++++-------------- hal/common/InterruptManager.cpp | 20 +++++++++----- 14 files changed, 129 insertions(+), 59 deletions(-) diff --git a/hal/api/AnalogIn.h b/hal/api/AnalogIn.h index 00ba2bc853..01b863f555 100644 --- a/hal/api/AnalogIn.h +++ b/hal/api/AnalogIn.h @@ -55,9 +55,9 @@ public: * @param name (optional) A string to identify the object */ AnalogIn(PinName pin) { - _mutex.lock(); + lock(); analogin_init(&_adc, pin); - _mutex.unlock(); + unlock(); } /** Read the input voltage, represented as a float in the range [0.0, 1.0] @@ -65,9 +65,9 @@ public: * @returns A floating-point value representing the current input voltage, measured as a percentage */ float read() { - _mutex.lock(); + lock(); float ret = analogin_read(&_adc); - _mutex.unlock(); + unlock(); return ret; } @@ -77,9 +77,9 @@ public: * 16-bit unsigned short representing the current input voltage, normalised to a 16-bit value */ unsigned short read_u16() { - _mutex.lock(); + lock(); unsigned short ret = analogin_read_u16(&_adc); - _mutex.unlock(); + unlock(); return ret; } @@ -104,6 +104,15 @@ public: #endif protected: + + virtual void lock() { + _mutex.lock(); + } + + virtual void unlock() { + _mutex.unlock(); + } + analogin_t _adc; static PlatformMutex _mutex; }; diff --git a/hal/api/AnalogOut.h b/hal/api/AnalogOut.h index d7d2b11c13..68488d9709 100644 --- a/hal/api/AnalogOut.h +++ b/hal/api/AnalogOut.h @@ -66,9 +66,9 @@ public: * Values outside this range will be saturated to 0.0f or 1.0f. */ void write(float value) { - _mutex.lock(); + lock(); analogout_write(&_dac, value); - _mutex.unlock(); + unlock(); } /** Set the output voltage, represented as an unsigned short in the range [0x0, 0xFFFF] @@ -77,9 +77,9 @@ public: * normalised to a 16-bit value (0x0000 = 0v, 0xFFFF = 3.3v) */ void write_u16(unsigned short value) { - _mutex.lock(); + lock(); analogout_write_u16(&_dac, value); - _mutex.unlock(); + unlock(); } /** Return the current output voltage setting, measured as a percentage (float) @@ -93,9 +93,9 @@ public: * This value may not match exactly the value set by a previous write(). */ float read() { - _mutex.lock(); + lock(); float ret = analogout_read(&_dac); - _mutex.unlock(); + unlock(); return ret; } @@ -123,6 +123,15 @@ public: #endif protected: + + virtual void lock() { + _mutex.lock(); + } + + virtual void unlock() { + _mutex.unlock(); + } + dac_t _dac; PlatformMutex _mutex; }; diff --git a/hal/api/BusIn.h b/hal/api/BusIn.h index 277e1c5fcb..9e91ccb9d3 100644 --- a/hal/api/BusIn.h +++ b/hal/api/BusIn.h @@ -94,6 +94,8 @@ protected: /* disallow copy constructor and assignment operators */ private: + virtual void lock(); + virtual void unlock(); BusIn(const BusIn&); BusIn & operator = (const BusIn&); }; diff --git a/hal/api/BusInOut.h b/hal/api/BusInOut.h index f4a7acc562..0d61eef1a3 100644 --- a/hal/api/BusInOut.h +++ b/hal/api/BusInOut.h @@ -101,6 +101,8 @@ public: #endif protected: + virtual void lock(); + virtual void unlock(); DigitalInOut* _pin[16]; /** Mask of bus's NC pins diff --git a/hal/api/BusOut.h b/hal/api/BusOut.h index 76200fbdff..4f3d672ae9 100644 --- a/hal/api/BusOut.h +++ b/hal/api/BusOut.h @@ -85,6 +85,8 @@ public: #endif protected: + virtual void lock(); + virtual void unlock(); DigitalOut* _pin[16]; /** Mask of bus's NC pins diff --git a/hal/api/CAN.h b/hal/api/CAN.h index 1f07148ccb..44e1e08795 100644 --- a/hal/api/CAN.h +++ b/hal/api/CAN.h @@ -242,6 +242,8 @@ public: static void _irq_handler(uint32_t id, CanIrqType type); protected: + virtual void lock(); + virtual void unlock(); can_t _can; Callback _irq[9]; PlatformMutex _mutex; diff --git a/hal/api/I2C.h b/hal/api/I2C.h index 8e36fe4936..817c590d6e 100644 --- a/hal/api/I2C.h +++ b/hal/api/I2C.h @@ -139,11 +139,11 @@ public: /** Acquire exclusive access to this I2C bus */ - void lock(void); + virtual void lock(void); /** Release exclusive access to this I2C bus */ - void unlock(void); + virtual void unlock(void); #if DEVICE_I2C_ASYNCH diff --git a/hal/api/InterruptManager.h b/hal/api/InterruptManager.h index dbcf7c5c8e..30c705f1ac 100644 --- a/hal/api/InterruptManager.h +++ b/hal/api/InterruptManager.h @@ -113,6 +113,10 @@ public: */ bool remove_handler(pFunctionPointer_t handler, IRQn_Type irq); +protected: + virtual void lock(); + virtual void unlock(); + private: InterruptManager(); ~InterruptManager(); diff --git a/hal/api/SPI.h b/hal/api/SPI.h index 499c4fbe67..c2b04ed354 100644 --- a/hal/api/SPI.h +++ b/hal/api/SPI.h @@ -116,11 +116,11 @@ public: /** Acquire exclusive access to this SPI bus */ - void lock(void); + virtual void lock(void); /** Release exclusive access to this SPI bus */ - void unlock(void); + virtual void unlock(void); #if DEVICE_SPI_ASYNCH diff --git a/hal/common/BusIn.cpp b/hal/common/BusIn.cpp index bfa00e828b..454b9c4dc1 100644 --- a/hal/common/BusIn.cpp +++ b/hal/common/BusIn.cpp @@ -53,23 +53,31 @@ BusIn::~BusIn() { int BusIn::read() { int v = 0; - _mutex.lock(); + lock(); for (int i=0; i<16; i++) { if (_pin[i] != 0) { v |= _pin[i]->read() << i; } } - _mutex.unlock(); + unlock(); return v; } void BusIn::mode(PinMode pull) { - _mutex.lock(); + lock(); for (int i=0; i<16; i++) { if (_pin[i] != 0) { _pin[i]->mode(pull); } } + unlock(); +} + +void BusIn::lock() { + _mutex.lock(); +} + +void BusIn::unlock() { _mutex.unlock(); } diff --git a/hal/common/BusInOut.cpp b/hal/common/BusInOut.cpp index 6b1559db56..d333d080df 100644 --- a/hal/common/BusInOut.cpp +++ b/hal/common/BusInOut.cpp @@ -52,55 +52,55 @@ BusInOut::~BusInOut() { } void BusInOut::write(int value) { - _mutex.lock(); + lock(); for (int i=0; i<16; i++) { if (_pin[i] != 0) { _pin[i]->write((value >> i) & 1); } } - _mutex.unlock(); + unlock(); } int BusInOut::read() { - _mutex.lock(); + lock(); int v = 0; for (int i=0; i<16; i++) { if (_pin[i] != 0) { v |= _pin[i]->read() << i; } } - _mutex.unlock(); + unlock(); return v; } void BusInOut::output() { - _mutex.lock(); + lock(); for (int i=0; i<16; i++) { if (_pin[i] != 0) { _pin[i]->output(); } } - _mutex.unlock(); + unlock(); } void BusInOut::input() { - _mutex.lock(); + lock(); for (int i=0; i<16; i++) { if (_pin[i] != 0) { _pin[i]->input(); } } - _mutex.unlock(); + unlock(); } void BusInOut::mode(PinMode pull) { - _mutex.lock(); + lock(); for (int i=0; i<16; i++) { if (_pin[i] != 0) { _pin[i]->mode(pull); } } - _mutex.unlock(); + unlock(); } #ifdef MBED_OPERATORS @@ -129,4 +129,12 @@ BusInOut::operator int() { } #endif +void BusInOut::lock() { + _mutex.lock(); +} + +void BusInOut::unlock() { + _mutex.unlock(); +} + } // namespace mbed diff --git a/hal/common/BusOut.cpp b/hal/common/BusOut.cpp index 4a9585733b..11e326954a 100644 --- a/hal/common/BusOut.cpp +++ b/hal/common/BusOut.cpp @@ -52,24 +52,24 @@ BusOut::~BusOut() { } void BusOut::write(int value) { - _mutex.lock(); + lock(); for (int i=0; i<16; i++) { if (_pin[i] != 0) { _pin[i]->write((value >> i) & 1); } } - _mutex.unlock(); + unlock(); } int BusOut::read() { - _mutex.lock(); + lock(); int v = 0; for (int i=0; i<16; i++) { if (_pin[i] != 0) { v |= _pin[i]->read() << i; } } - _mutex.unlock(); + unlock(); return v; } @@ -99,4 +99,12 @@ BusOut::operator int() { } #endif +void BusOut::lock() { + _mutex.lock(); +} + +void BusOut::unlock() { + _mutex.unlock(); +} + } // namespace mbed diff --git a/hal/common/CAN.cpp b/hal/common/CAN.cpp index 88a0bb8af1..780a106b73 100644 --- a/hal/common/CAN.cpp +++ b/hal/common/CAN.cpp @@ -34,75 +34,75 @@ CAN::~CAN() { } int CAN::frequency(int f) { - _mutex.lock(); + lock(); int ret = can_frequency(&_can, f); - _mutex.unlock(); + unlock(); return ret; } int CAN::write(CANMessage msg) { - _mutex.lock(); + lock(); int ret = can_write(&_can, msg, 0); - _mutex.unlock(); + unlock(); return ret; } int CAN::read(CANMessage &msg, int handle) { - _mutex.lock(); + lock(); int ret = can_read(&_can, &msg, handle); - _mutex.unlock(); + unlock(); return ret; } void CAN::reset() { - _mutex.lock(); + lock(); can_reset(&_can); - _mutex.unlock(); + unlock(); } unsigned char CAN::rderror() { - _mutex.lock(); + lock(); int ret = can_rderror(&_can); - _mutex.unlock(); + unlock(); return ret; } unsigned char CAN::tderror() { - _mutex.lock(); + lock(); int ret = can_tderror(&_can); - _mutex.unlock(); + unlock(); return ret; } void CAN::monitor(bool silent) { - _mutex.lock(); + lock(); can_monitor(&_can, (silent) ? 1 : 0); - _mutex.unlock(); + unlock(); } int CAN::mode(Mode mode) { - _mutex.lock(); + lock(); int ret = can_mode(&_can, (CanMode)mode); - _mutex.unlock(); + unlock(); return ret; } int CAN::filter(unsigned int id, unsigned int mask, CANFormat format, int handle) { - _mutex.lock(); + lock(); int ret = can_filter(&_can, id, mask, format, handle); - _mutex.unlock(); + unlock(); return ret; } void CAN::attach(Callback func, IrqType type) { - _mutex.lock(); + lock(); if (func) { _irq[(CanIrqType)type].attach(func); can_irq_set(&_can, (CanIrqType)type, 1); } else { can_irq_set(&_can, (CanIrqType)type, 0); } - _mutex.unlock(); + unlock(); } void CAN::_irq_handler(uint32_t id, CanIrqType type) { @@ -110,6 +110,14 @@ void CAN::_irq_handler(uint32_t id, CanIrqType type) { handler->_irq[type].call(); } +void CAN::lock() { + _mutex.lock(); +} + +void CAN::unlock() { + _mutex.unlock(); +} + } // namespace mbed #endif diff --git a/hal/common/InterruptManager.cpp b/hal/common/InterruptManager.cpp index 91c35595ed..4f38475c2f 100644 --- a/hal/common/InterruptManager.cpp +++ b/hal/common/InterruptManager.cpp @@ -56,7 +56,7 @@ InterruptManager::~InterruptManager() { } bool InterruptManager::must_replace_vector(IRQn_Type irq) { - _mutex.lock(); + lock(); int ret = false; int irq_pos = get_irq_index(irq); @@ -65,19 +65,19 @@ bool InterruptManager::must_replace_vector(IRQn_Type irq) { _chains[irq_pos]->add((pvoidf)NVIC_GetVector(irq)); ret = true; } - _mutex.unlock(); + unlock(); return ret; } pFunctionPointer_t InterruptManager::add_common(void (*function)(void), IRQn_Type irq, bool front) { - _mutex.lock(); + lock(); int irq_pos = get_irq_index(irq); bool change = must_replace_vector(irq); pFunctionPointer_t pf = front ? _chains[irq_pos]->add_front(function) : _chains[irq_pos]->add(function); if (change) NVIC_SetVector(irq, (uint32_t)&InterruptManager::static_irq_helper); - _mutex.unlock(); + unlock(); return pf; } @@ -85,13 +85,13 @@ bool InterruptManager::remove_handler(pFunctionPointer_t handler, IRQn_Type irq) int irq_pos = get_irq_index(irq); bool ret = false; - _mutex.lock(); + lock(); if (_chains[irq_pos] != NULL) { if (_chains[irq_pos]->remove(handler)) { ret = true; } } - _mutex.unlock(); + unlock(); return ret; } @@ -109,6 +109,14 @@ void InterruptManager::static_irq_helper() { InterruptManager::get()->irq_helper(); } +void InterruptManager::lock() { + _mutex.lock(); +} + +void InterruptManager::unlock() { + _mutex.unlock(); +} + } // namespace mbed #endif