Firmware Tips and Tricks

#Post your firmware Tips and Tricks here!#


Do you have some simple but useful coding tip that will save users time, or make them aware of an issue that they can work around? Post them here! Tips and Tricks should be short and to the point, no long libraries or big routines please. Also please don’t post questions here regarding anything other than the tips and tricks posted. I will organize and link to each relevant tip from this first post as the thread builds. If you have a way to improve a tip or trick, please make a suggestion. Thanks!

Please use these formatting techniques to submit your tips and tricks:


#Table of Contents#
for Tips and Tricks found in below posts

  1. Pause your application to make a Serial over USB connection
  2. sprintf() consumes 20KB of FLASH memory!
  3. Script DFU mode for local build and flash
  4. Die, with the possibility of reincarnation
4 Likes

##Pause your application to make a Serial over USB connection##
Here is a quick trick that makes opening a serial connection over USB on Windows easy and foolproof.

// The following line is for Local Builds, 
// but works fine in the (Web IDE)
#include "application.h"

void setup() {
  // Make sure your serial terminal is closed before starting your Core.
  // Start up your Spark Core, you should hear a USB driver connection
  // being made after the following line runs.
  Serial.begin(115200);

  // Now it's ok to open your serial terminal software, and connect to the
  // available COM port.  The following line effectively pauses your
  // application waiting for a character to be received from the serial
  // terminal.  While it's waiting it processes the background tasks to
  // keep your Core connected to the Cloud.  Press ENTER in your 
  // serial terminal to start your application.
  while(!Serial.available()) Spark.process();

  // Try commenting out the above line and see if it's hard to make a 
  // serial connection over USB ;-)  On Windows it will likely tell you
  // that your serial port is in use already.  That's because the RX buffer
  // on the computer is getting hammered with data.  Pausing the 
  // transmissions from the Spark Core solves this problem.
}

void loop() {
  // Just something to test print
  Serial.println("Hello Sparky!");
  delay(100);
}
3 Likes

##sprintf() consumes 20KB of FLASH memory!##
Here is a small work around for that which won’t eat up all of your FLASH memory, effectively costing you nothing, with an useful example:

// The following two lines are for Local Builds, 
// but work fine in the Sparkulator (web IDE)
#include "application.h"
const char* myIpAddress(void);

// allow us to use itoa() in this scope
extern char* itoa(int a, char* buffer, unsigned char radix);

const char* myIpAddress(void)
{
  IPAddress myIp = WiFi.localIP();
  static char buf[24] = "";
  //sprintf(buf, "%d.%d.%d.%d", myIp[0], myIp[1], myIp[2], myIp[3]);
  // The following code does the same thing as the above sprintf()
  // but uses 20KB less flash!
  char num[4];
  itoa(myIp[0],num,10);
  strcat(buf,num); strcat(buf,".");
  itoa(myIp[1],num,10);
  strcat(buf,num); strcat(buf,".");
  itoa(myIp[2],num,10);
  strcat(buf,num); strcat(buf,".");
  itoa(myIp[3],num,10);
  strcat(buf,num);
  return buf;
}

void setup() {
  // Make sure your serial terminal is closed before starting your Core.
  // Start up your Spark Core, you should hear a USB driver connection
  // being made after the following line runs.
  Serial.begin(115200);
  // Now it's ok to open your serial terminal software, and connect to the
  // available COM port.  The following line effectively pauses your
  // application waiting for a character to be received from the serial
  // terminal.  While it's waiting it processes the background tasks to
  // keep your Core connected to the Cloud.  Press ENTER in your 
  // serial terminal to start your application.
  while(!Serial.available()) Spark.process();

  // Print out the IP address the Spark Core is connected to
  Serial.print("Spark Core connected to IP: ");
  Serial.println(myIpAddress());
}

void loop() {
  // do nothing
}
4 Likes

That was a nice tips and trick, thank you :smile:

##Script DFU mode for local build and flash##

I build locally using the command line, and putting the spark into DFU mode manually can be a fiddle, so this simple addition to all sketches has allowed me to script the make and spark flash process. Its a little crude as the curl command just times out but it works for me. Perhaps the spark team can include this ability in a future firmware and spark-cli version.

#include "application.h"

int doDFU(String command) {

 FLASH_OTA_Update_SysFlag = 0x0000;
 Save_SystemFlags();
 BKP_WriteBackupRegister(BKP_DR10, 0x0000);
 USB_Cable_Config(DISABLE);
 NVIC_SystemReset();
 
 return 0;
}

void setup() {
    Spark.function("dfu",doDFU);
} 

void loop() {
}

Then your build script needs to include

