About ISR in MQX

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

About ISR in MQX

Jump to solution
5,072 Views
Nouchi
Senior Contributor II

Hello,

 

I didn't find the information in the MQX User Guide (but I maybe missed it),  I would like to know if it's possible to make a system call (_event_set(), _sem_post(), etc... ) in a non-maskable (level 7) interrupt?

Because I need to use EPF7 edge port pin, and it's not possible to change its interrupt level :smileysad:

 

 

 

Emmanuel

 

 

Message Edited by BugMan on 2009-06-18 08:59 AM
0 Kudos
1 Solution
1,230 Views
Nouchi
Senior Contributor II

Hello,

 

I don't know where was the BSP problem, but since I create a new PSP and BSP with MQX 3.2.1 compiled with:

 

#define MQX_ROM_VECTORS      0

 it works fine!

 

Emmanuel

 

 

View solution in original post

0 Kudos
12 Replies
1,230 Views
EAI
Contributor IV

No. You can call non-blocking functions from priority level n, where n <= MQX_HARDWARE_INTERRUPT_LEVEL_MAX.  This defaults to 6, and may be set to 0..6, but not to 7.

0 Kudos
1,230 Views
Nouchi
Senior Contributor II

So, the workaround could be this ?:

void myIsrLevel7(pointer user_isr_ptr)
{
  clearing Some Flags
  Force interrupt with a lower int level
  (INTFRCHn, INTFRCLn)
 }

then doing the needed system call in ISR with an allowed interrupt Level (0 to MQX_HARDWARE_INTERRUPT_LEVEL_MAX)

 

 

Emmanuel

 

 

 

 

 

0 Kudos
1,230 Views
EAI
Contributor IV

Yes, you want to install myIsrLevel7 using _int_install_kernel_isr. You'll want to declare myIsrLevel7 as _declspec(interrupt) void myIsrLevel7(void) ...

 

0 Kudos
1,230 Views
Nouchi
Senior Contributor II

Hello,

 

Can you explained how to enable the _int_install_kernel_isr function, because I tried to recompile the PSP and the BSP with:

#define MQX_ROM_VECTORS          0

but it doesn't works.

It seems that the BSP has to be modified, but I don't know how.

I think the VBR needs to point to ram vector table and ram vector table should be filled with _int_kernel_isr address.

Anyway, the application needs vector table in ram, because it's launched by a bootloader.

Can you provide a demo with vector table in RAM?

 

 

Emmanuel

Message Edited by BugMan on 2009-06-19 10:35 AM
0 Kudos
1,230 Views
Nouchi
Senior Contributor II

Hello,

 

Nobody has done this before?

0 Kudos
1,230 Views
DavidS
NXP Employee
NXP Employee

Hi Bugman,

Example enclosed.  I used the mqx/examples/isr as a starting point.

Regards,

David

 

isr.c

Message Edited by t.dowe on 2009-10-15 06:23 PM
0 Kudos
1,230 Views
JaimeR
Contributor III

Hi DavidS ,

 

I am trying to use your example code, however, the example crashes everytime I try to run it.

Could you help me solve this issue as I need to use IRQ1 as interrupt?

I am using MQX 3.1 to compile your example.

0 Kudos
1,230 Views
JaimeR
Contributor III

Hi, I wrote the code into the BSP and that part of my application is working. This is the code I am using as quick start to get a EPORT pin configured as interrupt input. Hope it helps.

 

 

