We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
I have a strange problem in interrupt, I am incrementing a variable in interrupt and displayng in main program, the code is working fine for some time , latter the system gets hanged , i dont know why??
if there is any solution to this problem plz let me know, I am using Silabs C8051F120
int var=0; void PCA_Timer_Interrupt(void) interrupt 9 using 2 { var++; } void main() { sprintf(buffer,"%d",(int)var); display(buffer,LINE1); }
"I am incrementing a variable in interrupt and displayng in main program"
Consider your situation: you have a multibyte variable that is being changed in the interrupt. This means that the interrupt will break in the middle of any operation you may be doing with the variable in the main program. That alone will not necessarily crash your program, but might, depending for example on how you are relying on domain values in your variable.
For instance, if you var is 0x00ff, your main program begins to process it by taking the LSB (0xFF). Then the interrupt kicks in and change the value to 0x0100. On return, the main program takes the MSB, which is now 0x01, thus getting the value 0x01FF, instead of 0x0100. Now let's say you use the value as an array subscript, or pointer offset. That will shure produce a wild pointer and if you are lucky will crash your program.
This is NOT a 'problem' with the compiler or the CPU, it is an effect of shared variables in multitasking systems. You should never share variables in this manner. Search the internet for "atomic operations" for detailed descriptions of what to do.
Another warning: your handler is compiled with register bank 2 function usage. If you have other functions with bank2 in the main program, your system may crash, and that has nothing to do with the shared var problem.
void main() { sprintf(buffer,"%d",(int)var); display(buffer,LINE1); // What happens next??!! }
What do you suppose will happen to your program when main() exits...?
Now let's say you use the value as an array subscript, or pointer offset.
He isn't using the var as an array subscript or a pointer offset,is he?
I guess that will happen around noon :)
Erik
"He isn't using the var as an array subscript or a pointer offset,is he?"
Well, he hasn't shown any code that does that - but then the code that he has shown doesn't make sense, does it?
Jonny was just proposing an example of one way that could lead to crashing the program
"What do you suppose will happen to your program when main() exits...?"
Well that will depend on the manufacturer of the chip, of course. If the chip is manufactured in the nordic countries, for example, the processing will continue in the Valhalla, as long as it was a valiant program.
If the fab is in the UK, it will continue in Valinor, but only if its linker produced the necessary ELF files. If only DWARF files are available, the processing will continue in Moria.
If it's a Philips 8051 chip, it will probably continue underwater.
Hello All,
A newbie to this forum, I was going through a lot of threads and found that this thread is already talking about the interrupt problem in Nordic nrf24e1. I am working with the same chip and having trouble programming the interrupt. Here is the brief. I am using the RTC to wake up from sleep. The program should vector to the programmed interrupt and after exiting the interrupt should go to the next instruction after the sleep (thats what it says in the manual...) and output the value that I am changing in the interrupt. It should keep doing this just to show that the interrupt works.
Here is the code: #pragma iv(0x0000) // Interrupt vector begins at 0 #pragma interval(8) // Interval for vector is 8
#include <Nordic\reg24e1.h> #include <stdio.h>
#define TICK 10e-3 // 10ms (100Hz) tick
unsigned char xdata a=0;
void WriteRTC(unsigned int w){
while(REGX_CTRL & 0x10) // Wait to be ready
;
REGX_MSB = w >> 8;
REGX_LSB = w & 0xff;
REGX_CTRL = 0x0a;
; }
void RTCINT (void) interrupt 12 using 0{
WDTI = 0; // reset RTC interrupt flag
a++;
}
void main(void){
EA = 1; // Enable Global Interrupt
EWDI = 1; // Enable RTC interrupt
PWDI = 1; // RTC Interrupt High priority
WriteRTC(1/TICK); // RTC Real time clock - 1 sec
while(1){
CK_CTRL = 0x01; // sleep
printf("%d\n",&a);
I have enabled global interrupts and only one other interrupt, that is RTC. I am sure they are no other interrupt sources. I have put in the using operator as '0' since the default register bank is '0'. So my interrupt function will also be in bank '0'. The interrupt number is also correct according to the manuals. I tried with the breakpoints but the program just does not vector to the interrupt and increment 'a'! I don't know whether it is to do with the using or declaration or something else. Has anyone done it before and any differently than I have?
Thanks in advance,
- Nikhil
"found that this thread is already talking about the interrupt problem in Nordic nrf24e1"
The Nordic chip is never mentioned in this thread. You should really open a new thread to discuss your problem. If not for netiquette, to show others that your problem is not the old problem already discussed in the thread.
One note regarding using 0: when you declare a interrupt function specifying using N, the interrupt entry code assumes that the declared bank is 'set aside' for the interrupt, and does not preserve any used registers. So, if you declare using 0 and your program uses bank 0 for anything else, your interrupt will overwrite main program registers, and if you're lucky your program will crash. If you're out of luck, the program may actually run with some weird side effect.
The using directive should only be used for ISRs that are at the same priority level, and that don't call any functions that are declared with other banked domains.