AnsweredAssumed Answered

Totally Confused - Interrupts and Bare Metal

Question asked by weblar on Nov 24, 2012
Latest reply on Nov 25, 2012 by weblar

Please can someone help as at present, I'm totally baffled.

 

I have a C++ application which I'm developing in IAR for the MK60FN1M0VLQ12 device. In debug mode, this works a charm and I can single step or breakpoint the code wherever I choose. The code runs without issue every time. When I switch to runtime mode, i.e. remove the debugger, then the application fails to start at all. I've even reduced the project down to bare minimum - disable the wdog, toggle an LED - but this still won't run.

 

This same code compiled using a different compiler works every time without fail during runtime.

 

My finger started to point towards IAR.

 

I've since opened up a project which came with the Kinetis 120MHz samples (the Hello World example) and successfully programmed this into my board and I'm happy to say that this project runs at runtime. Having compared the two projects - my original and the Hello World one - it seems that the differences are relating to the startup assembly files.

 

The one contained in my project (which doesn't run at runtime) contains a full list of interrupt vector functions. Something like...

 

MODULE ?cstartup

SECTION CSTACK:DATA:NOROOT(3)

SECTION .intvec:CODE:ROOT(2)

EXTERN __iar_program_start

PUBLIC __vector_table

 

DATA

__vector_table

DCD sfe(CSTACK)

DCD __iar_program_start

DCD NMI_Handler

; etc, etc

PUBWEAK NMI_Handler

; more PUBWEAKs for all interrupts

; etc, etc

SECTION .text:CODE:REORDER(1)

THUMB

NMI_Handler

; more handlers for interrupts

; etc, etc

 

Whereas the other startup file in the Hello World project contains the following...

 

SECTION .noinit:CODE

EXPORT __startup

__startup

MOV r0,#0

MOV r1,#0

; ...

MOV r12,#0

CPSIE i

import start

BL start

__done

B __done

END


Now, obviously there is a lot of difference. Firstly, I have no idea what most of the statements in the first assembler file do and why they are there, but I'm thinking that they may be related to my issue. Also, I've noticed that the linker configuration files differ significantly - my project uses MK60xN1M_12.icf whereas the Hello World project uses 1MB_Pflash.icf.


If I change my project to use the second linker file, I get errors when trying to download the binary to the device saying that "your application would set the system security of the device". I then have to use Seggers J-Link Commander to unlock the device before I can re-program it.


Finally, another point of confusion. In the Hello World example, I hooked up the SysTick_Handler interrupt without any problem. However, I have no idea where this function is defined. Likewise I'm trying to implement an interrupt handler for ports B and D and having set up the NVIC correctly, the interrupts never fire - presumably because the system doesn't know what interrupt function to point to.

 

There is a vectors.c file which defines a __vector_table array and populates it with default function pointers, but the Hello World example never seems to use this - its also not defined in the startup assembler file (but it is in the one in my project). How can I possibly use this to get working interrupts?


Please can someone improve my very chaotic and ultimately confusing Saturday.


Thanks in advance to any kind soul.


Kev

Outcomes