Switch statement & Table of Funciont Pointers (long)

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

Switch statement & Table of Funciont Pointers (long)

Jump to solution
2,371 Views
SebaS
Contributor III
THIS IS THE LONG DETAILED VERSION

Hello everybody, I'm here with a huge problem that's blowing my mind!!!

First of all, I'm working with HCS12 and I'm programming it in C language

This is what I had in the .PRM file:

DEFUALT_ROM PAGE_3C;

Then, the problem began when I ran out of allocation space at that page, so I changed the .PRM to this:

DEFUALT_ROM PAGE_3C,PAGE_38;

So, space is no longer a problem.... But know the problem is with the calling convention and moving from one page to another, using the switch statement or a Table of Function Pointers.

I'll try to explain this clearly:

Before I ran out of space, I've got this

#pragma CODE_SEG PAGE_3C
switch(var1){
case 1: ........
case 2: ........
}

and it all works fine, but then, when I changed the .PRM file, it stops working... And this is what I found out looking at the .MAP

When all works:

MODULE: -- rtshc12.c.o (ansibf.lib) --
- PROCEDURES:
_CASE_DIRECT_BYTE 3CB5C1 5 5 1 NON_BANKED
_CASE_CHECKED 3CB5C6 B 11 2 NON_BANKED
_CASE_CHECKED_BYTE 3CB5D1 14

so those procedures were located at page 3C (I don't know why. I mean why is it at page 3C and no another one.. it's some kind of default I guess), and so was my code (the one with the switch). And everything works fine because when I debbug it, I use Assembly Steps and when it reaches the switch statement, there was JSR instruction to _CASE_CHECKED. Everything was at the same page so there was so problem with that.

Then I use #pragma to set the CODE_SEG at page 38.... so now my code was at that page, but _CASE_CHECKED remains at PAGE 3C (I checked the .MAP again)... But when the Assembly Steps reach the switch, there was the JSR instruction again... and that's a problem because they are at different pages.. so it stop working... HOW CAN I SOLVE THAT??

Then I learnt that there was the Function Pointers, therefore a Table of Function Pointers... so I dive into that but I've got the same problem:

#pragma CODE_SEG PAGE_38
void func1(void){......}
void func2(void){......}
void func3(void){......}

const FuncPtrType switchFUNC[3]={func1,func2,func3};

switchFUNC[x]();

... so I check the .MAP agian and I found this:
- PROCEDURES:
func1 388000 1A 26 2 PAGINA_38
func2 38801A 192 402 28 PAGINA_38
func3 3881AC 1A 26 6 PAGINA_38
- VARIABLES:
switchFUNC 3CB017 F

so I don't know why they are at different pages and now, instead of JSR I found CALL[xxxx,Y] but again, there was no page reference
Labels (1)
Tags (1)
0 Kudos
Reply
1 Solution
878 Views
SebaS
Contributor III
Thanks a lot!!! Now it's working!!! Both the switch ant the Table of Function Pointers

I modified the .PRM file and I add this:

NON_BANKED INTO PAGE_C000

and now it's working...... I remember when I first create this project... this line were ther but I deleted because at that page I put the interrupts and I was afraid that would reduce the amount of code at that page.

THANKS!!! especially because you answer really fast!! THANKS A LOT!!

View solution in original post

0 Kudos
Reply
4 Replies
878 Views
CompilerGuru
NXP Employee
NXP Employee
Most runtime routines contained in rtshc12.c are supposed to be allocated non banked,
that's why they are allocated in the section NON_BANKED

_CASE_DIRECT_BYTE 3CB5C1 5 5 1 NON_BANKED

So to fix this, explicitely place NON_BANKED to non banked area, in 0x0000..0x7FFF or 0xC000..0xFFFF (in a area your chip has flash, of course).

Daniel
0 Kudos
Reply
879 Views
SebaS
Contributor III
Thanks a lot!!! Now it's working!!! Both the switch ant the Table of Function Pointers

I modified the .PRM file and I add this:

NON_BANKED INTO PAGE_C000

and now it's working...... I remember when I first create this project... this line were ther but I deleted because at that page I put the interrupts and I was afraid that would reduce the amount of code at that page.

THANKS!!! especially because you answer really fast!! THANKS A LOT!!
0 Kudos
Reply
878 Views
CompilerGuru
NXP Employee
NXP Employee
>so I don't know why they are at different pages and now,
>instead of JSR I found CALL[xxxx,Y] but again, there was no page reference


The two cases are different. For the switch, the compiler want to call the runtime routine which should be allocated non banked, and therefore the compiler uses JSR. Note that the table entries just contain addresses inside of the calling function, and therefore the table only contain 2 byte addresses (or even 1 byte offsets as optimization).
For the manually defined function pointer table, the compiler wants to call the functions the pointers refer too. Unqualified function pointers are far functions in the banked memory model, therefore the compiler uses the CALL instruction. The page number is encode as part of the 3 byte function pointers, its not part of the call instruction.

Daniel
0 Kudos
Reply
878 Views
J2MEJediMaster
Specialist I
You need to read Tech notes TN06, TN227, TN226, and TN236, which are Acrobat PDF files in the \Technical Notes\Build Tools directory. These tech notes explain some of the details on how to access code and data in different memory segments.
 
The  tech notes are part of the CodeWarrior installation. However, if you skipped installing the documentation, you need run the installer again and do that.
0 Kudos
Reply