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.

Compiler/LAUNCHXL2-RM57L: HalCoGen 04.07.00 generated GCC program doesn't run due to HERCULES_SW-6008 - incorrect GCC Naked Attribute on getResetSource (initially thought GNU ARM v7.2.1 compiler generated incorrect code for a Cortex-R5 function)

Part Number: LAUNCHXL2-RM57L
Other Parts Discussed in Thread: RM57L843, HALCOGEN

Tool/software: TI C/C++ Compiler

The attached project was created in CCS 10, targeting a RM57L843 using source code generated by HalCoGen. The project selects the GNU v7.2.1 (Linaro) compiler installed by CCS in the gcc-arm-none-eabi-7-2017-q4-major-win32 directory.

The following C function in the source/HL_system.c file:

resetSource_t getResetSource(void)
{
    register resetSource_t rst_source;

    if ((SYS_EXCEPTION & (uint32)POWERON_RESET) != 0U)
    {
        /* power-on reset condition */
        rst_source = POWERON_RESET;

        /* Clear all exception status Flag and proceed since it's power up */
        SYS_EXCEPTION = 0x0000FFFFU;
    }
    else if ((SYS_EXCEPTION & (uint32)EXT_RESET) != 0U)
    {
        /* Reset caused due to External reset. */
        rst_source = EXT_RESET;
        SYS_EXCEPTION = (uint32)EXT_RESET;
    }
    else if ((SYS_EXCEPTION & (uint32)DEBUG_RESET) !=0U)
    {
        /* Reset caused due Debug reset request */
        rst_source = DEBUG_RESET;
        SYS_EXCEPTION = (uint32)DEBUG_RESET;
    }
    else if ((SYS_EXCEPTION & (uint32)OSC_FAILURE_RESET) != 0U)
    {
     /* Reset caused due to oscillator failure.
        Add user code here to handle oscillator failure */
        rst_source = OSC_FAILURE_RESET;
        SYS_EXCEPTION = (uint32)OSC_FAILURE_RESET;
    }
    else if ((SYS_EXCEPTION & (uint32)WATCHDOG_RESET) !=0U)
    {
        /* Reset caused due watchdog violation */
        rst_source = WATCHDOG_RESET;
        SYS_EXCEPTION = (uint32)WATCHDOG_RESET;
    }
    else if ((SYS_EXCEPTION & (uint32)WATCHDOG2_RESET) !=0U)
    {
        /* Reset caused due watchdog violation */
        rst_source = WATCHDOG2_RESET;
        SYS_EXCEPTION = (uint32)WATCHDOG2_RESET;
    }
    else if ((SYS_EXCEPTION & (uint32)CPU0_RESET) !=0U)
    {
        /* Reset caused due to CPU0 reset.
        CPU reset can be caused by CPU self-test completion, or
        by toggling the "CPU RESET" bit of the CPU Reset Control Register. */
        rst_source = CPU0_RESET;
        SYS_EXCEPTION = (uint32)CPU0_RESET;
    }
    else if ((SYS_EXCEPTION & (uint32)SW_RESET) != 0U)
    {
        /* Reset caused due to software reset. */
        rst_source = SW_RESET;
        SYS_EXCEPTION = (uint32)SW_RESET;
    }
    else
    {
        /* No_reset occured. */
        rst_source = NO_RESET;
    }

    return rst_source;
}

Results in the following generated assembler (as shown in the Debug/HL_system.s file created by using the -save-temps -fverbose-asm options to make the compiler save the generated assembler):

	.align	2
	.global	getResetSource
	.syntax unified
	.arm
	.fpu vfpv3-d16
	.type	getResetSource, %function
getResetSource:
.LFB7:
	.loc 1 454 0
	.cfi_startproc
	@ Naked Function: prologue and epilogue provided by programmer.
	@ args = 0, pretend = 0, frame = 0
	@ frame_needed = 0, uses_anonymous_args = 0
