CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

ROM data out of order in HEX file

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
JDuncan



Joined: 10 Sep 2009
Posts: 2

View user's profile Send private message

ROM data out of order in HEX file
PostPosted: Mon Apr 20, 2015 2:34 pm     Reply with quote

I have written many bootloaders for various PIC devices based on the loader.c example. This all works fine, but I have run into an issue with storing data in ROM.

Compiler: Ver. 4.129
Target Device: 18F67J60
Single pass compile (not using multiple compilation units)
Build - Using Build button in IDE (No comple or link script)

I have two large arrays for command parsing information that I need to store in ROM in order to free up RAM. I declare these arrays using the ROM statement.


Code:

typedef struct
{
   int8  commandString[CMD_LEN_MAX]; 
   int8  cmdId;                     
   int8  validType;                                                     
   int8  cmdFlag;               
}  CMDTABLE_t;


typedef struct
{
   int8   cmdID;
   int8   numParams;
   int8   paramType[CMD_NUM_PARAMS];
   int32  paramMin[CMD_NUM_PARAMS];
   int32  paramMax[CMD_NUM_PARAMS];
}  PARAMTABLE_t;


rom CMDTABLE_t mCmdDictionary[CMD_ID_MAX+1] =       
{                   
       ... initialization values...
}


rom PARAMTABLE_t mParamTable[CMD_ID_MAX+1] =
{
      ... initialization values...
}



The application avoids addressing these arrays with pointers, so that issue should be avoided.

When I load the combined bootloader/application image with the programmer, everything works fine. When I use the bootloader to load the update image, my command parser does not recognize some of the commands it receives because the command tables have been damaged.

In analyzing the hex files output from the compiler, the two arrays are placed in memory as follows:

mCmdDictionary - 0xFD90 - 0xFFF0
mParamTable - 0xF708 - 0xFD8F

In the hex file, the lines giving the data for addresses 0xFD90 - 0xFFF0 are listed before the lines for addresses -0xF708 - 0xFD8F. It appears that these lines being out of order, combined with the page erase structure of the flash - causes a portion of the mCmdDictionary table to be erased when the mParamTable data is programmed by the bootloader.

I was able to temporarily work around this by changing the declaration for mCmdDictionary to CONST instead of ROM. That caused mCmdDictionary to be moved to low memory and eliminated the issue. However, the workaround has caused other issues and I would like to declare them both using the ROM declaration.

Is there any way to tell the compiler to place the lines in the hex file in order by target address? Any other solutions? Am I completely misunderstanding the problem?

Any thoughts would be appreciated.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Apr 20, 2015 4:07 pm     Reply with quote

I don't see this happening in vs. 5.044. I made a test program (which you
should have provided) as shown below. I compiled it, and went to View /
Program Memory and scrolled down to the end of ROM. It shows the
structure with the string in it, is placed last in memory, even though it
appears first in the declarations. The one with the string is identified
below by 42 41, 44 43, 45 (for "ABCDE")"
Code:

  65516    1FFD6      0312    MULWF 0x12, BANKED                     
  65517    1FFD8      0201    MULWF 0x1, ACCESS                     
  65518    1FFDA      0003    SLEEP               
  65519    1FFDC      0000    NOP                                   
  65520    1FFDE      0004    CLRWDT                                 
  65521    1FFE0      0000    NOP                                   
  65522    1FFE2      0005    PUSH                                   
  65523    1FFE4      0000    NOP                                   
  65524    1FFE6      0006    POP                                   
  65525    1FFE8      0000    NOP                                   
  65526    1FFEA      4241    RRNCF 0x41,F,ACCESS                 
  65527    1FFEC      4443    RLNCF 0x43,W,ACCESS                 
  65528    1FFEE      0045                                         
  65529    1FFF0      0000    NOP                                   
  65530    1FFF2      0000    NOP                                   
  65531    1FFF4      AA55    BTFSS 0x55,0x5,ACCESS               
  65532    1FFF6      FF01    NOP                                   


Here's a portion of the .HEX file. I don't see the hex address lines
being placed out of order. The address fields are in numerical order:
Code:

:020000040001F9
:0AFFD6001203010203000000040002
:10FFE00000000500000006000000414243444500B7
:08FFF0000000000055AA01FF0A

Again, this is with compiler vs. 5.044.

