How do you assign reset vectors in assembly? - MC9S08QE8

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

How do you assign reset vectors in assembly? - MC9S08QE8

4,527 Views
Rodo55
Contributor I
I'm a beginner to MCUs and I'm pulling my hair out trying to figure out how to assign my subroutine (ISR) to an RTC vector address in assembly. My code works fine in C but I'm new to assembly and QE8 MCUs and I just can't figure out how to get the interrupts to work in assembly.
 
Here's a snippet of my C code and if you would explain how to do it in assembly I'd appreciate it.
 
Below is where the ISR code is assigned to the vector address in "C".
 
void interrupt VectorNumber_Vrtc rtc_isr(void) 
 {
  RTCSC_RTIF = 1; /* Clear RTIF */
  LED3 = !LED3;   /* Toggle LED3 */
}
 
I understand that "Vrtc" is pre-defined in the file MC9S08QE8.inc to address $FFCE which is the vector from the RTC interrupt. But how do I assign the vector address to point to my code "rtc_isr"?
 
Rodo
 
 
Added p/n to subject.


Message Edited by NLFSJ on 2008-06-26 11:10 AM
Labels (1)
0 Kudos
26 Replies

1,365 Views
peg
Senior Contributor IV
Hello Rodo,

An ISR is just a normal subroutine except that it ends with RTI instead of RTS. And just like a normal subroutine it can be located anywhere in memory. To make it work you need to write the address of the start of the ISR into the interrupt vector location.

Normally done something tlike this:

ORG    InterruptVectorAddress
DW    ISRlabel

Usually it must do something to reset the source of the interrupt within the ISR.

0 Kudos

1,365 Views
Rodo55
Contributor I
Thanks Peg,
 
I understood it to be something like that so I tried:
 
ORG Vrtc
FDW IRQT
 
And many other styles of the command. I didn't realize the FDW was DW. Thanks for correcting that.
 
Here's the errors I get with:
 
ORG VectorNumber_Vrtc
DW IRQT
 
The error is pointing at the ORG command.
 
 
ORG Vrtc
DW IRQT
The error is pointing at the ORG command.
 
ORG $FFCE
DW IRQT
 
The error is pointing at the ORG command.
 
IRQT is the label I gave my ISR.
 
Have I missed something?
I'm using CodeWarrior 6.1. Maybe there is an issue with CW, QE devices and assembly? I'm leaning more towards my doing something wrong than that, though.
 
I appreciate your help.
 
Rodo
0 Kudos

1,365 Views
CompilerGuru
NXP Employee
NXP Employee
Please check the Help\PDF\Assembler_HC08.pdf for the list of assembly directives.
For a 16 bit constant, use DC.W, also make sure lines with directives or instructions start with a space.

Daniel
0 Kudos

1,364 Views
Rodo55
Contributor I
Thanks Daniel !!!!
 
You got me past the error pointing to the ORG statement. The ORG was left justified and when I added a space it accepted the "ORG Vrtc" like it was supposed to. There is no mention of the required space in any documentation I read. THANKS!
 
Now I'm down to an address assignment error. :smileysad:
 
I used the DC.W and it said it wasn't big enough so I went to DC.L and then it tells me:
 
L1119: Vector allocated at absolute address <Address> overlaps with sections placed in segment <Segm...

So now I have to find out what's causing that.

Anyone have any suggestions?

Thanks again Daniel,

Rodo

0 Kudos

1,365 Views
Rodo55
Contributor I
Hi Daniel,
 
I've been through that manual and it doesn't help. Below is the excerpt from it and you can see it suggest the same format as what Peg recommended and I've been trying. I've searched these forumns and used the help function of CW and I don't see any clear examples of the ORG statement being used to call an ISR. By the way it looks like that PDF manual is the help function within CW.
 

ORG - Set Location Counter

Syntax

ORG <expression>

Synonym

None

Description

The ORG directive sets the location counter to the value specified by<expression>. Subsequent statements are assigned memory locations starting with the new location counter value. The <expression> must be absolute and may not contain any forward, undefined, or external references. The ORG directive generates an internal section, which is absolute (see the Sections chapter).

