MQX releasing a semaphore in a interrupt handler

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MQX releasing a semaphore in a interrupt handler

546 Views
viveksrinivasan
Contributor I

Hello everyone,

I'm using KSDK_1.2.0 with twrk65f180m.

Initially I tested the uart_edma_blocking example with bare metal and it worked fine.

Then I copied the example under a thread in an application which uses MQX operating system.

Basically I copied the below code into a thread (this is the only thread in that application). I commented out hardware_init() and OSA_Init() since they are already done. I have also disabled BSPCFG_ENABLE_IO_SUBSYSTEM since I want to use the uart_edma_blocking  example instead.

    uint8_t dmaRxChar  = 0;

    uint32_t byteCountBuff = 0;

    // Store runtime state structure for the eDMA driver

    edma_state_t                state;

    // Store runtime state structure for UART driver with EDMA

    uart_edma_state_t           uartStateEdma;

    // Config the eDMA driver

    edma_user_config_t          userConfig = {

        .chnArbitration  = kEDMAChnArbitrationRoundrobin,

        .notHaltOnError  = false

    };

    // Config the UART driver

    uart_edma_user_config_t     uartConfig = {

        .bitCountPerChar = kUart8BitsPerChar,

        .parityMode      = kUartParityDisabled,

        .stopBitCount    = kUartOneStopBit,

        .baudRate        = BOARD_DEBUG_UART_BAUD

    };

    // Enable clock for PORTs, setup board clock source, config pin

    //hardware_init();

    // Call OSA_Init to setup LP Timer for timeout

    //OSA_Init();

   

#if defined (TEST_CODE)

    semaphore_t testSemaphore;   

    OSA_SemaCreate(&testSemaphore, 0);   

    osa_status_t syncStatus = OSA_SemaWait(&testSemaphore, 1000u);

#endif

   

    // Initialize EDMA module for UART

    EDMA_DRV_Init(&state, &userConfig);

    UART_DRV_EdmaInit(BOARD_DEBUG_UART_INSTANCE, &uartStateEdma, &uartConfig);

    // Inform to start dma-uart blocking example

    byteCountBuff = sizeof(buffStart);

    UART_DRV_EdmaSendDataBlocking(BOARD_DEBUG_UART_INSTANCE, buffStart, byteCountBuff, 0u);

    // Inform user of what to do

    byteCountBuff = sizeof(bufferData1);

    UART_DRV_EdmaSendDataBlocking(BOARD_DEBUG_UART_INSTANCE, bufferData1, byteCountBuff, 0u);

    while(true)

    {

        // Wait to receive input data

        if (kStatus_UART_Success == UART_DRV_EdmaReceiveDataBlocking(BOARD_DEBUG_UART_INSTANCE, &dmaRxChar,1, OSA_WAIT_FOREVER))

        {

            // Echo received character

            UART_DRV_EdmaSendDataBlocking(BOARD_DEBUG_UART_INSTANCE, &dmaRxChar, 1u, 0u);

        }

    }

It sends the first set of data (buffStart) to the terminal after which it crashes and goes to hardfault handler.

The problem is when I step through the code it does not crash. I can see that the DMA interrupt happens. The call back function (UART_DRV_EdmaCompleteSendData) is called which posts the semaphore (txIrqSync). It continues to send the second set of data (bufferData1).

I'm not sure if I'm doing something wrong here. If I create, pend and release the semaphore outside an interrupt handler, I don't see this issue happening.

I'm not sure if I have to do some kind of critical section protection here. Not much information available on the MQX reference manual.

Any help is greatly appreciated.

Thank you.

0 Kudos
1 Reply

279 Views
Carlos_Musich
NXP Employee
NXP Employee

Hi Vivek,

Which exact functions are you calling within interrupts?

Please refer to 'MQX RTOS Reference Manual.pdf' located in C:\Freescale\KSDK_1.2.0\doc\rtos\mqx

Note that many of the lwsem functions cannot be called from interrupts.

Regards,

Carlos

0 Kudos