sprintf Problem

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

sprintf Problem

3,835 Views
PabloA
Contributor II
Hello to every body!
 
I'm new in the forum and I have a little problem with my C code for a MC908QB8 microcontroller.
 
I try to use "sprintf " like this:
 
#include <hidef.h> /* for EnableInterrupts macro */
#include <stdio.h>
#include "derivative.h" /* include peripheral declarations */

void main(void)
{

  char Str_Buffer [10] ;
  signed int Num = 1500;
 
 
  (void) sprintf (Str_Buffer, "%d", Num);

  for(;:smileywink:
  {
    __RESET_WATCHDOG(); /* feeds the dog */
  } /* loop forever */
  /* please make sure that you never leave this function */
 
 
}
But wen I try to simulate it the Real Time Debugger Stop with the following mensage:
 
Error: At location 0002 -
Error: Attempt to use unimplemented (--) memory.
Im not using floating point.
 
I don't understand way it dosen't work, so if any body can help me I will appreciate it.
 
Thank you very much!
 
Pablo Suarez
Labels (1)
0 Kudos
6 Replies

422 Views
Lundin
Senior Contributor IV
On a mcu with limited memory, and possibly demands on realtime performance, you might want to concider writing your own int-to-ASCII routine instead of using sprintf(). sprintf() will not only give you RAM problems, but it will also slaughter the flash. Ahe function is also very slow, with a huge amount of overhead you don't need.

No matter the platform, the only reason to use sprintf() is really when you are using float numbers, since that will be time and memory consuming no matter how you do. For simple integer to ASCII conversions, there are much smoother ways.
0 Kudos

422 Views
PabloA
Contributor II
Thak you very much CompilerGuru you are right! 
 
 
0 Kudos

422 Views
CompilerGuru
NXP Employee
NXP Employee
Hi,

the problem is the too small stack. A wizard generated projects allocates 0x30 bytes for the stack, but that sprintf did use 0x43 bytes for me (HC08 V5.1, SMALL memory model, default options).

Here an adapted prm file providing 0x60 bytes for the stack.

Daniel

Code:
/* This is a linker parameter file for the QB8 */NAMES END /* CodeWarrior will pass all the needed files to the linker by command line. But here you may add your own files too. */SEGMENTS /* Here all RAM/ROM areas of the device are listed. Used in PLACEMENT below. */    ROM                      =  READ_ONLY    0xDE00 TO 0xFDFF;    Z_RAM                    =  READ_WRITE   0x0040 TO 0x00DF;    SSTACK_AREA              =  READ_WRITE   0x00E0 TO 0x013F;    ROM1                     =  READ_ONLY    0xFFB0 TO 0xFFBD;    ROM2                     =  READ_ONLY    0xFFC2 TO 0xFFCF;ENDPLACEMENT /* Here all predefined and user segments are placed into the SEGMENTS defined above. */    SSTACK                                      INTO  SSTACK_AREA;    DEFAULT_ROM, ROM_VAR, STRINGS               INTO  ROM; /* ROM1,ROM2 In case you want to use ROM1,ROM2 as well, be sure the option -OnB=b is passed to the compiler. */    DEFAULT_RAM,_DATA_ZEROPAGE, MY_ZEROPAGE     INTO  Z_RAM;ENDSTACKSIZE 0x60VECTOR 0 _Startup /* Reset vector: this is the default entry point for an application. */

 

0 Kudos

422 Views
bigmac
Specialist III
Hello,
 
It is my understanding that the simulation error occurred because the stack attempted to exceed the boundary
of the segment used by the stack, and not when the STACKSIZE parameter was exceeded.  Had the boundary
not been exceeded, but more than the STACKSIZE limit used, an error would not have been reported, but
serious problems could still potentially occur.
 
It would appear that the default PRM file generated by CW, specifically for the HC908QB8 device, has
significant shortcomings for all but the simplest of projects.  The following is the default arrangement
generated by CW.
 
/* This is a linker parameter file for the QB8 */
NAMES END
 
SEGMENTS
    ROM                      =  READ_ONLY    0xDE00 TO 0xFDFF;
    Z_RAM                    =  READ_WRITE   0x0040 TO 0x00FF;
    RAM                      =  READ_WRITE   0x0100 TO 0x013F;
    ROM1                     =  READ_ONLY    0xFFB0 TO 0xFFBD;
    ROM2                     =  READ_ONLY    0xFFC2 TO 0xFFCF;
END
 
PLACEMENT
    DEFAULT_RAM                         INTO  RAM;
    DEFAULT_ROM, ROM_VAR, STRINGS       INTO  ROM;
    _DATA_ZEROPAGE, MY_ZEROPAGE         INTO  Z_RAM;
END
 
STACKSIZE 0x30
 
VECTOR 0 _Startup
 
 
Because there is no segment specifically allocated to the stack, the stack automatically becomes allocated to
DEFAULT_RAM.  Additionally, any global variables are also allocated to DEFAULT_RAM.  This means that,
by default, the stack and any global variables must share a total of only 64 bytes, with every chance that the
variables will be over-written by the stack, without any warning whatsoever.
 
Daniel's alternative PRM neatly solves this problem by providing an explicit segment for the stack, and by
DEFAULT_RAM being allocated to the Z_RAM segment.  Thus there is much wider separation between the
global variables and the stack, and a simulation error should occur if the stack usage exceeds its segment
boundary.  The STACKSIZE value would appear unimportant if using a separate stack segment.
 
The alternative PRM would seem a much better default arrangement for the QB8 device, to suit a wider
variety of projects.
 
I totally agree with Lundin's comments concerning use of sprintf() - more than 1.5K just for that function, in
a device with 8K total flash - very expensive!  I recall that there are other threads within this forum that address
binary-to-BCD conversions.  These should be easily adapted for 16-bit binary-to-ASCII.
 
Regards,
Mac
 
0 Kudos

422 Views
Lundin
Senior Contributor IV
Actually... since the algo is pretty simple, here you go, no charge:

void gpfunc_getDecStr (uint8* str, uint8 len, uint32 val)
{
uint8 i;

for(i=1; i=len; i++)
{
str[len-i] = val % 10 + '0';
val /=10;
}
str[i-1]='\0';
}


On a HCS12 this gave 80 bytes instead of 1500 bytes. A slight improvement... :smileywink:
0 Kudos

422 Views
PabloA
Contributor II
Thak you very much all of you.
 
I'll try Lundin's code!
 
Best regards
 
Pablo
0 Kudos