Listing 8.49 Using ORG to set the location counter

org $2000

b1: nop

b2: rts

Viewing Listing 8.50, you can see that the b1 label is located at address $2000 and label b2 is at address $2001.

Listing 8.50 Assembler output listing from the source code in Listing 8.49

Abs. Rel. Loc Obj. code Source line

---- ---- ------ --------- -----------

1 1 org $2000

2 2 a002000 9D b1: nop

3 3 a002001 81 b2: rts

 

I'm starting to lean towards CW may have an issue with the ORG statement as it applies to ISRs..

 

I appreciate your help,

Rodo

0 Kudos

1,365 Views
bigmac
Specialist III
Hello Rodo,
 
The use of the label VectorNumber_Vrtc is inappropriate for the ORG statement, since the label refers to a vector number rather than a vector address.  The ORG directive requires an address, in this case a vector address.
 
 The use of the label Vrtc or the explicit address $FFCE should be OK provided there is a space prior to the directive, as Daniel has indicated.  In all cases, the DW directive is incorrect for CW, as Daniel has also said.
 
I happen to know that Peg uses the P&E assembler, where DW is a valid directive, and is equivalent to DC.W for CW assembler.  Again, this directive must be preceeded by a space or so.  Many of the directives differ between the two assemblers, or if the name is the same, the format is different.  The CW assembler is the more powerful one, and it allows the use of relocatable assembly.
 
DC.W is correct for a vector address - anything larger would tend to overlap to more than one vector.  I am not sure why you needed to change this - what error did you get with the use of DC.W? 
 
Regards,
Mac
 


Message Edited by bigmac on 2008-06-26 11:27 AM
0 Kudos

1,364 Views
peg
Senior Contributor IV
Hi Mac,

The S08 assembler from P&E supports relocatable assembly.

0 Kudos

1,364 Views
peg
Senior Contributor IV
Hi Mac,

Sorry. I could not resist that. Of all the things you could have mentioned you picked the only one that has been partially addressed. In fact in only supports "sections" and whether this qualifies as "supports relocatable assembly" probably depends on your definition of it. Aside from obviously supporting the S08 instruction set this is probably the only difference.

Still not willing to make the jump.....



0 Kudos

1,364 Views
bigmac
Specialist III
Hello Peg,


peg wrote:
Hi Mac,

The S08 assembler from P&E supports relocatable assembly.


Thank you for the correction.  This must have be a major enhancement of the S08 assembler over the previous 908 assembler, presumably with a lot more directives now available.
 
Regards,
Mac

 
0 Kudos

1,365 Views
Rodo55
Contributor I
Mac,
 
Is there a specific module where the ORG statement should be declared? I'm doing it in a subroutine where I do my MCU initialization.
 
Here's my code:
 
 ORG $FFCE
 DC.W IRQT
 
Error Code:
 
0 Kudos

1,365 Views
CompilerGuru
NXP Employee
NXP Employee
No, no special module or location. Note though that the ORG directive remains effective until the next ORG or SECTION is found.
According to the error message the issue is now that the vector is defined twice, so once in your added snippet, and somewhere else too.
Vectors can be defined in many ways, for example:
- in the prm file (if you have a prm file) with the VECTOR directive
- in C with a vector number in a interrupt handler (interrupt <num> void intHandler....)
- in assembly (as you did)
- in C with a fixed allocated constant
- ....

Also check the map file what else is at that address. I think it gets generated partially in case the linking fails. Otherwise ignore the L1119 temporarly to generate a more complete map file.

Daniel




Message Edited by CompilerGuru on 2008-06-26 04:33 AM
0 Kudos

1,365 Views
Rodo55
Contributor I
Here's the entire the information to fill in the blanks. Maybe this will help narrow down the overlap.
 
Vector allocated at absolute address 0xFFFE overlaps with sections placed in segment .absSeg0.abs
 
I don't know what .absSeg0.abs is.
0 Kudos

1,365 Views
Rodo55
Contributor I
Here's information from the segment section of the prm file:
 
