CR_PRINTF_CHAR functionality broken ?

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

CR_PRINTF_CHAR functionality broken ?

807 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by robert hulsebos on Thu Dec 17 13:07:20 MST 2015
Hello all,

We have a working application for the LPC1769 MCU that was originally built with LPCXpresso v7.4.0. It uses the CR_PRINTF_CHAR symbol to force printf output on a character-by-character base to a console UART.
See https://www.lpcware.com/content/faq/lpcxpresso/using-printf for details. The CR_PRINTF_CHAR is explicitly defined file as it prevents printf() from using heap functions like malloc(), etc.
Because our application is to be MISRA-C compliant, use of heap functions is not allowed. We defined our own __sys_write() function to do UART output and all worked fine.

Then we switched to LPCXpresso v7.9.2 and suddenly console output is gone. Input seams to work OK. Setting a breakpoint at function _sys_write() learned that this output function is still called, but only once, during startup. If we remove the CR_PRINTF_CHAR symbol from our project, then console output is back to normal again. Input and output. So it looks that somewhere between v7.4.0 and v7.9.2 the CR_PRINTF_CHAR functionality was broken...
I am not able to pinpoint the source of the problem (GCC/LPCXpresso/RedLib), as I do not have the source code of the C run-time library -  debugging its assembler code is rather cumbersome...  Any suggestions?
Labels (1)
0 Kudos
7 Replies

708 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by lpcxpresso-support on Tue Dec 22 02:41:44 MST 2015
I am glad to hear that you now have things working.

And thank you for your feedback. We will add some clarifications to the FAQ.

Regards,
LPCXpresso Support
0 Kudos

708 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by robert hulsebos on Mon Dec 21 02:53:03 MST 2015
Yes I tried and it works - thanks! thanks! thanks!
But what boggled me is how this could have worked flawlessly for so long?!? Only when we switched to LPCXpresso v7.9.2 this problem popped up...
Also why didn't it pop up with other users working with the wrong return value? But you probably already answered that one...

Practically, I have a suggestion for improvement of the text on the https://www.lpcware.com/content/faq/lpcxpresso/using-printf  page:
In the section about the Redlib implementation there are two lines that may pull your legs:
First the line mentioning both __sys_write() and __write() is easily misinterpreted by concluding both function calls using the same return values. (suggesting only name of function is changed) The fact that both functions use the same calling parameters only seems to affirm this.
Secondly, if you download the RDB1768 example code that is mentioned a few lines below (for example from here: https://www.lpcware.com/content/nxpfile/sample-code-bundle-rdb1768-using-lpcxpresso-and-red-suite ) you end up with a __write()  function example that returns the number of characters successfully written. Not zero. I think a lot of users just copied this function and renamed it to __sys_write().
Also if you don't have the RDB1768 example code and google  directly on __sys_write(), then you may find examples that do a one-on-one replacement of both functions. (example: http://keadrone.googlecode.com/svn/trunk/firmware/SimpleDemo/retargetPrintf.c)
So my recommendation would be to explicitly add a statement that care should be taken as both functions do not share the same calling convention. And add examples of __sys_write() and _write() functions directly on the page rather than through mentioning of existence of RDB1768 example code. (without link) This bans the need for googling and ending up with faulty example code from other LPC users.
0 Kudos

708 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by lpcxpresso-support on Sat Dec 19 00:37:18 MST 2015
Have you actually tried the fix I suggested?

The __sys_* functions called by the bottom layer of the File IO functions from Redlib are expected to follow the spec of the underlying semihosted SWIs as originally defined by ARM (https://www.lpcware.com/content/faq/lpcxpresso/semihosting).

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0058d/BACBEDJI.html

From memory, this may not matter for the default printf (which goes around some of the standard file i/o functionality in order to print the string in one go) but for "print by character" mode it does matter.

I'll follow up with the LPCOpen team to fix the code they supply in their packages. I suspect that very few people use the "print by character' mode, which is why this hasn't been spotted before.

Regards
LPCXpresso Support
0 Kudos

708 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by robert hulsebos on Fri Dec 18 16:06:19 MST 2015
Are you sure?
I thought __sys_write() should return the number of bytes successfully written...
Can you point me the original spec for the _sys_write() function?
Almost all examples I can find on the internet return the same as my _sys_write() function does:
https://github.com/openxc/nxp-bsp/blob/master/bsp.c
http://keadrone.googlecode.com/svn/trunk/firmware/SimpleDemo/retargetPrintf.c
https://www.lpcware.com/content/forum/lpcxpresso-and-redlib-vprintf-problems
http://se.hatenablog.jp/entry/2015/04/29/113130
http://rancidbacon.com/lpcopen/docs/lpcopen_docs_v2_00a_11xx/retarget_8h_source.html

Are these guys all wrong?
0 Kudos

708 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by lpcxpresso-support on Fri Dec 18 08:44:32 MST 2015
__sys_write() should returns number of unwritten bytes if an error occurs, otherwise 0 for a successful output of data.

But your version is always returning the number of characters being passed in. Fixing this appears to solve the problem.

Regards,
LPCXpresso Support



0 Kudos

708 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by robert hulsebos on Fri Dec 18 07:20:31 MST 2015
I cloned the projected, converted into 'hello world', stripped all non-relevant code and exported it. In the .zip attachment there is a separate directory with the map files that you asked for. Hope this helps you helping me...
BTW1: Thanks for your suggestion for 'complete heap avoidance' - I will look into it!
BTW2: I also quickly tested it with NewLib -> no problem there. So it seems RedLib specific...

Robert
0 Kudos

708 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by lpcxpresso-support on Thu Dec 17 13:46:11 MST 2015
Seems to work OK here (I'm using LPCXpresso IDE v8.0, but I wouldn't expect any difference in behaviour here from 7.9.2).

If you create a new 'hello world' project using the new project wizard, do you see the same problem?

The next step, assuming that you can just export a project that exhibits the problem (https://www.lpcware.com/content/faq/lpcxpresso/how-importexport-projects) would be to ZIP up and post the linker map files generated for both the working and non-working cases.

Note that you will still get heap usage in your application even using CR_PRINTF_CHAR, though not directly from printf() - as this is used in setting up the file io stream layer that the printf family of functions sit on - done from __main().

If you want to avoid heap completely, you will need to link against the "None" variant of Redlib (rather than "Nohost" or "Semihost"), and provide your own printf type code (e.g. something like http://www.menie.org/georges/embedded/printf-stdarg.html).

Regards,
LPCXpresso Support
0 Kudos