Hello!
I'm having a very weird problem with a K65. The behavior I'm seeing is different based on wether optimizations are enabled and/or JTAG is connected.
Here are the details:
Code Compiled with Any Optimization Level Enabled | Code Compiled with Optimizations Disabled | |
---|---|---|
JTAG Connected | K65 boots fine. Voltage on RESET pin is equal to our system voltage of 2.1V (read on multimeter). | K65 boots fine. Voltage on RESET pin is equal to our system voltage of 2.1V (read on multimeter). |
JTAG Disconnected | K65 boots fine. Voltage on RESET pin is equal to our system voltage of 2.1V (read on multimeter). | K65 does not boot. Voltage on RESET pin is read on multimeter to be at 1.2V. Proving the RESET line on oscilloscope shows that the reset line is behaving like a square wave that keeps toggling between high and low. So the K65 keeps resetting. |
I was able to track down a small part of the code that if I optimized individually, I no longer see the issue. That part of the code is the 2 functions NVIC_SetPriority() and NVIC_EnableIRQ() which are only used in an enable_interrupt() function:
void enable_interrupt(uint8_t irqNum, uint8_t prio)
{
NVIC_SetPriority(irqNum, prio);
NVIC_ClearPendingIRQ(irqNum);
NVIC_EnableIRQ(irqNum);
}
NVIC_SetPriority() and NVIC_EnableIRQ() are from the Freescale KSDK 1.3 and I haven't modified them:
__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if((int32_t)IRQn < 0) {
SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
}
else {
NVIC->IP[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
}
}
__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
{
NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
So if I optimize these 2 functions only with the reset of my code unoptimized and JTAG disconnected, the K65 boots fine and the RESET line voltage goes to 2.1V. I do that by adding __attribute__((optimize("O1"))) to both function definitions:
__attribute__((optimize("O1"))) __STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if((int32_t)IRQn < 0) {
SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
}
else {
NVIC->IP[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
}
}
__attribute__((optimize("O1"))) __STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
{
NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
}
Any help would be greatly appreciated!
When changing optimization levels breaks something this is frequently a sign that the keyword volatile is missing from someplace that it is needed.
In the function shown NVIC is not passed as a parameter, it is a global. Is something with it changing with the optimization level? Perhaps passed in a register in one level and on the stack in an other.
Hi,
Could you let us know which IDE software you are using?
Wish it helps.
Have a great day,
Ma Hui
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
I'm using Rowley Crossworks (Release 3.5.1.2015071000.25017).
Hi Will,
For the Rowley Crossworks is not our supported compiler tool, we couldn't provide related support.
There with below IDE software customer could select to use:
KDS: Kinetis Design Studio Integrated Development |NXP
Or you could find support from Rowley Crossworks. Thank you for the understanding.
Wish it helps.
best regards,
Ma Hui