When I compile my source code for S12X processor, the compiler is creating calls to PPAGE at the old S12 address

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

When I compile my source code for S12X processor, the compiler is creating calls to PPAGE at the old S12 address

1,495 Views
Jiun_Yong
Contributor III

Hi

I am in the process of moving a project over from an MC9S12A256 processor to MC9S12XS256

When I was debugging the code, it crashed when there was a call to a banked page of memory (from unbanked)

Looking at the assembler code, it is loading the banked page number into address 0x30. This was the address of the PPAGE register on the MC9S12A256.

On the MC9S12XS256 the PPAGE register is stored at address 0x15.

I have checked and the project target CPU in the Compiler settings is  -CpuHCS12X

Somehow, the compiler is losing track of the fact that it is compiling for the S12X series.

Is there a #pragma or keyword I can use at the start of the source code file to force/remind the compiler that it is compiling for the S12X.

 

I would appreciate any suggestions please as I am under a lot of time pressure.

 

Many thanks

Steve

Labels (1)
0 Kudos
9 Replies

771 Views
ZhangJennie
NXP TechSupport
NXP TechSupport

Hi Steve,

can you please create a demo project and upload it here to showcase your issue?

please also send us a screenshot of the problem.

Best Regards,

ZhangJun

0 Kudos

771 Views
Jiun_Yong
Contributor III

Hi ZhangJun

Here is a summary of the problem:

I am compiling and testing the code for an MC9S12XS256 processor.

I have defined a look up table of functions which I can call.

A typical line in this table reads:

/* tU08 is an in house definition of an unsigned char or byte */

/* function prototype declarations */

typedef tU08 (* __far tFunction_far_8_ptr0)(tUSB_Max3421_Data *my_usb_hub);

/* look up table */

const tFunction_far_8_ptr0 Run_Check_Max3421 = (* BT_check_max3421);

In my application, I have a section of code which calls this routine:

/* 1. If we have not yet checked if there is a MAX3421, then do that now */

if (uUSB_Status.flags.bit.usb_checked == 0)

{

  /* 1.1 try to communicate with the MAX3421 and initialise it */

  uUSB_Max_Data.item.mode = USB_POWER_UP;

  if (Run_Check_Max3421(&uUSB_Max_Data) == USB_SUCCESS)

  {

  uUSB_Status.flags.bit.usb_fitted = 1;

  }

  /* 1.2 Flag that we have checked the MAX3421 */

  uUSB_Status.flags.bit.usb_checked = 1;

}

When I dissemble the code, I see the following. I have highlighted the offending lines in bold.

  220: /* 1. If we have not yet checked if there is a MAX3421, then do that now */
  221: if (uUSB_Status.flags.bit.usb_checked == 0)

  0145 1e0000081c   [5]     BRSET uUSB_Status,#8,*+33 ;abs = 0166

  222: {
  223: /* 1.1 try to communicate with the MAX3421 and initialise it */
  224: uUSB_Max_Data.item.mode = USB_POWER_UP;

  014a c6ff         [1]     LDAB  #255

  014c 7b0000       [3]     STAB  uUSB_Max_Data:1

  227: if (Run_Check_Max3421(&uUSB_Max_Data) == USB_SUCCESS)

  014f cc0000       [2]     LDD   #uUSB_Max_Data

  0152 180b000030   [4]     MOVB  #PAGE(Run_Check_Max3421),/*PPAGE*/48

0157 4bfb0000     [10]    CALL  [Run_Check_Max3421,PCR]

  015b 046104       [3]     TBNE  B,*+7 ;abs = 0162

  228: {
  229: uUSB_Status.flags.bit.usb_fitted = 1;

  015e 1c000010     [4]     BSET  uUSB_Status,#16

  230: }
  231:
  232: /* 1.2 Flag that we have checked the MAX3421 */
  233: uUSB_Status.flags.bit.usb_checked = 1;

  0162 1c000008     [4]     BSET  uUSB_Status,#8

  234: }
  235:

Note the comment that the PPAGE register is at memory location 48 (0x30)

When I step through the code in the debugger, the assembler code tries to store the page number in memory location 0x30. But on the MC9S12XS processor, the PPAGE register is stored at memory location 0x15. So the PPAGE register is not set correctly. When the next line is executed (the CALL operation) the program pointer goes to the wrong page and the application crashes.

I am happy to zip up the whole of my project as I have it now for you to experiment.

0 Kudos

771 Views
kef2
Senior Contributor IV

Hi

It was nice puzzle indeed. Unless it is a nonbanked routine, compiler has no right to write anything to PPAGE register, because it would break your code immediately. So I though you had to fool compiler somehow. And I know how you could do it:

#pragma CONST_SEG __PPAGE_SEG PAGED_ROM

const tFunction_far_8_ptr0 Run_Check_Max3421 = (* BT_check_max3421);

