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

cross mob
KyTr_1955226
Level 6
Level 6
250 sign-ins 10 likes given 50 solutions authored

Hi All,

I've got a question regarding floating point formatting for printf/sprintf on PSoC5LP when *not* using newlib nano.

I'm finding in my project for CY8C5468AXI-LP106 that, much like I've seen in the past, using newlib nano absolutely breaks strtok() in my code for some re...   As a result, I need to disable newlib nano in my code in order to be able to actually use strtok().  One thing this seems to do is remove float formatting functionality entirely, and enabling/disabling newlib nano float formatting (-u _printf_float)seems to have no effect.  I simply get no characters where the formatted string should be.

So my question is this:  Now that I'm using the C standard libraries, is there a flag or anything I need to provide in order to get float formatting working?  Or should this simply "just work"? I should have plenty of stack/heap (0x1000/0x0800 bytes respectively) so that *shouldn't* be the issue.

Any thoughts?

 

 

0 Likes
1 Solution

Kyle,

If the problem is actually with the strtok() function.  You should be able to create your own strtok() function.   Looks pretty easy and fairly straight-forward.

It would be nice if the strtok() source code was provided.  That way we could "debug" why it is not operating properly in your case.

Here is a link to a version of strtok() source code:  string.subproj/strtok.c.auto.html 

Try it.   What would it hurt?

Len
"Engineering is an Art. The Art of Compromise."

View solution in original post

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

Kyle,

Can you give us an example on how you plan to use strtok()?

With a short test sequence for using strtok(), we can try to reproduce your results and issues.  With that, we might be able to suggest a solution.

Len
"Engineering is an Art. The Art of Compromise."
0 Likes

Hi Len,

Unfortunately I have not been able to create something easily reproducible for the strtok() issue.  It's a problem that only seems to show up in my full application and not when I create a minimal example.  It's in the thread I linked in my first post, but I'll put it here as well:

/** Tokenize
 * - Splits incoming string into individual substrings
 * - Splits on comma, space, or underscore characters
 * - This should normally break out upon finding strtok() finding the end of the input string
 *   For some reason, this function can continue running even when pch==NULL.
 *   - Added a break if count >= MAX_NUM_CMDS to protect from this overrun.
*/
static void Tokenize(char* src, char dest[MAX_NUM_CMDS][CMD_MAX_CHAR]){
    uint8_t count = 0;
    char * pch;
    pch = strtok(src, ", _");
    
    while (pch != NULL){
        memcpy(dest[count++], pch, CMD_MAX_CHAR);
        pch = strtok(NULL, ", _");
        
        if (count >= MAX_NUM_CMDS){
            break;   
        }
        
    }
    
}
The string I am sending to reproduce this is simple, "00\r\n". The first pch=strtok(src, ", _"); line performs as expected, I drop into the while() loop, and the 2nd call pch=strtok(NULL, ", _") is what gets stuck. I can confirm the entire string "00\r\n" is getting copied to dest[0], so the call should just give back null (the rest of src is just null characters, 0x00), and I should exit the while loop. Instead I am getting stuck inside strtok() on this call.

It is getting stuck in looping endlessly inside strtok_r when I step through in the disassembly:
0x000077AC ldrb.w r6, [r7], #1
0x000077B0 cmp r5, r6
0x000077B2 beq.n 77c4 <__strtok_r+0x48>
0x000077B4 cmp r6, #0
0x000077B6 bne.n 77ac <__strtok_r+0x30>

It's wild, because I just can't think of any reason that it would loop infinitely there in my application but work fine when I create a minimal example on my -050 test kit.  The only explanation I can think of is the specific part, this code (application and all) works fine when I use a CY8C5667AXI-LP040, and it works when I try and create a minimal example on the CY8C5868AXI-LP035 as part of the 050 kit,  but when we switched to a CY8C5468AXI-LP106 due to part availability it loops as described above.  Unfortunately it wasn't reproducible by in my least thread.

I did find the workaround to get strtok() going again was to disable newlib nano, thus leading to my issue of appearing to break float formatting.

0 Likes

Kyle,

There are  couple of things you said in your previous post.

First -- When you use the newlib nano with float support, I'm confident you will need to increase the heap size.    See this answer on this link:  PSoC5LP-Tracking-down-the-cause-of-entry-into-the-IntDefaultHandler-errno-ENOMEM .

I don't know about what the heap or stack requirements for strtok() is.

In general, if strtok() is 'internally' recursive, you might need to increase the stack.  This is specially true if you are generally using recursive functions or many ISRs that may be nested.

Additionally the compiler normally places variables local to the function on the stack which might require more stack.

Consult with Infineon about the heap and stack requirements of strtok().

Suggestion #1:  Try increasing the stack size.  If it fixes the issue ... great!

Suggestion #2:  If Suggestion #1 does make an improvement, try doubling the heap size.

Len
"Engineering is an Art. The Art of Compromise."
0 Likes

I'm not sure I follow.  I am not receiving any entrance into the default handler and I'm not receiving an ENOMEM error code which would denote I'm overrunning the heap.  It simply spins inside that strtok_r loop infinitely when I attempt to use it when newlib nano is enabled.

My Stack/Heap is already 0x0800/0x1000, which should be more than enough considering the project I normally use this code on (using a CY8C5667AXI-LP040) manages to handle this with no problems when Stack = 0x0800 and Heap = 0x0200.

But to clarify, I in theory should not need to add any special flags other than -u _printf_float to the linker in order to make use of float formatting?

0 Likes

Kyle,

It looks like you have good heap and stack settings.  Also u _printf_float  is correct to enable the float features of the newlib nano library.

... It simply spins inside that strtok_r loop infinitely when I attempt to use it when newlib nano is enabled. ...

I assume you found this by debugging the code and using the call stack monitor window.

Question:  If you use newlib nano WITHOUT the float features, your float results will probably be '0's.   However does strtok() work?  If so, you might be able to create printf() %f equivalents using %d and some integer math magic.

Len
"Engineering is an Art. The Art of Compromise."
0 Likes

I assume you found this by debugging the code and using the call stack monitor window.

Correct, yes.

 

Question:  If you use newlib nano WITHOUT the float features, your float results will probably be '0's.   However does strtok() work?

It does not.  Enabling newlib nano at all regardless of the float features causes this behavior in strtok.

 

I may end up changing the command that returns the floating point number and simply return the nearest integer number.  In this case I was using it to return a temperature reading with 2 decimal places of precision but for this application, fractions of a degree won't matter all that much.  That's my planned workaround for now anyway.

0 Likes

Kyle,

If the problem is actually with the strtok() function.  You should be able to create your own strtok() function.   Looks pretty easy and fairly straight-forward.

It would be nice if the strtok() source code was provided.  That way we could "debug" why it is not operating properly in your case.

Here is a link to a version of strtok() source code:  string.subproj/strtok.c.auto.html 

Try it.   What would it hurt?

Len
"Engineering is an Art. The Art of Compromise."
0 Likes

I may indeed try that.
Thanks!

0 Likes
LeoMathews
Moderator
Moderator
Moderator
First question asked 500 replies posted 100 solutions authored

Hi @KyTr_1955226 ,

Thread was locked due to inactivity for long time, you can continue the discussion on the topic by opening a new thread with reference to the locked one. The continuous discussion in an inactive thread may mostly be unattended by community users.

Thanks and Regards,
Leo

0 Likes