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.
pull/1863/head
Russ Butler 2016-06-10 17:54:00 +01:00
parent e4f6e1b327
commit b174d6a314
14 changed files with 129 additions and 59 deletions

View File

@ -55,9 +55,9 @@ public:
* @param name (optional) A string to identify the object * @param name (optional) A string to identify the object
*/ */
AnalogIn(PinName pin) { AnalogIn(PinName pin) {
_mutex.lock(); lock();
analogin_init(&_adc, pin); analogin_init(&_adc, pin);
_mutex.unlock(); unlock();
} }
/** Read the input voltage, represented as a float in the range [0.0, 1.0] /** 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 * @returns A floating-point value representing the current input voltage, measured as a percentage
*/ */
float read() { float read() {
_mutex.lock(); lock();
float ret = analogin_read(&_adc); float ret = analogin_read(&_adc);
_mutex.unlock(); unlock();
return ret; return ret;
} }
@ -77,9 +77,9 @@ public:
* 16-bit unsigned short representing the current input voltage, normalised to a 16-bit value * 16-bit unsigned short representing the current input voltage, normalised to a 16-bit value
*/ */
unsigned short read_u16() { unsigned short read_u16() {
_mutex.lock(); lock();
unsigned short ret = analogin_read_u16(&_adc); unsigned short ret = analogin_read_u16(&_adc);
_mutex.unlock(); unlock();
return ret; return ret;
} }
@ -104,6 +104,15 @@ public:
#endif #endif
protected: protected:
virtual void lock() {
_mutex.lock();
}
virtual void unlock() {
_mutex.unlock();
}
analogin_t _adc; analogin_t _adc;
static PlatformMutex _mutex; static PlatformMutex _mutex;
}; };

View File

@ -66,9 +66,9 @@ public:
* Values outside this range will be saturated to 0.0f or 1.0f. * Values outside this range will be saturated to 0.0f or 1.0f.
*/ */
void write(float value) { void write(float value) {
_mutex.lock(); lock();
analogout_write(&_dac, value); analogout_write(&_dac, value);
_mutex.unlock(); unlock();
} }
/** Set the output voltage, represented as an unsigned short in the range [0x0, 0xFFFF] /** 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) * normalised to a 16-bit value (0x0000 = 0v, 0xFFFF = 3.3v)
*/ */
void write_u16(unsigned short value) { void write_u16(unsigned short value) {
_mutex.lock(); lock();
analogout_write_u16(&_dac, value); analogout_write_u16(&_dac, value);
_mutex.unlock(); unlock();
} }
/** Return the current output voltage setting, measured as a percentage (float) /** 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(). * This value may not match exactly the value set by a previous write().
*/ */
float read() { float read() {
_mutex.lock(); lock();
float ret = analogout_read(&_dac); float ret = analogout_read(&_dac);
_mutex.unlock(); unlock();
return ret; return ret;
} }
@ -123,6 +123,15 @@ public:
#endif #endif
protected: protected:
virtual void lock() {
_mutex.lock();
}
virtual void unlock() {
_mutex.unlock();
}
dac_t _dac; dac_t _dac;
PlatformMutex _mutex; PlatformMutex _mutex;
}; };

View File

@ -94,6 +94,8 @@ protected:
/* disallow copy constructor and assignment operators */ /* disallow copy constructor and assignment operators */
private: private:
virtual void lock();
virtual void unlock();
BusIn(const BusIn&); BusIn(const BusIn&);
BusIn & operator = (const BusIn&); BusIn & operator = (const BusIn&);
}; };

View File