Can you post similar data that shows your problem ?

Test program:
Code:

#include <18F67J60.h>
#fuses HS, NOWDT
#use delay(clock=4M)

#define CMD_LEN_MAX 10
#define CMD_NUM_PARAMS 2
#define CMD_ID_MAX 0

typedef struct
{
   int8  commandString[CMD_LEN_MAX]; 
   int8  cmdId;                     
   int8  validType;                                                     
   int8  cmdFlag;               
}  CMDTABLE_t;


typedef struct
{
   int8   cmdID;
   int8   numParams;
   int8   paramType[CMD_NUM_PARAMS];
   int32  paramMin[CMD_NUM_PARAMS];
   int32  paramMax[CMD_NUM_PARAMS];
}  PARAMTABLE_t;


rom CMDTABLE_t mCmdDictionary[CMD_ID_MAX+1] =       
{                   
  {
   "ABCDE",
   0x55,
   0xAA,
   0x01
  }
};


rom PARAMTABLE_t mParamTable[CMD_ID_MAX+1] =
{
  {
   0x12,
   0x03,
   {1, 2},
   {3, 4},
   {5, 6}
  }
};



//===================================
void main()
{
int8 temp;
int8 i = 0;

temp = mCmdDictionary[i].cmdID;

temp = mParamTable[i].numParams;


while(TRUE);
}
Ttelmah



Joined: 11 Mar 2010
Posts: 19432

View user's profile Send private message

PostPosted: Tue Apr 21, 2015 2:19 am     Reply with quote

I'd suspect that his problem is not what he thinks it is.....

Remember the config words on these chips are in the last page of the program memory. A page is 64bytes. So the upper table will result in the config words being erased, and having to be re-written. The bootloader normally should not do this. Look at figure 5-1.

I'd suggest moving the tables down in memory a little, so that the tables end by 0xFFBF. Any attempt to write above 0xFFC0, will result in the config words becoming involved.

Use #ROM to locate the tables both to page boundaries, and ensure both end before the last page. Or just use a #ORG immediately before the rom declarations to force them down in memory (remember to include 'default').
Ttelmah



Joined: 11 Mar 2010
Posts: 19432

View user's profile Send private message

PostPosted: Tue Apr 21, 2015 4:05 am     Reply with quote

Thinking about it, I'd suggest the easiest way to do it is:
(modified from PCM_Programmers example):
Code:

#include <18F67J60.h>
#fuses HS, NOWDT
#use delay(clock=4M)

#define CMD_LEN_MAX 10
#define CMD_NUM_PARAMS 2
#define CMD_ID_MAX 0

typedef struct
{
   int8  commandString[CMD_LEN_MAX];
   int8  cmdId;                     
   int8  validType;                                                     
   int8  cmdFlag;               
}  CMDTABLE_t;


typedef struct
{
   int8   cmdID;
   int8   numParams;
   int8   paramType[CMD_NUM_PARAMS];
   int32  paramMin[CMD_NUM_PARAMS];
   int32  paramMax[CMD_NUM_PARAMS];
}  PARAMTABLE_t;

#org 0x1F400
rom CMDTABLE_t mCmdDictionary[CMD_ID_MAX+1] =       
{                   
  {
   "ABCDE",
   0x55,
   0xAA,
   0x01
  }
};

#org 0x1F800
rom PARAMTABLE_t mParamTable[CMD_ID_MAX+1] =
{
  {
   0x12,
   0x03,
   {1, 2},
   {3, 4},
   {5, 6}
  }
};
#org default
#include <bootloader.h>
//This forces the arrays onto _page_ boundaries, with enough space to stop
//below the config data (with his sizes), and then loads the bootloader
//org data, to set the base of memory, so that the build will be at the
//correct addresses.

//===================================
void main()
{
int8 temp;
int8 i = 0;

temp = mCmdDictionary[i].cmdID;

temp = mParamTable[i].numParams;


while(TRUE);
}
JDuncan



Joined: 10 Sep 2009
Posts: 2

View user's profile Send private message

PostPosted: Fri May 15, 2015 5:06 pm     Reply with quote

Ttelmah and PCM programmer,

Thanks so much for your response. I was called away unexpectedly and only just now have seen your posts.

