FreeRTOS Sempahore from ISR not working

ableeldhose wrote on Thursday, January 23, 2014:

I need to make a data accusition device whose one task is to samples some GPIO’s and record the GPIO status and send it to PC via UART to display in PC. The algorithm i chose was (please correct me since iam very novice in RTOS) to create a timer running at 1us and then poll the status of all GPIO needed. For that i used a timer in the freertos demo. And give a semaphore in the timer ISR which should call a task which do all the remaining job.

Don’t know why but the code i edited dont work

My main() is

int main(void) {
  /* Prepare the hardware to run this demo. */
  prvSetupHardware();

  vSemaphoreCreateBinary(SemaphoreTask);
  if( SemaphoreTask != NULL )
  {
    xTaskCreate( SemaphoreTakeTask, "SemaphoreTakeTask", 240, NULL , 3, NULL );
    vTaskStartScheduler();
  }
  for(;;);
  return 0;
}

Task 1 a dummy function i wrote just to try out if semaphore is working

void SemaphoreTakeTask(void* parameter){
  vSetupTimerTest(10);                 // Timer initialization function in FreeRtos DEMO
  TRISEbits.TRISE6 = 0;                // Set the GPIO as Output
  xSemaphoreTake( SemaphoreTask, 0 );  // As mentioned in user guide just take the semaphore once to clear the semaphore at start
  for(;;){
    xSemaphoreTake( SemaphoreTask, portMAX_DELAY );
    LATEbits.LATE6 ^= 1;               // Toggle an IO to see whether its working
  }
}

Timer ISR handler

void vT2InterruptHandler(void) {
  portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
  /* Clear the timer interrupt. */
  IFS0CLR = _IFS0_T2IF_MASK;
  xSemaphoreGiveFromISR(SemaphoreTask, &xHigherPriorityTaskWoken);
  if (xHigherPriorityTaskWoken != pdFALSE) {
    portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
  }
}

When i put break point in the ISR handler it comes there but the GPIO is not toggling (which i placed in Task 1)

Iam a novice in RTOS so please pardon me if i missed any basic things in the code

I just need to give a semaphore from ISR handler

edwards3 wrote on Thursday, January 23, 2014:

I cant see anything wrong with your use of the FreeRTOS API. You dont need to test xHigherPriorityTaskWoken before callilng portEND_SWITCHING_ISR as the test is in the macro, but it wont cause you a problem.

But do you really want to do this at 1uS. That is too fast to use a queue in this way. At that speed you need to do the IO sampling inside the interrupt handling function, even then it is very fast. You will need to pack the sampled bits into larger data variables to send at that rate over a uart.

ableeldhose wrote on Friday, January 24, 2014:

@Medwards
I added one extra task Task1 which just blinks another LED1 using vTaskDelay.
Another task Task2 which waits for the semaphore and toggles an LED2 when recieved semaphore.

When Semaphore is given from the Task1 everything works fine.

When that semaphore is given from ISR which occurs after 5 second
Untill the xSemaphoreGiveFromISR is called the Task1 is working, but when it is called everything gets stuck and the code moves to a infinite loop in vAssertCalled(). So for 5 seconds LED1 will toggle and after that its does not.

When i commented that xSemaphoreGiveFromISR in the ISR then Task1 is working without any issue

I placed a breakpoint just below the xSemaphoreGiveFromISR and the control never reach that line. When the xSemaphoreGiveFromISR is commented then control reaches there.

I cant understand the issue since iam a starter in RTOS

rtel wrote on Friday, January 24, 2014:

Each call to configASSERT() contains a condition that is tested to ensure the system status (variable values, hardware state, etc.) is valid. As vAssertCalled() is being called then a condition passed to configASSERT() has been found to be invalid - which is presumably why your application is not working.

Which call to configASSERT() is failing?

Regards.

ableeldhose wrote on Friday, January 24, 2014:

The configAssert() call from the below #define is found to get stuck

 portASSERT_IF_INTERRUPT_PRIORITY_INVALID();

The #define expansion is

 #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() configASSERT( portCURRENT_INTERRUPT_PRIORITY <= configMAX_SYSCALL_INTERRUPT_PRIORITY )

After this function call everything gets stuck.
No task is running after this

davedoors wrote on Friday, January 24, 2014:

You must set the priority of the interrupt to below your configMAX_SYSCALL_INTERRUPT_PRIORITY setting. Read the Configuration section of the web page that details how to use the port. THe following page might help (or serve to confuse more) too http://www.freertos.org/RTOS-Cortex-M3-M4.html

ableeldhose wrote on Friday, January 24, 2014:

@Dave
Thanks man
It works