MaJerle / lwgps

Lightweight GPS NMEA parser for embedded systems
MIT License
393 stars 128 forks source link

How lightweight is lightweight? Does not fit in flash #24

Closed coratron closed 1 year ago

coratron commented 1 year ago

Hi,

Thanks for this library. I am trying to use it in a project with an STM32G030 (which has only 32 kB of flash), and it looks like lwGPS needs around 24kB of flash?

Before using library: 22136 Bytes used After using library : 13720 Bytes of flash overflowed at compilation so that's 32000+13720 - 22136 = 23485 Bytes of flash just for lwGPS.

It does not make a lot of sense. Am I missing something?

MaJerle commented 1 year ago

I agree with you that flash usage was high due to math library. I added option to remove distance and bearing calculation (that uses sin/atan, ...) and parsing of the float is now done manually - test were a pass.

Try to download new code and try. Also, enable the optimization.

Lib itself takes around 3-4kB of NVM, the rest is compiler specific.

MaJerle commented 1 year ago

You can read this - https://stackoverflow.com/questions/52428872/replacing-aeabi-dsub-to-save-space-flto-issues

It has to do with Cortex-M0+ not really being able to do division with hardware - so functions are implemented to do it in sw

coratron commented 1 year ago

Thanks for your prompt reply, @MaJerle . I don't know exactly what is going on with my compiler but after trying again today my code does fit and it is all well within the size of the flash as I originally expected.

The library now seems to add around 4KB indeed. This number seems like a good reference to underline the fact that it is a lightweight library. Perhaps something for the readme?

I don't understand yet what cause the original issue so I will need to proceed with care but in any case it seems to be platform/compiler related.

My tools are VSCode, the STM32 for VSCode plugin. The project is generated with CubeMX+HAL.

Compiler version: (arm-none-eabi-gcc/11.3.1-1.1.2/.content/bin/arm-none-eabi-gcc)

Thanks again for your help

coratron commented 1 year ago

Actually, the new revision does make a big difference. I only replaced the files and recompiled and the binary is much smaller. Not sure what is the reason behind that.

I get : 32444 Bytes with default options (bearing and distance enabled) 28720 Bytes with double precision disabled

If I revert to the previous commit and compile there with default options I get a the flash overflow that I mentioned in my first message.

I now need to do some tests and confirm everything is working as expected.

MaJerle commented 1 year ago

@coratron, IDE does not play any role here, but GCC compiler does. I tested on the same version as you - latest one.

The problem is that when you work with GPS, there are floats and/or doubles (library allows to set, depending on precision you'd like to achieve). Since Cortex-M0+ has no hardware support for floating point manipulation (add, sub, ...), compiler adds software instructions. In some cases, added functions can have even 1.8kB (see below, screen shoot from build analyzer in STM32CubeIDE, that uses same GCC). You can try to calculate this - it is huge.

image

In the update from yesterday, I tried to remove as much as possible math.h library features. Parsing the float was done with strtod and strtof, but now it is a custom function that provides full control. Code size is definitely smaller, just because of that parsing.

So here is the update, from my quick tests yesterday - STM32G030: