Hi, I'm new to embedded development so please correct me if I'm wrong here.
Currently AudioStream.cpp uses allocate() and release() functions to allocate memory to audio blocks. These functions call __disable_irq() and __enable_irq(), which can lead to problems if the user has disabled interrupts beforehand, since allocating or releasing memory will re-enable interrupts. I discovered it when working on some issues with usb audio transfers, and replacing __disable_irq() and __enable_irq() inside of allocate/release functions with ATOMIC_BLOCK(ATOMIC_RESTORESTATE) from avr-libc util/atomic.h seems to solve this problem. By this I mean
As far as I understood atomic block macro checks global interrupt state when entering its scope, disables interrupts and enables them again only if they were set when entering its scope.
Currently AudioStream.cpp uses allocate() and release() functions to allocate memory to audio blocks. These functions call __disable_irq() and __enable_irq(), which can lead to problems if the user has disabled interrupts beforehand, since allocating or releasing memory will re-enable interrupts. I discovered it when working on some issues with usb audio transfers, and replacing __disable_irq() and __enable_irq() inside of allocate/release functions with ATOMIC_BLOCK(ATOMIC_RESTORESTATE) from avr-libc util/atomic.h seems to solve this problem. By this I mean
Code:
void AudioStream::release(audio_block_t *block)
{
//if (block == NULL) return;
uint32_t mask = (0x80000000 >> (31 - (block->memory_pool_index & 0x1F)));
uint32_t index = block->memory_pool_index >> 5;
//__disable_irq();
ATOMIC_BLOCK(ATOMIC_RESTORESTATE){
if (block->ref_count > 1) {
block->ref_count--;
} else {
//Serial.print("reles:");
//Serial.println((uint32_t)block, HEX);
memory_pool_available_mask[index] |= mask;
if (index < memory_pool_first_mask) memory_pool_first_mask = index;
memory_used--;
}
}
//__enable_irq();
}
As far as I understood atomic block macro checks global interrupt state when entering its scope, disables interrupts and enables them again only if they were set when entering its scope.