cancel
Showing results for 
Search instead for 
Did you mean: 

FreeRTOS +UART TX DMA+ UART RX Size variant buffer

r2s
Associate II
Posted on November 22, 2016 at 22:11

Hi guys, I'm facing out some problems and i wonder if some of you can give some of your wisdom.

Here are some inputs:

  • MCU: STM32L053 (Host)

  • GSM Module: handles GSM network connecctions and notifify via UART the MCU. It also receives MCU commands.

  • UART-USB converters: They let me monitor what happens in each pin (RX and TX) by means of hiperterminals

  • UART TX +DMA for transmissions of AT commands

  • UART  RX for reception of messages of different sizes.

  • I don t use the hal library for the uart IRQ. (unfortunately, ST doesn't provide std firmware neither! So i ve )

My purpose is as follows:

trigger 2 different threads depending on a received buffer pattern. For this, i will use a preemptive scheduler (FreeRTOS V8.2.3+ cmis os interface).

Here are some code snippets with brief some brief explanation:

static void EmergencyButtonEventProcess(void)

{

    DelSMS();

}

 void DelSMS(void)

 {

      Send_AT_Command(eDelete_All_Sms);

 }

static void Send_AT_Command(AT_CommandId_tE  Cmd_Id_tE)

{

...

      U8 source[MAX_SIZE_FOR_BUFFER]; 

      switch(Cmd_Id_tE)

      {

            case eCheck_Gsm_Module:

                  strcpy(source, CHECK_GSM_MODULE);

                  sizeOfBuffer = LibTyp_StrLen(&source);

           

   HUart_Transmit( HUart_eUart2, source,

sizeOfBuffer );

                  break;

            case eRead_SMS:

                  strcpy(source, READ_SMS_COMAND);

                  sizeOfBuffer = LibTyp_StrLen(&source);

           

   HUart_Transmit( HUart_eUart2, source,

sizeOfBuffer );

                  break;

            case eDelete_All_Sms:

                  strcpy(source, DELETE_ALL_SMS_COMAND);

                  sizeOfBuffer = LibTyp_StrLen(&source);

           

   HUart_Transmit( HUart_eUart2, source,

sizeOfBuffer );

                  break;

            default:

                  break;

      }

}

These functions are called when a button is pressed  and after a debounce time has passed. I used the IRQ of a GPIO and IRQ of a timer.

When the button is pressed more than 5 seconds a command is sent to the GSM module and this one responds with an OK. The transmition is done with a uart peripheral of the MCU and DMA. All works correctly and as expected. In this case i have not used any of the OS services but maybe in the future, i would sync with a semaphore. I don't think this is necessary.

void USART2_IRQHandler (void)

{

   //Store DR

  //Detect patern and store it in appropiate buffers...

if(TX_RX_Buffer_Flag_tb ==TRUE)

{

... //more pattern tests...

      //store TX_RX_Buffer[] 

      TX_RX_Buffer_Flag_tb =FALSE;

      osSignalSet(ThreadId_2, BIT_2 );

}

if(RX_Buffer_Flag_tb==TRUE)

{

... more process

   //store RX_Buffer[]       

   osSignalSet(ThreadId_1, BIT_1);

}

  

}

In the UART IRQ, i fill up 2 buffers depending on the start of the message. Basically, we have 2 types:

  • TX_RX_Buffer[] = ''AT+something

    \n'' pattern corresponds to a answer of the gsm module after a command has been sent.

  • RX_Buffer[] = ''\r  something \n'' pattern corresponds to a notification of the gsm module. 

A event flag is set and notified to the OS. A related thread (depending on the buffer patern detected) has to be triggered 

static void Thread1_RX_Buffer(void const *argument)

 {

      osEvent event;

      for(;;)

      {

        event = osSignalWait( BIT_1, osWaitForever);

        if(event.value.signals == BIT_1)

        {

            Send_AT_Command(eRead_SMS); //UART Transmit with DMA is called

           }

}

static void Thread2_TX_RX_Buffer (void const *argument)

{

  (void) argument;

  osEvent event;

  RelayId_tE Id_tE;

  for(;;)

  {

    event = osSignalWait( BIT_2 , osWaitForever);

    if(event.value.signals == (BIT_2 ))

    {

        Send_AT_Command(eMakeCall);  //UART Transmit with DMA is called

    }

  }

}

Here the Threads are triggered as expected. The problem is that only 3 characters are transmitted and the rest are incoherent (i.e

AT+C����[02][00]).

On the other hand, the same transmission function is called when the button is pressed and all is ok.

 

I think that the tick interrupt related to the OS corrupts the UART DMA transmission. How can i sort this out ? Any suggestions? 

PS: Any suggestions are welcome concerning the design/implementation. There are still some improvements to do like copy the buffer for deferred processing ....

#freertos-+uart-tx-dma+-uart-rx
0 REPLIES 0