@ -101,6 +101,8 @@ public:
#endif #endif
protected: protected:
virtual void lock();
virtual void unlock();
DigitalInOut* _pin[16]; DigitalInOut* _pin[16];
/** Mask of bus's NC pins /** Mask of bus's NC pins

View File

@ -85,6 +85,8 @@ public:
#endif #endif
protected: protected:
virtual void lock();
virtual void unlock();
DigitalOut* _pin[16]; DigitalOut* _pin[16];
/** Mask of bus's NC pins /** Mask of bus's NC pins

View File

@ -242,6 +242,8 @@ public:
static void _irq_handler(uint32_t id, CanIrqType type); static void _irq_handler(uint32_t id, CanIrqType type);
protected: protected:
virtual void lock();
virtual void unlock();
can_t _can; can_t _can;
Callback<void()> _irq[9]; Callback<void()> _irq[9];
PlatformMutex _mutex; PlatformMutex _mutex;

View File

@ -139,11 +139,11 @@ public:
/** Acquire exclusive access to this I2C bus /** Acquire exclusive access to this I2C bus
*/ */
void lock(void); virtual void lock(void);
/** Release exclusive access to this I2C bus /** Release exclusive access to this I2C bus
*/ */
void unlock(void); virtual void unlock(void);
#if DEVICE_I2C_ASYNCH #if DEVICE_I2C_ASYNCH

View File

@ -113,6 +113,10 @@ public:
*/ */
bool remove_handler(pFunctionPointer_t handler, IRQn_Type irq); bool remove_handler(pFunctionPointer_t handler, IRQn_Type irq);
protected:
virtual void lock();
virtual void unlock();
private: private:
InterruptManager(); InterruptManager();
~InterruptManager(); ~InterruptManager();

View File

@ -116,11 +116,11 @@ public:
/** Acquire exclusive access to this SPI bus /** Acquire exclusive access to this SPI bus
*/ */
void lock(void); virtual void lock(void);
/** Release exclusive access to this SPI bus /** Release exclusive access to this SPI bus
*/ */
void unlock(void); virtual void unlock(void);
#if DEVICE_SPI_ASYNCH #if DEVICE_SPI_ASYNCH

View File

@ -53,23 +53,31 @@ BusIn::~BusIn() {
int BusIn::read() { int BusIn::read() {
int v = 0; int v = 0;
_mutex.lock(); lock();
for (int i=0; i<16; i++) { for (int i=0; i<16; i++) {
if (_pin[i] != 0) { if (_pin[i] != 0) {
v |= _pin[i]->read() << i; v |= _pin[i]->read() << i;
} }
} }
_mutex.unlock(); unlock();
return v; return v;
} }
void BusIn::mode(PinMode pull) { void BusIn::mode(PinMode pull) {
_mutex.lock(); lock();
for (int i=0; i<16; i++) { for (int i=0; i<16; i++) {
if (_pin[i] != 0) { if (_pin[i] != 0) {
_pin[i]->mode(pull); _pin[i]->mode(pull);
} }
} }
unlock();
}
void BusIn::lock() {
_mutex.lock();
}
void BusIn::unlock() {
_mutex.unlock(); _mutex.unlock();
} }

View File

@ -52,55 +52,55 @@ BusInOut::~BusInOut() {
} }
void BusInOut::write(int value) { void BusInOut::write(int value) {
_mutex.lock(); lock();
for (int i=0; i<16; i++) { for (int i=0; i<16; i++) {
if (_pin[i] != 0) { if (_pin[i] != 0) {
_pin[i]->write((value >> i) & 1); _pin[i]->write((value >> i) & 1);
} }
} }
_mutex.unlock(); unlock();
} }
int BusInOut::read() { int BusInOut::read() {
_mutex.lock(); lock();
int v = 0; int v = 0;
for (int i=0; i<16; i++) { for (int i=0; i<16; i++) {
if (_pin[i] != 0) { if (_pin[i] != 0) {
v |= _pin[i]->read() << i; v |= _pin[i]->read() << i;
} }
} }
_mutex.unlock(); unlock();
return v; return v;
} }
void BusInOut::output() { void BusInOut::output() {
_mutex.lock(); lock();
for (int i=0; i<16; i++) { for (int i=0; i<16; i++) {
if (_pin[i] != 0) { if (_pin[i] != 0) {
_pin[i]->output(); _pin[i]->output();
} }
} }
_mutex.unlock(); unlock();
} }
void BusInOut::input() { void BusInOut::input() {
_mutex.lock(); lock();
for (int i=0; i<16; i++) { for (int i=0; i<16; i++) {
if (_pin[i] != 0) { if (_pin[i] != 0) {
_pin[i]->input(); _pin[i]->input();
} }
} }
_mutex.unlock(); unlock();
} }
void BusInOut::mode(PinMode pull) { void BusInOut::mode(PinMode pull) {
_mutex.lock(); lock();
for (int i=0; i<16; i++) { for (int i=0; i<16; i++) {
if (_pin[i] != 0) { if (_pin[i] != 0) {
_pin[i]->mode(pull); _pin[i]->mode(pull);
} }
} }
_mutex.unlock(); unlock();
} }
#ifdef MBED_OPERATORS #ifdef MBED_OPERATORS
@ -129,4 +129,12 @@ BusInOut::operator int() {
} }
#endif #endif
void BusInOut::lock() {
_mutex.lock();
}
void BusInOut::unlock() {
_mutex.unlock();
}
} // namespace mbed } // namespace mbed

