I have noticed that the Kiel compiler doesn't produce the correct interrupt vector if 8051 interrupt numbers are used. For example for external interrupt 0 (IE0), the interrupt number has to be 0, instead of 1 to produce a jump at location 1. Example:
void edge1 (void) interrupt 0{ /*produces correct code
while
void edge1 (void) interrupt 1{ /*produces wrong code
This is the case with all the interrupts I have used. My questions is what do you have to do to produce a reset vector? Reset is interrupt number 0 in 8051 numbering. Using -1 or 255 both produce a compile error.
Please post a couple of specific examples.
"It would be useful to be able to program this vector with the interrupt statement"
That is not what the interrupt keyword does. The interrupt keyword does exactly what it says on the tin - nothing more, nothing less.
See: http://www.keil.com/support/man/docs/c51/c51_le_interruptfuncs.htm
"...cases where the C startup code was not used"
If the standard C startup is not being used, then you will have to provide your own anyhow - and it will have to be in assembler. It is easy in assembler!
"Kiel (sic) manual section on interrupts is incomplete and misleading"
No, it isn't. It tells you exactly what it does. It would be impossible to list all the things it doesn't do!
"It shows an interrupt as a stand-alone program"
Which particular section are you looking at?
The one cited above shows an example of an interrupt function - no suggestion that it is a complete program.
Atmel 8-bit Flash Microcontroller AT89C51RD2 page 73 This page www.e8051.com/InterruptVectors.htm lists the vector addresses, starting with RESET. Here is the disassembled code from a program that uses the EX0 interrupt, with vector address 3 C:0x0000 020187 LJMP STARTUP1(C:0187) C:0x0003 020247 LJMP edge1(C:0247)
In the brief Keil manual section on interrupts there are no long jumps in the assembly listing - clarifying what I said earlier. Of course you can do whatever you want in assembly code but you shouldn't have to do that when you are using a C compiler. The Keil C compiler for 8051 doesn't provide a way of installing a reset vector.
Well, there you go!
I still say that the Reset is not really an interrupt.
I beleive that the Philips 80C51_FAM_*.pdf docs are just copies of the intel originals, and they clearly show Reset as distinct from the interrupt vectors:
www.semiconductors.philips.com/.../80C51_FAM_ARCH_1.pdf - Figure 3.
Unfortunately, the intel original is no longer available at developer.intel.com/.../272383.htm
"In the brief Keil manual section on interrupts there are no long jumps in the assembly listing"
That's because it's just the disassembly of the function - not the vector table!
As it says on that page, "...shows you what the code generated to enter and exit the interrupt function looks like" - it does not claim to show the vector table.
"clarifying what I said earlier"
Not at all!
"The Keil C compiler for 8051 doesn't provide a way of installing a reset vector."
Because it isn't meaningful to the Keil C51 compiler!
The Keil C51 compiler relies upon its main() being called from the startup code - see: http://www.keil.com/support/man/docs/c51/c51_ap_startup.htm
The e8051 says it's used on the Dallas Semiconductor DS89C450, but their datasheet also treats Reset as distinct from the interrupts: datasheets.maxim-ic.com/.../DS89C430-DS89C450.pdf
lists the vector addresses, starting with RESET.
No, the e8051 page does specifically say "interrupt vectors", and does include Reset among them.
Then again, it does define Reset as, "Power-on program execution start" - so precision of terminology is clearly not their strong point...
Source Priority Within Level 1. IE0 (highest) 2. TF0 3. IE1 4. TF1 5. RI+TI (lowest)
You have now responded with:
I don't see how that has anything to do with interrupt numbers - and it certainly doesn't suggest that reset is "interrupt 0".
The point is this:
The 8051 documentation does assign numbers to the interrupts. These numbers reflect each interrupts priority level.
VERY incomplete statement and many have been led astray by this.
Which part of "Source Priority Within Level" do you not understand?
Thus the only safe way to get an 'interrupt number' is by the formula ((interrupt_vector_address/8 ) -3)
Time to give the debugger a fresh cup of tea.
That's not my reading of that list.
The left hand column of the table that appears in the Intel datasheet and the many copies of it such as the oft cited Philips documentation associates a number with each interrupt. My point is nothing more than the fact that many people have mistaken that number for the number that should be typed into the source code following the 'interrupt' keyword. It really is nothing more than that.
Atmel 8-bit Flash Microcontroller AT89C51RD2 page 73
That table lists all of the vectors from which code execution starts after some hardware generated event. I think it is perfectly reasonable to view reset as an interrupt, although it differs from the other interrupts in at least two ways - it is non-maskable and has no flag through which it can be invoked in software.
The C runtime does not need to take any action in response to a non-reset interrupt occurring, but you might. So, the compiler provides a 'C' mechanism (the 'interrupt' qualified function) for you to provide code that will be invoked following a non-reset interrupt.
The C runtime does need to take action in response to a reset. It therefore does its level best to make sure that it places code at location zero that jumps to it's startup code.
However, given that this is an embedded environment full of people with peculiar requirements it does provide you with a mechanism to defeat its normal bahaviour: startup.a51. Yes, it isn't C, but if you are programing in C Keil assume that there is some expectation on your part that you would like your C program to behave as a correct C program.
In other words, the compiler does not provide you with a C mechanism to prevent the C environment from functioning correctly.
If you actually want to receive any useful advice may I suggest that rather than proceed with your assertion that it's all wrong, poorly documented and generally no good you explain what you are trying to achieve and why.
No, I don't think it does.
It simply presents them in an ordered list, using '1' to indicate the highest priority and '5' the lowest.
Saying, "IE0 has priority level 1 (highest)" is not at all the same as saying, "IE0 is interrupt number 1".
Another - possibly more fundamental difference - is that interrupts by definition interrupt normal program execution and return where they left off afterwards
This is like pulling teeth! You're not usually quite this obtuse.
Yes, you're right.
I don't disagree with you (that is surely the only interpretation you can put on it by now?) - however the table that does what you describe (correctly) above leads to confusion because people assume that the number given to/assigned to/written beside/stated along with/beside/near/asscoiated with each interrput is the very same number that should be entered following the 'interrupt' keyword.
If you disagree further with my attempt to agree with but expand on your explanation then you may consider me well and truly beaten.
That describes the normal usage of an interrupt, but at the risk of getting into another intractable and pedantic discussion you might say that:
"interrupts by definition interrupt normal program execution"
and that:
"the return from interrupt instruction by definition returns to where execution was interrupted by the last interrupt provided that there was no messing with the stack in the intervening period"
I'm sure you'll now point me to some document that defines interrupt as precisely what you've written. above, though.
I don't understand why precise definitions are needed when different manufacturers use different terminology. Some call interrupts and RESET an exception. Others classify RESET as an NMI. The only thing I'm concerned with is that if Keil had used the same numbering scheme as the chip manufacturers (RESET = 0, int0 = 1, etc) your code would be capable of producing a RESET vector.
Now you're just being needlessly pedantic...!
;-)