PSoC Creator sprintf function with the GCC compiler

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
MiNe_85951
Level 7
Level 7
Distributor - TED (Japan)
50 likes received 500 replies posted 50 solutions authored

Hi,

We are using PSoC 5LP and also using the SPRINTF function in the firmware.

This product uses μItron compliant RTOS.

(1)

Does the sprintf function in GCC support multitasking?

The current development environment is as follows.
-- PSoc Creator 4.2
-- ARM GCC 5.4-2016-q2-update
-- Linker settings
-- Use Newlib-nano: True
-- Use Newlib-nano Float Formatting: True

We think that sprintf may be causing problems due to simultaneous access from multiple tasks.

So I'm trying to use re-entrant "_sprintf_r".
However, the _reent structure must be defined, and the size of this structure is large and memory overflows.

Looking at the GCC document, it is written that if you define "_REENT_SMALL", the size will be reduced.
However, We don't know how to specify it.

(2)

Do you know how to define "_REENT_SMALL" ?

Regards,

0 Likes
1 Solution
DheerajK_81
Moderator
Moderator
Moderator
First comment on KBA First comment on blog 5 questions asked

Does the sprintf function in GCC support multitasking?

Typically they are thread safe. However, if you change the locale mid session, you must make sure that these functions aren't affected. Making them reentrant is a good idea.

Do you know how to define "_REENT_SMALL" ?

Go to Build Settings > ARM GCC > Compiler > Preprocessor Definitions and add "_REENT_SMALL" as shown:

pastedImage_0.png

Regards,

Dheeraj

View solution in original post

0 Likes
4 Replies
DheerajK_81
Moderator
Moderator
Moderator
First comment on KBA First comment on blog 5 questions asked

Does the sprintf function in GCC support multitasking?

Typically they are thread safe. However, if you change the locale mid session, you must make sure that these functions aren't affected. Making them reentrant is a good idea.

Do you know how to define "_REENT_SMALL" ?

Go to Build Settings > ARM GCC > Compiler > Preprocessor Definitions and add "_REENT_SMALL" as shown:

pastedImage_0.png

Regards,

Dheeraj

0 Likes
MiNe_85951
Level 7
Level 7
Distributor - TED (Japan)
50 likes received 500 replies posted 50 solutions authored

Dheeraj-san,

Thank you for useful infomation.

We will try it.

Regards,

0 Likes
Len_CONSULTRON
Level 9
Level 9
Beta tester 500 solutions authored 1000 replies posted

MaMi,

After implementing Dheeraj suggestion I'd like to make another recommendation:

sprintf(char *str ...) functions are not "safe" functions to use for embedded systems string processing.

Let me illustrate:

char tstr[10]; // This string allocation has only 10 bytes

sprintf(tstr, "This string has 48 characters and needs 49 bytes");    // Remember the '\0' character terminates a string

With the code above, you just overwrote past the tstr array by 39 bytes.  Who knows what havoc occurs next.  Many times you get a stack violation or a watchdog failure (if the WDT is running).

use snprintf(char *str , int str_sz...) instead.  Since you declare the maximum size to be written as the second argument it has checking for the array for str built in.  It prevents array overruns and is considered "safe".

Here what the previous snippet of code would look like with snprintf():

char tstr[10];  // This string allocation has only 10 bytes

snprintf(tstr, sizeof(tstr), "This string has 48 characters and needs 49 bytes");   // Remember the '\0' character terminates a string

Trust me. I learned the hard way about sprintf().  Many crashes and bizarre anomalies later.  I routinely use snprintf()  instead.  I make only FEW exceptions.

Len

Len
"Engineering is an Art. The Art of Compromise."
MiNe_85951
Level 7
Level 7
Distributor - TED (Japan)
50 likes received 500 replies posted 50 solutions authored

Len-san,

It was very helpful!

Tyank you.

Regards,

0 Likes