Compiler behaviour inconsistent

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

im developing a bootloader for an UC3C1512C, and the compiler drives me nuts! I already deactivated any optimizations (linker aswell compiler), removed the "-relax" option and any other from the toolchain. I use a custom loader script from the bootloader example. Now my problem is this: "sometimes" (I have no clue what causes this except changes in code that should be unrelated) if I f.e. dont write "Enable_global_interrupt" at first thing in my main loop, the .init section in memory will be filled with "ffffffff"'s instead of actual pointers, so calls to addresses written there crash. "Sometimes" it works without, and I dont know why. I dont even have to change the code, just the order of functions that are getting called, and it "compiles" .init valid or not, I dont know how to control that. Do I have to write it all out it assembler?!

Its also a difference if you call f.e. MyFunction(); or add "inline", define it as macro or just write its content into a sub bracket like {...code of MYFunction...} inlined. Its also a difference if the implementation is in the source/header file that calls it, or if its in another source/header file. Do I really need to make an declaration in .h files and then implementations in .c files? I put most code simply in .h files, so I dont have double work...

I use an external OSC of 12Mhz, make with a mul4/div3 pll to a 16Mhz clock and use it for all buses. Also a problem: if I ever get through all of this, the actual command to write to flash doesnt change anything (I can watch in memory view)

 

flashc_memcpy((void*)currentPageAddress, pageBuffer, PAGE_BUFFER_SIZE, true);

 

also what is the proper order to setup the clock? sofar I have it as:

1.select OSC0

2.enable OSC0

3.setup PLL

4.set PLL0 source to OSC0

5.set flash wait state(0) //(16mhz<33mhz)

6.set sysclk source to PLL0

 

and then go on init the rest, right? (enable gpio, set interrupt handler)

 

this is so frustrating, because its so hard to pinpoint what im doing wrong, here my main function, any input would be great
                       

int main(void)
{
	/* Initialize the clocks */
	Enable_global_interrupt(); //this should not be neccessary
	//Disable_global_interrupt();
	sysclk_init();

	ftm_can_init_clock();
	ftm_tc_init_clock();

	/* Set all interrupts. */
	Disable_global_interrupt();
	INTC_init_interrupts();
	ftm_can_init_interrupt();
	ftm_tc_init_interrupt();
	Enable_global_interrupt();

	/*Load settings*/
	InitUserData();

	while (1)
		StateMachineLoop();
}

 

 

greetz

Last Edited: Wed. Sep 28, 2016 - 05:59 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I feel your pain.  In my AVR32 project I have avoided the ASF, but your code looks OK to me.  However, a couple things I can think of:

1. Don't enable global interrupts until everything is set up. Ii looks like that's what you ultimately intended.

2. Do you have any initialized global variables not shown in your listing?  I have found strange problems associated with this.  Basic types like integers are OK, but complex types like structs or in C++ static class instances cause problems.  The order that things execute before main() starts seems to be somewhat undefined, and sometimes that initialization process just goes crazy and causes all kinds of unpredictable bad behavior.  I never figured out if it's a bug in the compiler or the linker, I just avoid it.

 

Did you ever solve it?

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

well, after carefully comparing input c code and output assembler, I decided to write my entire initialisation routine in assembler (clock, can and timer) :P is there for example a way to use the "mfsr" opcode? I had to insert the actual opcode bytes to get it assembled:

 

here the clock code:

                pushm	LR					//Save return address		
                rcall	_is_Pll_Locked				//check if PLL already locked
                cp.w    R0, 1
                breq    _init_clocks_end			//if so, exit
                rcall	_init_OSC0				//init OSC0
                rcall	_init_PLL0				//init PLL0
_init_clocks_end:		
                popm	PC					//get return from stack
                
////////////////////
_init_PLL0:
                pushm	LR					//Save return address	
                rcall	_setup_PLL0				//setup PLL0
                rcall	_enable_PLL0				//enable PLL0
                rcall	_wait_for_PLL0				//wait for PLL0 to get ready
                rcall	_set_clk_src_PLL0			//set the system clock source to PLL
                popm	PC					//get return from stack
                
////////////////////
_wait_for_PLL0:
                pushm	LR					//Save return address
_wait_for_PLL0_loop1:
                mov	R0, -63488		 
                ld.w	R0, R0[20]		 
                andl	R0, 0x0010, COH		 
                breq	_wait_for_PLL0_loop1
                popm	PC					//get return from stack
