Hi,
yes, you should use something like a mutex but if you modify a global
variable in a ISR that variable must be volatile. Most commercial
compilers like the ones from IAR do handle every variable as volatile
but gcc does not. ANSI allows both versions.
Without volatile the code is less portable.
Rolf
Chris Liechti schrieb:
Georg Ritter wrote:
Hello,
following the description of NMIs (chapter 2.2.1 in msp430x1xx
userguide ) I want to implement an NMI handler.
I use:
interrupt (NMI_VECTOR) INT_NMI(void) // 0xFFFC
{
if ( (IFG1 & NMIIFG) != 0) // NMIIFG NMI
{
IFG1 &= ~NMIIFG;
RS232printf( "NMIIFG\r\n");
note, acessing peripherals from interrupts and from the forground task
is usualy a bad idea. you could end up calling RS232printf while an
other RS232printf is already in the works. in the best case, you get
mixed strings and a lost character.
it would be better to set a flag and then check that in the foreground
and do all the loggig there.
e.g.
#define MSG_NMIFG BIT0
#define MSG_OSCIFG BIT1
unsigned short messages;
//in the interrupt
messages |= MSG_NMIFG;
//in main()
if (mesages & MSG_NMIFG) printf("a");
if (mesages & MSG_OSCIFG) printf("b");
//etc.
}
else if ( (IFG1 & OFIFG) != 0) // OFIFG osc faul
{
IFG1 &= ~OFIFG;
RS232printf( "osc failed\r\n");
}
else if ( (IFG1 & ACCVIFG) != 0) // ACCVIFG flash mem access
violation
{
IFG1 &= ~ACCVIFG;
RS232printf( "flash mem access violation\r\n");
}
else
{
RS232printf( "don't know what caused this int in NMI \r\n
IFG1=%u\r\n",(unsigned int)IFG1);
}
IE1 |= ( ACCVIE | NMIIE | OFIE | WDTIE );
}
the doc Note says (at the bottom of chapter 2.2.2):
Note: Enabling NMI Interrupts with ACCVIE, NMIIE, and OFIE The ACCVIE,
NMIIE, and OFIE enable bits should not be set inside of an NMI
interrupt service routine, unless they are set by the last instruction
of the routine before the RETI instruction. Otherwise, nested NMI
interrupts may occur, causing stack overflow and unpredictable operation.
At the moment it generates:
How could I accomplish that from within C? is it possible to get the
...
bis.b #llo(51), &0x0000
/* epilogue: frame size=0 */
pop r12
pop r13
pop r14
pop r15
reti
you may get away with not calling functions in the interrupt
but if you realy make it sure, do it in assembler. there are two
variations:
use a .S file, pure asm
or make a "naked" C function with asm("") statements. to keep as much as
possible in C, call a C funtion as fast as possible (.S example):
interrupt (NMI_VECTOR)
push r15
push r14
push r13
push r12
call #NMIHandler //implemented in C, as normal function
pop r12
pop r13
pop r14
pop r15
bis.b #(ACCVIE | NMIIE | OFIE | WDTIE), &0x0000
reti
The reason for beeing interested is, that my app seems to run for
several hours and then the f149 reboots and I don't know why. Stack
probably but how would I attack that and why could the stack overflow
from a C program (no dyn. mem allocation). Nested ints perhaps?
that could be.
chris
greetings,
Georg
-------------------------------------------------------
This SF.net email is sponsored by: IT Product Guide on ITManagersJournal
Use IT products in your business? Tell us what you think of them. Give us
Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out
more
http://productguide.itmanagersjournal.com/guidepromo.tmpl
_______________________________________________
Mspgcc-users mailing list
Mspgcc-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mspgcc-users
-------------------------------------------------------
This SF.net email is sponsored by: IT Product Guide on ITManagersJournal
Use IT products in your business? Tell us what you think of them. Give us
Your Opinions, Get Free ThinkGeek Gift Certificates! Click to find out more
http://productguide.itmanagersjournal.com/guidepromo.tmpl
_______________________________________________
Mspgcc-users mailing list
Mspgcc-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mspgcc-users