Drivers: locking sleep fix for attach/detach

As attach provides API to change a callback, lock/unlock should
only happen if we are doing the first/last callback (start-stop).
pull/4912/head
Martin Kojtal 2017-08-17 08:55:40 +01:00
parent e6d8a9a8a4
commit e57f0bcd26
5 changed files with 21 additions and 7 deletions

View File

@ -116,7 +116,10 @@ int CAN::filter(unsigned int id, unsigned int mask, CANFormat format, int handle
void CAN::attach(Callback<void()> func, IrqType type) { void CAN::attach(Callback<void()> func, IrqType type) {
lock(); lock();
if (func) { if (func) {
sleep_manager_lock_deep_sleep(); // lock deep sleep only the first time
if (_irq[(CanIrqType)type] == callback(donothing)) {
sleep_manager_lock_deep_sleep();
}
_irq[(CanIrqType)type] = func; _irq[(CanIrqType)type] = func;
can_irq_set(&_can, (CanIrqType)type, 1); can_irq_set(&_can, (CanIrqType)type, 1);
} else { } else {

View File

@ -77,7 +77,10 @@ void SerialBase::attach(Callback<void()> func, IrqType type) {
// Disable interrupts when attaching interrupt handler // Disable interrupts when attaching interrupt handler
core_util_critical_section_enter(); core_util_critical_section_enter();
if (func) { if (func) {
sleep_manager_lock_deep_sleep(); // lock deep sleep only the first time
if (_irq[type] == donothing) {
sleep_manager_lock_deep_sleep();
}
_irq[type] = func; _irq[type] = func;
serial_irq_set(&_serial, (SerialIrq)type, 1); serial_irq_set(&_serial, (SerialIrq)type, 1);
} else { } else {

View File

@ -25,8 +25,11 @@ namespace mbed {
void Ticker::detach() { void Ticker::detach() {
core_util_critical_section_enter(); core_util_critical_section_enter();
remove(); remove();
// unlocked only if we were attached (we locked it)
if (_function) {
sleep_manager_unlock_deep_sleep();
}
_function = 0; _function = 0;
sleep_manager_unlock_deep_sleep();
core_util_critical_section_exit(); core_util_critical_section_exit();
} }

View File

@ -64,10 +64,10 @@ namespace mbed {
class Ticker : public TimerEvent, private NonCopyable<Ticker> { class Ticker : public TimerEvent, private NonCopyable<Ticker> {
public: public:
Ticker() : TimerEvent() { Ticker() : TimerEvent(), _function(0) {
} }
Ticker(const ticker_data_t *data) : TimerEvent(data) { Ticker(const ticker_data_t *data) : TimerEvent(data), _function(0) {
data->interface->init(); data->interface->init();
} }
@ -103,8 +103,11 @@ public:
* @param t the time between calls in micro-seconds * @param t the time between calls in micro-seconds
*/ */
void attach_us(Callback<void()> func, us_timestamp_t t) { void attach_us(Callback<void()> func, us_timestamp_t t) {
// lock only for the initial callback setup
if (!_function) {
sleep_manager_lock_deep_sleep();
}
_function = func; _function = func;
sleep_manager_lock_deep_sleep();
setup(t); setup(t);
} }

View File

@ -41,8 +41,10 @@ void Timer::start() {
void Timer::stop() { void Timer::stop() {
core_util_critical_section_enter(); core_util_critical_section_enter();
_time += slicetime(); _time += slicetime();
if (_running) {
sleep_manager_unlock_deep_sleep();
}
_running = 0; _running = 0;
sleep_manager_unlock_deep_sleep();
core_util_critical_section_exit(); core_util_critical_section_exit();
} }