Stokes, Mark wrote:

Just want to clarify.  I didn't know about the global <= a word (int) ok on 
global IRQ
vars.

interrupts can only be executed between asm instructions. so, e.g
bis #1, var
mov &a, &b
are elementary. anyway, if you're unsure if the compiler uses an elementary operation, just use dint()/eint() or, write a function with the "critical" attribute

critical unsigned long long getTime(void) {
        return _time;
}

that has the advantage that the GIE bit is restored, so that you can call that function in a part with interrupts enabled or disabled, without accidently activating interrupts.

>I had used dint() ... eint() for the calculation of an average updated by an
IRQ:

also a note about dint(): dint/eint, on purpose, lock/enable the interrupts one instruction later (thats used for eint; reti, without filling the stack with reocouring ints, see slau049, NMI/WDT int)

so if you want to be safe, use
dint();
nop();

eint() is usualy uncritical, unless you implement interrupt handlers in asm like the WDT timer mentioned above.

// Global declaration
unsigned int avg[32];
unsigned int loopinc = 0;
unsigned int agvnum = 16;

int Myaverage()
{
unsigned int i;
unsigned long int templong = 0;

    dint( );
    for ( i = 0; i < avgnum; i++ )
        templong += avg[i];
    eint( );
    return ( templong / avgnum );
}

//IRQ
{
    avg[loopinc] = newnumber;
    loopinc++;
    if ( loopinc > avgnum )
        loopinc = 0;
}

But found that it worked correctly either way.  Since the array "avg[]" is 
declared as
unsigned int, I don't have to use dint() eint() correct?

you should lock interrupts if you want to have the counter (loopinc) synchronized with the number of elements in the array.

look's like it doesn't matter in this case as you don't access loopinc in Myaverage()

I suppose I should declare avg[] as volitile.

volatile is a must if you want to check for changed values within a loop inside a function.

all globals are accessed on function entry, then the values might be cached within the function. thats good enough in most cases and works well without volatile. so, in your example above, a call to Myaverage loads the variables from memory anyway, so youre fine w/o volatile.

e.g. with a wait function, where you wait for an interrupt, volatile is important:

volatile click;

interrupt (TIMERA0_VECTOR) xxx(void)
{
 click=1;
}

void wait(void)
{
  click = 0;
  while(!click) {}
}

this would block forever w/o volatile as the compiler would cache the click variable in a register.
but it's forced to do a reload with volatile

chris

Thoughts?/Thanks.
-Mark


-----Original Message-----
From: Chris Liechti [mailto:cliec...@gmx.net] Sent: Monday, June 21, 2004 5:20 PM
To: mspgcc-users@lists.sourceforge.net
Subject: Re: [Mspgcc-users] dint()

Robert Seczkowski wrote:


Does anyone has idea in what cases use dint()....eint().
If I run the code with one oscilator, Do I need to use
dint() when I write to common variable.


it has nothing to do with the clock source.

if you modify a global var larger than a word, you have to use dint();nop() ... eint() because the write operation is not elementary and a interrupt could occour while accesing the data.

chris


Reply via email to