BinarySemaphore is not working form UART ISR

Go To Last Post
12 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

* Moved by moderator. *

 

 

I want to create BinarySemaphore for uart ISR. I create two task "handler_task1" , "perodic_task2".

 

1."handler_task1" is for uart ISR and it take BinarySemaphore for UART isr.

 

2."perodic_task2" is run in 700 ms and it transmit "Periodic task running" form UART, it work well until any interrupt come on rx of uart. If even a single interrupt come them there is no response on hyper terminal. and even perodic_task2 also stop sending message on terminal and led blink is also stop (connected on port c). 

 

Free rtos setting are same, as come in example code from freertos

 

So please help to solve this issue

 

/*******************************

//Microcontroller-- atmega32

//Complier --WINAVR 20100110 ,AVR STDIO 7

//CRESTAL FREQ-11.0592Mhz

//free rtos version-- FreeRTOS V9.0

//uart board rate-9600

 

//Memory uses, output window

//Program Memory Usage     :    5598 bytes   17.1 % Full
//Data Memory Usage         :    1665 bytes   81.3 % Full

*******************************/

 

 

 #include <avr/io.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include<stdbool.h>
 #include<util/delay.h>
 #include <avr/interrupt.h>                                    

                                     #include "uart.c"                        
                                     #include "uart.h"
 
 #include "FreeRTOS.h"
 #include "task.h"
 #include "queue.h"
 #include "list.h"                                                                                  
 #include "semphr.h"
     
#define mainMY_TASK_PRIORITY            (tskIDLE_PRIORITY + 3)
/* The period between executions of the check task. */
#define mainCHECK_PERIOD                (( portTickType ) 30 / portTICK_RATE_MS  )     

 

unsigned char blink=0x00;                                //variable for led blink connected on PORTC                                 

 

SemaphoreHandle_t  xBinarySemaphore;            //Semaphore variable         

//char reci,Temp;                                              //not used
ISR(USART_RX_vect) // ISR
{
  //Temp=UDR;
  //reci = Temp;
  //UART_TxChar('R');                        

   

   xSemaphoreGiveFromISR( xBinarySemaphore,NULL);        //give semaphore to handler task "handler_task1"    
 }                                     
                        
                                                
                                                 
#if (configUSE_IDLE_HOOK == 1) 
/*
 * The idle hook is used to scheduler co-routines.
 */
void vApplicationIdleHook(void);
#endif

    

 

    static void handler_task1( void *pvParameters);                        //uart interrupt handler task, this take semaphore
    static void perodic_task2( void *pvParameters);                        //This print "Periodic task running" on hypertermical in every 700ms
      
int main(void)

        PORTC=0XFF;                                        //for blinking led, connected on PORT C
        DDRC=0XFF;
        
        //Create binary semaphore
        vSemaphoreCreateBinary( xBinarySemaphore );    
            
        UART_init();                        //Init UART,BOUD RATE 9600,rx interrupt enable
        sei();                                //Enable interrupt
        
        if(xBinarySemaphore!=NULL)            //If semaphore not created,don't start scheduler    
         {        
         xTaskCreate( handler_task1,(signed portCHAR * ) "handler_task1",configMINIMAL_STACK_SIZE, NULL,2, NULL );        //UART interrupt handler task, this take semaphore
         xTaskCreate( perodic_task2,(signed portCHAR * ) "perodic_task2",configMINIMAL_STACK_SIZE, NULL,1, NULL );        //periodic task, this run continuously in 700ms 
         vTaskStartScheduler();
         }
    
     while (1) 
     {
        ;
     }
}
   //This task never run, when a single character come form uart isr it stop perodic_task2 also 
   

static void handler_task1( void *pvParameters )
   {
       //The parameters are not used.
       
       for( ;; )
       {
               xSemaphoreTake( xBinarySemaphore,portMAX_DELAY);        
               UART_TxChar('A');                //when interrupt come, print A,B on hyper terminal
               UART_TxChar('B');
       }
   }
 
 //It run but when ever rx interrupt come it stop and nothing come on hyper terminal 
     

