-H option of IAR C

Go To Last Post
11 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello everyone.
I wonder how to use -HFF(fill unused momery with 0xFF) and -H1895(fill unused interrupt vector with RETI(0X1385)) at the same time. The linker outputs the following warning:Option -H must not be defined more than once.
Thanks.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In your project options, in the General category, under the System tab, there should be an "Initialize unused interrupt vectors with RETI instructions." checkbox. In fact, AFAIK, the default is for it to be checked.

/* John Butera */

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oh I see... that option wont work if you are using the -H option in the linker. However, I noticed that while the IAR disassembler window shows unused code as being filled with 0x0000's, if you load the object file into AVR Studio, they are 0xFFFF's

/* John Butera */

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hello,
"-H1895" doesn't fill only the unused interrupt vectors but also the whole program mmeory.
The best is to use only -H1895

regards
gerhard

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

gerhardf wrote:
hello,
"-H1895" doesn't fill only the unused interrupt vectors but also the whole program mmeory.
The best is to use only -H1895

While I would agree that filling unused interrupt vectors with RETI is good practice, filling the rest of the unused program memory with RETI could be very bad. It's a better idea to fill the rest of the program memory that will return you to some known point (usually reset) if the MCU somehow ends up executing code from there.

RETI will pop a return address off thes stack and resume execution from there, but where is "there" if the program has already gone haywire? Even the standard fill of 0xFFFF isn't as benign as some think.

So what happens when an AVR tries to execute 0xFFFF? If you look in a recent instruction set, you will find that no instruction corresponds to 0xFFFF. However, in early databooks (May 1997), SBRS is given the opcode of 1111 111r rrrr Xbbb, X meaning dont-care. This means that 0xFFFF corresponds to SBRS r31, 7!

So if the MCU goes haywire and starts executing code from the unused portion of the program memory (filled with 0xFFFF), it will keep executing SBRS r31, 7 until the PC rolls over to the reset vector. But if but 7 in r31 is set, the PC will skip over every other instruction. Things work out fine if the first 0xFFFF occupied an even address in the program memory, but if it occupied an odd location, the MCU will skip all even addresses, including the reset vector location of 0x0000. The MCU would execute address 0x0001, which is either the 2nd interrupt vector, or the 2nd half of a JUMP instruction. Either one of those options would be bad if you expected the MCU to happily jump to the reset vector when something went wrong.

Filling the unused program memory with 0x0000 (NOP) would be best, however I remember hearing (on this board) that filling unused program memory with 0x0000 would cause the MCU to consume more power than if it was filled with 0xFFFF. I don't know if this is true or not, but if it is, a single NOP at the last memory location would be sufficient to force the MCU to rollover to the reset vector even if bit 7 of r31 was set.

/* John Butera */

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

here is a simple assembly program that demonstrates this

.include "m163def.inc"

rjmp    reset       ; jump over the next few lines

; PORTB will only output 0x0F if the mcu reaches this point
after_reset:        ; flash location 0x0001
ldi     r16, 0xFF
out     DDRB, r16   ; set PORTB as output
ldi     r16, 0x0F
out     PORTB, r16  ; output 0x0F
rjmp    PC          ; loop forever


reset:
ldi     r31, 0x80   ; // set bit 7 in r31

; now the mcu will start executing 0xFFFFs
; starting from address 0x0007
;
;nop
;
; uncommenting the NOP will cause the 0xFFFFs
; to start from 0x0008 and the mcu will never
; execute the PORTB code

/* John Butera */

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

pepsi wrote:
If you look in a recent instruction set, you will find that no instruction corresponds to 0xFFFF. However, in early databooks (May 1997), SBRS is given the opcode of 1111 111r rrrr Xbbb, X meaning dont-care. This means that 0xFFFF corresponds to SBRS r31, 7!

But presumably only on the older AVRs released before the instruction set was modified? The SBRS opcode had already been changed to 1111 111r rrrr 0bbb by the June 1999 databook, which suggests either an error in the earlier ones or a change in the AVR core to stop 0xFFFF being treated as a valid instruction.

Regards
Chris

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

chriscoulson wrote:
But presumably only on the older AVRs released before the instruction set was modified? The SBRS opcode had already been changed to 1111 111r rrrr 0bbb by the June 1999 databook, which suggests either an error in the earlier ones or a change in the AVR core to stop 0xFFFF being treated as a valid instruction.

You'd think.. but I just ran my test code on a mega8515 as well as a mega163, neither of which were around for the June 1999 databook. Both turned on half of the port B pins, which would mean that 0xFFFF is still treated as SBRS r31, 7. Now, if you ask the simulator in AVR studio, 0xFFFF does nothing.

I have a mega8 that I could try, but I'd have to find it. Im confident though that it will do the same thing.

/* John Butera */

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I use the following in my XCL files, it fills only the vector table with 1895, and leaves all other unused areas untouched.

/* Fill unused interrupt vectors with RETI */
-H1895
-h(CODE)0-_..X_INTVEC_SIZE

Writing code is like having sex.... make one little mistake, and you're supporting it for life.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In fact my question appears when i check "General-System-Initialize unused interrupt vectors with RETI" and "Linker-Processing-fill unused memory" at the same time.
I also notice that if -Hxx is not checked, the linker will not add xx behind useful code to fill the unused address in hex file,so when load hex file into AVR STADIO or other programmer , the unused memory is automaticly filled by 0xFF.Now i decide only use -H1895 to unused fill interrupt vector.
BTW,it seems that filling unused memory space with 0xFF is a general method for many programmer, maybe that will rapid programming speed.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

forest_j wrote:
BTW,it seems that filling unused memory space with 0xFF is a general method for many programmer, maybe that will rapid programming speed.

For the AVR's at least, erasing the flash causes all the memory locations to become 0xFF's, so the programmer can safely assume that any memory locations it does not explicitly program will contain 0xFF.. as long as it issues a chip erase first.

/* John Butera */