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.