EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

Returning from Subroute

Started by terry November 21, 2004
Hi,

I used Atmega32(DIP) in my prototype board to test part of my source
code, the execution is smooth. Then I ported the code to Atmega64,
only little code modifications are required.

However, I found the program counter quickly goes to an unknown
address when the program runs in the beginning. I then trace the
program using the debugger and find the program retrieve a wrong
program counter after calling subroute, which finally brings the
program to reset. Why this happens? Could anyone help me? The code
segment is attached in the following. Thanks!

int main(void)
{
  unsigned char key,sc;
  unsigned char uc;
	

  timerInit();


:
:

  timerAttach(TIMER0OVERFLOW_INT,&timer);
  initKB();

:
:
}

void timerInit(void)
{
  u08 intNum;
  // detach all user functions from interrupts
  for(intNum=0; intNum<TIMER_NUM_INTERRUPTS; intNum++)
    timerDetach(intNum);

  // initialize all timers
  timer0Init();
  timer1Init();
  #ifdef TCNT2	// support timer2 only if it exists
    timer2Init();
  #endif
  // enable interrupts
  sei();
}

void timerDetach(u08 interruptNum)
{
  // make sure the interrupt number is within bounds
  if(interruptNum < TIMER_NUM_INTERRUPTS)
  {
    // set the interrupt function to run nothing
    TimerIntFunc[interruptNum] = 0;//<---------reset after running
this command
  }
}

:
170:      		TimerIntFunc[interruptNum] = 0;
+00000D93:   2FE8        MOV     R30,R24          Copy register
---- No Source ------------------------------------------------------------------------------------
+00000D94:   27FF        CLR     R31              Clear Register
+00000D95:   0FEE        LSL     R30              Logical Shift Left
+00000D96:   1FFF        ROL     R31              Rotate Left Through
Carry
+00000D97:   5EE7        SUBI    R30,0xE7         Subtract immediate
+00000D98:   4FFD        SBCI    R31,0xFD         Subtract immediate
with carry
+00000D99:   8210        STD     Z+0,R1           Store indirect with
displacement
+00000D9A:   8211        STD     Z+1,R1           Store indirect with
displacement
+00000D9B:   9508        RET                      Subroutine
return<-------Go to an unknown address
+00000D9C:   9508        RET                      Subroutine return
:
"terry" <leonlai2k@yahoo.com> wrote in message 
news:9904d48.0411210316.392afca5@posting.google.com...
> Hi, > > I used Atmega32(DIP) in my prototype board to test part of my source > code, the execution is smooth. Then I ported the code to Atmega64, > only little code modifications are required. > > However, I found the program counter quickly goes to an unknown > address when the program runs in the beginning. I then trace the > program using the debugger and find the program retrieve a wrong > program counter after calling subroute, which finally brings the > program to reset. Why this happens? Could anyone help me? The code > segment is attached in the following. Thanks!
Have you checked the actual machine code against the assembler listing? It could be a bug in the compiler. I've known compilers (usually beta releases, but not always) generate the wrong code, in some circumstances. 8-( Leon
In article <9904d48.0411210316.392afca5@posting.google.com>,
terry <leonlai2k@yahoo.com> wrote:
>However, I found the program counter quickly goes to an unknown >address when the program runs in the beginning.
> // enable interrupts > sei(); > TimerIntFunc[interruptNum] = 0;//<---------reset after running >this command
Those are basically the last few instructions to execute. I'd guess there is a bug in your interrupt handler. Even if it works correctly (in terms of processing interrupts) it may trash the stack or otherwise fail to preserve all of the necessary state to resume after it runs. -- Ben Jackson <ben@ben.com> http://www.ben.com/
Leon Heller wrote:
> "terry" <leonlai2k@yahoo.com> wrote in message > news:9904d48.0411210316.392afca5@posting.google.com... > >>Hi, >> >>I used Atmega32(DIP) in my prototype board to test part of my source >>code, the execution is smooth. Then I ported the code to Atmega64, >>only little code modifications are required. >> >>However, I found the program counter quickly goes to an unknown >>address when the program runs in the beginning. I then trace the >>program using the debugger and find the program retrieve a wrong >>program counter after calling subroute, which finally brings the >>program to reset. Why this happens? Could anyone help me? The code >>segment is attached in the following. Thanks! > > > Have you checked the actual machine code against the assembler listing? It > could be a bug in the compiler. I've known compilers (usually beta releases, > but not always) generate the wrong code, in some circumstances. 8-( > > Leon
The function stores a 16 bit zero in a location of the vector. It can clobber the return address in the stack if the array and/or the stack is improperly set up. The code doubles the index input in r24 and subtracts 0xfde7 from it, effectively pointing to the location 0x219 + 2*index, and stores two bytes of zeroes in the location pointed to and the next byte. The compiler is not defined, but is seems to be GCC-AVR. -- Tauno Voipio tauno voipio (at) iki fi
> if(interruptNum < TIMER_NUM_INTERRUPTS) > { > // set the interrupt function to run nothing > TimerIntFunc[interruptNum] = 0;//<---------reset after running this
command
> }
Is the call to timerDetach that resets the one called from timerInit or is it a later call? Post your timer interrupt service routine. I assume it's checking if TimerIntFunc[x] is 0 before jumping or calling the routine? I'm guessing that you assign 0 to TimerIntFunc[x], a timer interrupt happens, and you jump to 0 (don't know if that's the reset address for AVR).
"Leon Heller" <leon_heller@hotmail.com> wrote in message news:<41a07d68$0$10974$cc9e4d1f@news-text.dial.pipex.com>...
> "terry" <leonlai2k@yahoo.com> wrote in message > news:9904d48.0411210316.392afca5@posting.google.com... > > Hi, > > > > I used Atmega32(DIP) in my prototype board to test part of my source > > code, the execution is smooth. Then I ported the code to Atmega64, > > only little code modifications are required. > > > > However, I found the program counter quickly goes to an unknown > > address when the program runs in the beginning. I then trace the > > program using the debugger and find the program retrieve a wrong > > program counter after calling subroute, which finally brings the > > program to reset. Why this happens? Could anyone help me? The code > > segment is attached in the following. Thanks! > > Have you checked the actual machine code against the assembler listing? It > could be a bug in the compiler. I've known compilers (usually beta releases, > but not always) generate the wrong code, in some circumstances. 8-( > > Leon
I have checked both the machine codes of CALL and RET instructions and they are both correct.8-(
> > I used Atmega32(DIP) in my prototype board to test part of my source > code, the execution is smooth. Then I ported the code to Atmega64, > only little code modifications are required. > > However, I found the program counter quickly goes to an unknown > address when the program runs in the beginning. I then trace the > program using the debugger and find the program retrieve a wrong > program counter after calling subroute, which finally brings the > program to reset. Why this happens? Could anyone help me? The code > segment is attached in the following. Thanks! > > int main(void) > { > unsigned char key,sc; > unsigned char uc;
You don't show all the file: are you aware that the interrupt vector table needs to customized for each AVR chip. An interrupt vector can be at one address on the mega32 and at another adress on the mega64. The effect is that anything can happen. Do you initialize all unused interrupts to the "RETI" instruction? -- Best Regards Ulf at atmel dot com These comments are intended to be my own opinion and they may, or may not be shared by my employer, Atmel Sweden.

The 2024 Embedded Online Conference