Assuming you have a steady stream of data coming in via DMA, and you want to process it in chunks. The DMA’s half-transfer-complete interrupt is perfect for this.
I am a big fan of task notifications, especially using eSetBits. It would look something like this (starting from your pseudocode just to illustrate eSetBits):
#define BUF_ITEM_COUNT 10
uint16_t Dbuf[BUF_ITEM_COUNT * 2];
#define BUFFER_A (Dbuf)
#define BUFFER_B (Dbuf + BUF_ITEM_COUNT)
#define NOTIFICATION_FLAG_BUFFER_A_READY (1UL << 0)
#define NOTIFICATION_FLAG_BUFFER_B_READY (1UL << 1)
static TaskHandle_t consumerThreadHandle;
void DMAz_StreamX_IRQHandler(void)
{
uint32_t notificationFlags = 0UL;
if (DMA_IsActiveFlag_TCy(DMAz)) {
DMA_ClearFlag_TCy(DMAz);
// We know here that the second half of the
// DMA transfer has been complete
notificationFlags |= NOTIFICATION_FLAG_BUFFER_B_READY;
}
if (DMA_IsActiveFlag_HTy(DMAz)) {
DMA_ClearFlag_HTy(DMAz);
// We know here that the first half of the
// DMA transfer has been complete
notificationFlags |= NOTIFICATION_FLAG_BUFFER_A_READY;
}
BaseType_t wasHigherPriorityTaskWoken = pdFALSE;
xTaskNotifyFromISR(consumerThreadHandle, notificationFlags, eSetBits, &wasHigherPriorityTaskWoken);
portYIELD_FROM_ISR(wasHigherPriorityTaskWoken);
}
void consumer_thread()
{
uint32_t notificationValue;
while (1) {
// access buf1 or buf2,
// depending on buf_flag, choose access to the relevant buffer
//
// Just that we should not Read the buffer to which DMA is writing
// We will need to sleep, in case the buffer is not yet ready
//
// The idea is that the consumption rate is higher
// than the producer rate. Which is easy with additional sleep
// for the consumer.
xTaskNotifyWait(0, ULONG_MAX, ¬ificationValue, portMAX_DELAY);
if (notificationValue & NOTIFICATION_FLAG_BUFFER_A_READY) {
consumeBuffer(BUFFER_A);
}
if (notificationValue & NOTIFICATION_FLAG_BUFFER_B_READY) {
consumeBuffer(BUFFER_B);
}
}
}
As others suggested you would still want to add code to verify you are meeting your real-time deadlines. If you get behind, you might end up processing buffer ‘A’ while the DMA is filling buffer ‘A’, which of course is no good.