Calling _lwsem_post or _lwevent_set from interrupt routine caused Cpu_ivINT_Hard_Fault

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

Calling _lwsem_post or _lwevent_set from interrupt routine caused Cpu_ivINT_Hard_Fault

1,474 Views
z3
Contributor II

I am using FRDM-KL25Z platform with OpenSDA. MQX-Lite (V1.1.0) is the OS. I ported the Freescale USB stack (V5.0) HID keyboard to my project. Without using lwsem or lwevent, the code worked fine. With either lwsem or lwevent, the system crashes. The PC is restored to 0x00000000 upon return from USB_ISR. Here is the code:

extern void usb_int_cb(void);

void __attribute__ ((interrupt)) USB_ISR(void)

{

   if (lowlevel_usb_isr != NULL)

   {

      lowlevel_usb_isr(isr_param_usb_isr);

      usb_int_cb();

   }

}

void usb_int_cb(void)

{

   retval0 = _lwevent_set(&commevt, 1);

}

void Task2_task(uint32_t task_init_data)

{

   _mqx_uint retval = _lwevent_create(&commevt, LWEVENT_AUTO_CLEAR);

   USB_init();

   while (1)

   {

      USB_task();

      retval = _lwevent_wait_ticks(&commevt, 1, TRUE, 1000);

      if ( !(retval == MQX_OK || retval == LWEVENT_WAIT_TIMEOUT) )

         _time_delay_ticks(10);

   }

}

Without lwsem or lwevent, MQX-Lite is useless. Any ideas?

5 Replies

734 Views
CarlosCasillas
NXP Employee
NXP Employee

Hi Qing,

On MQX-Lite, the interrupts are not managed by the RTOS; they are executed outside of the operating system context (like bare-metal). Therefore, using MQX-functions inside Interrupts will cause unexpected exceptions, so, the recommendation for these cases is “setting flags” inside the interrupts that could be used by the RTOS for setting the proper events or calling MQX-functions.

Hope this will be useful for you.

Best regards!

/Carlos

0 Kudos

734 Views
jwiblin
Contributor II

I am running into similar problems trying to use _lwevent_set in a ISR with MQX lite. Are you saying that it is not possible to use MQX-functions in 2nd level (user) ISRs at all Carlos?

My understanding from the reference manual was that it was possible to use MQX functions in 2nd level ISRs (those declared with _int_install_isr() ) but not in kernel ISRs (those declared with _int_install_kernel_isr() )

Thanks,

James.

0 Kudos

734 Views
CarlosCasillas
NXP Employee
NXP Employee

Hi James,

MQX Lite handles all hardware interrupts as defined in the Interrupt Vector Table generated by PEx (see vector.c). Similarly to standard MQX, MQX Lite provides a first level ISR (kernel ISR), which is written in assembly language. The first-level ISR runs before any other ISR, and performs these tasks:

• It saves the context of the active task.

• It switches to the interrupt stack.

• It calls the appropriate, second-level, (application) ISR.

• After the ISR has returned, it restores the context of the highest-priority ready task (context switch may occur).

First-level ISR can be replaced by the user-specific ISR on a per-vector basis. MQX Lite provides second-level application ISRs that are coded as regular functions and are installed into MQX Lite Interrupt Table through the Interrupt component API.

Default second-level ISR for all possible interrupt sources is installed when MQX Lite starts. MQX Lite also supports the installation of the user-specific, default, second-level ISR. When a second-level ISR is called, the parameter, which the application defines when the application installs the ISR, is passed to the ISR.

Each entry of the MQX Lite Interrupt Table consists of:

• A pointer to the ISR to call.

• Data to pass as a parameter to the ISR.

• A pointer to an exception handler for that ISR.

MQX Lite supports installing an exception handler and enabling and disabling the Hardware interrupts.

The difference between the Interrupt component in the standard MQX and the MQX Lite is minimal and involves statistical allocation of certain internal resources. The list of Interrupt component API functions ( _int_ prefix) is stated together with detailed description of each function in the Freescale MQX™ Lite RTOS Reference Manual(MQXLITERM).

Hope this will be useful for you.

Best regards!

/Carlos

734 Views
jeremygordon
Contributor II

Hi Carlos,

I understand what you are saying is that from a bare metal ISR, you can't call MQX functions like lwevent_set, but if you are calling a second level ISR method (one that the kernel ISR handler "proxies" to your second level ISR) you are fine to call lwevent_set.

I noticed if I let processor expert install the ISR for the component (SPI0 in my case) I was not able to call methods like lwevent_set without a crash (as you describe). If I instead use the MQX function from code to install the ISR as a second level ISR (e.g. the _int_install_isr MQX function) then I no longer get the crash.

My problem is that in my second level ISR, I call lwevent_set but my _lwevent_wait_ticks() function (called with a very long timeout) always returns timed out (i.e. with the error code of 0x310). However, when I look at the event structure I am waiting on, the VALUE member is "1" which is the event flag I'm waiting on.

My task is priority 8, and I have tried my ISR at both priority 0 and priority 8.

Any ideas?

Thanks!

Jeremy

0 Kudos

734 Views
PO220
Contributor IV

what a desappointment :-(

Set an event is not possible from an ISR !???

Yet the documentation (MQXLITEUG) says it is made for that...

"1.2.5 Lightweight Events

Lightweight events can be used either to synchronize two tasks or to synchronize a task

and an ISR (Interrupt Service Routine)."

Would it not be a solution without “setting flags” ?

I don't undrestand LWEVENT_KL25Z example, with a "simulated_isr_task". why an event example with "simulated" ISR if it's not possible with a "true" ISR ?

Thanks in advance for explanation and solutions.

0 Kudos