I am doing a custom board porting an MQX app from the twrk40 and I am stuck.
After MQX initialization I get a default ISR fault when the systick interrupt occurs. I see in the code where the default ISRs are copied to the beginning of RAM in startup.C, followed by setting VTOR appropriately. In MQX I see where the pointer to the systick interrupt is installed in memory allocated by MQX (either sparse or not). But I can't find where either VTOR is modified by MQX or the original vector in RAM is modified by MQX.
Solved! Go to Solution.
The problem was when I migrated from CW to KSDK, I was still using a startup.S file, which precluded boot.S from being used. I can see that this might be a problem later when I try to add a boot loader that may not use MQX, but at least I know now what I was doing wrong.
The problem was when I migrated from CW to KSDK, I was still using a startup.S file, which precluded boot.S from being used. I can see that this might be a problem later when I try to add a boot loader that may not use MQX, but at least I know now what I was doing wrong.
Hi Michael,
Thanks for letting us know the resolution.
Regards,
David
Maybe I should be using boot.s instead of startup.s? Let me read up some more.
Hi Michael,
I am not sure I understand your question.
Are you using MQX in KSDK_1.3?
Or using MQX_4.2?
For a new project built using KDS_3.0 + KSDK_1.3 + PE +MQX the init_bsp.c file has _bsp_pre_init() function that initializes the systick (MQX tick timer).
The vector table by default is in RAM when using PE. The CPU component Inspector has a "Build options" tab that has Vector table copy in RAM enabled/checked.
The startup.c init_data_bss() function then handle setting VTOR accordingly.
MQX4.2 has a header file small_ram_config.h that has following #define: #define MQX_ROM_VECTORS 1
1 = VTOR points to Flash
0 = VTOR points to SRAM
To over ride the default just add the #define to user_config.h and set to 0.
The init_bsp.c _bsp_pre_init() function sets the VTOR accordingly with a call to _int_set_vetor_table().
Later in that same function the hwtimer (aka systick) is initialized with several function calls:
/* Initialize , set and run system hwtimer */
result = hwtimer_init(&systimer, &BSP_SYSTIMER_DEV, BSP_SYSTIMER_ID, BSP_SYSTIMER_ISR_PRIOR);
if (MQX_OK != result) {
return result;
}
result = hwtimer_set_freq(&systimer, BSP_SYSTIMER_SRC_CLK, BSP_ALARM_FREQUENCY);
if (MQX_OK != result) {
hwtimer_deinit(&systimer);
return result;
}
result = hwtimer_callback_reg(&systimer,(HWTIMER_CALLBACK_FPTR)_bsp_systimer_callback, NULL);
if (MQX_OK != result) {
hwtimer_deinit(&systimer);
return result;
}
result = hwtimer_start(&systimer);
if (MQX_OK != result) {
hwtimer_deinit(&systimer);
return result;
}
Hope this helps.
Regards,
David
I am using ksdk 1.3, MQX with no PE. uP is MK22FX512A.
The init_data_bss function in startup.c, does indeed copy the vectors at ROM location 0 to RAM location 0x1FFF0000 and sets VTOR to 0x1FFF0000.
The _bsp_pre_init() function has the code:
//****************************************************************************************************
result = _psp_int_init(BSP_FIRST_INTERRUPT_VECTOR_USED, BSP_LAST_INTERRUPT_VECTOR_USED);
if (result != MQX_OK) return result;
/******************************************************************************
Init MQX tick timer
******************************************************************************/
/* Initialize , set and run system hwtimer */
result = HWTIMER_SYS_Init(&systimer, &BSP_SYSTIMER_DEV, BSP_SYSTIMER_ID, NULL);
if (kStatus_OSA_Success != result) return MQX_INVALID_POINTER;
/* Set isr for timer*/ | |
if (NULL == OSA_InstallIntHandler(BSP_SYSTIMER_INTERRUPT_VECTOR, HWTIMER_SYS_SystickIsrAction)) | |
{ | |
return kHwtimerRegisterHandlerError; | |
} |
//***************************************************************************************************
_psp_int_init() calls _int_init() in psp_iinit.c which calls _int_init() in int.c. _int_init() allocates a block of memory (at 0x1fff4f1c in my case) for an interrupt table, initializes the table with internal default ISR vectors.
OSA_InstallIntHandler() calls _int_install_isr(), which puts the vector into the table allocated by _int_init().
However, at the end of all this, VTOR still points to 0x1FFF0000, and none of the vectors in that table have been changed from the original copies from ROM location 0. So when I get the first MQX systick interrupt, it goes to the original default ISR specified in the oriiginal ROM table and hangs.
I would think that MQX code would use and modify the RAM vector table already pointed to by VTOR. It certainly can't set VTOR to 0x1fff4f1c because it isn't aligned properly. What am I missing?
Hi Michael,
You have documented the flow well and correctly.
There is a #define that is affecting the behavior of the system and its default setting is what you have characterized.
Search the code for MQXCFG_SPARSE_ISR_TABLE.
In the small_ram_config.h header it is set to 1.
Good spot to read about this is: C:\Freescale\KSDK_1.3.0\doc\rtos\mqx\MQX RTOS for Kinetis SDK User's Guide.pdf
Look on page 146 for following:
MQX_SPARSE_ISR_TABLE
Default is zero. <--Ok..that is not correct at least for newly generated projects.
One: The MQX RTOS interrupt service routine table is allocated as an "array of linked
lists" instead of linear array. This option is independent on the MQX_ROM_VECTORS
as it deals with the "logical" table managed by the interrupt dispatcher in MQX RTOS.
With the sparse ISR table, only the ISRs installed by the _int_install_isr call consume
RAM memory. Interrupt latency increases as MQX RTOS needs to walk the list to find
user ISR to be invoked.
I'm guessing the developers enabled this so it is easy to switch from flash to sram based vector table???
In short, the MQX default ISR routine will look to see what isr's were registered and then call them from the table.
You can disable the sparse interrupt table by setting setting the #define to a "0". The the installed isr's will be placed into the VTOR SRAM rather than the table.
I just did that with my example project and can use Memory Browser to see the tick handler (SysTick_Handler) is at 0x1fff003C
Regards,
David
I already had MQX_SPARSE_ISR_TABLE set to 0. Either way, the vectors in RAM pointed to by VTOR are not getting changed. And I can't find anything in the MQX source code where MQX tries to alter the vectors in RAM.
By the way, MQX_ROM_VECTORS is no longer used in KSDK 1.3.