What does _mqx_exit() do?

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

What does _mqx_exit() do?

Jump to solution
959 Views
martinpi
Contributor III

Hi everybody,

I am trying to start some code after mqx has finished.

In other words, I want mqx to terminate and continue execution from a predefined address in RAM (where I loaded some code).

I modified the bsp and psp so that _mqx_exit is enabled.

Then I modified mqx_main.c like this:

int main
   (
      void
   )
{ /* Body */

   extern const MQX_INITIALIZATION_STRUCT MQX_init_struct;

   /* Start MQX */
   _mqx( (MQX_INITIALIZATION_STRUCT_PTR) &MQX_init_struct );
  
   // mqx has terminated and is ready to run the loaded program
   (*pFuncPointer)();
  
   return 0;

} /* Endbody */

where pFuncPointer holds the address of the code to be run.

I do not expect this "function" to return.

In the debugger (CodeWarrior), I see that a brakpoint at pFuncPointer ist reached, but when I continue execution I stop in the idle task again and again.

I expected _mqx_exit to stop all tasks.

What do I need to do so I have only the code at pFuncPointer running?

Thanks and regards,

Martin

0 Kudos
1 Solution
511 Views
c0170
Senior Contributor III

Hello martinpi,

can you share more code with us or at least detailed description which always helps to duplicate the behavior here on our side Smiley Wink

We believe your application enables interrupts because during exiting from MQX, users' interrupt vectors are restored (_int_set_vector_table in  int_vtab.c) and interrupts are disabled (. Do you enable INT?

I created small application with enabled interrupts after _mqx_exit() and it did not enter the Idle task. To further answer your question what does _mqx_exit do, first it executes _mqx_exit where int are disabled, invokes exit handler if there's any and then jump to the this code which is in mqx.c file also:

#if MQX_EXIT_ENABLED || MQX_CRIPPLED_EVALUATION

    /* Setup a longjmp buffer using setjmp, so that if an error occurs

     * in mqx initialization, we can perform a longjmp to this location.

     *

     * Also _mqx_exit will use this jumpbuffer to longjmp to here in order

     * to cleanly exit MQX.

     */

    if ( MQX_SETJMP( _mqx_exit_jump_buffer_internal ) ) {

        _GET_KERNEL_DATA(kernel_data);

        _int_set_vector_table(kernel_data->USERS_VBR);

        return kernel_data->USERS_ERROR;

    } /* Endif */

#endif


Regards,

MartinK

View solution in original post

0 Kudos
4 Replies
511 Views
c0170
Senior Contributor III

Hello martinpi,

have you read MQX reference manual about _mqx_exit function? Please read this NOTE:

"It is important to ensure that the environment (boot call stack) the MQX is

returning to is in the consistent state. This is not provided by distributed

MQX BSPs, because the boot stack is reused (rewritten) by MQX Kernel

data. Set the boot stack outside of Kernel data section to support correct

_mqx_exit functionality."

Regards,

MartinK

0 Kudos
511 Views
martinpi
Contributor III

Yes, thank you, I did read that.

I compared the lcf to "Appendix C: linker command file (.lcf) in Code Warrior" in the document "Ethernet Bootloader for the MCU" and found the same values for bstack and end_of_kd. And, I think, this exactly what the bootloader should do: terminate and hand the control over.

Regards, Martin

0 Kudos
512 Views
c0170
Senior Contributor III

Hello martinpi,

can you share more code with us or at least detailed description which always helps to duplicate the behavior here on our side Smiley Wink

We believe your application enables interrupts because during exiting from MQX, users' interrupt vectors are restored (_int_set_vector_table in  int_vtab.c) and interrupts are disabled (. Do you enable INT?

I created small application with enabled interrupts after _mqx_exit() and it did not enter the Idle task. To further answer your question what does _mqx_exit do, first it executes _mqx_exit where int are disabled, invokes exit handler if there's any and then jump to the this code which is in mqx.c file also:

#if MQX_EXIT_ENABLED || MQX_CRIPPLED_EVALUATION

    /* Setup a longjmp buffer using setjmp, so that if an error occurs

     * in mqx initialization, we can perform a longjmp to this location.

     *

     * Also _mqx_exit will use this jumpbuffer to longjmp to here in order

     * to cleanly exit MQX.

     */

    if ( MQX_SETJMP( _mqx_exit_jump_buffer_internal ) ) {

        _GET_KERNEL_DATA(kernel_data);

        _int_set_vector_table(kernel_data->USERS_VBR);

        return kernel_data->USERS_ERROR;

    } /* Endif */

#endif


Regards,

MartinK

0 Kudos
511 Views
martinpi
Contributor III

Thank you for your answer and sorry for not anwering for so lang time. I had an influenza.

I started with the serial_to_telnet example for the K60F120 tower.

When I found that still get into the idle task, I tried to disable the interrupts befor entering the code to be executed.

(for some reasons I cannot paste code here, it looks somewhat like this:)

void (*pFuncPointer)() = 0;


in main (void)

{

  extern const MQX_INITIALISATION_STRUCT MQX_init_struct;

  mqx ( (MQX_INITIALISATION_STRUCT_PTR) &MQX_init_struct);   //the normal mqx call

  // now mqx has terminated and is ready to run the loaded program

  if (pFuncPointer != 0)

  {

     _int_disable();   // just to see if I can prevent mqx from entering the idle task again

     (*pFuncPointer)();

     // should never reach this point here as pFuncPointer should contain a program with an infinite loop

  }

  return 0;

} // endbody

Regards, Martin

0 Kudos