View File

@ -52,24 +52,24 @@ BusOut::~BusOut() {
} }
void BusOut::write(int value) { void BusOut::write(int value) {
_mutex.lock(); lock();
for (int i=0; i<16; i++) { for (int i=0; i<16; i++) {
if (_pin[i] != 0) { if (_pin[i] != 0) {
_pin[i]->write((value >> i) & 1); _pin[i]->write((value >> i) & 1);
} }
} }
_mutex.unlock(); unlock();
} }
int BusOut::read() { int BusOut::read() {
_mutex.lock(); lock();
int v = 0; int v = 0;
for (int i=0; i<16; i++) { for (int i=0; i<16; i++) {
if (_pin[i] != 0) { if (_pin[i] != 0) {
v |= _pin[i]->read() << i; v |= _pin[i]->read() << i;
} }
} }
_mutex.unlock(); unlock();
return v; return v;
} }
@ -99,4 +99,12 @@ BusOut::operator int() {
} }
#endif #endif
void BusOut::lock() {
_mutex.lock();
}
void BusOut::unlock() {
_mutex.unlock();
}
} // namespace mbed } // namespace mbed

View File

@ -34,75 +34,75 @@ CAN::~CAN() {
} }
int CAN::frequency(int f) { int CAN::frequency(int f) {
_mutex.lock(); lock();
int ret = can_frequency(&_can, f); int ret = can_frequency(&_can, f);
_mutex.unlock(); unlock();
return ret; return ret;
} }
int CAN::write(CANMessage msg) { int CAN::write(CANMessage msg) {
_mutex.lock(); lock();
int ret = can_write(&_can, msg, 0); int ret = can_write(&_can, msg, 0);
_mutex.unlock(); unlock();
return ret; return ret;
} }
int CAN::read(CANMessage &msg, int handle) { int CAN::read(CANMessage &msg, int handle) {
_mutex.lock(); lock();
int ret = can_read(&_can, &msg, handle); int ret = can_read(&_can, &msg, handle);
_mutex.unlock(); unlock();
return ret; return ret;
} }
void CAN::reset() { void CAN::reset() {
_mutex.lock(); lock();
can_reset(&_can); can_reset(&_can);
_mutex.unlock(); unlock();
} }
unsigned char CAN::rderror() { unsigned char CAN::rderror() {
_mutex.lock(); lock();
int ret = can_rderror(&_can); int ret = can_rderror(&_can);
_mutex.unlock(); unlock();
return ret; return ret;
} }
unsigned char CAN::tderror() { unsigned char CAN::tderror() {
_mutex.lock(); lock();
int ret = can_tderror(&_can); int ret = can_tderror(&_can);
_mutex.unlock(); unlock();
return ret; return ret;
} }
void CAN::monitor(bool silent) { void CAN::monitor(bool silent) {
_mutex.lock(); lock();
can_monitor(&_can, (silent) ? 1 : 0); can_monitor(&_can, (silent) ? 1 : 0);
_mutex.unlock(); unlock();
} }
int CAN::mode(Mode mode) { int CAN::mode(Mode mode) {
_mutex.lock(); lock();
int ret = can_mode(&_can, (CanMode)mode); int ret = can_mode(&_can, (CanMode)mode);
_mutex.unlock(); unlock();
return ret; return ret;
} }
int CAN::filter(unsigned int id, unsigned int mask, CANFormat format, int handle) { 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); int ret = can_filter(&_can, id, mask, format, handle);
_mutex.unlock(); unlock();
return ret; return ret;
} }
void CAN::attach(Callback<void()> func, IrqType type) { void CAN::attach(Callback<void()> func, IrqType type) {
_mutex.lock(); lock();
if (func) { if (func) {
_irq[(CanIrqType)type].attach(func); _irq[(CanIrqType)type].attach(func);
can_irq_set(&_can, (CanIrqType)type, 1); can_irq_set(&_can, (CanIrqType)type, 1);
} else { } else {
can_irq_set(&_can, (CanIrqType)type, 0); can_irq_set(&_can, (CanIrqType)type, 0);
} }
_mutex.unlock(); unlock();
} }
void CAN::_irq_handler(uint32_t id, CanIrqType type) { 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(); handler->_irq[type].call();
} }
void CAN::lock() {
_mutex.lock();
}
void CAN::unlock() {
_mutex.unlock();
}
} // namespace mbed } // namespace mbed
#endif #endif