@ ../source/HL_system.c:457:     if ((SYS_EXCEPTION & (uint32)POWERON_RESET) != 0U)
	.loc 1 457 0
	mvn	r3, #0	@ tmp127,
	ldr	r3, [r3, #-27]	@ _1, MEM[(volatile uint32 *)4294967268B]
	tst	r3, #32768	@ _1,
	bne	.L25	@,
@ ../source/HL_system.c:465:     else if ((SYS_EXCEPTION & (uint32)EXT_RESET) != 0U)
	.loc 1 465 0
	mvn	r3, #0	@ tmp130,
	ldr	r3, [r3, #-27]	@ _3, MEM[(volatile uint32 *)4294967268B]
	tst	r3, #8	@ _3,
	bne	.L26	@,
@ ../source/HL_system.c:471:     else if ((SYS_EXCEPTION & (uint32)DEBUG_RESET) !=0U)
	.loc 1 471 0
	mvn	r3, #0	@ tmp133,
	ldr	r3, [r3, #-27]	@ _5, MEM[(volatile uint32 *)4294967268B]
	tst	r3, #2048	@ _5,
	bne	.L27	@,
@ ../source/HL_system.c:477:     else if ((SYS_EXCEPTION & (uint32)OSC_FAILURE_RESET) != 0U)
	.loc 1 477 0
	mvn	r3, #0	@ tmp136,
	ldr	r3, [r3, #-27]	@ _7, MEM[(volatile uint32 *)4294967268B]
	tst	r3, #16384	@ _7,
	bne	.L28	@,
@ ../source/HL_system.c:484:     else if ((SYS_EXCEPTION & (uint32)WATCHDOG_RESET) !=0U)
	.loc 1 484 0
	mvn	r3, #0	@ tmp139,
	ldr	r3, [r3, #-27]	@ _9, MEM[(volatile uint32 *)4294967268B]
	tst	r3, #8192	@ _9,
	bne	.L29	@,
@ ../source/HL_system.c:490:     else if ((SYS_EXCEPTION & (uint32)WATCHDOG2_RESET) !=0U)
	.loc 1 490 0
	mvn	r3, #0	@ tmp142,
	ldr	r3, [r3, #-27]	@ _11, MEM[(volatile uint32 *)4294967268B]
	tst	r3, #4096	@ _11,
	bne	.L30	@,
@ ../source/HL_system.c:496:     else if ((SYS_EXCEPTION & (uint32)CPU0_RESET) !=0U)
	.loc 1 496 0
	mvn	r3, #0	@ tmp145,
	ldr	r3, [r3, #-27]	@ _13, MEM[(volatile uint32 *)4294967268B]
	tst	r3, #32	@ _13,
	bne	.L31	@,
@ ../source/HL_system.c:504:     else if ((SYS_EXCEPTION & (uint32)SW_RESET) != 0U)
	.loc 1 504 0
	mvn	r3, #0	@ tmp148,
	ldr	r3, [r3, #-27]	@ _15, MEM[(volatile uint32 *)4294967268B]
	tst	r3, #16	@ _15,
	bne	.L32	@,
@ ../source/HL_system.c:513:         rst_source = NO_RESET;
	.loc 1 513 0
	mov	r0, #0	@ <retval>,
.LVL18:
@ ../source/HL_system.c:517: }
	.loc 1 517 0
.LVL19:
.L25:
@ ../source/HL_system.c:463:         SYS_EXCEPTION = 0x0000FFFFU;
	.loc 1 463 0
	mvn	r3, #0	@ tmp128,
	movw	r2, #65535	@ tmp129,
	str	r2, [r3, #-27]	@ tmp129, MEM[(volatile uint32 *)4294967268B]
@ ../source/HL_system.c:460:         rst_source = POWERON_RESET;
	.loc 1 460 0
	mov	r0, #32768	@ <retval>,
.LVL20:
.L26:
@ ../source/HL_system.c:469:         SYS_EXCEPTION = (uint32)EXT_RESET;
	.loc 1 469 0
	mov	r0, #8	@ tmp132,
	mvn	r3, #0	@ tmp131,
	str	r0, [r3, #-27]	@ tmp132, MEM[(volatile uint32 *)4294967268B]
.LVL21:
.L27:
@ ../source/HL_system.c:475:         SYS_EXCEPTION = (uint32)DEBUG_RESET;
	.loc 1 475 0
	mov	r0, #2048	@ tmp135,
	mvn	r3, #0	@ tmp134,
	str	r0, [r3, #-27]	@ tmp135, MEM[(volatile uint32 *)4294967268B]
.LVL22:
.L28:
@ ../source/HL_system.c:482:         SYS_EXCEPTION = (uint32)OSC_FAILURE_RESET;
	.loc 1 482 0
	mov	r0, #16384	@ tmp138,
	mvn	r3, #0	@ tmp137,
	str	r0, [r3, #-27]	@ tmp138, MEM[(volatile uint32 *)4294967268B]
.LVL23:
.L29:
@ ../source/HL_system.c:488:         SYS_EXCEPTION = (uint32)WATCHDOG_RESET;
	.loc 1 488 0
	mov	r0, #8192	@ tmp141,
	mvn	r3, #0	@ tmp140,
	str	r0, [r3, #-27]	@ tmp141, MEM[(volatile uint32 *)4294967268B]
.LVL24:
.L30:
@ ../source/HL_system.c:494:         SYS_EXCEPTION = (uint32)WATCHDOG2_RESET;
	.loc 1 494 0
	mov	r0, #4096	@ tmp144,
	mvn	r3, #0	@ tmp143,
	str	r0, [r3, #-27]	@ tmp144, MEM[(volatile uint32 *)4294967268B]
.LVL25:
.L31:
@ ../source/HL_system.c:502:         SYS_EXCEPTION = (uint32)CPU0_RESET;
	.loc 1 502 0
	mov	r0, #32	@ tmp147,
	mvn	r3, #0	@ tmp146,
	str	r0, [r3, #-27]	@ tmp147, MEM[(volatile uint32 *)4294967268B]
.LVL26:
.L32:
@ ../source/HL_system.c:508:         SYS_EXCEPTION = (uint32)SW_RESET;
	.loc 1 508 0
	mov	r0, #16	@ tmp150,
	mvn	r3, #0	@ tmp149,
	str	r0, [r3, #-27]	@ tmp150, MEM[(volatile uint32 *)4294967268B]
	.cfi_endproc
.LFE7:
	.size	getResetSource, .-getResetSource

The generated assembler seems to have garbled the if structure in the source function and placed all the assignments to SYS_EXCEPTION in one linear sequence which are all executed unconditionally at the end of the function. Also, there is no "bx lr" at the end of the function, so execution just continues into what ever follows the getResetSource function in memory.

RM57L843_GCC_halcogen.zip

  • Chester Gillon said:
    The project selects the GNU v7.2.1 (Linaro) compiler

    I also tried compiler the project using GNU v9.2.1 (Linaro), but the generated assembler for the getResetSource was unchanged. I.e. the later version compiler hasn't fixed the issue.

  • Chester Gillon said:
    The generated assembler seems to have garbled the if structure in the source function and placed all the assignments to SYS_EXCEPTION in one linear sequence which are all executed unconditionally at the end of the function. Also, there is no "bx lr" at the end of the function, so execution just continues into what ever follows the getResetSource function in memory.

    I have only just noticed, but in the Debug/HL_system.s file created by using the -save-temps -fverbose-asm options there is the following comment:

    	@ Naked Function: prologue and epilogue provided by programmer.

    Which is explained by the following declaration in the include/HL_system.h which has been generated by HalCoGen 04.07.00:

    resetSource_t getResetSource(void) __attribute__((naked));

    If I temporarily comment out the __attribute__((naked)) in the declaration for the getResetSource function, then the assembler generated for the getResetSource looks correct.

    I.e. there doesn't appear to be an issue with the GNU ARM compiler after all, but the fact that HalCoGen marked the getResetSource function as naked. Need to check if this is a bug in HalCoGen.

  • Chester Gillon said:
    I.e. there doesn't appear to be an issue with the GNU ARM compiler after all, but the fact that HalCoGen marked the getResetSource function as naked. Need to check if this is a bug in HalCoGen.

    I was using HalCoGen 04.07.00.

    Found that HalCoGen 04.07.01 has the following bug fix:

    [HERCULES_SW-6008] || getResetSource GCC Naked Attribute should be removed

    I.e. upgrading to HalCoGen 04.07.01 fixes this issue.

  • Chester,

    Thank you for being so diligent and closing the loop on this one!

    -George