Undefined reference to Systeminit error for Kinetis K60 (MK60N512) target board

Asked by Krishnaraj Bhat

Hello everyone,

I am using GNU ARM toolchain to build my application for kinetis k60 (MK60N512) target. I can compile my source files. After this, I have used linker script and startup code as mentioned in the readme file. But when linking I am getting below mentioned error message:

/kinetis.S:164: undefined reference to `SystemInit'
collect2.exe: error: ld returned 1 exit status

Could any one please let me know what should I do to fix this issue and to generate the final executable.

Regards,
Krishnaraj.

Question information

Language:
English Edit question
Status:
Answered
For:
GNU Arm Embedded Toolchain Edit question
Assignee:
No assignee Edit question
Last query:
Last reply:
Revision history for this message
Terry Guo (terry.guo) said :
#1

Hi Krishnaraj,

can you please share your command line or a small case for us to reproduce your issue?

Revision history for this message
Terry Guo (terry.guo) said :
#2

Hi Krishnaraj:

Can you please share your command line or a small case for us to reproduce
your issue? Thanks.

On Thu, Mar 21, 2013 at 5:31 PM, Krishnaraj Bhat <
<email address hidden>> wrote:

> New question #224815 on GCC ARM Embedded:
> https://answers.launchpad.net/gcc-arm-embedded/+question/224815
>
> Hello everyone,
>
> I am using GNU ARM toolchain to build my application for kinetis k60
> (MK60N512) target. I can compile my source files. After this, I have used
> linker script and startup code as mentioned in the readme file. But when
> linking I am getting below mentioned error message:
>
> /kinetis.S:164: undefined reference to `SystemInit'
> collect2.exe: error: ld returned 1 exit status
>
> Could any one please let me know what should I do to fix this issue and to
> generate the final executable.
>
> Regards,
> Krishnaraj.
>
> --
> You received this question notification because you are a member of GCC
> ARM Embedded Developers, which is an answer contact for GCC ARM
> Embedded.
>

Revision history for this message
Krishnaraj Bhat (krishnarajbhat06) said :
#3

Hi Terry,

Thank you for taking your time to go through this. I have tried to provide as much details as possible below. Please let me know how can I fix this issue.

I have tried with a simple printf() statement in my main() program. Below is the code from main() function of test.c.

--------------------------------------------------------------------
#include <stdio.h>

int main()
{
    printf("Hello World\n");
    return 0;
}
-------------------------------------------------------------------

Below are the commands used to compile and link the program.

C:\Documents and Settings\KRaj\Desktop\Test1>arm-none-eabi-gcc -c -Wall -mcpu=cortex-m4 -mthumb -o Test.o Test.c

C:\Documents and Settings\KRaj\Desktop\Test1>arm-none-eabi-gcc -c -Wall -mcpu=cortex-m4 -mthumb -o Startup_CM4.o Startup_CM4.S

C:\Documents and Settings\KRaj\Desktop\Test1>arm-none-eabi-gcc -T kinetis.ld -mcpu=cortex-m4 -mthumb -o Test.elf Test.o Startup_CM4.o

I have got below mentioned error on linking:

Startup_CM4.o: In function `Reset_Handler':
(.text+0x14): undefined reference to `SystemInit'
collect2.exe: error: ld returned 1 exit status

I have used the startup_ARMCM4.S which is available with GNU ARM toolchain installation location (GNU Tools ARM Embedded\4.7 2012q4\share\gcc-arm-none-eabi\samples\startup).

Below is the code from my linker script. I got this code from the link https://answers.launchpad.net/gcc-arm-embedded/+question/211513

-----------------------------------------------------------------------------------
/* Library configurations */
GROUP(libgcc.a libc.a libm.a libnosys.a)

/* Linker script to configure memory regions. */
MEMORY
{
  FLASH (rx) : ORIGIN = 0x0, LENGTH = 0x80000 /* 512k */
  RAM (rwx) : ORIGIN = 0x1FFF0000, LENGTH = 0x20000 /* 128k */
}

/* Linker script to place sections and symbol values. Should be used together
 * with other linker script that defines memory regions FLASH and RAM.
 * It references following symbols, which must be defined in code:
 * Reset_Handler : Entry of reset handler
 *
 * It defines following symbols, which code can use without definition:
 * __exidx_start
 * __exidx_end
 * __etext
 * __data_start__
 * __preinit_array_start
 * __preinit_array_end
 * __init_array_start
 * __init_array_end
 * __fini_array_start
 * __fini_array_end
 * __data_end__
 * __bss_start__
 * __bss_end__
 * __end__
 * end
 * __HeapLimit
 * __StackLimit
 * __StackTop
 * __stack
 */
ENTRY(Reset_Handler)

