What does _mqx_exit() do?

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

What does _mqx_exit() do?

跳至解决方案
1,835 次查看
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 项奖励
回复
1 解答
1,387 次查看
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 项奖励
回复
4 回复数
1,387 次查看
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 项奖励
回复
1,387 次查看
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 项奖励
回复
1,388 次查看
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 项奖励
回复
1,387 次查看
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 项奖励
回复