Is there a bug or fault on Processor Expert for the Kinetis L 04 series?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Is there a bug or fault on Processor Expert for the Kinetis L 04 series?

2,384 Views
luizdavimartins
Contributor II

Hello all!!

I'm facing a CPU interrupt every-time the initialization code created by Processor Expert is run on a KL04Z8 processor.

The function where I get the interrupt is called from the

void __thumb_startup(void)

{

        // Setup registers

        __init_registers();

        // setup hardware

        __init_hardware();

          //    zero-fill the .bss section

        zero_fill_bss();

}

zero_fill_bss is the function where the uC gets the CPU interrupt.

Does anyone know what might be the causes for that?

If I force the CPU with something like asm("b main") from within the Fault Interrupt routine, it apprently works. But it doesn't loook good.

I appreciate your help!!

Many thanks

0 Kudos
Reply
5 Replies

1,330 Views
Kan_Li
NXP TechSupport
NXP TechSupport

Hi Luiz Martins,

Where did the bss section locate in your project? The zero_fill_bss is the function to write zero to bss section, so if bss resides in some nonwritable space like flash , it would cause fault interrupt as your case. Would you please help to clarify? Thanks for your patience!


Have a great day,
Kan

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

1,330 Views
luizdavimartins
Contributor II

Hi Kan,

thanks for your quick answer!!

My project is still the unmodified version of the generated code by the Processor Expert.

The lines of code in asm are those below. The interruption comes from a line "bold" at the end of the code. Please take a look.

But before i copied the zero_fill_bss function:

223  zero_fill_bss();

000007c0:   bl zero_fill_bss (0x794)   ; 0x00000794

      zero_fill_bss:
131   {

00000794:   push {r7,lr}

00000796:   add r7,sp,#0

139  memset(__START_BSS, 0, (__END_BSS - __START_BSS));

00000798:   ldr r2,[pc,#20]

0000079a:   ldr r3,[pc,#24]

0000079c:   subs r3,r2,r3

0000079e:   ldr r2,[pc,#20]

000007a0:   mov r0,r2

000007a2:   movs r1,#0

000007a4:   mov r2,r3

000007a6:   bl memset (0x840)      ; 0x00000840
141   }

000007aa:   cpy sp,r7

000007ac:   pop {r7,pc}

000007ae:   nop

000007b0:   .short 0xfe541fff

000007b4:   .short 0xfe001fff

The code where the error/interruption is called is below.

      __fill_mem: //declared as void _EWL_CDECL __fill_mem(void * dst, int_t val, uint32_t n)
67   {

000016c4:   push {r4-r5,lr}

134   }

000016c6:   uxtb r1,r1

68  uchar_t  *cpd    = ((uchar_t *) dst);

000016c8:   mov r3,r0

73  if (n >= 32UL) {

000016ca:   cmp r2,#31

000016cc:   bls __fill_mem+0x6e (0x1732); 0x00001732

76  i = (uint32_t)(-(int32_t) dst) & 3UL;

000016ce:   neg r4,r0

000016d0:   movs r3,#3

000016d2:   ands r3,r4

77  if :smileyinfo: {

000016d4:   beq __fill_mem+0x1e (0x16e2); 0x000016e2

78  n -= i;

000016d6:   subs r2,r2,r3

27   void _EWL_CDECL    __fill_mem      (void * dst, int val, unsigned long n) _EWL_CANT_THROW;

000016d8:   adds r5,r0,r3

82  deref_auto_inc(cpd) = (uchar_t)v;

000016da:   strb r1,[r0,#0]

000016dc:   adds r0,#1

83  } while (--i);

000016de:   cmp r0,r5

000016e0:   bne __fill_mem+0x16 (0x16da); 0x000016da

86               if (v) {

000016e2:   cmp r1,#0

000016e4:   beq __fill_mem+0x2e (0x16f2); 0x000016f2

87                   v |= (v << 24) | (v << 16) | (v <<  8);

000016e6:   lsls r5,r1,#24

000016e8:   lsls r4,r1,#16

000016ea:   orrs r4,r5

000016ec:   lsls r3,r1,#8

000016ee:   orrs r1,r4

000016f0:   orrs r1,r3

97               i = n >> 5;

000016f2:   lsrs r4,r2,#5

90               lpd = (uint32_t *)cpd;

000016f4:   mov r3,r0

99               if ( i) {

000016f6:   cmp r4,#0

000016f8:   beq __fill_mem+0x54 (0x1718); 0x00001718

000016fa:   mov r5,r4

111                   while (--i);

000016fc:   subs r5,#1

102                      deref_auto_inc(lpd) = v; //This is the line where it jumps back to the interruption

000016fe:   str r1,[r3,#0]

103                       deref_auto_inc(lpd) = v;

00001700:   str r1,[r3,#4]

104                       deref_auto_inc(lpd) = v;

00001702:   str r1,[r3,#8]

105                       deref_auto_inc(lpd) = v;

00001704:   str r1,[r3,#12]

106                       deref_auto_inc(lpd) = v;

00001706:   str r1,[r3,#16]

107                       deref_auto_inc(lpd) = v;

00001708:   str r1,[r3,#20]

108                       deref_auto_inc(lpd) = v;

0000170a:   str r1,[r3,#24]

109                       deref_auto_inc(lpd) = v;

0000170c:   str r1,[r3,#28]

Please feel free to ask any other detail or information. I appreciate it.

Many thanks again.

0 Kudos
Reply

1,330 Views
BlackNight
NXP Employee
NXP Employee

Do you know which interrupt you get?

(see Oh my! An Interrupt… | MCU on Eclipse and enable 'own Handler for every').

I think two things could happen:

- normal reset: then it is probably the watchdog. Is it disabled?

- hard fault (see Debugging Hard Faults on ARM Cortex-M | MCU on Eclipse and A Processor Expert Component to Help with Hard Faults | MCU on Eclipse), then it could be that you access memory out of range (wrong linker file?). I have pasted below the linker file I get with KDS V1.1.1. Do you have the same memory map (RAM/FLASH)?

MEMORY {

  m_interrupts (RX) : ORIGIN = 0x00000000, LENGTH = 0x000000C0

  m_text      (RX) : ORIGIN = 0x00000410, LENGTH = 0x00001BF0

  m_data      (RW) : ORIGIN = 0x1FFFFE00, LENGTH = 0x00000500

  m_cfmprotrom  (RX) : ORIGIN = 0x00000400, LENGTH = 0x00000010

}

Erich

/* ################################################################### */

/*##

/*##     This component module is generated by Processor Expert. Do not modify it. */

/*##                                   */

/*##     Filename  : ProcessorExpert.ld */

/*##                                   */

/*##     Project   : kl04z8            */

/*##                                   */

/*##     Processor : MKL04Z8VFM4       */

/*##                                   */

/*##     Compiler  : GNU C Compiler    */

/*##                                   */

/*##     Date/Time : 2014-09-17, 20:54, # CodeGen: 0 */

/*##                                   */

/*##     Abstract  :                   */

/*##                                   */

/*##     This file is used by the linker. It describes files to be linked, */

/*##     memory ranges, stack size, etc. For detailed description about linker */

/*##     command files see compiler documentation. This file is generated by default. */

/*##     You can switch off generation by setting the property "Generate linker file = no" */

/*##     in the "Build options" tab of the CPU component and then modify this file as needed. */

/*##

/*##                                   */

/*## ###################################################################*/

/* Entry Point */

ENTRY(__thumb_startup)

/* Highest address of the user mode stack */

_estack = 0x20000300;    /* end of m_data */

__SP_INIT = _estack;

/* Generate a link error if heap and stack don't fit into RAM */

__heap_size = 0x50;                    /* required amount of heap  */

__stack_size = 0x50;                   /* required amount of stack */

MEMORY {

  m_interrupts (RX) : ORIGIN = 0x00000000, LENGTH = 0x000000C0

  m_text      (RX) : ORIGIN = 0x00000410, LENGTH = 0x00001BF0

  m_data      (RW) : ORIGIN = 0x1FFFFE00, LENGTH = 0x00000500

  m_cfmprotrom  (RX) : ORIGIN = 0x00000400, LENGTH = 0x00000010

}

/* Define output sections */

SECTIONS

{

  /* The startup code goes first into INTERNAL_FLASH */

  .interrupts :

  {

    __vector_table = .;

    . = ALIGN(4);

    KEEP(*(.vectortable)) /* Startup code */

    . = ALIGN(4);

  } > m_interrupts

  .cfmprotect :

  {

    . = ALIGN(4);

    KEEP(*(.cfmconfig))    /* Flash Configuration Field (FCF) */

    . = ALIGN(4);

  } > m_cfmprotrom

 

  /* The program code and other data goes into INTERNAL_FLASH */

  .text :

  {

    . = ALIGN(4);

    *(.text)           /* .text sections (code) */

    *(.text*)          /* .text* sections (code) */

    *(.rodata)         /* .rodata sections (constants, strings, etc.) */

    *(.rodata*)        /* .rodata* sections (constants, strings, etc.) */

    *(.glue_7)         /* glue arm to thumb code */

    *(.glue_7t)        /* glue thumb to arm code */

    *(.eh_frame)

    KEEP (*(.init))

    KEEP (*(.fini))

    . = ALIGN(4);

    _etext = .;        /* define a global symbols at end of code */

  } > m_text

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

    .ARM : {

    __exidx_start = .;

      *(.ARM.exidx*)

      __exidx_end = .;

  } > m_text

.ctors :

  {

    __CTOR_LIST__ = .;

    /* gcc uses crtbegin.o to find the start of

       the constructors, so we make sure it is

       first.  Because this is a wildcard, it

       doesn't matter if the user does not

       actually link against crtbegin.o; the

       linker won't look for a file to match a

       wildcard.  The wildcard also means that it

       doesn't matter which directory crtbegin.o

       is in.  */

    KEEP (*crtbegin.o(.ctors))

    /* We don't want to include the .ctor section from

       from the crtend.o file until after the sorted ctors.

       The .ctor section from the crtend file contains the

       end of ctors marker and it must be last */

    KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))

    KEEP (*(SORT(.ctors.*)))

    KEEP (*(.ctors))

    __CTOR_END__ = .;

  } > m_text

  .dtors :

  {

    __DTOR_LIST__ = .;

    KEEP (*crtbegin.o(.dtors))

    KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))

    KEEP (*(SORT(.dtors.*)))

    KEEP (*(.dtors))

    __DTOR_END__ = .;

  } > m_text

  .preinit_array     :

  {

    PROVIDE_HIDDEN (__preinit_array_start = .);

    KEEP (*(.preinit_array*))

    PROVIDE_HIDDEN (__preinit_array_end = .);

  } > m_text

  .init_array :

  {

    PROVIDE_HIDDEN (__init_array_start = .);

    KEEP (*(SORT(.init_array.*)))

    KEEP (*(.init_array*))

    PROVIDE_HIDDEN (__init_array_end = .);

  } > m_text

  .fini_array :

  {

    PROVIDE_HIDDEN (__fini_array_start = .);

    KEEP (*(SORT(.fini_array.*)))

    KEEP (*(.fini_array*))

    PROVIDE_HIDDEN (__fini_array_end = .);

    ___ROM_AT = .;

  } > m_text

  /* reserve MTB memory at the beginning of m_data */

  .mtb : /* MTB buffer address as defined by the hardware */

  {

    . = ALIGN(8);

    _mtb_start = .;

    KEEP(*(.mtb_buf)) /* need to KEEP Micro Trace Buffer as not referenced by application */

    . = ALIGN(8);

    _mtb_end = .;

  } > m_data

  /* Initialized data sections goes into RAM, load LMA copy after code */

  .data : AT(___ROM_AT)

  {

    . = ALIGN(4);

    _sdata = .;        /* create a global symbol at data start */

    *(.data)           /* .data sections */

    *(.data*)          /* .data* sections */

    . = ALIGN(4);

    _edata = .;        /* define a global symbol at data end */

  } > m_data

  ___data_size = _edata - _sdata;

  /* Uninitialized data section */

  . = ALIGN(4);

  .bss :

  {

    /* This is used by the startup in order to initialize the .bss section */

    __START_BSS = .;

      PROVIDE ( __bss_start__ = __START_BSS );

    *(.bss)

    *(.bss*)

    *(COMMON)

    . = ALIGN(4);

    __END_BSS = .;

       PROVIDE ( __bss_end__ = __END_BSS );

  } > m_data

  _romp_at = ___ROM_AT + SIZEOF(.data);

  .romp : AT(_romp_at)

  {

    __S_romp = _romp_at;

    LONG(___ROM_AT);

    LONG(_sdata);

    LONG(___data_size);

    LONG(0);

    LONG(0);

    LONG(0);

  } > m_data

 

  /* User_heap_stack section, used to check that there is enough RAM left */

  ._user_heap_stack :

  {

    . = ALIGN(4);

    PROVIDE ( end = . );

    PROVIDE ( _end = . );

    __heap_addr = .;

    __HeapBase = .;

    . = . + __heap_size;

    __HeapLimit = .;

    . = . + __stack_size;

    . = ALIGN(4);

  } > m_data

  .ARM.attributes 0 : { *(.ARM.attributes) }

}

0 Kudos
Reply

1,330 Views
luizdavimartins
Contributor II

Erich,

You were on the right path. Here is what I discovered:

There is a error with the MEMORY map at the m_data area. This below is the correct configuration:

MEMORY {

  m_interrupts (RX) : ORIGIN = 0x00000000, LENGTH = 0x000000C0

  m_text      (RX) : ORIGIN = 0x00000410, LENGTH = 0x00001BF0

  m_data      (RW) : ORIGIN = 0x1FFFFF00, LENGTH = 0x00000400

  m_cfmprotrom  (RX) : ORIGIN = 0x00000400, LENGTH = 0x00000010

}

I hope Freescale sees it and correct it ASAP.

Many thanks again for your support.

Luiz

0 Kudos
Reply

1,330 Views
BlackNight
NXP Employee
NXP Employee

Hi Luiz,

indeed, that linker file and memory map is wrong :-(

I have submitted a ticket (Reference KDS-171) to have this fixed asap.

Many thanks,

Erich

0 Kudos
Reply