SECTIONS
{
 .text :
 {
  KEEP(*(.isr_vector))

  /* hard code Flash configuration field of mk60n512 board. */
  . = 0x400;
  FILL(0xFFFFFFFF)
  . = 0x40c;
  LONG(0xFFFFFFFE)
  . = 0x410;
  FILL(0x00)
  . = 0x800;

  *(.text*)

  KEEP(*(.init))
  KEEP(*(.fini))

  /* .ctors */
  *crtbegin.o(.ctors)
  *crtbegin?.o(.ctors)
  *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
  *(SORT(.ctors.*))
  *(.ctors)

  /* .dtors */
   *crtbegin.o(.dtors)
   *crtbegin?.o(.dtors)
   *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
   *(SORT(.dtors.*))
   *(.dtors)

  *(.rodata*)

  KEEP(*(.eh_frame*))
 } > FLASH

 .ARM.extab :
 {
  *(.ARM.extab* .gnu.linkonce.armextab.*)
 } > FLASH

 __exidx_start = .;
 .ARM.exidx :
 {
  *(.ARM.exidx* .gnu.linkonce.armexidx.*)
 } > FLASH
 __exidx_end = .;

 __etext = .;

 .data : AT (__etext)
 {
  __data_start__ = .;
  *(vtable)
  *(.data*)

  . = ALIGN(4);
  /* preinit data */
  PROVIDE_HIDDEN (__preinit_array_start = .);
  KEEP(*(.preinit_array))
  PROVIDE_HIDDEN (__preinit_array_end = .);

  . = ALIGN(4);
  /* init data */
  PROVIDE_HIDDEN (__init_array_start = .);
  KEEP(*(SORT(.init_array.*)))
  KEEP(*(.init_array))
  PROVIDE_HIDDEN (__init_array_end = .);

  . = ALIGN(4);
  /* finit data */
  PROVIDE_HIDDEN (__fini_array_start = .);
  KEEP(*(SORT(.fini_array.*)))
  KEEP(*(.fini_array))
  PROVIDE_HIDDEN (__fini_array_end = .);

  . = ALIGN(4);
  /* All data end */
  __data_end__ = .;

 } > RAM

 .bss :
 {
  __bss_start__ = .;
  *(.bss*)
  *(COMMON)
  __bss_end__ = .;
 } > RAM

 .heap :
 {
  __end__ = .;
  end = __end__;
  *(.heap*)
  __HeapLimit = .;
 } > RAM

 /* .stack_dummy section doesn't contains any symbols. It is only
  * used for linker to calculate size of stack sections, and assign
  * values to stack symbols later */
 .stack_dummy :
 {
  *(.stack*)
 } > RAM

 /* Set stack top to end of RAM, and stack limit move down by
  * size of stack_dummy section */
 __StackTop = ORIGIN(RAM) + LENGTH(RAM);
 __StackLimit = __StackTop - SIZEOF(.stack_dummy);
 PROVIDE(__stack = __StackTop);

 /* Check if data + heap + stack exceeds RAM limit */
 ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
}
------------------------------------------------------------------------------------------------------

Please let me know how can I fix this issue.

Regards,
Krishnaraj.

Revision history for this message
Terry Guo (terry.guo) said :
#4

Hi Krishnaraj,

The problem is that you need to implement a function named SystemInit. You can put it in test.c or another file. Inside this function, you can do something to setup the board such as setting the board frequency, enabling the access to FPU. For the time being you can simply define it as an empty function like:

----------------------------------------------------------
void SystemInit ()
{}
----------------------------------------------------------

Another quick solution is to add option -D__NO_SYSTEM_INIT when you build Startup_CM4.S.

Revision history for this message
Krishnaraj Bhat (krishnarajbhat06) said :
#5

Hi Terry,

Thank you for providing the answer. Yes, when I add a dummy function to test.c as you mentioned above, the issue solved.

You mentioned that we have to write board setup code inside the SystemInit() function. By any chance, do you have any such code for initializing the kinetis k60 (MK60N512) hardware?

Thank you once again for your help.

Regards,
Krishnaraj.

Revision history for this message
Terry Guo (terry.guo) said :
#6

The enabling of some features are common to all M4 based boards. You can find them in either armv7-m architecture reference manual or cortex-m4 technical reference manual. Those manuals are at ARM website http://infocenter.arm.com/help/index.jsp. For example the code to enable the FPU is at: http://infocenter.arm.com/help/topic/com.arm.doc.ddi0439c/BEHBJHIG.html.

Meanwhile there are some features are specified to the boards, like how to configure the frequency. You need to check the manuals along with the board or the board vendor. I happen to find that Freescale provides some sort of sample code for K60 series board. I don't know this board very well. But I guess you could try those samples to see how to initialize the board. The URL is http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=K60_120&nodeId=01624698C9DE2DDDAF&fpsp=1&tab=Design_Tools_Tab#. The sample is under bullet "Software Development Tools" -> "Snippets, Boot Code, Headers, Monitors, etc. (3)" -> "KINETIS_120MHZ_SC".

Revision history for this message
Krishnaraj Bhat (krishnarajbhat06) said :
#7

Hi Terry,

Thank you for your help. I will go through these links and try to fix my issue.

Regards,
Krishnaraj.

Can you help with this problem?

Provide an answer of your own, or ask Krishnaraj Bhat for more information if necessary.

To post a message you must log in.