I think that the issue probably is with the high memory position and the configuration data. If I allow the compiler to place both arrays in rom without any location information, it begins at 0x1F83E (not a page boundary) and goes up to 0x1FFF7.

I tried using #orgs to place the tables at a lower location as you have done in your example. However, the compiler indicates that something has already reserved that space. When it hits the first #org command for my rom tables, I get an Invalid ORG range error. The associated error info shows a segment already reserved at 0x1F000 - 0x000000.



    --- Info 300 "C:\Users\Judy\Documents\AubTechGrp\Leeson\AT\ATRepo\cmdTables.h" Line 179(1,8): More info: Segment at 00000-007FE (0000 used) Priv
    --- Info 300 "C:\Users\Judy\Documents\AubTechGrp\Leeson\AT\ATRepo\cmdTables.h" Line 179(1,8): More info: Segment at 00800-0FFFE (0000 used)
    --- Info 300 "C:\Users\Judy\Documents\AubTechGrp\Leeson\AT\ATRepo\cmdTables.h" Line 179(1,8): More info: Segment at 10000-1FFF6 (0000 used)
    --- Info 300 "C:\Users\Judy\Documents\AubTechGrp\Leeson\AT\ATRepo\cmdTables.h" Line 179(1,8): More info: Attempted to create: 1F000-00000 for #org
    *** Error 126 "C:\Users\Judy\Documents\AubTechGrp\Leeson\AT\ATRepo\cmdTables.h" Line 179(1,8): Invalid ORG range
    1 Errors, 10 Warnings.
    Build Failed.



A condensed sample of the code defining the tables is below.

Code:
// Data structure for command dictionary table
typedef struct
{
   int8  commandString[CMD_LEN_MAX]; 
   int8  cmdId;                     
   int8  validType; 
   int8  cmdFlag;   
}  CMDTABLE_t;

// Data structure for command param table
typedef struct
{
   int8   cmdID;
   int8   numParams;
   int8   paramType[CMD_NUM_PARAMS];
   int32  paramMin[CMD_NUM_PARAMS];
   int32  paramMax[CMD_NUM_PARAMS];
}  PARAMTABLE_t;


#org 0x1F000
rom CMDTABLE_t mCmdDictionary[CMD_ID_MAX+1] =       
{                   
   { "FPGAREG",     FPGAREG,    VAL_READWRITE,   CMD_FLAG_NORMAL, }, 
   { "HORPAN",      HORPAN,     VAL_READWRITE,   CMD_FLAG_NORMAL, },

   { CMD_ENDTABL,   CMD_ID_MAX,  0,              CMD_FLAG_NORMAL} // Mark end of command table
};   



/* ******- Param List - ********
#org 0x1F800
rom PARAMTABLE_t mParamTable[CMD_ID_MAX+1] =
{
   {  FPGAREG, 3,  {PARAM_INT32, PARAM_INT32, PARAM_INT32},
                              {0,0,1},   {65535,255,3} },     
   {  HORPAN,    2, {PARAM_INT32, PARAM_RL},
                             {HPAN_MIN, 0},  {HPAN_MAX, 1} }, 
   // Mark end of table
   {  CMD_ID_MAX, 0, {}, {}, {}},
   
};
#org default


I have all of the various #orgs, etc in the code that control the placement of the bootloader, pretty much identical to the CCS bootloader example. But I'm not sure what is causing the segment from 0x100000-0x1FFF6 to be reserved. My boot loader uses 0x0000 - 0x007FE and the application code begins at 0x800.

I'm using the IDE Build All button to compile.
Any ideas on how to get it to let me place data in those locations?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri May 15, 2015 5:50 pm     Reply with quote

Quote:
{"FPGAREG", FPGAREG, VAL_READWRITE, CMD_FLAG_NORMAL, },
{ "HORPAN", HORPAN, VAL_READWRITE, CMD_FLAG_NORMAL, },

{ FPGAREG, 3, {PARAM_INT32, PARAM_INT32, PARAM_INT32},
{0,0,1}, {65535,255,3} },
{ HORPAN, 2, {PARAM_INT32, PARAM_RL},
{HPAN_MIN, 0}, {HPAN_MAX, 1} },
// Mark end of table
{ CMD_ID_MAX, 0, {}, {}, {}},


Can you provide the code where you declare or #define all this stuff so
it's possible to make a test program ?
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group