View File

@ -56,7 +56,7 @@ InterruptManager::~InterruptManager() {
} }
bool InterruptManager::must_replace_vector(IRQn_Type irq) { bool InterruptManager::must_replace_vector(IRQn_Type irq) {
_mutex.lock(); lock();
int ret = false; int ret = false;
int irq_pos = get_irq_index(irq); 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)); _chains[irq_pos]->add((pvoidf)NVIC_GetVector(irq));
ret = true; ret = true;
} }
_mutex.unlock(); unlock();
return ret; return ret;
} }
pFunctionPointer_t InterruptManager::add_common(void (*function)(void), IRQn_Type irq, bool front) { pFunctionPointer_t InterruptManager::add_common(void (*function)(void), IRQn_Type irq, bool front) {
_mutex.lock(); lock();
int irq_pos = get_irq_index(irq); int irq_pos = get_irq_index(irq);
bool change = must_replace_vector(irq); bool change = must_replace_vector(irq);
pFunctionPointer_t pf = front ? _chains[irq_pos]->add_front(function) : _chains[irq_pos]->add(function); pFunctionPointer_t pf = front ? _chains[irq_pos]->add_front(function) : _chains[irq_pos]->add(function);
if (change) if (change)
NVIC_SetVector(irq, (uint32_t)&InterruptManager::static_irq_helper); NVIC_SetVector(irq, (uint32_t)&InterruptManager::static_irq_helper);
_mutex.unlock(); unlock();
return pf; return pf;
} }
@ -85,13 +85,13 @@ bool InterruptManager::remove_handler(pFunctionPointer_t handler, IRQn_Type irq)
int irq_pos = get_irq_index(irq); int irq_pos = get_irq_index(irq);
bool ret = false; bool ret = false;
_mutex.lock(); lock();
if (_chains[irq_pos] != NULL) { if (_chains[irq_pos] != NULL) {
if (_chains[irq_pos]->remove(handler)) { if (_chains[irq_pos]->remove(handler)) {
ret = true; ret = true;
} }
} }
_mutex.unlock(); unlock();
return ret; return ret;
} }
@ -109,6 +109,14 @@ void InterruptManager::static_irq_helper() {
InterruptManager::get()->irq_helper(); InterruptManager::get()->irq_helper();
} }
void InterruptManager::lock() {
_mutex.lock();
}
void InterruptManager::unlock() {
_mutex.unlock();
}
} // namespace mbed } // namespace mbed
#endif #endif