Code stuck in ISR, semaphore not given/taken

Hi I am learning freeRTOS on a TI-RSLK with a msp432p401r. I am trying to use ISR to unblock a task using semaphores. However, the program runs, goes into the ISR and gets stuck. It also displays some weird motor function where it sometimes just stop, while other times it speeds up. The speeding up I suspect is due to the ISR suspending all other tasks other than the motor_forward task. But what is peculiar is my program plays a song normally while moving, if the ISR stops all other tasks at a random point depending on when I press it, then shouldn’t there be a chance where the song is left playing i.e. the task_playsong is the only one left running? But that never happens which baffles me.

The main problem I wanted to solve is the semaphore problem, the motor behavior is given in case it provides any clues. Below are the code snippets.

The interrupt is initalized with the following code:

void ISRBumpSwitch_Init(void){
    P4->SEL0 &= ~0xED;
    P4->SEL1 &= ~0xED;      // configure as GPIO
    P4->DIR &= ~0xED;       // make in
    P4->REN |= 0xED;        // enable pull resistors
    P4->OUT |= 0xED;        // pull-up
    P4->IES |= 0xED;        // falling edge event
    P4->IFG &= ~0xED;       // clear flag
    P4->IE |= 0xED;         // arm the interrupt
    // priority 2 on port4
    NVIC->IP[9] = (NVIC->IP[9]&0xFF00FFFF)|0x00400000;
    // enable interrupt 38 in NVIC on port4
    NVIC->ISER[1] = 0x00000040;
    //NVIC_EnableIRQ(PORT4_IRQn);
}
Interrupt_enableInterrupt(INT_PORT4);
Interrupt_registerInterrupt(INT_PORT4, *PORT4_IRQHandler);
Interrupt_setPriority(INT_PORT4,3);

The interrupt handler is below, I know it goes into the handler as the corresponding LED lights up.

void PORT4_IRQHandler(void){
    //Port2_Output2(RED);
    //UBaseType_t uxSavedInterruptStatus;
    BaseType_t xHigherPriorityTaskWoken;
    BaseType_t test;
    xHigherPriorityTaskWoken = pdFALSE;

    bumpSwitch_status = P4-> IV;
    switch(bumpSwitch_status){  //coloured LED indicates which bumpswitch is hit
               case 0x02:
                 Port2_Output2(RED);
                 break;
               case 0x06:
                 Port2_Output2(GREEN);
                 break;
               case 0x08:
                 Port2_Output2(YELLOW);
                 break;
               case 0x0C:
                 Port2_Output2(BLUE);
                 break;
               case 0x0E:
                 Port2_Output2(PINK);
                 break;
               case 0x10:
                 Port2_Output2(SKYBLUE);
                 break;

             }
    //vTaskResume(taskHandle_ISRdcMotor);
    //uxSavedInterruptStatus=taskENTER_CRITICAL_FROM_ISR();
    xSemaphoreGiveFromISR( xSemaphore, &xHigherPriorityTaskWoken );
    //taskEXIT_CRITICAL_FROM_ISR(uxSavedInterruptStatus);
    P4->IFG &= ~0xED;
    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}

The semaphore is declared globally and created inside the main code that also creates the tasks. I made sure it is created with if xSemaphore != NULL:

SemaphoreHandle_t xSemaphore;

xSemaphore = xSemaphoreCreateBinary();

The task that is supposed to take the semaphore and run:

static void taskISRdcMotor( void *pvParameters )
{
    //dcMotor_Init();
    for(;;){
    //bumpSwitch_status = Bump_Read_Input();
    xSemaphoreTake( xSemaphore, portMAX_DELAY );
    vTaskSuspend(taskHandle_MotorForward);
    Port2_Output2(YELLOW);
    SysTick_Wait10ms(20);
    ISRdcMotor_response(bumpSwitch_status);
    vTaskResume(taskHandle_MotorForward);   
    }
}

The unblocked task has the same priority of 1 as all my other tasks in the scheduler. The interrupt has a priority of 3 if the Interrupt_setPriority() function is working fine, if not then it might be declared by the NVIC to have a priority of 2. In this system higher priority gets a higher number. I am not sure whether the problem is with the semaphore not being given by the ISR; or it not being taken by the task. If there is a way to test this please let me know and I will update the post. Thank you for reading and I apologize for all the commented out code, it’s just things I tried to no avail.

Hi @samc ,

A couple of quick checks I can suggest…

From experience if you are running multiple tasks at the same priority it would be worth while checking you have

#define configUSE_TIME_SLICING					1
#define configUSE_PREEMPTION					1

set in your configuration file.

Also it may be worth checking none of your processes are running in a tight loop without any kind of yielding.

Hope that is helpful.

Kind Regards,

Pete

Hi samc,

from your description it is not clear whether you have reason to believe that the ISR gets called repeatedly, locking out the rest of the system, or the system itself continues running but your motor subsystem does not. Obviously nothing is faulting?

If the first case is true, the only thing that can really cause your problem is failing to reset the interrupt source. In the second case, you may want to check for possible deadlocks. What does the task do that is being suspended? Also, what is the implementation of SysTick_Wait10ms (not a FreeRTOS function)? Could it be that your timer ISR gets permanently locked out (to test, monitor xTickCount in a real time watch window)?

1 Like

How is the ISR suspending all other tasks? Just to check they aren’t using the same semaphore as your dc motor task you’ve given, right?


Is the ISR exiting? I’d think if the playsong task is the only one unblocked then it should be running unimpeded once the ISR has completed.