How to make compiler allocate several EEPROM pages to large data

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

How to make compiler allocate several EEPROM pages to large data

ソリューションへジャンプ
1,561件の閲覧回数
johnandy
Contributor I

Hi,

I am using MC9S12XEP100 in the project. There is large block of data which larger than 2k need to be stored into EEPROM. I am using paged EEPROM for the large data. Part of the .prm file and code is as below:

In the .prm file:

SEGMENTS

      EEPROM_FC = READ_ONLY DATA_FAR IBCC_FAR 0xFC0800 TO 0xFC0BFF;
      EEPROM_FD = READ_ONLY DATA_FAR IBCC_FAR 0xFD0800 TO 0xFD0BFF;
      EEPROM_FE = READ_ONLY DATA_FAR IBCC_FAR 0xFE0800 TO 0xFE0BFF;

END

PLACEMENT

       EVENT_LOG         INTO  EEPROM_FC,EEPROM_FD,EEPROM_FE; 

END

In the source code:

#pragma DATA_SEG EVENT_LOG
static U16 Checksum_Fault_Log;
static EVENT_LOG_DATA_TYPE  Event_Log;
#pragma DATA_SEG DEFAULT

 

I also add the command "-PSegObj" into the compiler command. Currently all the commands are: -CpuHCS12XE -Mb -D__NO_FLOAT__ -MapFLASH -D__MAP_FLASH__ -D__FAR_DATA  -PSegObj

It is a large struct data more than 2k bytes. I expected the data will be allocated separately automatically into EEPROM_FC,EEPROM_FD,EEPROM_FE by compiler. But the codewarrior reported an error:

Link Error : L1102: Out of allocation space in segment EEPROM_FC at address 0xFC0802.

My question is: Is it possible to allocate a large data which beyond the size of one EEPROM page into several paged EEPROM automatically and How?

Any help would be appreciated. Thank you in advance.

0 件の賞賛
返信
1 解決策
1,459件の閲覧回数
kef2
Senior Contributor V
  • I expected the data will be allocated separately automatically into EEPROM_FC,EEPROM_FD,EEPROM_FE by compiler.

No, you expected to much. Allocated object can't be larger than segment you try to allocate your data to. So for EEPROM pages you are limited to 1k, for GPAGE pages you are limited to 64k. So for your large struct you have two options, either split big object into smaller ones using SW, or use GPAGE addressing.

For GPAGE addressing you need to combine your EEPROM segments into single because object still can't be larger than segment. So instead of this

SEGMENTS

      EEPROM_FC = READ_ONLY DATA_FAR IBCC_FAR 0xFC0800 TO 0xFC0BFF;
      EEPROM_FD = READ_ONLY DATA_FAR IBCC_FAR 0xFD0800 TO 0xFD0BFF;
      EEPROM_FE = READ_ONLY DATA_FAR IBCC_FAR 0xFE0800 TO 0xFE0BFF;

END

you need this

      //EEPROM_FC     = READ_ONLY   DATA_FAR IBCC_FAR  0xFC0800 TO 0xFC0BFF;
      //EEPROM_FD     = READ_ONLY   DATA_FAR IBCC_FAR  0xFD0800 TO 0xFD0BFF;
      //EEPROM_FE     = READ_ONLY   DATA_FAR IBCC_FAR  0xFE0800 TO 0xFE0BFF;
      // gpage address is 0x140000 - (0x100-EEpageno)*0x400
      // FC-> 0x13F000
      // FD   0x13F400
      // FE   0x13F800
      EEPROM_FCFE   = READ_ONLY                      0x13F000'G TO 0x13FBFF'G;

'G is global address notation in PWM.

Then change your placement to

PLACEMENT

       EVENT_LOG         INTO  EEPROM_FCFE  

END

Now you should tell compiler you will use global addressing to access your large object:

#pragma DATA_SEG __GPAGE_SEG EVENT_LOG
static U16 Checksum_Fault_Log;
static EVENT_LOG_DATA_TYPE  Event_Log;

char bigdata[2*0x400 + 5]; // more than 2 EE pages
#pragma DATA_SEG DEFAULT

if bigdata is shared, please round declaration in header file with the same pragmas

Edward

元の投稿で解決策を見る

0 件の賞賛
返信
2 返答(返信)
1,460件の閲覧回数
kef2
Senior Contributor V
  • I expected the data will be allocated separately automatically into EEPROM_FC,EEPROM_FD,EEPROM_FE by compiler.

No, you expected to much. Allocated object can't be larger than segment you try to allocate your data to. So for EEPROM pages you are limited to 1k, for GPAGE pages you are limited to 64k. So for your large struct you have two options, either split big object into smaller ones using SW, or use GPAGE addressing.

For GPAGE addressing you need to combine your EEPROM segments into single because object still can't be larger than segment. So instead of this

SEGMENTS

      EEPROM_FC = READ_ONLY DATA_FAR IBCC_FAR 0xFC0800 TO 0xFC0BFF;
      EEPROM_FD = READ_ONLY DATA_FAR IBCC_FAR 0xFD0800 TO 0xFD0BFF;
      EEPROM_FE = READ_ONLY DATA_FAR IBCC_FAR 0xFE0800 TO 0xFE0BFF;

END

you need this

      //EEPROM_FC     = READ_ONLY   DATA_FAR IBCC_FAR  0xFC0800 TO 0xFC0BFF;
      //EEPROM_FD     = READ_ONLY   DATA_FAR IBCC_FAR  0xFD0800 TO 0xFD0BFF;
      //EEPROM_FE     = READ_ONLY   DATA_FAR IBCC_FAR  0xFE0800 TO 0xFE0BFF;
      // gpage address is 0x140000 - (0x100-EEpageno)*0x400
      // FC-> 0x13F000
      // FD   0x13F400
      // FE   0x13F800
      EEPROM_FCFE   = READ_ONLY                      0x13F000'G TO 0x13FBFF'G;

'G is global address notation in PWM.

Then change your placement to

PLACEMENT

       EVENT_LOG         INTO  EEPROM_FCFE  

END

Now you should tell compiler you will use global addressing to access your large object:

#pragma DATA_SEG __GPAGE_SEG EVENT_LOG
static U16 Checksum_Fault_Log;
static EVENT_LOG_DATA_TYPE  Event_Log;

char bigdata[2*0x400 + 5]; // more than 2 EE pages
#pragma DATA_SEG DEFAULT

if bigdata is shared, please round declaration in header file with the same pragmas

Edward

0 件の賞賛
返信
1,459件の閲覧回数
johnandy
Contributor I

I did the method of GPAGE. It works well. Thank you very much!

0 件の賞賛
返信