DMA usart issue on STM32F4

Hello, I’m working on STM32F437 and FreeRTOS 8.0.0. I have a problem with USART and DMA transmit: If I pass through InitVariablesForOs(), my DMA for USART transmit complete doens’t work. The first “111” is sent but the counter of the DMA is not decremented and obviously no DMA interrupt transmit complete(needed for RS485 direction)triggers. And in consequence the program wait endless the DMA buffer is empty before sendign the second “222”. int main void (void) { InitVariablesForOs();//init mutex, queue and semaphore Initlowlevel();//init hardware and NVIC SendOnUsart1(“111”,3); SendOnUsart1(“222”,3); SendOnUsart1(“333”,3); Initsometask here… vTaskStartScheduler(); } If I comment the first line DMA works well (obviously assert from Feertos will block later because the variable are NULL) I think interrupt are correct: void NVICConfiguration(void) { NVICInitTypeDef NVIC_InitStructure; /* Configure the NVIC Preemption Priority Bits */ NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 ); NVICInitStructure.NVICIRQChannelPreemptionPriority = 15; NVICInitStructure.NVICIRQChannelSubPriority = 0; NVICInitStructure.NVICIRQChannelCmd = ENABLE; /* Enable the Ethernet global Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = ETH_IRQn; NVIC_Init(&NVIC_InitStructure); NVICInitStructure.NVICIRQChannel = EXTI1510IRQn; NVICInit(&NVICInitStructure); NVICInitStructure.NVICIRQChannel = SDIOIRQn; NVICInit(&NVIC_InitStructure); NVICInitStructure.NVICIRQChannel = DMA2Stream3IRQn; NVICInit(&NVICInitStructure); /* Enable the USARTx Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_Init(&NVIC_InitStructure); NVICInitStructure.NVICIRQChannel = DMA2Stream7IRQn; NVICInit(&NVICInitStructure); } To be honnest I don’t see the link between os variable initialization and DMA. I ran step-by-step and I didn’t see why the behaviour is modified? Because I can work without usart DMA, I disabled it. Pierre

DMA usart issue on STM32F4

Your interrupt code looks ok – and I agree that there is no obvious reason for a link between calling the function the operation of the DMA. Please post the code InitVariablesForOs() so I can be sure. Regards, Richard Barry

DMA usart issue on STM32F4

Hi this is the code. With only one of these lines appears the problem.
void InitVariablesForOs (void)
{
    os.xQueueHandle_RXFromBrowser = xQueueCreate(10, sizeof (messageFromBrowser_t));
    os.xQueueHandle_RXFromCodine = xQueueCreate(10, sizeof (messageStatusFromcodine_t));

    os.signalACKfromCodineCard = xQueueCreate(1, sizeof (commandeAcknowledge_t));

    os.xQueueHandle_RXCodineStillAlive = xQueueCreate(5,sizeof(U16));
    os.SoftwareTimerCodineStillAlive = xTimerCreate( (const char *) "PollingCodine", VAL_TIMER_CALL,
                            pdTRUE, ( void * ) 0, TimerCallback);

    /*
    * Les mutex sont en variables static dans les fichiers
    */
    InitMutex__cust_log_RAM_access();
    InitMutex__List();
    InitMutex__cust_log_SD_access();
    InitMutex__cust_log_SD_access_technical();
    InitMutex__GlobalRAM();
    InitMutex__MuseogGlobalRAM();
    InitMutex__Tablelogin();
    InitSemaphore__DigOutput();
    InitMutex__EEPROM_access();




    /*LOG*/
    os.xQueue_log.xQueueFromModule = xQueueCreate(1, sizeof (logFromModule_t));
    os.xQueue_log.xQueueFromModuleMuseoguard = xQueueCreate(1, sizeof (logFromModuleMuseoguard_t));
    os.xQueue_log.xQueueFromWeb = xQueueCreate(5, sizeof (logFromWeb_t));
    os.xQueue_log.xQueueListenBroadcastServer = xQueueCreate(2, sizeof (logFromModuleBroadcastMessage_t));
    os.xQueue_log.xQueueTechnicalForDebug = xQueueCreate(5, sizeof (logTechnicalDebug_t));

    /*debug queues*/
// vQueueAddToRegistry( os.xQueueListenBroadcastServer, (signed char*)"misc Queue" );
// vQueueAddToRegistry( os.xQueueHandle_RXFromBrowser, (signed char*)"misc Queue" );
// vQueueAddToRegistry( os.xQueueHandle_RXFromCodine, (signed char*)"misc Queue" );
// vQueueAddToRegistry( os.signalACKfromCodineCard, (signed char*)"misc Queue" );
// vQueueAddToRegistry( os.xQueueHandle_MessageMuseoguard, (signed char*)"misc Queue" );
// vQueueAddToRegistry( os.xQueueHandle_RXCodineStillAlive, (signed char*)"misc Queue" );
}

DMA usart issue on STM32F4

With only one of these lines appears the problem.
Do you mean that including any of these lines will cause the problem, or that including one specific line will cause the problem (if so, which one?). If including any of these lines causes the problem then it would seem unlikely but not impossible it was the line itself that was the problem. I say not impossible because the lines are calling into the FreeRTOS kernel, which means critical sections will be being entered and exited – but that should definitely not cause a problem. Are you 100% sure the start up code is initialising the system correctly? Can you check the value of uxCriticalNesting both on entry into main() and immediately before starting the scheduler. uxCriticalNesting is defined in port.c, but I’m not sure which compiler you are using. You will find port.c in FreeRTOS/source/portable/[compiler]/ARMCM3 (or ARMCM4F). It should be non zero (probably 0xaaaaaaaa) when you enter main, and close to the same value before the scheduler is started. If the start up code was not executing properly you may find it had a different value. Regards.

DMA usart issue on STM32F4

Hi Richard, Yes including any of these lines. The first one is enough to stop the DMA. I’m on GCC. I checked uxCriticalNesting and it is not modified so far I can reach because the program loops in DMA_GetCurrDataCounter() under SendOnUsart1(). Then it doesn’t reach vTaskStartScheduler(). I checked with the DMA disabled and, the uxCriticalNesting variable is not modified before the scheduler starts. May be I must check all the SFR to see a possible change.

DMA usart issue on STM32F4

because the program loops in DMA_GetCurrDataCounter() under SendOnUsart1(). Then it doesn’t reach vTaskStartScheduler().
Ah! So you are trying to use the UART DMA interrupts before the scheduler has been started. That makes much more sense then. FreeRTOS will deliberately leave interrupts at and below configMAXSYSCALLINTERRUPT_PRIORITY masked until the scheduler has started. This is done to ensure interrupts do not try to use a FreeRTOS API function while the scheduler is in an inconsistent state. When you call the first FreeRTOS API function interrupts will be enabled, but when you come out they will be masked (still enabled, but masked to a certain priority level). Hence the interrupt stops working. The interrupts are automatically unmasked when the scheduler is started (when the tasks start running). Regards.

DMA usart issue on STM32F4

OK now. First I start a “main task” and the scheduler. So FreeRTOS runs before interrupt. At the end of the main task I delete it. Thank you