How can I prevent the compiler from adding PSHH/PULH in my ISR automatically?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How can I prevent the compiler from adding PSHH/PULH in my ISR automatically?

4,603 Views
sypii
Contributor I
When I use Codewarrior to develop a C program with interrupt subroutines for HCS08 MCU, I found the compiler add a opcode PSHH at the beginning of the interrupt subroutine and a opcode PULH at the end automatically. I know the HCS08 MCU won't push the register H to stack when interrupt occurs, but what can I do if I don't want to save the register H in the interrupt subroutines?
 
Another question, I read the document for the compiler of CodeWarrior, but I didn't find any explanation of the feature of the compiler referred above. How can I use the document to find the needed information more quickly?
 
I'm just a beginner of the HCS08, any suggestion or explanation will be greatly appreciated. Thanks a lot!
Yang.


Message Edited by sypii on 2007-05-24 07:12 PM
Labels (1)
Tags (1)
0 Kudos
9 Replies

786 Views
CrasyCat
Specialist III
Hello
 
In order to tell the compiler not to save/restore register H in interrupt function entry/exit code, just specify following pragma in front of the interrupt function implementation
 
#pragma TRAP_PROC SAVE_NO_REGS
 
CrasyCat
0 Kudos

786 Views
sypii
Contributor I
Hello, bigmac and CrasyCat
Thanks very much for your help!
 
In my interrupt subroutines, the program may jump to another subroutine and return from the new subroutine sometimes. So if the program pushes the register H to stack when the interrupt occurs, it is possible that the saved data for H could not be pulled. I think this may cause some errors, so I want to avoid the added opcode PSHH and PULH. I tried your suggestion and it worked correctly.
 
Thanks to you all!
 
Yang.
0 Kudos

786 Views
CrasyCat
Specialist III
Hello

Just make sure H register is not used in any of the interrupt function otherwise your application will not work.

Anyway I do not understand why you are not returning to the main interrupt function and returning from there?

This will be much cleaner and will avoid any trouble with H register not being restored appropriately.

CrasyCat
0 Kudos

786 Views
sypii
Contributor I
Thank you for your advice!
I'm debugging a serial monitor program for HCS08 which is not written by me, but I found it doesn't work correctly and I'm trying to modify it. The program uses DBG module to generate a hardware breakpoint as following. You see, if the background mode has not been enabled by a serial WRITE_CONTROL command through the BKGD pin, the CPU will execute an SWI instruction. But sometimes the user program will also use the SWI, so the monitor has to judge where the interrupt comes from. If it's from the user program, the monitor program will jump to the SWI subroutine defined by user. In this case the program will return from the user SWI subroutine and won't return to the main interrupt function. Do you have some good suggestions to solve this problem better? Thank you!
 
Yang.
0 Kudos

786 Views
J2MEJediMaster
Specialist I
A lot of effort has gone into making the HC08 do what it can to preserve the context (registers) during an interrupt. You don't want to work against what the MCU and compiler does for you autmotically, because you're just looking for trouble. A general rule of thumb for ISR code is: you want to enter the ISR without doing any funny stuff (consequently defeating the context saving efforts of the hardware), and exit the ISR using its "return from interrupt instruction" so that the hardware then cleans up the context properly. Stated more tersely: you want only one entry point into the ISR, and only one exit point. In your case, I'd do the following, as pseudo-code:

SWI_ISR() {
char mode;

mode = Check_mode();
if (mode == monitor_mode)
   Do_monitor_stuff();
else
  Do_user_mode stuff();

} // implicit RTI if using C

Don't jump out of the middle of the ISR, to never return! Certain registers might be left with bogus values in them, which is going to create hard to track down bugs elsewhere. Also, if another interrupt fires in the midde of your ISR (assuming interrupts aren't disabled), it's going to jigger the stack and registers before returning control to your ISR. If you're *lucky*, your ISR will die a quick and horrible death. HTH.

---Tom
0 Kudos

786 Views
sypii
Contributor I
Hello, Tom
I appreciated your help. I will think about what you said seriously and try your suggestion. But there is still a question, if I develop this ISR according to the method you described in the pseudo-code, do you mean I have to write the user_mode_stuff function as a normal subroutine rather than a interrupt subroutine? I don't know whether I have fully understood what you mean correctly.
Thanks a lot!
 
Yang.
0 Kudos

786 Views
J2MEJediMaster
Specialist I
You'd write the system mode and user mode routines as standard functions, not as an ISR. You're already in an ISR. Depending upon how you determine the cause of the SWI, you may be able to use a switch statement and avoid the use of function calls, with their overhead on stack set-up and clean-up.

---Tom
0 Kudos

786 Views
sypii
Contributor I
I got it now. Thanks very much, Tom!
0 Kudos

786 Views
bigmac
Specialist III
Hello Yang,
 
I assume you wish to write the ISR code entirely in inline assembler.  If so, there are a number of #pragmas that might be considered, i.e.  NO_ENTRY, NO_EXIT and NO_FRAME.  These are described in the compiler manual (found within the CW installation).
 
However, it will be much safer if you let the compiler generate the ISR code automatically - after all, the inclusion of unnecessary PSHH and PULH instructions do not add very many bus cycles.
 
Regards,
Mac
 
0 Kudos