How many nested functions can be called from an isr?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How many nested functions can be called from an isr?

2,543 Views
TDKamalAru
Contributor I

I am doing my project on HCS08SG8 controller. I have a infinite loop in a third level nested function called from timer channel capture interrupt service routine. But i could find a output variable which is calculated in the non-isr changing with random values.

 

Actually i was expecting the cpu to be blocked or arrested in the while loop present in the isr. Also i am having any software nested interupt mechanism.

 

As of now, i understood that when my cpu enters any isr, global interrupt will be disabled automatically and will be enabled back when it returns from the isr. If my understandings are correct, then if any of my isr has infinite while loop with out any conditions, then the cpu should be arrested there itself. But contradict to my understandings, when i have infinite while loop inside a second level nested function calling from an isr, the cpu is arrested. But if i moved my infinite while loop to the third level nested function calling from the isr, one of my output variable calculating at the non-isr is assigning some garbage value. Also i could find my initialisation value one among the garbage value.

Aftee this i doubted whether my controller may get reset due to some illegal operand execution or illegal operation etc.But i was surprised in seeing the cpu not halting at the break point set at the first statement of my main function once it gets started.

 

I really fed up with the cpu behaviour of the freescale micro architecture. If any of you encountered the same problem or if you have any suggestion to get out of this mission.

 

The following are my pseudocodes:

 

   /********* Start Of Isr **********/

   tpm1ch1 capture isr()

  {

     function1();

  }

  /********* End of Isr ***********/

 

  /*********Start Of Function1 *****/ 

  function1()

  {

     function2();

  }

 /********* End Of Function1 ******/

 

/*********Start Of Function2 *****/ 

  function2()

  {

     function3();

  }

 /********* End Of Function2 ******/

 

/*********Start Of Function3 *****/ 

  function3()

  {

     while(1);

  }

 /********* End Of Function3 ******/

 

Thanks & Regards....

Message Edited by TDKamalAru on 2009-12-08 10:14 AM
Labels (1)
0 Kudos
Reply
8 Replies

1,412 Views
tonyp
Senior Contributor II
This is a recursion problem (equivalent).  The simple answer is: As many as stack memory will allow.  Or, as many as non-ISR code will allow less the memory needed by the ISR itself.

 

If you mean nested ISR calls, again there isn't always an easy solution.  You need to figure out stack usage for each and every function call, and those within them until you reach the leaves of the tree.

 

I think the easiest way (except for educated guesses) would be to run a single level of the ISR with a call to all its functions (considering all possible conditional paths) after having filled the memory with some specific bit pattern (like $FF or $AA) and when done, see how much memory was affected.

 

This will give you a good estimate for a single ISR level.

 

Multiply that by the nesting level you need and you get total memory.

 

Or, divide total available RAM (i.e. after global variable allocation) by the single ISR's RAM needs, and use a global counter to not allow more than so many nested calls of the ISR.  You must also consider the possibility of other interrupts happening in between (unless you only allow this one ISR to run.)

 

PS. OK, my reply was written based only on your subject line before you edited to add the details.   But, I think it should cover you.

Message Edited by tonyp on 2009-12-08 12:24 PM
0 Kudos
Reply

1,412 Views
TDKamalAru
Contributor I

Dear Tonyp,

 I have a couple of questions? Is there any way to calculte my stack requirement for my function theoritically with out doing stack test if my function has less than 10 lines of codes?

   If i have allocated several memory locations for Stack in the linker file and some other disjoint RAM memory loactions for my global variables . whether stack will take my variable memory locations for its operation or stack memory will be overwritten at the time of in-sufficent stack?

 

Message Edited by TDKamalAru on 2009-12-08 10:31 AM
0 Kudos
Reply

1,412 Views
tonyp
Senior Contributor II

If you used assembly language it would be much easier, since you would (should) know all calling overhead and actual memory usage.

 

With a compiler, there are several unknowns (until you examine the produced assembly/machine code under a "microscope").  If you don't know how your compiler would translate certain variable constructs, how it passes parameters into or out of a function (sometimes in registers, sometimes on stack, sometimes a combination of both), it would be tough to make an accurate purely theoretical estimate.

 