#pragma CONST_SEG DEFAULT

You need to move your function pointers to regular nonbanked CONST_SEG.

0 Kudos

771 Views
Jiun_Yong
Contributor III

Hi Edward

Just to clarify on my original email:

1. The main function which calls these routines is running in NON BANKED memory. Otherwise, as you say, it will break!

2. My pragma declaration for the block where the function pointer is declared is as you suggested i.e. #pragma CONST_SEG __PPAGE_SEG BOOT_USB_API - I just have a different name for the memory segment.

3. The code was originally written to run on an S12 processor. It worked as expected on there.

If I disassemble the code for the S12 project, the the function call reads:

if (Run_Check_Max3421(&uUSB_Max_Data) == USB_SUCCESS)

  01aa cc0000       [2]     LDD   #uUSB_Max_Data

  01ad 180b000030   [4]     MOVB  #PAGE(Run_Check_Max3421),/*PPAGE*/48

  01b2 4bfb0000     [10]    CALL  [Run_Check_Max3421,PCR]

For the S12X processor, when I disassemble the code I get:

  0160 cc0000       [2]     LDD   #uUSB_Max_Data

  0163 180b000030   [4]     MOVB  #PAGE(Run_Check_Max3421),/*PPAGE*/48

  0168 4bfb0000     [10]    CALL  [Run_Check_Max3421,PCR]

Note: the compiled code is identical, but in the first project I have specified that I am compiling the code for the HCS12 family and in the second project for the HCS12X family.

But here's the catch, in the HCS12X family, Freescale relocated the PPAGE register to address 21 (Hex 15) from 48 (Hex 30) in the S12.

But when I compile the code for the HCS12X, as you can see it still uses the old PPAGE address.

My thoughts are:

1. Somehow I have left some directive in the code that says "compile this bit for the old HCS12 processor"

2. When the compiler was updated for the HCS12X processor, Freescale overlooked the change of PPAGE address

Many thanks for looking through this for me.

Steve


0 Kudos

771 Views
Jiun_Yong
Contributor III

Hi Edward and Jun

I have cracked it! The issue was in the compiler settings! I am using an HCS12XS processor. (MC9S12XS256CAL)

When I went to the Project Settings, I looked up Compiler Options, Code Generation. Half way down the list is an option "Generate code for specific HC12 families". This was set to "HCS12X family", which would appear to be correct to my inexperienced eye. Because of the way the pull down list of options opens up, it is not obvious that there is a further option HCS12XE family. This is the correct choice because the S12XS is derived from the S12XE - but without the XGATE module.

How did this come about? Well I used the New Project Wizard to to create the project and Processor Expert in the Rapid Application Development options. If you select an HCS12XS processor, then when the project is created the Compiler option is set to "HCS12X Family". This is possibly a bug in the New Project Wizard or Processor Expert. If you select an HCS12XE processor then the compiler is set correctly to "HCS12XE Family".

You can try this out yourself in a few minutes to confirm.

And if you look through Application Note AN 3242 (S12XD and S12XE compatibility) it says there that the PPAGE register was relocated for the S12XE.

At this point I think it is over to Freescale to check this.

I am going home now, a much happier man!

Best regards

Steve

0 Kudos

771 Views
kef2
Senior Contributor IV

Hi Steve

and thanks for feedback.

I thought it is a bug. Ok, perhaps you have some large structs with pointers to functions and want to place4 them in __PPAGE_SEG. Still I see problem with this. You need to restore PPAGE before exiting from your nonpaged function to paged caller of nonpaged function. I hope you solved it somehow.

You need to use -CpPPAGE=0x15 compilers option. It will fix your issue. But. -CpPPAGE has one side effect. It makes compiler saving restoring PPAGE register on entry and exit from interrupt handlers. Save/restore may be optimized out, but more complex ISR's will be slowed down with extra save/restore PPAGE code. If you don't want this, you may not add -CpPPAGE to compiler options, but instead add this option only for your nonbanked function like this:

/*ppage_sx is any unique name for added options set*/

#pragma OPTION ADD ppage_sx "-CpPPAGE=0x15"

int foo(void)

{

}

#pragma OPTION DEL ppage_sx

0 Kudos

771 Views
ZhangJennie
NXP TechSupport
NXP TechSupport

Hi Steve,

please send us the demo project. we need to reproduce the problem on my side. thanks!

Best Regards,

ZhangJun

0 Kudos

771 Views
Jiun_Yong
Contributor III

Hi ZhangJun

Do you have an email address that I can send the demo project?

I have put the whole project into a zip file.

Many thanks

Steve Lewis !

0 Kudos

771 Views
ZhangJennie
NXP TechSupport
NXP TechSupport

Hi Steve.

please send the project to support@freescale.com

please also include this thread link.

I can check it.

thanks!

Best Regards,

Zhang Jun

0 Kudos