SEGMENTS /* Here all RAM/ROM areas of the device are listed. Used in PLACEMENT below. */
    Z_RAM                    =  READ_WRITE   0x0060 TO 0x00FF;
    RAM                      =  READ_WRITE   0x0100 TO 0x025F;
    ROM                      =  READ_ONLY    0xE000 TO 0xFFAD;
    ROM1                     =  READ_ONLY    0xFFC0 TO 0xFFCD;
 /* INTVECTS                 =  READ_ONLY    0xFFCE TO 0xFFFF; Reserved for Interrupt Vectors */
END
The information about the 0xFFCE to 0xFFFF is commented out but it says it's read only?
 
Here's the information from the Section Allocation from the map file.
 
SECTION-ALLOCATION SECTION
Section Name                    Size  Type     From       To       Segment
---------------------------------------------------------------------------------------------
main.asm__ORG00001                75     R     0xFFCE    0x10018   .absSeg0
Summary of section sizes per section type:
READ_ONLY (R):          4B (dec:       75)
*********************************************************************************************
VECTOR-ALLOCATION SECTION
    Address     InitValue   InitFunction
---------------------------------------------------------------------------------------------
*********************************************************************************************
OBJECT-ALLOCATION SECTION
     Name               Module                 Addr   hSize   dSize     Ref    Section   RLIB
---------------------------------------------------------------------------------------------
MODULE:                 -- main.asm.o --
- PROCEDURES:
     VAR00001                                  FFCE       2       2       0   .text      
     MAIN_INIT                                 FFD0      24      36       0   .text      
     IRQT                                      FFF4       2       2       0   .text      
     main                                      FFF6       2       2       0   .text      
     mainLoop                                  FFF8      1A      26       0   .text      
     LOOP1                                    10012       7       7       0   .text      
I'm new at this so I don't know how to read these so any help is appreciated.
 
Rodo
0 Kudos

1,365 Views
Rodo55
Contributor I
Here's the simple program I wrote to learn how RTIs work in assembly and is giving me such a fit. Maybe someone can see where I'm going wrong? I started with the ASM template CW provides and I added some to it. Once I get it to compile I will add more meat but for now I just want to learn how to make assignments.
 
; Include derivative-specific definitions
            INCLUDE 'derivative.inc'
; export symbols
            XDEF _Startup, main
            ; we export both '_Startup' and 'main' as symbols. Either can
            ; be referenced in the linker .prm file or from C/C++ later on
            XREF __SEG_END_SSTACK   ; symbol defined by the linker for the end of the stack
;******************************************************************************************
; variable/data section
LOOP EQU $64
LED1 EQU PTCD_PTCD0
LED2 EQU PTCD_PTCD1
SW1 EQU PTAD_PTAD2
 
  ORG $FFCE
  DC.W IRQT

MAIN_INIT:
            ;Initialize Micocontroller
            LDA #$22
            STA SOPT1
            MOV #$FB, PTADD
            MOV #$FF, PTBDD
            MOV #$FF, PTCDD
            MOV #$FF, PTDDD
            MOV #$FF, PTCD
           
            LDA #$04
            STA PTAPE
           
            LDA #$92
            STA RTCSC
            LDA #$7E
            STA RTCMOD
          RTS
 
          ; RTC Interrupt Routine
         
IRQT:                 
            NOP
            rti
main:
_Startup:
            BSR MAIN_INIT
mainLoop:           
           
            SEI  ; Disable Interrupts
            
            
            CLR LOOP
           CLI                     ; enable interrupts
           
            BCLR PTCD_PTCD0,PTCD ; Turns on LED
LOOP1:
            DEC LOOP
            NOP
            BNE LOOP1    
         BRA    mainLoop
           
0 Kudos

1,365 Views
CompilerGuru
NXP Employee
NXP Employee
As I mentioned in my pref post, the ORG directive starts a absolute section.
As there is no other directive before the code, all the code afterwards gets places just behind it, clearly not what was intended.
So you either have to place the vector definition to the end, or to start a relocatable section again with SECTION ( or another ORG with a more reasonable address).

Code:
  ORG $FFCE
  DC.W IRQT

