There are three levels of synchronization supported:
Synchronization with ISRs. This normally means disabling
interrupts to prevent the ISR running during a critical
section. In an SMP environment, this will also require the use of
a spinlock to synchronize with ISRs, DSRs or threads running on
other CPUs. This is implemented by the
cyg_drv_isr_lock()
and
cyg_drv_isr_unlock()
functions. This
mechanism should be used sparingly and for short periods only.
For finer grained synchronization, individual spinlocks are also
supplied.
Synchronization with DSRs. This will be implemented in the kernel
by taking the scheduler lock to prevent DSRs running during
critical sections. In non-kernel configurations it will be
implemented by non-kernel code. This is implemented by the
cyg_drv_dsr_lock()
and
cyg_drv_dsr_unlock()
functions. As with ISR
synchronization, this mechanism should be used sparingly. Only
DSRs and threads may use this synchronization mechanism, ISRs are
not allowed to do this.
Synchronization with threads. This is implemented with mutexes and condition variables. Only threads may lock the mutexes and wait on the condition variables, although DSRs may signal condition variables.
Any data that is accessed from more than one level must be protected against concurrent access. Data that is accessed by ISRs must be protected with the ISR lock, or a spinlock at all times, even in ISRs. Data that is shared between DSRs and threads should be protected with the DSR lock. Data that is only accessed by threads must be protected with mutexes.