////////////////////
_enable_PLL0:
                pushm	LR					//Save return address
                rcall	_read_SR				//Save status register				 
                sub	SP, 4
                st.w	SP[0], R0			
                mov	R0, -63488				//AVR32_SCIF.unlock = 0xaa000000 | (AVR32_SCIF_PLL);
                mov	R1, 28		 
                orh	R1, 0xaa00		 
                st.w	R0[24], R1
                mov	R0, -63488				//AVR32_SCIF.pll[0] = cfg->ctrl | (1U << AVR32_SCIF_PLLEN);
                mov	R1, pll_cfg		 
                ld.w	R1, R1[0]		 
                sbr	R1, 0		 
                st.w	R0[28], R1	
                ld.w	R0, SP[0]				//Restore status register	 	
                sub	SP, -4		
                rcall	_write_SR
                popm	PC					//get return from stack

////////////////////
_setup_PLL0:
                pushm	LR					//Save return address	
                mov	R0, 0
                rcall	_enable_PLL_Option:
                mov	R0, 1
                rcall	_enable_PLL_Option:
                mov	R0, pll_cfg				//load config address
                ld.w	R0, R0[0]		 
                mov	R1, R0		 
                orh	R1, 0x3f07		 
                orl	R1, 0x0300		 
                mov	R0, pll_cfg		 
                st.w	R0[0], R1	
                popm	PC					//get return from stack

////////////////////
_set_clk_src_PLL0:
                pushm	LR					//Save return address	
                rcall	_read_SR				//Save status register				 
                sub	SP, 4
                st.w	SP[0], R0									
                mov	R0, -64512				//AVR32_PM.unlock = 0xaa000000 | AVR32_PM_MCCTRL;
                mov	R1, 0
                orh	R1, 0xaa00		 
                st.w	R0[88], R1
                mov	R0, -64512				//AVR32_PM.mcctrl = src; 
                mov	R1, 3
                st.w	R0[0], R1		
                ld.w	R0, SP[0]				//Restore status register	 	
                sub	SP, -4		
                rcall	_write_SR
                popm	PC					//get return from stack
                
////////////////////
_enable_PLL_Option:
                pushm	LR					//Save return address
                mov	R1, pll_cfg
                ld.w	R2, R1[0]		 
                mov	R1, R0
                sub	R1, -3		 
                mov	R3, 1		 
                lsl	R1, R3, R1		 
                or	R2, R1		 
                mov	R1, pll_cfg	 
                st.w	R1[0], R2	
                popm	PC					//get return from stack

////////////////////
_init_OSC0:
                pushm	LR					//Save return address		
                rcall	_is_OSC0_Ready				//check if OSC0 is ready
                cp.w    R0, 1
                breq    _init_OSC0_end				//if so, exit
                rcall	_enable_OSC0				//enable OSC0
_init_OSC0_loop1:
                rcall	_is_OSC0_Ready				//check if OSC0 is ready
                cp.w    R0, 0
                breq    _init_OSC0_loop1			//if so, try again
_init_OSC0_end:		
                popm	PC					//get return from stack
                
////////////////////
_enable_OSC0:
                pushm	LR					//Save return address	
                rcall	_read_SR				//Save status register				 
                sub	SP, 4
                st.w	SP[0], R0									
                mov	R0, -63488				//AVR32_SCIF.unlock = 0xaa000000 | AVR32_SCIF_OSCCTRL;	 
                mov	R1, 36		 
                orh	R1, 0xaa00		 
                st.w	R0[24], R1			
                mov	R0, -63488				//AVR32_SCIF.oscctrl[0] =	 
                mov	R1, 68615		 
                st.w	R0[36], R1	
                ld.w	R0, SP[0]				//Restore status register	 	
                sub	SP, -4		
                rcall	_write_SR
                popm	PC					//get return from stack

////////////////////
_is_OSC0_Ready:
                pushm	LR
                mov	R0, -63488		 
                ld.w	R0, R0[20]		 
                bfextu	R0, R0, 0, 1	
                popm	PC					//get return from stack

////////////////////
_is_Pll_Locked:
                pushm	LR					//Save return address	
                mov	R0, -63488		 
                ld.w	R1, R0[20]		 
                mov	R0, 16
                and	R0, R1
                srne	R0	
                popm	PC					//get return from stack
                
////////////////////
_read_SR:
                pushm	LR					//Save return address
.byte	0xe1,0xb0,0x00,0x00					//mfsr	R0, SR 
                ssrf	16					
                popm	PC					//get return from stack
                
////////////////////
_write_SR:
                pushm	LR					//Save return address
                andh	R0, 0x0001, COH				//check if cpu irq was enabled
                brne	_write_SR_end	
                csrf	16					//enable interrupt
_write_SR_end:
                popm	PC					//get return from stack

 

greetz

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hmm, it works for me with r12.

(avr toolchain 3.4.2.1573)

What is the error message you get for 'mfsr r0, 0'?

BR

M

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"mfsr R0, 0" works, "mfsr R0, SR" ,as which it get disassembled, instead produces "undefined reference to 'SR'"

 

greetz

Last Edited: Mon. Oct 17, 2016 - 06:37 AM