1

I am using IAR embedded workbench for MSP430 v5.60.7, which is IAR embedded workbench version 6.6. I am using C99.

I am trying to override __program_start() with my own symbol, a function called __unit_test_main(). I have gone to the linker config tab and checked the box "override default program entry", selected the "entry symbol" option and typed in __unit_test_main. This compiles and links however it does not run in the simulator. I get the message "User error: Illegal opcode found on address 0x0". When I try to run this on the target it just doesn't work - the controller goes into low power mode.

The PC and SP are both initialized to 0x00 at startup.

So what else do I need to do/define to get the PC and SP initialized properly?

My unit test main function is trivial right now, here's the whole file its in:

    #include <cstdio>
    void __unit_test_main(void);
    void __unit_test_main(void)
    {
        printf("Hello World");
        for(;;)
        {
        }
    }
Nick
  • 1,361
  • 1
  • 14
  • 42
  • I am not sure if you can call library functions in that function. If I have understood correctly, you are taking over the program when initialization work is not yet done; `.bss` section is not zeroed and `.data` section is not initialized. This likely means that any global variables required by library funcions (I imagine `printf` has some) have garbage values. Note: This is just a guess, I haven't worked with MSP, or entry overriding. – user694733 Dec 04 '14 at 07:56
  • I can't even run to __unit_test_main though - not sure why that would have anything to do with the CLIB. – Nick Dec 04 '14 at 15:09

1 Answers1

0

__program_start: is defined in cstartup.s43. This file can be copied into your project directory and included in your project which overrides the library version.

Immediately after __program_start: label the stack pointer is initialized, __low_level_init() is called, and then ?cstart_call_main is called.

Around the ?cstart_call_main: label (line 339) is the following:

    XRSEGCSTART
    PUBLIC  ?cstart_call_main

    EXTERN  main
    EXTERN  exit

?cstart_call_main:
    XXCALL  main
    XXCALL  exit

There you can add the symbol of the function you want to replace main with.

You can do it conditionally with some #ifdef preprocessor logic.

So I have

    XRSEGCSTART
    PUBLIC  ?cstart_call_main
#ifdef UNIT_TEST
    EXTERN  test_runner_main
#else
    EXTERN  main
#endif
    EXTERN  exit

?cstart_call_main:
#ifdef  UNIT_TEST
    XXCALL  test_runner_main
#else
    XXCALL  main
#endif
    XXCALL  exit

    PUBLIC  ?cstart_end

I had to define my UNIT_TEST symbol in the assembler and the compiler options.

Another option would have been implementing the function __low_level_init() somewhere in my project and conditionally making a call to test_runner instead of calling main()

Nick
  • 1,361
  • 1
  • 14
  • 42