DMA overførsel via FreeRtos queue systemet fra ISR routine.

På mit arbejde har jeg længe haft et problem med, ikke at kunne få kald til FreeRtos queue systemet til at virke fra en  ISR routine, når jeg brugte DMA overførsel. Problemet var, at min DMA overførsel gik i stå efter et lille stykke tid. Jeg har levet med det, og lavet en work-around, hvor jeg brugte en global buffer i stedet. Ikke særlig optimalt, men det virkede.

I dag fandt jeg endelig ud af, hvorfor FreeRtos queues ikke virkede. Problemet viste sig, at være fordi, kørte DMA’en i Normal mode, hvilke bevirkede at DMA’en nogle gange hang. Ved at sætte DMA’en i Circurlar mode, bliver DMA’en genstarter fra begyndelsen, hver gang ny data modtages.

Så nedenstående simple ændring fiksede mit problem.

Mit git diff  🙂

–    hdma_usart1_tx.Init.Mode = DMA_NORMAL;

+    hdma_usart1_tx.Init.Mode = DMA_CIRCULAR;

 

–       rxBuffer[wr_ptr] = aRxBuffer[0];

–       uint8_t new_wr_ptr = (wr_ptr + 1) % RXBUFFER_MAX;

–       if (new_wr_ptr == rd_ptr) {

–               vSerialPutString(( signed char * ) “Buffer overflow”);

–       } else {

–               wr_ptr = new_wr_ptr;

–       }

–       //xQueueSendToBackFromISR(uartFifo, ( void * ) &aRxBuffer[0], 100);

+       xQueueSendToBackFromISR(uartFifo,  &aRxBuffer[0], NULL );^M

}

 

Leave a Reply

Your email address will not be published. Required fields are marked *