Electronics > Microcontrollers

A quick fix to use a function from the stdlib in the CUBE IDE (STM32)


Isaac Moreira:
 So, I'm starting to learn how to use the STM32CUBE IDE.
I’m not using the Nucleo boards because those cost a fortune here in Brazil, and I’m not paying a sizable chunk of the minimum wage here when I can solve my cravings for knowledge with the cheap Blue Pill and Black Pill from Shopee.

In this useless-but-usefull-for-learning project I've set up for accomplishing those things:

1 - Programing 2 STM32 MCUs to comunicante via SPI under a simple protocol;
2 - In the Master (STM32F411 aka "Black Pill"), use a 16x2 generic I2C display to show important information;
3 - In the Slave (STM32F103 aka "Blue Pill"), use DMA to acquire data from the ADC, average the data 200 times and than sent to the master when required to.

Ok, so far so good, very basic stuff, bla bla bla. I made an overcomplicated thermometer and I’m not ashamed. The slave reads a the analog voltage from a PTC 200 times via DMA, averages it, puts the 12 bits of data in two bytes of a buffer and sends it when the master requests it. The Master then puts those 2 bytes back together into a short integer, does the necessary conversion to celcius into a float and then sends to the display. The 16x2 display requires that each character from the temperature is an ASCII char. Naturally, stdllib has a function called gcvtf(); that does just that.
In a previous version of the code, I was using itoa(); to display just the data before the decimal point (I was converting the 2 bytes read from de SPI to a short int) and the code compiled and uploaded fine. I got greedy and tried to measure .1 and .01 resolution (just to see the fluctuation of the measurements from noise and that sort of thing) using gcvtf();. This time I received a warning, the function was not compiled but the code uploaded without it  :wtf:. The temperature displayed was 0 (the preloaded value from the float used to store the conversion).
I scratched my head for hours and then I had the idea to look further inside the header file of the stdlib. I copied the function prototype of the gcvtf(); to a location where the  itoa(); was declared (inside a #if #endif block) and it worked!

A quick fix, I know, but it worked.

I could implement my own gcvtf();, but why bother when it's done already? No need to reinvent the wheel, right?

Why did I had to go through all this trouble to use an stdlib function that should be available? Am I missing something?


--- Quote ---Naturally, stdllib has a function called gcvtf(); that does just that.

--- End quote ---

What do you mean with stdlib? The gcvtf() function is not a part of C. It seems gcvtf() comes from the SUSv3 standard.
So, there are some #ifdefs around so you don't get them when your code is only supposed to be standard C.
This is for reasons of portability, as one might want to be restricted to standard C to ensure it can be ported.

Isaac Moreira:

--- Quote ---What do you mean with stdlib?
--- End quote ---

The stdlib.h file.

--- Quote ---The gcvtf() function is not a part of C. It seems gcvtf() comes from the SUSv3 standard.
--- End quote ---

I see what you mean. So even if I include the stdlib.h into my code (which I did), the CUBE IDE would give me the same warning message?

Despite all that, It seems strange that it gave me a warning, compiled and uploaded to the MCU anyway.

The warning was something like "implicit declaration of function gcvtf". I've received this warning before when putting the #include "stdlib.h" at the bottom of the lists of includes. The internet suggested that I should put it first and it worked. I thought that this was the case in this particular application, but no... Had to manually go there and change the header file from the stdlib.

If I then remove the stdlib from my includes, compile, put it back and compile again with the original code of the stdlib (without the quick fix), the warning comes back.

When I play with uCs from scratch, the first thing I do is get the UART working.  Second up is to rip the formatting code (like itoa()) from "The C Programming Language" book (either edition but I use the 1st edition).  I don't use any library string functions or functions that use the library string functions (like printf()) because I really don't want to get forced into implementing a heap.  If the linker thinks function _sbrk() is undefined, somebody is expecting a heap.  If it is defined, somebody else actually implemented a heap.  I'm quite happy if the linker knows nothing about _sbrk().

I also implement some hex output functions for byte, short and int with or without the leading 0x.

C allows implicit declarations, and only gives a warning if you do so.
The function is in the library, and as such, the linker will find it.
However, the compiler does not know the signature of the function, and will assume they are all int.
As in this case, there is a float, the function is called incorrectly.
This is also why this causes a warning, as the compiler knows things might go wrong like they did here.

Defining _XOPEN_SOURCE_EXTENDED as 1 before including stdlib should provide the function declarations

--- Code: ---#define _XOPEN_SOURCE_EXTENDED 1
#include <stdlib.h>

--- End code ---


[0] Message Index

There was an error while thanking
Go to full version
Powered by SMFPacks Advanced Attachments Uploader Mod