.text: SECTION

 
Also the I assume the reset vector points to _Startup, and at that label directly a BSR is coded without loading the stack pointer first.
I would recommend to at least check how the wizard generated assembly code is handling such things, even better, start with a wizard generated project.

Note that the error message about the vector refers very probably to a VECTOR command in the prm file (in an area not shown in your snippet. A "VECTOR 0 _Startup" in the prm generates a 2 byte vector entry at 0xFFFE (just as a
   ORG $FFFE   DC.W _Startup
in an assembly file would (as in the asm file I did attach....)).

Daniel
 

0 Kudos

1,365 Views
Rodo55
Contributor I
Thanks Daniel,
 
I'm getting so frustrated. :smileysad:
 
Who'd of thought that such a simple program would be so hard. I wrote the same thing in C in about 10 minutes but I've spent two days trying to get it to work in assembly.
 
I tried moving the ISR to the end and to just about every module in my very simple code and I get errors saying everything from it's out of range, absolute overlaps, overflow in main loop, etc...
 
I tried removing the references to _Startup in the .map, .prm and the .asm files but it must be a hard coded requirement in CodeWarrior because it keeps saying it can't find _Startup.
 
I looked at the files you attached "sources" and "sources1" but I'm not quite sure what you're showing me? Like I said I'm new at this and I don't understand.
 
I included my project so maybe you or someone else could take look at the file and see why I'm having trouble.
 
I'm beginning to think CW doesn't like assmebly. :smileysad:
 
Thanks for your help.
 
Rodo
 
0 Kudos

1,365 Views
CompilerGuru
NXP Employee
NXP Employee
Not sure why you attaching the mcp, I doubt that it shows the problem. I'm a bit confused what you are moving around, in order to help we would need to know how it actually looks like. The ISR was not the problem, just the definition of the vector was using an ORG directive which was still in effect afterwards. Did you try the simlpe fix of adding the SECTION directive after the DW.C in order to switch back to relocatable mode, so the linker can place the code reasonably? If you tried, what was the outcome? Did you look at the VECTOR directives in the prm? Are there any? If so, do you understand what they (or it) is for?

Looking at the thread, I just don't know what you are currently struggling with, the last problem, the overlapping should be easely fixed with the added SECTION directive.

The zip file (same thing attached twice) contained what the wizard generates for an absolute assembly program. (And the two incorrect directives shown in this thread before, should not be in there. I did not notice that I ziped the version with them).

Daniel

0 Kudos

1,364 Views
Rodo55
Contributor I
Hi Daniel,
 
My ISR is very simple. It turns a LED off and then returns to the main program.
 
          ; RTC Interrupt Routine
IRQT:                 
            BSET PTCD_PTCD0,PTCD
            NOP
            rti
When I compile (without errors now, Thank You) and run the program the program hangs in the IRQT ISR. When I step through the program I see it execute the BSET, then NOP and then the RTI sends it back to BSET rather than exit the ISR.
 
Is this another quirk of CW. Is there a different command to exit the ISR instead of "RTI"?
 
Thank,
 
Rodo
0 Kudos

1,364 Views
Rodo55
Contributor I
Never Mind!
 
In my excitement I was so thrilled to get a clean compile I forgot to reset the interrupt flag when I entered my ISR.
 
Thanks again for everyone's help and suggestions.
 
Rodo
0 Kudos

1,365 Views
Rodo55
Contributor I
Thanks Daniel,
 
I included the mcp because I was trying anything to see if I could get this figured out. I figured the more information available the better.
 
I added the .Text section as you suggested and it compiles with out an error. Thank You, Thank You, Thank You. I didn't realize the first time I read your previous note to add that to my code. I thought you were showing an example. My mistake. :smileysad:
 
  ORG $FFCE
  DC.W IRQT
 .text: SECTION

 
I'm somewhat new to this so would you explain what that does and why it worked? I re-read all of your responses and I read the help file on "Section" and I still don't understand how it straightened out the issue.
 
If I explicitly linked the name of my ISR to the Vrtc address why was it an overlap? The Vrtc location $FFCE should have been free for me to write to.
 
I do thank you and everyone else for the help.
 
Rodo
 
 
0 Kudos