make
curl https://api.spark.io/v1/devices/{{device}}/dfu -d access_token={{token}} -d "args=DO"
spark flash firmware core-firmware.bin
14 Likes

Wow, really cool @deancs! Thanks for contributing a sweet trick :wink: It looks like you can omit the last bit of your curl command -d "args=DO"

I could see this working for a full local build with toolchain as well, with some tweaks. I’ve been wanting to do something about that for a while now. The button presses are quite annoying when you are building over and over. If the USB could put the Core into DFU mode automatically kind of like the Arduino works, that would be super sweet. I think your method is about the closest we could probably get to being automatic.

Before I commit to migrating everything over to the command line/eclipse whats the difference in flash time? Currently it can take up to 4 mins to flash the spark via the IDE. How long is it via the command line (local)?

“Spark flash” is fast, about 15-20 seconds as it’s all performed locally. “spark cloud flash” will take about the same time as the web IDE. Local compiles are only a few seconds, especially if it’s only the sketch that has changed

Times… After employing the great tutorial "How to video for compiling locally in Windows " I have been using the NetBeans IDE. This is very stable, and I NEVER want to go into command line modes.
In NetBeans, a full clean & build is about 20 seconds, and a small update build is 2 seconds. Loading is “automatic” from the IDE taking about 10 - 15 seconds; the dfu need information is embedded in the IDE setups.

Again I propose, why are we comfortable with using command line sequences when the integrated platforms make the tedious items so easy???

Great thanks… I’ll give Net Beans ago.

If I may ask. How did you configurate Netbeans to flash the core?:slight_smile:

This is a pretty neat step-by-step tutorial. Working nicely so far :slight_smile:

Thanks BDUB! Could it be that strlcpy function consumes a lot of Flash memory too? I’m having some problmes with it.

##Die, with the possibility of reincarnation##
Sometimes you want to create a “kill loop” which is just an infinite loop that terminates the execution of your program. However on the Spark Core this will cause your Core to not process the background tasks that allow it to talk to the Cloud, and also allow it to be reflashed OTA (Over The Air). To create a kill loop, that allows you to reprogram your core, you can just infinitely call the background tasks directly with code like this. Here we detect a failure connecting to our temperature sensor, and die… with the possibility of reincarnation :wink:

if (!bmp.begin()) {
  Serial.println("Could not find a valid BMP085 sensor, check wiring!");
  while(1) Spark.process(); // Die, with the possibility of reincarnation
}
3 Likes

If you do not want to wait for curl to time out after the Core goes to DFU mode, you can add -m 5to the curl command, which sets the timeout to (in this case) five seconds.

From the curl manual:

-m, --max-time {seconds}

Maximum time in seconds that you allow the whole operation to take. This is useful for preventing your batch jobs from hanging for hours due to slow networks or links going down. See also the --connect-timeout option.

If this option is used several times, the last one will be used.

1 Like

That's a cool function. I added it to my commandline parser and can now flash the core without pressing the buttons. But what if I accindently start the DFU loader this way. Is there a way to reset to normal mode without really flashing? Some button tricks, timeouts or so.

I just managed to "brick" my core, it is now flashing blue. I have to look what that means. :slight_smile:

Flashing blue usually means the Core is in listening mode to accept WiFi credentials via USB serial.
I guess you always could do a factory reset.

This code will force the core to enter DFU mode but will not leave until a code is programmed via DFU-util.

Maybe I’ll check when I have time on how we can do it like a normal button pressed DFU mode that exits when the reset button is hit.

A little tip to speed up your TCP connections. the TCPclient print method is slow as it writes one character at a time to the cc3k and every now and then there is a big delay of a second or more… Changing to the write method prints an entire buffer at once. But how to change to the write you ask? easy with this little function

Create a function like this (assume you created the instance called client, using TCPClient client;)

void out(const char *s) {
client.write( (const uint8_t*)s, strlen(s) ); 
}

Now just change everywhere you used client.print("whatever"); to out("whatever");

Ahh but what about the client.println()? thats easy too just add \r\n like this out("whatever\r\n");

it also works well with variables too, i often have a buffer using sprintf, like this (also a handy thing to know when using an ip address)
sprintf(buf, "Host: %d.%d.%d.%d:%d\r\n", ip[0], ip[1], ip[2], ip[3], port); out(buf);

and if you want to print it on the serial port? just add the line serial.write( (const uint8_t*)s, strlen(s) ); to the out function.

3 Likes

@deancs I got the automatic dfu working, but I have to hit Ctrl-C to stop the curl command. This sounds reasonable, as the command doesn’t end up returning anything. Is this true for you as well? Do you have a method that automatically ends the process (I guess there are many where you can kill a process after x seconds)

Thanks!