pb with sprinf since use of const string in banked mem

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

pb with sprinf since use of const string in banked mem

4,505 次查看
hdan
Contributor III
hello,

I create a new post (too far away from the begining)

My program was running but i had to move the string in banked memory.

I use the FAQ "FAQ-27439". (thx crasycat for the tip)

But now i have a problem with sprintf.

a simply example:

char stH[10]=" --- ";
char stO[30];
nInd = sprintf(stO,stH); // => good result
nInd = sprintf(stO,"%s",stH); // => bad one
why ?

I search on post and found this :
tim_milliken
Problem with CW12 4.5
http://forums.freescale.com/freescale/board/message?board.id=CW816COMM&message.id=87&query.id=11133#...

I think tim_milliken had the same problem.
he wrote in the message 5:
"I made a compltely new project and that is the only thing I did, and it did not work. I sometime step into sprintf and notice that the format that gets passed in is messed up."

I have the same problem with the format.

someone have an idea?

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

1,460 次查看
CompilerGuru
NXP Employee
NXP Employee
One problem with the (s)printf type of functions in C is that the open argument part is completely untyped.
The compiler is not knowing what you should pass on the open arguments, therefore it will just pass through whatever you put there, that's completely independent of the expected arguments.
Your problem now is that the type of the actual argument (stH) does not match what the compiler expects for the %s part.
Out of the box (as specified by the ANSI standard), %s expects a "(const)char*".
If you changed the ANSI library by modifying LIBDEF_StringPtr to be a "(const)char*__far", then it now expects that type.

I do recommend to explicitely cast every single argument to an open argument function like (s)printf,
so in your case:
> sprintf(stO, "%s", (LIBDEF_StringPtr)stH);

That will make sure that sprintf gets what it expects. If LIBDEF_StringPtr is a far pointer then that will fix your issue.
Note that I do recommend that cast independetly of the far/near pointer story, I do the same for %d -> (int), %lx -> (unsigned long), ...
Basically this way the compiler will at least adapt the type as much as possible, well if the type does not fit, that just cuts, but that's far better than to put a part of the content into the next arguments...

Daniel


BTW: Other problems with sprintf:
- no overflow checking in the output buffer
- you get always all features of sprintf even if you just use 5% of them (and you pay with code space for all the features)
- can cause crashers if open arguments are incorrect
- correctness affected by the complex C rules for type propagation
- bugs are found at runtime, if at all. Not at compile time.
- many details to know about all the formatting possibilities and the effects of all the flags.
- slow (relatively)

The only good thing I know about sprinf, calling sprintf is rather dense, both in code size and in source code length.

Also use strcpy(stO, stH) to copy strings, not sprintf(stO, "%s", (LIBDEF_StringPtr)stH); :smileyhappy:.
0 项奖励
回复

1,460 次查看
hdan
Contributor III
hello,

Great Thx for the soluce, it run.

hdan.
0 项奖励
回复

1,460 次查看
hdan
Contributor III
sticky pb...


in another part of my code i use struct like this :
( it's a simplification)
#pragma CONST_SEG CONST_USR // const in banked memory
struct sVd
{
unsigned int d;
};

// in global an array of sVd:
const struct sVd tVd[2]=
{
0x10,
0x20
};

in program:

volatile unsigned int tmpTY;

tmpTY =tVd[0].d;

in debug mode i can read:
tmpTY=0x16c1 !!!
and if i ask the value tVd[0].d at the debugger he give 0x10.

I suppose (not really sure)that i have this problem since i tell the compiler to put string in banked memory.
0 项奖励
回复

1,460 次查看
CompilerGuru
NXP Employee
NXP Employee
Well, I don't see any string here.
Anyway, the way the CONST_USR section is used in the pragma, it must be allocated non banked in the banked memory model. Therefore what is the address of tVd in our map file?
Also, I wonder how you did actually "put string in banked memory", what did you change? Make sure to explicitly allocate all your custom, explicitly banked, CONST sections into banked area. Don't place DEFAULT_ROM or ROM_VAR banked as that would cause sections to get banked allocated which are not prepared for that, like this CONST_USR section.


Daniel
0 项奖励
回复

1,460 次查看
hdan
Contributor III
Hello,



for the String I have put to 1 these:
#define LIBDEF_FAR_CONST_STRINGS 1
#define LIBDEF_FAR_STRINGS 1
in libdefs.h
but i test with a normal libdefs and it's the same.

My Placement in .prm is:
PLACEMENT
_PRESTART, /* Usemto _Se ctart */
STARTUP, /* starttures */
ROM_VAR, /* constant variables */
STRINGS, /* string literals */
VIRTUAL_TABLE_SEGMENT, /* C++ virtsegment */
NON_BANKED, /* runtbe banked */
CODE_CPY,
CONST_CPY,
COPY INTO ROM_C000/*, ROM_4000*/;

DEFAULT_ROM,
STRING_H,
CONST_USR INTO PAGE_30,PAGE_31,PAGE_32,PAGE_33;
DEFAULT_RAM INTO RAM;


The address of tVd is : 0x339669 with the #pragma CONST_SEG CONST_USR and without at 0xDF98.
i need my const in banked memory.

hdan
0 项奖励
回复

1,460 次查看
CompilerGuru
NXP Employee
NXP Employee
I was under the obviously wrong impression that you intended to allocate strings only (say string literals) and not all constants banked.
OK, so the problem is the #pragma you are using.
If you allocate variables/constants not the default way the memory model dictates, then the pragma has to mention that too. More specific, your pragma should be

#pragma CONST_SEG __PPAGE_SEG  CONST_USR

just as the STRING_SEG is qualified in the FAQ. It's the same thing for the CONST_SEG too.

Daniel
0 项奖励
回复

1,460 次查看
hdan
Contributor III
THANK YOU, it was my problem!
0 项奖励
回复