static void perodic_task2( void *pvParameters )
     {
         /* The parameters are not used. */
      
         (void) pvParameters;
         
         portTickType xLastWakeTime;
         
         xLastWakeTime = xTaskGetTickCount();

         for( ;; )
         {
                  PORTC=blink;                                                   //blink led, connected on port c
                  blink=~blink;
                   
                 send_string("Periodic task running");                    //Send data on serial port
                 UART_TxChar('\r');
                 UART_TxChar('\n');  
               
           vTaskDelayUntil( &xLastWakeTime, (700 / portTICK_RATE_MS ) );      //Here the task execute in 700ms
         }
     }
     
    #if (configUSE_IDLE_HOOK == 1)
    void vApplicationIdleHook( void )
    {
        //vCoRoutineSchedule();
    }
    #endif 
      

This topic has a solution.
Last Edited: Sat. Dec 1, 2018 - 05:43 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Surely if you have a sem4 then the plan is that BOTH tasks try to take it when they need access to the resource? I see task1 doing a xSemaphoreTake() but there's no sign of task2 attempting this?

 

Also I don't know the syntax of FreeRTOS but shouldn't you be releasing the sem4 after you have made local use of the resource?

 

(quick look at FreeRTOS site seems to suggest opposite of take is xSemaphoreGive() - which I guess is the expected name)

 

Perhaps see this example code in the user manual:

 

https://www.freertos.org/a00123....

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think thats a pretty clunky way of handling the usart - rtos or no rtos. Surely you would want a circular buffer. Nevertheless,where is UDR read? The rxc interrupt flag never gets cleared and will keep on interrupting.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank for replay,

 

1.I use  "xSemaphoreGiveFromISR" in ISR. but processor stop working.

 

2. And in second post as suggested to use circular buffer for uart is a good idea but I want to try this for different interrupts like compactor or io. So I have to use  Semaphore.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Do you have a design diagram that explains what you expect your execution sequence to be here?

 

As I see it task 1 takes the sem4 then transmits 'A', 'B' but then for the sem4 to be given back it seems like you are waiting for an Rx so does this mean that after the receiving end has got the "AB" it's then going to return a character to trigger the ISR so the sem4 can be released? But even if that s the case the task 2 is not making an attempt to then take the sem4 before it makes use of the shared resource (UART) So how is task 2 protected from not using the UART resource while task 1 has the sem4 if it doesn't try to take the same thing?

 

Also why a sem4 anyway? Wouldn't you just use a mutex ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Please see the attachment for flow chart.

 

And as you ask--

 

Q.how is task 2 protected from not using the UART resource while task 1 has the sem4 if it doesn't try to take the same thing?

A. I also disable periodic task but the result are same. 

 

And just I want to know why  Semaphore  is not working in ISR. I following freertos manual but it is not working.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Perhaps you should seek help from a freertos forum:  https://www.freertos.org/FreeRTO...

 

Click Link: Get Free Stock: Retire early!

share.robinhood.com/jamesc3274

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Again, where do you read UDR?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

At presently I am generating uart interrupt only. And I want to use binary and counting semaphore for my application (taking command form serial port). and as you see, in ISR some code is commented, I already try by reading UDR but this make no difference.

   

One more think, I try counting semafore and it work when I send a character but It continuously send 'A' and 'B' on terminal.

 

For using counting semafore I change configUSE_COUNTING_SEMAPHORES     1     in  FreeRTOSConfig.h

 

And just for review this my UART init functions.

 

/********************************************************************************************************/

#define USART_BAUDRATE 9600
#define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)

 

void UART_init(void)
{
    UCSRB |= (1 << TXEN);
    UCSRB |= (1 << RXEN) | (1 << RXCIE);/* Turn on the transmission and reception */
    UCSRC |= (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1);/* Use 8-bit character sizes */

    UBRRL = BAUD_PRESCALE;        /* Load lower 8-bits of the baud rate */
    UBRRH = (BAUD_PRESCALE >> 8);    /* Load upper 8-bits */
}

 

 

 

Last Edited: Sat. Nov 10, 2018 - 07:59 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Then you have multiple problems!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No, I testing with counting semaphore and I found this.

 

 But first I want to solve issue with binary semaphore.

 

 Is there any other setting in  FreeRTOSConfig.h ?

 

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This code is correct. Problem come when I send some byte from serial port of PC. This is solved