uint_32 IRQ_Initialize(    // los valores estan en binario   /* [IN] DTIM channel number */   uint_8 chn_num, pointer isr){ /* Body */      void     (_CODE_PTR_ result)(pointer);   uint_32   return_code = EPORT_OK;   VMCF5225_STRUCT_PTR reg_ptr = _PSP_GET_IPSBAR(); //Controlar registros del Micro   volatile PSP_INTERRUPT_TABLE_INDEX index;   volatile MCF5225_EPORT_STRUCT_PTR        eport_reg_ptr; // Estructura para controlar DTIM   eport_reg_ptr = (pointer)(&((VMCF5225_STRUCT_PTR)_PSP_GET_IPSBAR())->EPORT[0]);      switch(chn_num)   {       case(1):             reg_ptr->GPIO.PNQPAR |= 0x0004; //Funcion Primaria             reg_ptr->GPIO.PNQPAR &= ~0x0008;             index = MCF5225_INT_EPORT0_EPF1;             eport_reg_ptr->EPPAR &= ~0x000C;//Level Edge Triggered(LOW LEVEL)             eport_reg_ptr->EPDDR &= ~0x02;//Configuracion como Entrada             eport_reg_ptr->EPIER |= 0x02;//Habilita la interrupcion             break;       case(3):             reg_ptr->GPIO.PNQPAR |= 0x0040;             reg_ptr->GPIO.PNQPAR &= ~0x0080;             index = MCF5225_INT_EPORT0_EPF3;             eport_reg_ptr->EPPAR &= ~0x00C0;             eport_reg_ptr->EPDDR &= ~0x08;             eport_reg_ptr->EPIER |= 0x08;             break;       case(5):             reg_ptr->GPIO.PNQPAR |= 0x0400;             reg_ptr->GPIO.PNQPAR &= ~0x0800;             index = MCF5225_INT_EPORT0_EPF5;             eport_reg_ptr->EPPAR &= ~0x0C00;             eport_reg_ptr->EPDDR &= ~0x20;             eport_reg_ptr->EPIER |= 0x20;             break;       case(7):             reg_ptr->GPIO.PNQPAR |= 0x4000;             reg_ptr->GPIO.PNQPAR &= ~0x8000;             index = MCF5225_INT_EPORT0_EPF7;             eport_reg_ptr->EPPAR &= ~0xC000;             eport_reg_ptr->EPDDR &= ~0x80;             eport_reg_ptr->EPIER |= 0x80;             break;       default:             return EPORT_INT_ENABLE_FAILED;             break;   }      result = _int_install_isr (index, (void (_CODE_PTR_))isr, (pointer)eport_reg_ptr);    if(result == NULL)   {      return_code = _task_get_error();   }      switch(chn_num)   {       case(1):              if ( _mcf5225_int_init(index, EPORT1_INT_LEVEL, EPORT1_INT_SUBLEVEL, TRUE) != MQX_OK)              {                  return (EPORT_INT_ENABLE_FAILED);              }             break;       case(3):              if ( _mcf5225_int_init(index, EPORT3_INT_LEVEL, EPORT3_INT_SUBLEVEL, TRUE) != MQX_OK)              {                  return (EPORT_INT_ENABLE_FAILED);              }             break;       case(4):              if ( _mcf5225_int_init(index, EPORT5_INT_LEVEL, EPORT5_INT_SUBLEVEL, TRUE) != MQX_OK)              {                  return (EPORT_INT_ENABLE_FAILED);              }             break;       case(7):              if ( _mcf5225_int_init(index, EPORT7_INT_LEVEL, EPORT7_INT_SUBLEVEL, TRUE) != MQX_OK)              {                  return (EPORT_INT_ENABLE_FAILED);              }             break;       default:             return EPORT_INT_ENABLE_FAILED;             break;   }   return return_code;} /* Endbody */void IRQ_ClearFlag(    /* [IN] DTIM device number */   uint_8 dev_num ){ /* Body */   volatile MCF5225_EPORT_STRUCT_PTR  eport_reg_ptr;   eport_reg_ptr = (pointer)(&((VMCF5225_STRUCT_PTR)_PSP_GET_IPSBAR())->EPORT[ 0 ]);   switch( dev_num )   {       case(1): eport_reg_ptr->EPFR |= 0x02;                break;       case(3): eport_reg_ptr->EPFR |= 0x08;                break;       case(5): eport_reg_ptr->EPFR |= 0x20;                break;       case(7): eport_reg_ptr->EPFR |= 0x80;                break;       default: break;   }          } /* Endbody */

 

 

 

 

0 Kudos
1,230 Views
Nouchi
Senior Contributor II

Hi David,

 

Thanks for your example, but it doesn't work with M52259Demo BSP. Something missing, because _int_install_kernel_isr function do nothing and just return NULL pointer.

I think the BSP need to be modified with MQX_ROM_VECTORS disabled and the vector table relocated in RAM (1 kbytes wasted).

I was asking if a such BSP (or something similar) exist, or if I have to rewite it from the scratch?

 

Emmanuel

0 Kudos
1,231 Views
Nouchi
Senior Contributor II

Hello,

 

I don't know where was the BSP problem, but since I create a new PSP and BSP with MQX 3.2.1 compiled with:

 

#define MQX_ROM_VECTORS      0

 it works fine!

 

Emmanuel

 

 

0 Kudos
1,230 Views
gmnelson
Contributor III

Just to confirm from your previous post, this solution relocates the vector table in RAM which consumes over 1KB of RAM space.  Right?

 

I am running into the exact same problem.  I would like to install a very fast kernel IRQ7 interrupt whose only job is to enable a QSPI transfer.  I tried installing a kernel ISR using  _int_install_kernel_isr( ), but this kept returning a NULL pointer which I presume was caused by the fact that the vector table was located in ROM space.  I then added the line "#define MQX_ROM_VECTORS 0" in the user_define.h file of the BSP.  This is fine except it now seems to use up over 1KB of RAM space.

 

I'm working on an alternative which would be to have the vector table installed in ROM space (#define MQX_ROM_VECTORS 1), and then hard code the isr function in the vectors.c module of the BSP.   Obviously, I won't need to make the MQX call _int_install_kernel_isr( ) with this method.

0 Kudos
1,230 Views
admin
Specialist II

BugMan up above had problems changing the MQX_ROM_VECTORS define.  If you are using the m52259demo board, add the following line to the board-specific MQX settings in Freescale MQX 3.4\config\m52259demo\user_config.h:

#define MQX_ROM_VECTORS          0

 

Here's the part I messed up, open Freescale MQX 3.4\config\m52259demo\build_libs.mcp.  Build this project which will update all of the sub-libraries.

 

Here is the simplest program that I can think of to create a kernel isr and start measuring some latencies.  Create a blank hello world MQX project.

 

Here is the irq function:

extern void external_isr(pointer);
__declspec(interrupt:0) void  external_isr(pointer testVal)
{
  /* Set the bit */
  PORTTC |= 0x08;
  EPFR = 0x02;
}

 

add the following to the main task:

  unsigned short         temp;
  int                         counter;
  int                         outCnt;
  unsigned char          tmpU8;

#define PIT_INTRPT_FLAG     0x0004

  /* Set up the PIT0 timer to provide 1 ms pulse */
  PMR0 = 0x270f;
  PCSR0 = 0x0217;
  DDRTC = 0x0f;
  PORTTC = 0x00;
  counter = 0;
  outCnt = 0;
 
  /* Set up the Eport bit 1 to generate an interrupt on falling edge */
  EPPAR = 0x0008;
  EPIER = 0x02;
 
  /* Install the kernel ISR */
  _int_install_kernel_isr(MCF5225_INT_EPORT0_EPF1, external_isr);
  _interrupt_controller_unmask(MCF5225_INT_EPORT0_EPF1);

  while(1)
  {
      /* See if the PIT has timed out */
      temp = PCSR0;
      if (temp & PIT_INTRPT_FLAG)
      {
        PCSR0 |= PIT_INTRPT_FLAG;
        counter++;
        if (counter == 1000)
        {
          outCnt++;
          outCnt &= 0x7;
          if (outCnt == 0)
          {
            /* Clear all bits including interrupt indication */
          PORTTC = 0;
          }
          else
          {
          tmpU8 = PORTTC;
              tmpU8 &= ~0x7;
              tmpU8 |= outCnt;
          PORTTC = tmpU8;
          }
            counter = 0;
        }
      }
  }

 

This counts from 1 to 7 using LED1 to LED3 on the board, and pressing SW2 causes a kernel interrupt and lights LED4.  When the LED1 to LED3 goes to 0, it also clears LED4 so you can take another measurement.  I apologize for the code not being commented very well, but hopefully this will help somebody not waste an hour or two trying to get this to work.

 

Oh yeah, to answer gmnelson, this does put the vector table in RAM which consumes the 1KB of RAM.  In production you might want to save the real vector table in flash so you don't lose this space.

 

Message Edited by HSpahr on 2009-11-11 03:07 PM
0 Kudos