Lines of code means nothing as far as stack usage goes.  (Ten lines of code may handle hundreds of bytes, and hundred lines of code may work primarily with registers and some minor stack storage).

 

You're more interested in local variable allocations, parameter passing conventions, and calls to other functions.

 

Equally important is the possibility the compiler may use internal library functions that you must also account for, as they too have similar memory overhead.

 

About separate RAM areas for stack.  This is only good for multitasking where each task has its own stack memory.  But each single stack should be in a single block of contiguous memory locations.

Message Edited by tonyp on 2009-12-08 01:08 PM
0 Kudos
Reply

1,412 Views
TDKamalAru
Contributor I

Tonyp,

Thanks for your time spent for me.

If we write our program in C language and if we want to know the stack usage, then filling the stack memories with default value, running the code, halt the code after sometime and checking the used memory is the only method it seems.

0 Kudos
Reply

1,412 Views
bigmac
Specialist III

Hello,

 

A further point about your original query -

"But if i moved my infinite while loop to the third level nested function calling from the isr, one of my output variable calculating at the non-isr is assigning some garbage value. Also i could find my initialisation value one among the garbage value."

I am not sure that I fully understand what you mean, but if you are attempting to call any of the functions from both within the ISR, and outside of the ISR, the functions will need to be fully "re-entrant", with only local stack based variables written within each function.  The writing of any global variable will potentially result in conflict between the two instances of the function, with corruption of the variable.

 

Notwithstanding, any global variable that may be written within an ISR will need to be declared as volatile.

 

If you are temporarily using an infinite loop for ISR test purposes, you will need to disable the COP timer during the test procedures, to prevent COP reset.

 

Regards,

Mac

0 Kudos
Reply

1,412 Views
TDKamalAru
Contributor I

Mac,

I am sorry if you could not understand my query....

Actually i am having an isr which calls function1 which inturn calls function2 which inturn calls function3.I have done this three level nested implementation based on my clear task split up. As i faced unexpected result of my application, i wanted to debug this software. So i identified some testing points on my code and decided to have while loop with unexpected condition. So that if my code experience undesired condition, the control should be arrested there itself so that i can ensure that becasue of the undesired condition, my code behaves like mad.

   

       For example: One of my flag is suppose to be in reset condition when my capture event(Timer Channel) occurs. If this flag is not in reset state, then this could be one of the reasonn for my code to fail. As my code failed , i suspected this could be the cause for the death of my code. Also this is not happening at the first time occurence of my capture event and it happens after some random time say after 20 minutes or 30 minutes. So i decided to have a while loop in the third level nested function called from the isr and expecting the control to be arrested there it self.

 

function3()

{

   ............. /* My statements */

   if(Flag == 1)

   {

      while(1);

   }

}

 

 

     If i have a break point and run the software, as per my expection the control was caught in the while loop. After halting just i killed the breakpoint and give continuous run with out resetting the software. In such a case if my control is constantly arrested there, then none of my other code should run. But i found one of the variable which is modified by one of my non-isr routine is changing. There is no function/routine or flags or variables shared between non-isr and isr.

   

0 Kudos
Reply

1,412 Views
eckhard
Contributor V

Hello,

 

if this only happens when you call the third functionyou seem to have a stack problerm.

The stack holds all th local variables and all the return adresses plus the registers saved by entering the ISR. 

 

In the PRM file of the project there should be an entry called STACKSIZE

 

So the stackpointer begins directly above your global variables plus the stacksize.

As default the stacksize is very low, 50 if I remember correct. So try to set a higher value in the PRM file for STACKSIZE.

 

Eckhard

0 Kudos
Reply

1,412 Views
TDKamalAru
Contributor I

Ekhard,

Thanks for the suggestion. I increased stack to the maximum possible but still am facing the same problem. Is it like still the stack is not sufficient? Also Eckhard eventhough if my stack is not sufficient, will my variable memory location value gets altered due to stack overflow?

 

0 Kudos
Reply