help with technical note TN228 CW5.7 9s08RE16

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

help with technical note TN228 CW5.7 9s08RE16

4,010 次查看
stevec
Contributor III
I have been looking for a way to write to FLASH by transferring code to RAM and running from there. I have found TN228 which covers my needs nicely. However I have the following questions:

1.  The copy routine to copy from ROM to RAM goes

    char *srsPtr, *dstPtr;
    int count;

    srcPtr = (char *)Start_Copy_In_RAM;
    dstPtr = (char *)&func;                         //produces error "Non standard conversion used"

    for(count  = 0; count < (int) Size_Copy_In_RAM; count++;dstPtr++;srcPtr++)
    {
       *dstPtr = *srcPtr;
    }

 "func" is the name of the function to be copied across

Why the error here?


2. The note details "Start_In_ROM refers to the beginning of the segment...."  There is no mention in the code of this name. Is this a typo error.(You will have had to have read the TN to understand this)?

The note says it is valid for linker V5.0.19 or higher (HC08 V2.1.x or higher).

Has anyone ever used this TN?

Steve
标签 (1)
标记 (1)
0 项奖励
回复
7 回复数

1,723 次查看
CompilerGuru
NXP Employee
NXP Employee
About the 1. point only.
There is no error for this line, "C1805: Non standard conversion used" is (by default) only a warning. And the warning that the ANSI standard does not cover this conversion is correct (according to the standard), but at the same time there is no real problem here too.
By casting first to a (void*) you can avoid the diagnostic message.


    char *dstPtr;

    dstPtr = (char *)(void*)&func;


Also the linker version is not a problem if you are not using really acient tools :smileyhappy:.

Daniel

0 项奖励
回复

1,723 次查看
dkelly
Contributor I
HC12 rather than the O.P.'s HC08, but still the same tech note. Codewarrior is not returning the address of my function. This is mostly per TN228:

extern UINT16 far __SEG_START_RUN_FROM_RAM[]; // source from ROM
extern UINT16 far __SEG_END_RUN_FROM_RAM[]; // end of ROM source
extern UINT16 far __SEG_SIZE_RUN_FROM_RAM[]; // size of ROM source

#pragma MESSAGE DISABLE C12002
void
rom_to_ram( void )
{
UINT16 *far source;
UINT16 *dest;

// Multiple casts to mute compiler warning
dest = (UINT16 *)(void *)&ram_updater
source = __SEG_START_RUN_FROM_RAM;
while( source __SEG_END_RUN_FROM_RAM )
*dest++ = *source++;
}
#pragma MESSAGE DEFAULT C12002

ram_updater() is compiled with "#pragma CODE_SEG RUN_FROM_RAM_first" and is the only routine in RUN_FROM_RAM_first so that its address should be (confirmed, it is) the start of RUN_FROM_RAM and usable for the above copy.

In my .prn file I have:

SEGMENTS
// Stuff that must run from RAM to update FLASH
ROM_IMAGE = READ_ONLY 0x3d9000 TO 0x3dbffd RELOCATE_TO 0x2000;
...

PLACEMENT
RUN_FROM_RAM_first,
RUN_FROM_RAM INTO ROM_IMAGE;
...

Disassembly of the above address assignment:
355: // Multiple casts to mute compiler warning
356: dest = (UINT16 *)(void *)&ram_updater
0002 cc0000 [2] LDD #LOW_PAGE(ram_updater)
0005 6c83 [2] STD 3,SP

Viewing the above loaded on my target in "True-Time Simulator & Real Time Debugger" shows LDD #0 but when ram_updater is actually called its CALL 0x2000,0x00 as expected.

Have tried every variation on the syntax of the address assignment and not hit on one that works.
0 项奖励
回复

1,723 次查看
CompilerGuru
NXP Employee
NXP Employee
Is the issue that you get a unexpected address for ram_updater?
For the S12 (which device are you using (HC12, S12, S12X, ...?)) the address of a far function has a different byte ordering than the address of a far data pointer, check the manual.
If that is the issue, and ram_updater is only executed from non paged, then marking it as __near (while still allocating it paged on flash, non paged at runtime) should help.
Also the declaration of ram_updater and the pragma it is allocated with may help.
Which memory model?

Daniel
0 项奖励
回复

1,723 次查看
dkelly
Contributor I
1) Yes, 0x0000 is an unexpected address. 0x2000 is expected.

2) 9S12NE64, banked memory model.

3) Yes, ram_updater() is using the default far.

Have tried putting the calling routine in #pragma CODE_SEG NON_BANKED same as my interrupt service routines but am getting C3801 complaints. Just how do I determine what attributes the compiler thinks are different?

Once Upon A Time I found documentation in the online help on the difference in byte orders for far objects. Believe there were example macros for converting. Can't find that now.

For lack of the above macros I thought to try something else. Created a big union for plucking parts out of a value:

typedef union {

struct {
UINT08 a, b, c, d;
} bytes;

struct {
UINT08 a;
UINT16 bc;
UINT08 d;
} mixed;

struct {
UINT16 ab, cd;
} words;

UINT32 u32;

} FAR_EXPERIMENT;

And now the disassembly looks correct:

373: UINT16 *far source;
374: UINT16 *dest;
375: FAR_EXPERIMENT addr;
376:
377: addr.u32 = (UINT32)&ram_updater
0002 cc0000 [2] LDD #ram_updater
378:
379: // Multiple casts to mute compiler warning
380: dest = (UINT16*)addr.words.cd;
0005 6c83 [2] STD 3,SP

Which prompted me to try a similar reduced version:

dest = (UINT16*)((UINT32)&ram_updater);

which I tried before my first post and for some reason didn't believe it worked. Am using the same trick somewhere else, upcasting to UINT32 before pulling it back down into something smaller. IIRC am using it elsewhere because it locally mutes the "loss of precision" warning in a situation that loss of precision is exactly what I wanted but for some reason was too lazy to do the union/struct thing above.

Next: figure out what I have to do to debug code that has been relocated to RAM. First attempt the debugger crashed and wanted to tell Microsoft about it.
0 项奖励
回复

1,723 次查看
stevec
Contributor III
Daniel,

Thanks for that. That warning has gone away now. However more have been thrown up. I shall try sorting them, but may be back!!
0 项奖励
回复

1,723 次查看
allawtterb
Contributor IV
Your code has some errors if this is the exact code you used.
 
1) You defined srcPtr as srsPtr.
2) In the for loop you seperated the increments with a semi-colon instead of a comma.  The semi-colon only goes at the end after srcPtr++.
0 项奖励
回复

1,723 次查看
stevec
Contributor III
Allawtterb,
The srsPtr was a typing error on my part.

The 'for' loop was exactly as in the technical note, so Metroworks got that wrong.
0 项奖励
回复