Writing core firmware to external flash

If you really don’t need the cloud at all (not just the OTA update, but variables, functions etc…) there’s an experimental branch at https://github.com/spark/firmware/tree/feature/hal-no-cloud that compiles without cloud support.

You build using the command line, and add SPARK_CLOUD=n. This will reduce the binary size by some 40k. Please keep in mind that this is experimental, and the branch might not be around forever, but might help you solve your size problem in the short term, or until the Photon is available! :smile:

I also have that size problem and tried to use the above hal-no-cloud version.
I can compile it, but it has a totally different design, so now I have to learn anew how to use libraries and how to add my own application.

In my old build environment (I don’t know which version it was, where can I see it?), I could add “APP=Hello” to show the build which application to build. This seems to be not working with this build.

I even don’t know where is the actual application.cpp and which makefile is the right one to use? Is it the one in the root dir, or the one in the main dir (i think that).

Or maybe the SPARK_CLOUD=n switch is even in the main version now? I am lost, I don’t know what to use.

Thanks for help

@Bluescreen, I’ll take a look later and get back to you unless @mdma beats me to it :smile:

@Bluescreen, your app needs to go under the “main” directory and can be compiled with “APP=appname”. Look at the way the tinker application is done to give you some guidance. The SPARK_CLOUD=n switch only exists in this branch of the master. :smile:

Ok, I now find the time to try and it works. But there is a strange behaviour of the WiFi Class. If I print out the IP adress of the Core like this:

str->print( "IP Address: "); str->println(WiFi.localIP());
str->print( "Subnetmask: "); str->println(WiFi.subnetMask());
str->print( "Gateway   : "); str->println(WiFi.gatewayIP());

I get the adresses in the wrong order. If my IP is I get this output:

IP Address:
Gateway :

If I compile using the standard master branch everything is ok. It has nothing to with the SPARC_CLOUD=n setting, it’s wrong if I use either setting. Maybe it’s some thing with the platform stuff and it’s endian settings.

@peekay123 Avoiding sprintf() will save 20KB of code? Well, I did a quick test. I compiled the “led_blink” example in the Particle IDE. The output BIN file size: 77,360 bytes. I added the following lines (grabbed from an example):

char publishString[100];
sprintf(publishString,"{“mV”: %i}",12456);

After rebuilding the project (yes, I saved the INO file first ;-)), the BIN file size is 77,456 bytes, or only 96 bytes more. Is there really a way to save 20KB by not referencing sprintf? Or is the entire sprintf library getting automatically included in the build, and not optimized out?

@WebDust21, it cannot be analysized from the .bin file size but more of the output.


1 Like

@kennethlimcp : Not meaning to hijack this thread at all, but where is that compiler output displayed ? I’ve been using the Web IDE and before the change from spark to particle it was displaying every time - these days it seems to have vanished.

The introduction of photon firmware compiling in the :cloud: somehow ended with this feature not existing.

Ahhh nightmare. Oh well… it was useful while it lasted :stuck_out_tongue:

OK, now I’m confused. As far as I know (and have done a couple of times), the .BIN file is what you flash with dfu-util, and it sends every byte of the file over. From my experience with the arm-none-eabi toolchain (a la DevKitPro, for programming the Nintendo GameBoy Advance–it’s a really handy little machine!), the output BIN is exactly what goes on to the GameBoy.

Admittedly, in every single past project (microprocessor or GameBoy Color/Advance), I’ve always ended up getting so frustrated with the compiler that I ended up programming the entire project in Assembler. Most compilers/IDEs tend to pack an incredible amount of “baggage” onto an empty project, generally 60K+. . .C/C++ and I are not the best of friends.
I actually wrote my largest GBA project in pure ARM7TDMI assembler: 718KB of source code (15,541 lines) plus a 10KB compressed helpfile resulting in a 47K output BIN. (And yes, I do heavily comment ASM code!) That was a complete BASIC/ASM IDE on the little GBA, making it a pretty handy little debug terminal. (The link port on the back can serve as RS-232, shift-clock, or 4 GPIOs.)

@WebDust21, are you building for the Photon? According to this post by @mdma, sprintf has been moved to the system firmware for the develop branch, so it’s possible (I’m not sure what firmware the cloud/ide is building against) that sprintf is already included, so adding that line doesn’t change the user-part.bin at all.

No, I’m building for the Core. (I will be building for the Photon in the future.) I also am not including <string.h> in the project. If I’m not using x=String(); or the typedef “String var;”…theoretically that library shouldn’t be included, either? FWIW I don’t get an error for not including <string.h> in a project referencing it.

@mdma sprintf has been moved to system firmware? I seem to recall reading another post last night saying that sprintf(); was being deprecated for 0.4.0 to save the 20KB of firmware space. Unfortunately, I can’t find that post, either…

Or are all libraries (including the non-used I2C, SPI, etc.) now being included no matter what? Does this mean that I need to figure out how to compile the Core firmware myself in order to manually exclude the unused libraries?

P.S. I don’t think I’m going to go the ASM route on this one. It’s not worth reinventing the wheel, inner tube, tire, valve stem, Schrater valve…AND the air to inflate the tire :weary:

@mumblepins, I found the post that I was referencing, in which @mdma wrote that sprintf() support FOR FLOAT will be removed from 0.4.0. Reading closer sometimes helps :wink: Issues with converting float to string with sprintf

But do we yet have a solution for unnecessarily large firmware due to unused libraries? I’m aware that the Particle IDE builds the project in the :cloud:, meaning that I can’t just rename some firmware header files on my local system to exclude them from the build. Perhaps Particle IDE just needs an #exclude directive!

@WebDust21, oops :smile: . FWIW, it’s pretty straightforward to setup a local build environment, especially for the Core. For one of my projects, I had to do that and strip out a lot of things, even including the whole serial port interface (which made debugging a bit tricky at times, I must admit). See here for the toolchain.

I wasn’t referring to you on the post by mdma…I was referring to my former post about misunderstanding sprintf support as being deprecated in 0.4.0. Nothing personal :wink:.

I’m glad to hear that it’s pretty straightforward to setup a local build environment. devKitPro was the very first toolchain that I was successfully able to install and use. If I start running out of memory, I guess that’ll be my first stop. I don’t think I could get away with removing serial port support–you’re a brave programmer to do that! Thanks for the link.

@kennethlimcp I’m looking inside a compiled BIN file, and there’s 537 bytes consumed with the following plain-text message:

** Even though the CC3000 supposedly supports WEP,
** we at Spark have never seen it work.
** If you control the network, we recommend changing it to WPA2.
Thanks! Wait about 7 seconds while I save those credentials…

Awesome. Now we’ll connect!

If you see a pulsing cyan light, your Spark Core
has connected to the Cloud and is ready to go!

If your LED flashes red or you encounter any other problems,
visit https://www.spark.io/support to debug.

Spark <3 you!

Your core id is {“f”:[ ],“v”:{ ": }}

Did someone’s code comments somehow get included into the project? As far as I know, there’s no way the Core/Photon could tell you any of the above if it wasn’t connected to the network, or was having problems. What in the world is this?

Everyone: you can check your BIN files in a plain-text editor. Turn word-wrap on, and down at the bottom of the file, you’ll see the above text.

Well, this is what the serial terminal says when you input the Wifi credentials manually. So I’m guessing that’s what it is? Unless I’m misunderstanding you…

OK, I forgot about that…
…but I’m watching the “space remaining” gauge count down, and was eying what looked to be some potential optimization!

Yup i’m sure we can strip those out to save some space :wink: