Trouble with FreeRTOS and xQueueSendFromISR()

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Trouble with FreeRTOS and xQueueSendFromISR()

Jump to solution
4,640 Views
mukelarvin
Contributor IV

Hi all,

I'm learning how to use FreeRTOS on the IMXRT1050 and I'm having trouble sending a message on a Queue from an ISR. I'm the pushbutton on the IMXRT1050-EVKB and the gpio input interrupt sample code.

When I set a flag in the ISR, read the flag in a task, then call xQueueSend() from the task it works okay.

However when I try to use xQueueSendFromISR() I get stuck on line 782 of port.c.

configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );

ucCurrentPriority is 0 and ucMaxSysCallPriority is 32. 

I'm kind of lost as to what to do. I tried setting NVIC_SetPriority(EXAMPLE_SW_IRQ, 32U); but that didn't help.

Any suggestions?

My code:

void EXAMPLE_GPIO_IRQHandler(void)
{
   /* clear the interrupt status */
   GPIO_PortClearInterruptFlags(EXAMPLE_SW_GPIO, 1U << EXAMPLE_SW_GPIO_PIN);
   /* Change state of switch. */
   g_InputSignal = true;

//    PRINTF("Pushbutton ISR");

   xQueueSendFromISR(publish_queue, &event, NULL);

/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
exception return operation might vector to incorrect interrupt */
#if defined __CORTEX_M && (__CORTEX_M == 4U)
__DSB();
#endif
}

void gpio_init(void)
{
   /* Define the init structure for the input switch pin */
   gpio_pin_config_t sw_config = {
      kGPIO_DigitalInput,
      0,
      kGPIO_IntRisingEdge,
   };

   

   /* Init input switch GPIO. */
//    NVIC_SetPriority(EXAMPLE_SW_IRQ, 32U);
   EnableIRQ(EXAMPLE_SW_IRQ);
   GPIO_PinInit(EXAMPLE_SW_GPIO, EXAMPLE_SW_GPIO_PIN, &sw_config);

   /* Enable GPIO pin interrupt */
   GPIO_PortEnableInterrupts(EXAMPLE_SW_GPIO, 1U << EXAMPLE_SW_GPIO_PIN);

   publish_queue = broker_register_publisher(topic);

   if (xTaskCreateStatic(gpio_task, "gpio_task", GPIO_TASK_STACK_SIZE, NULL, GPIO_TASK_PRIORITY,    gpio_task_stack, &gpio_task_buffer) == NULL)
   {
      PRINTF("Task creation failed!.\r\n");
      while (1)
         ;
   }
}

void gpio_task(void *pvParameters)
{
   while (1)
   {
      if (g_InputSignal)
      {
         delay();
         if (1 == GPIO_PinRead(EXAMPLE_SW_GPIO, EXAMPLE_SW_GPIO_PIN))
         {
//             PRINTF("Sending Pushbutton\r\n");
//            xQueueSend(publish_queue, &event, 0);
         }

         /* Reset state of switch. */
         g_InputSignal = false;
         taskYIELD();
      }
   }
}

static void delay(void)
{
   volatile uint32_t i = 0;
   for (i = 0; i < 1000000; ++i)
   {
      __NOP(); /* delay */
   }
}

Tags (3)
0 Kudos
Reply
1 Solution
4,247 Views
brucemckenney
Contributor III

I have a piece of code I paste in whenever I'm about to enable an interrupt. From memory, it looks like:

> NVIC_SetPriority(xxx_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);

That second argument isn't the value being compared -- that's configMAX_SYSCALL_INTERRUPT_PRIORITY,  which is what the CPU actually works with. Your choice of 32 is probably too large,  since __NVIC_PRIO_BITS is 4 in the RT1015.

View solution in original post

2 Replies
4,247 Views
mukelarvin
Contributor IV

Hi Bruce,

Okay setting the priority to 4 seemed to get the interrupt to work.That's the priority of my tasks.

I put a breakpoint on the line that was crashing before and my ucCurrentPriority came out as 64. I don't really understand the relationship between my ISR priority and the priority that appears in that port.c function but that's a problem for another day.

Thanks.

0 Kudos
Reply
4,248 Views
brucemckenney
Contributor III

I have a piece of code I paste in whenever I'm about to enable an interrupt. From memory, it looks like:

> NVIC_SetPriority(xxx_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY);

That second argument isn't the value being compared -- that's configMAX_SYSCALL_INTERRUPT_PRIORITY,  which is what the CPU actually works with. Your choice of 32 is probably too large,  since __NVIC_PRIO_BITS is 4 in the RT1015.