STM32 RTOS (H743) Crashing when using sprintf or snprintf with float formatting - printf

I have read a few older threads on this issue, and quite frankly the discussion flew over my head a bit. So I'm hoping for some help that I will hopefully be able to follow.
I am programming an STM32 with RTOS (two threads needed). It's a sensor application with some fairly intensive computation on the data gathered (hence the H7). Computation feedback is sent through CDC in the form of a char array, size 12. Nothing difficult. The computation feedback is a float. And this where I am having problems.
Prior to sending the data I need to convert the float to a char[].
my function looks like this:
void ASCII_transmitFloat(float value) {
uint8_t buffer[DEF_ASCII_TX_BUF];
snprintf((char *)buffer, sizeof(buffer), "%11.9f\n", value);
CDC_Transmit_FS(buffer, sizeof(buffer));
}
I am not getting an error, just a crash on the snprintf.
I tried sprintf with the same results
casting my float to a uint32_t and changing the arg type in my function to uint32_t, works. (I'm losing precision so this is not a solution, but tried anyway)
I have the same version of the function for integers, and these work fine as well
oh and I kinda of mickey-moused between uint8_t and char, it's probably as bad as it is ugly, but I haven't found a better way yet
anyhow thanks for any help you can provide
cheers
edit:
Editing in response to the first response.
I had the "use float with printf" option selected in the project properties (MCU settings) - see the screenshot below (not sure if this check box does the same as adding the flag manually)
I tried adding the line -u _printf_float in the linked as suggested in your link, but I have the same results. Crashes when executing the snprintf.

Here is how I fixed the problem.
The problem is known, and ST hasn't fixed the issue since it was first brought up here a year ago, see:
https://community.st.com/s/question/0D50X0000BB1eL7SQJ/bug-cubemx-freertos-projects-corrupt-memory
and here's the recommended fix:
http://www.nadler.com/embedded/newlibAndFreeRTOS.html
A bit over my head so I chose to go the route of using a lighter version of the printf function:
https://github.com/mpaland/printf
I hope it helps someone else with the issue.
Cheers

Probably because float support is not included by default using newlib.
See printf floats with newlib on STM32

This problem happened to me too. I'm not sure yours is same with mine but maybe it can help yoou. I just fixed it and the only thing i did is, i included "stdio.h". Then my warning gone.

Related

S71200 LSQL-Microsoft, Datatype changed, after copying Function Block - How do I fix this?

I am integrating SQL-Connection to one or our existing Siemens S7-1200 PLCs right now.
After copying a Function Block from a working project, one of the data types has changed and is causing trouble now.
Original:
Copied FB:
Does anybody know, how to fix this?
Someone in the Siemens-Forum could answer my question right away.
Leaving his answer here for the next person with my problem :
With the introduction of the OUC library in version V4.x, the TCON instruction, among other things, has changed. Try to update the program on the CPU. In this case, the prerequisite is that the CPU must have at least firmware version V4.1. There is also the risk that translation errors will occur in other places where the older versions were previously used. In this case, the PLC code would have to be adjusted accordingly.

Tips needed! Program has wrong behavior using inline asm to call function instead of C function

I'm currently writing my own operating system. It is a non-preemptive OS and my threads are working fine with the scheduler. I have one edge case though. If I don't call my yield() function from C but do asm("call yield") the calculations later on fails but only with -O2 optimization.
Like many have said, it is always our fault
I have tried all approaches i can think of but now I'm desperate.
So if anybody has some tips on what might be happening or what i should investigate please share.
I guess this gets shutdown for being offtopic but any tips is greatly appreciated.
When the compiler generates a call to a function, it preserves the contents of any registers which may be modified by the called function ("caller-save registers") before making the call.
Since you've buried this function call within an inline assembler block, the compiler doesn't know it needs to save and restore registers around the call.
Simple solution: Don't do that, then. If you want to call a function, use C function call syntax.
Complicated solution: Declare which registers this function call will clobber using extended inline assembler syntax.
Thanks for all the comments. It helped allot. I finally figured it out. My context switch did not handle the state of the FPU. After going back to dissable once again I observed that the normal generated C code helped me save the FPU state.
After implementing FSAVE/FNSAVE and FRSTOR in the context switch the -O2 optimized code also worked as expected.
#melpomene: As you asked:
Have you looked at the generated code?
In retrospect, obviously not hard enough.
Thanks for all suggestions, and I hope this thread can help others to remember the x87 FPU instructions now :-P

Getting reference error from appledoc when embedding code in comments

I have some code comments like this:
/**
How to use this method.
#discussion To use it, do something like the following
id hook = [[STDeallocHook alloc] initWithBlock:^{
// Do something when 'hook' is dealloced
}];
*/
So the code example is indented with 4 spaces. When I compile the docset with appledoc, it compiles correctly and shows the code as code in the API reference I generate. However back in XCode (Where I have appledoc creating warnings for issues in the doco) I get the warning:
Invalid [[STDeallocHook alloc] reference found hear STDeallocHook.h#16, unknown object: [STDeallocHook !
I think what's happening is that appledoc is looking for markdown links inside the code block.
How can I stop this warning from appearing?
I've been unable to stop it as well. It looks like it's been a known bug since 2011, but it's still broken.
Interestingly enough, I don't get it for everything. In a large code example, I'll only get a few of them... still haven't figured out how it determines to cause me grief or not...
Workarounds
This works around the warning, and looks fine in the generated documentation, but looks like crap in plain text: substitute the leading [ with the HTML escape code [
Future Fix
Supposedly, the mythical version 3 has addressed it, but I can't find any mention of an ETA for it. There is a "3.0exp1" branch from March 2012, and a "3.0dev" branch from October 2014.
If you have both the time and inclination, maybe you can see how it was fixed and patch it yourself (though the codebase has apparently changed a ton since then).
My Attempt
I felt unsatisfied with that answer, so, I went back and looked at the source code. First time in that code. It's not exactly easy to navigate... and none of the classes are documented, which I find quite strange, especially for a documentation tool.
Anyway, I think I know why I only get the warning sometimes. The parser treats all underscores as formatting markers. Thus, if it finds two of them in the same "block" of text, it splits them up. Since the code I tested on had category documentation, only the last one encountered in each "block" caused a warning... because all the others were treated as italics... and then ignored.
Also, it seems that I may be able to coerce it into skipping source-code blocks if they are marked as either...
#code
[self wjh_doSomething];
#endcode
or
```
[self wjh_doSomething];
```
or
~~~
[self wjh_doSomething];
~~~
The first is common in documentation blocks, the latter two in markdown.
It's a hack, but it seems to work. I sent a PR, which can be found here. Who knows if it will get accepted, but feel free to try it out yourself if you are so inclined.
I think I'll at least use it locally, as it cleans up a ton of warnings for me... and I may just go try to regenerate all my documented stuff to boot.
Edit
Well, I guess I should have gone and looked at the open PRs first. There seems to be a PR already sitting there that deals with the same issue, that has been there since May. It would have saved me time... but it was a little fun experimenting with it a bit ;-)
You may want to use that one... it seems to be simpler. Simpler is better, but I have not used that one and I'm not sure it completely ignores the blocks, but he seems to have quieted the warnings with his patch.
That one does not support #code/#endcode, which I'm glad to have.

STM32 IAR no ITM trace output unless printf is included in the code

I have a small project that I added my own custom debug functions to so I could have some extra functionality. They have been working great, and use the following method to send the data:
while(*bp)
ITM_SendChar(*bp++);
I finally got around to switching over all the printf statements to use my own function and all the output just stopped. A little playing around and I figured out as long as I have one single printf function compiled in, no matter where, ITM_SendChar works right out the gate.
It would seem there is some functionality compiled in when printf is used in the project that allows ITM_SendChar to work.
It is not a huge deal but I am fairly curious as to why this is. Is there perhaps another way to initialize the ITM (Instrumentation Trace Macrocell) system without having to stick in a dummy printf?
I came across the same problem and I tried everything with correct configuration of the ITM Registers. But I couldn't figure it out.
My solution to not use memory intense printf, is to use putchar:
while(*bp)
putchar(*bp++);
It even works, when I just have one putchar somewhere in the code which outputs one character and then output the other things with ITM_SendChar()
I assume the IAR automatically adds some configuration function as soon as the putchar function is included.

Fix bugs in library code, or abandom them?

Assume i have a function in a code library with a bug in it i've found a bug in a code library:
class Physics
{
public static Float CalculateDistance(float initialDistance, float initialSpeed, float acceleration, float time)
{
//d = d0 + v0t + 1/2*at^2
return initialDistance + (initialSpeed*time)+ (acceleration*Power(time, 2));
}
}
Note: The example, and the language, are hypothetical
i cannot guarantee that fixing this code will not break someone.
It is conceivable that there are people who depend on the bug in this code, and that fixing it might cause them to experience an error (i cannot think of a practical way that could happen; perhaps it has something to do with them building a lookup table of distances, or maybe they simply throw an exception if the distance is the wrong value not what they expect)
Should i create a 2nd function:
class Physics
{
public static Float CalculateDistance2(float initialDistance, float initialSpeed, float acceleration, float time) { ... }
//Deprecated - do not use. Use CalculateDistance2
public static Float CalculateDistance(float initialDistance, float initialSpeed, float acceleration, float time) { ... }
}
In a language without a way to formally deprecate code, do i just trust everyone to switch over to CalculateDistance2?
It's also sucky, because now the ideally named function (CalculateDistance) is forever lost to a legacy function that probably nobody needs, and don't want to be using.
Should i fix bugs, or abandon them?
See also
How to work in untestable legacy code- in bug fixing
Should we fix that bug?
Should this bug be fixed?
Working Effectively With Legacy Code
You'll never succeed at catering to every existing project using your library. Attempting to do so may create a welcomed sense of predictability, but it will also lead to it being bloated and stagnant. Eventually, this will leave it prone to replacement by a much more concise library.
Like any other project, it should be expected to go through iterations of change and rerelease. As most of your current user base are programmers that should be familiar with that, change really shouldn't come as a surprise to them. As long as you identify releases with versioning and document the changes made between, they should know what to expect when they go to update, even if it means they decide to stay with the version they already have.
Also, as a possible new user, finding your library to have an ever-growing number of lines of legacy code due to the blatant unwillingness to fix known bugs tells me that the maintainability and sustainability of the project are both potentially poor.
So, I would honestly just say to fix it.
Good question. I'm looking forward to some other answers. Here's my 2 cents on the issue:
Generally, if you suspect that many people indeed rely on the bug, then that's an argument for not fixing the bug and instead creating a new function CalculateDistance2.
On the other hand, and I think that's the better option, don't forget that people who rely on the bug can always continue using a specific, older version of your library. You can still document the removal of the bug (and therefore the modified behaviour or your library function) in the release notes.
(If your class happens to be a COM component, the conventional wisdom would be to create a new interface ICalculateDistance2 that makes the original interface obsolete, but preserves it for backwards compatibility.)
Another option is to fix the bug, but leave the old code around as a LegacyCalculateDistance method that's available if anybody really needs it.
You could even implement the ability to select the "legacy" implementation based on (for example) a configuration file or an environment variable setting, if you're concerned about offering a compatibility solution to users who may not be able to make code-level changes.
I once fought for a number of days with some MFC code that was behaving in an entirely unexpected way. When I finally figured out it was an error in the Microsoft supplied library, I checked the knowledge base. It was documented as (approximately) "this is a known bug we found 2 OS versions ago. We aren't fixing it because someone is probably depending on it".
I was a little mad...
I'd say that you should deprecate it. If you're upgrading the library your code depends on, you should test the code with the new library. If it's legacy code, then there's a known configuration it works on. Advise your users and move forward...
As you aready described, this is a tradeoff between satisfying two different user groups:
Existing users who have build their software based on a bug in your library
New users who will be using your library in the future
There is no ideal solution, nor do I think that there is a universal answer. I think this depends entirely on the bug and function in question.
I think you have to ask yourself
"Does the function make any sense with the currently existing bug?"
If it does, then leave I'd it in the library. Otherwise, I'd probably toss it out.
Just for the sake of argument, let's assume your hypothetical language was C++ (even though it looks a lot more like Java). In that case, I'd use namespaces to create a fork that was (reasonably) easy to deal with from a viewpoint of both new and legacy code:
namespace legacy {
class physics {
Float CalculateDistance(float initialDistance, float initialSpeed, float acceleration, float time)
{
// original code here
}
}
}
namespace current {
class physics {
Float CalculateDistance(float initialDistance, float initialSpeed, float acceleration, float time)
{
// corrected code here
}
}
From there you have a couple of options for choosing between the two. For example, existing code could add a using directive: using legacy::physics;, and they'd continue to use the existing code without any further modification. New code could add a using current::physics; instead, to get the current code. When you did this, you'd (probably) deprecate the legacy::physics class, and schedule it for removal after some given period of time, number of revisions, or whatever. This gives your customers a chance to check their code and switch over to the new code in an orderly fashion, while keeping the legacy namespace from getting too polluted with old junk.
If you really want to get elaborate with this, you can even add a version numbering scheme to your namespaces, so instead of just legacy::physics, it might be v2_7::physics. This allows for the possibility that even when you "fix" code, it's remotely possible that there might still be a bug or two left, so you might end up revising it again, and somebody might end up depending on some arbitrary version of it, not necessarily just the original or the current one.
At the same time, this restricts "awareness" of the version to be used to one (fairly) small part of the code (or at least a small part of each module) instead of it being spread throughout all the code. It also gives a fairly painless way for somebody to compile a module using the new code, check for errors, switch back to the old code if needed, etc., without having to deal directly with every individual invocation of the function in question.