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.
Kevin,
I think we determined before that the gcc 'naked' attribute is the right one.
EDIT: this should be handled by HalCoGen if GCC is the selected toolchain.
See the template file: <HalCoGen_InstallDir>\v04.05.01\drivers\TMS570LC4357ZWT\SYSTEM570v000\sys_startup.c
The options for the supported toolchains are all there:
/* Startup Routine */
#if %%TOOLS:GCC%%
void %%CORE_HANDLER_TABLE_RESET_ENTRY%%(void) __attribute__((noreturn));
#else
void %%CORE_HANDLER_TABLE_RESET_ENTRY%%(void);
#endif
@@USERCODE
#if %%TOOLS:TI%%
#pragma CODE_STATE(%%CORE_HANDLER_TABLE_RESET_ENTRY%%, 32)
#pragma INTERRUPT(%%CORE_HANDLER_TABLE_RESET_ENTRY%%, RESET)
#pragma WEAK(%%CORE_HANDLER_TABLE_RESET_ENTRY%%)
#endif
#if %%TOOLS:ARM%%
__declspec(noreturn)
__attribute__ ((section ("reset")))
#endif
#if %%TOOLS:GHS%%
__attribute__((noreturn))
#endif
#if %%TOOLS:IAR%%
/* Note: stackless keyword is supported since compiler version 6.20.1 */
__stackless
__arm
#endif
#if %%TOOLS:GCC%%
__attribute__ ((naked))
#endif
void %%CORE_HANDLER_TABLE_RESET_ENTRY%%(void)
{
I do not believe this to be the case.
It may be helpful for me to paste the code, please take a look below.
That is the only code that I have been able to have properly (no esm errors on FRESH power on) initialize the CPU.
If I introduce delays in my _start, the ESM errors present them selves and the longer the delay the higher the probability of them happening.
I am initializing the Stack pointer in my _memInit_ method by running the following:
_memInit_:
ldr sp,STACK # Setup stack pointer
ldr r12, MINITGCR @Load MINITGCR register address
mov r4, #0xA
str r4, [r12] @Enable global memory hardware initialization
ldr r11, MSIENA @Load MSIENA register address
mov r4, #0x1 @Bit position 0 of MSIENA corresponds to SRAM
str r4, [r11] @Enable auto hardware initalisation for SRAM
mloop: @Loop till memory hardware initialization comletes
ldr r5, MSTCGSTAT
ldr r4, [r5]
tst r4, #0x100
beq mloop
mov r4, #5
str r4, [r12] @Disable global memory hardware initialization
bx lr
STACK is defined in my Linker to point to stack.
_coreInitRegisters_:
@ After reset, the CPU is in the Supervisor mode (M = 10011)
mov r0, lr
mov r1, #0x0000
mov r2, #0x0000
mov r3, #0x0000
mov r4, #0x0000
mov r5, #0x0000
mov r6, #0x0000
mov r7, #0x0000
mov r8, #0x0000
mov r9, #0x0000
mov r10, #0x0000
mov r11, #0x0000
mov r12, #0x0000
; Enter Privileged + User mode
mrc p15, 0, r2, c1, c0, 2
orr r2, r2, 0x00F00000
mcr p15, 0, r2, c1, c0, 2
; Enable VFP coprocessor
fmrx r2, fpexc
orr r2, r2, 0x40000000
fmxr fpexc, r2
mov fp, 0
fmdrr d0, r1, r1
fmdrr d1, r1, r1
fmdrr d2, r1, r1
fmdrr d3, r1, r1
fmdrr d4, r1, r1
fmdrr d5, r1, r1
fmdrr d6, r1, r1
fmdrr d7, r1, r1
fmdrr d8, r1, r1
fmdrr d9, r1, r1
fmdrr d10, r1, r1
fmdrr d11, r1, r1
fmdrr d12, r1, r1
fmdrr d13, r1, r1
fmdrr d14, r1, r1
fmdrr d15, r1, r1
bl next1
next1:
bl next2
next2:
bl next3
next3:
bl next4
next4:
bx r0
My reset looks like:
__vectors:
B _start
B _undefined
B _interrupt
B _prefetch_handler
B _abort_handler
B _reserved_handler
ldr pc,[pc,#-0x1b0]
ldr pc,[pc,#-0x1b0]
and _start looks like:
void _start(void) __attribute__((noreturn));
__attribute__ ((naked))
void _start(void)
{
/* Initialize L2RAM to avoid ECC errors right after power on */
_memInit_();
/* Initialize Core Registers to avoid CCM Error */
_coreInitRegisters_();
// MORE code here omitted!
}
The other issue I spoke of is changing the __vectors table to look like:
__vectors:
B __entry # Reset goes to the entry function
LDR pc,UNDEFINED # Undefined handler
LDR pc,SWI # Software interrupt handler
LDR pc,PREFETCH # Prefetch exception handler
LDR pc,ABORT # Abort exception handler
LDR pc,RESERVED # Reserved exception handler
LDR pc,[pc,#-0x1b0] # IRQ interrupt handler
LDR pc,[pc,#-0x1b0] # FIQ interrupt handler
#
#
__entry:
LDR sp,STACK # Setup stack pointer
LDR pc,START # Jump to startup
#
#
START:
.data.w _start # Reset goes to startup function
UNDEFINED:
.data.w _undefined # Undefined handler
SWI:
.data.w _swi_interrupt # Software interrupt handler
PREFETCH:
.data.w _prefetch_handler # Prefetch exception handler
ABORT:
.data.w _abort_handler # Abort exception handler
RESERVED:
.data.w _reserved_handler # Reserved exception handler
Never seems to get rid of the ESM light. It looks like it HAS to be branches which I believe put the VIM in hardware mode.
I am using Halcogen code. In the Halcogen code the first executed instructions are determining your reset source. With the TI toolchain, this seems to be fine as it will execute fast enough but with GNU it seems that it takes too long and the Error bit is set. I have tried having the initialize registers function set the stack pointer and have it execute before _memInit_ but that does not seem to do the trick.
Value of esmREG-> SR1:
ESMSR1 [0] 0x80000000
ESMSR2 [1] 0x0
ESMSR3 [2] 0x8
Hi Dmitri,
The delay you added uses the uninitialized registers. Look at the assembly instructions to see what registers are modified. The assembly will tell the story. (I do not believe that delay is the issue.)
If you want to prove that the initialization is the problem, manually initialize the used registers (either in code or in the debugger). I'd want to pay special attention to the stack pointer...
If you want to attach the .out file, I'll look at this...
Best Regards,
Kevin Lavery
I have attached the GNU .out file with no modifications to the Halogen HAL code to demonstrate the issue.
To recreate the failure power down the board completely, with the USB debugger detached as it keeps memory powered, and power on the board. It has a failure rate of about 90% but if you repeat power on / power off eventually it will pass initialization and run the LED demo main.
As mentioned before, initializing registers before the memory init does not work for me. Only the sequence I mentioned has worked for me with GNU tools to properly initialize the processor. (_vector, _memInit_, modified _registerInit_).
Hi Kevin,
That is what I am seeing when I step through it.
This is Halcogen generated code unmodified that I have submitted and should simple to reproduce on your end if you generate a GNU HAL for more in depth analysis with symbols.
I can set up the stack pointer in the .out, but I wanted to submit what Halcogen generates as correct Initialization code with out modification.
I have working initialization code written as I said, but I would like to clarify why my code is properly working and that it is doing what TI intended as it deviates from what Halcogen Generates for GNU tools. It also concerns me that the TI compiler Halcogen code looks almost identical to the GNU TI compiler generated code yet the two produce different initialization behaviours.
Hi Kevin,
Thanks for the the reply.
Here is a list of what I am trying to find out.
1.) Yes, there seems to be a bug in GNU code generation.
2.) Setting the stack pointer with the GNU tool-chain does fix the issue of the ESMSR3 error preventing boot, but the behavior of the init code still seems to differ from the TI compiler. The ESM light will flash briefly between _memInit_ and _coreInitRegisters_ in the GNU code, but not on the TI compiler.
Is there any documentation around the timing of bring up? More specifically how quickly the registers must be initialized on boot as you mentioned?
The other question I had was regarding LDR instructions instead of branches in the reset vector. I believe branches set the VIM into hardware mode and LDR sets the vim into Software mode?
Thanks Kevin,
Initializing the stack pointer in GNU seems to fix the ESMSR[2] issues.