This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
I'm using GCC and trying to figure out a way to solve USCI28 issue. For that I wanted to create a custom startup code that would allow me to optimize startup and add the things I need. Where/how can I get the source for for the current startup used by GCC?
Gennadiy Kiryukhin said:I'm using GCC and trying to figure out a way to solve USCI28 issue. For that I wanted to create a custom startup code that would allow me to optimize startup and add the things I need. Where/how can I get the source for for the current startup used by GCC?
I just tried to find it but we've switched over to the msp432 and there things are in different places.
try compiling with the -v (verbose) switch. That should tell you every file that it is processing, including start up files.
On the MSP430, gcc's run-time library is not implemented by GNU libc but by newlib; the startup code is in libgloss/msp430/crt0.S.
Hi!
You can add your own code to the startup without modifying the supplied startup code.
See how I add a function to the startup code in my post https://e2e.ti.com/support/development_tools/code_composer_studio/f/81/p/534236/1946470#1946470.
Copy the stackInit(void) function and rename it. Don't forget to copy all __attribute__ lines as well.
To place it just after the stack has been initialized use the section ".crt_0001workaroundUSCI28" instead.
Use the code referenced by Brian Boorman just to know where you want to place your code by using the correct section attribute.
Clemens Ladisch said:The workaround must be executed before the stack pointer register is initialized. This is not possible with any .crt_xxxx section.
Sure no problem, as said just use the correct section name.
Eg. this code:
void workaroundUSCI28(void) __attribute__ ((naked)); void workaroundUSCI28(void) __attribute__ ((used)); void workaroundUSCI28(void) __attribute__ ((section (".crt_0000_before_start"))); void workaroundUSCI28(void) { /* * Only use as few variables as possible and only of type register. * You've certainly got no stack set up. */ register uint8_t somevar; /* code */ __no_operation(); }
will be placed before stack init, see this snippet from the map file created:
.text 0x0000450c 0x314 0x0000450c PROVIDE (_start, .) 0x0000450c . = ALIGN (0x2) *(SORT(.crt_*)) .crt_0000_before_start 0x0000450c 0x2 ./main.o 0x0000450c workaroundUSCI28 .crt_0000start 0x0000450e 0x4 /home/USER/ti/msp430_gcc-4.1.0.0/bin/../lib/gcc/msp430-elf/5.3.0/../../../../msp430-elf/lib/large/crt0.o 0x0000450e __crt0_start .crt_0100init_bss 0x00004512 0x10 /home/USER/ti/msp430_gcc-4.1.0.0/bin/../lib/gcc/msp430-elf/5.3.0/../../../../msp430-elf/lib/large/libcrt.a(crt_bss.o) 0x00004512 __crt0_init_bss .crt_0300movedata 0x00004522 0x14 /home/USER/ti/msp430_gcc-4.1.0.0/bin/../lib/gcc/msp430-elf/5.3.0/../../../../msp430-elf/lib/large/libcrt.a(crt_movedata.o) 0x00004522 __crt0_movedata .crt_0700call_init_then_main
Clemens Ladisch said:And what are the contents of the reset vector? Still __crt0_start?
.section ".resetvec-patched", "a" __msp430_resetvec_hook: .word workaroundUSCI28
In the linker script, eg. for my project msp430fr5969.ld, change the following lines
__reset_vector : { KEEP (*(__interrupt_vector_56)) KEEP (*(__interrupt_vector_reset)) KEEP (*(.resetvec)) } > RESETVEC
to
__reset_vector : { KEEP (*(.resetvec-patched)) } > RESETVEC
Look up the location of the reset vector in the linker script, here for example I'm using msp430fr5969.ld:
MEMORY { [...] RESETVEC : ORIGIN = 0xFFFE, LENGTH = 0x0002 }
Now recompile and start a debug session.
Open a disassembly view and enter the address of the reset vector, in this example 0xfffe, to resolve where reset jumps to (click image for full size):
In this example the start of the code is at 0x4420, the encircled number in the picture.
Now enter that address into the disassembly view and you should get this (click image for full size):
The NOP represents code you'd want to run before everything else.
If you want to debug the whole startup deselect the following two settings in the debug settings(click image for full size):
Example worked out:
Implementing the work-around requires two pieces: inserting the work-around code before crt0_start (loading the stack pointer SP) and changing the reset vector to point to the work-around crt0_beforestart code so it executes on reset, catching the spurious USCI28 reset vectors.
/*
* usci28.c
*
* Work around USCI28 errata.
*
* This MUST go before crt_0000start which resets the stack pointer,
* destroying our ability to return from the interrupt (misvectored to
* the reset vector).
*
* "beforestart" sorts before "start", which achieves our objective.
*/
void __crt0_beforestart(void) __attribute__ ((naked));
void __crt0_beforestart(void) __attribute__ ((used));
void __crt0_beforestart(void) __attribute__ ((section (".crt_0000beforestart")));
void __crt0_beforestart(void)
{
__asm("\t BIT.B\t #0x0C,&0x0001"); // If USB0 TXIE or RXIE is set, an erroneous reset occurred
__asm("\t JZ\t Start_Normal"); //
__asm("\t RETI"); // so return from the interrupt call.
__asm("Start_Normal:");
}
void __crt0_resetvec(void) __attribute__ ((naked));
void __crt0_resetvec(void) __attribute__ ((used));
void __crt0_resetvec(void) __attribute__ ((section (".resetvec_usci28")));
void __crt0_resetvec(void)
{
__asm("\t .word __crt0_beforestart");
}
@@ -117,7 +117,7 @@ SECTIONS
{
KEEP (*(__interrupt_vector_32))
KEEP (*(__interrupt_vector_reset))
- KEEP (*(.resetvec))
+ KEEP (*(.resetvec_usci28))
} > RESETVEC
.rodata :
Being picky, I think the comment should say "UCB0" or "USCI_B0" rather than "USB0".Gerald Van Baren said:__asm("\t BIT.B\t #0x0C,&0x0001"); // If USB0 TXIE or RXIE is set, an erroneous reset occurred
In our case we check configuration of one of the ports to know if we entered the reset erroneously. Who know what kind of other interrupt could cause a reset. This method is implementation specific and may need to be tweaked if used in a different project that keeps that particular port in default (reset) configuration.
**Attention** This is a public forum