This post comes almost out of the blue, but in reality is the culmination of a long time of work. It is the final piece of software that was needed in one of the projects that I have spent the most time working on, the SHADE Sun Photometer. This is a handheld low cost instrument for measuring atmospheric aerosols that is intended to be used in aerosol measurement campaigns and as part of the GLOBE program, allowing kids and students to obtain measurements that are up to par with the data quality requirements that NASA scientists need, without having a huge price tag on it. Although we have been delayed many times, and have faced many difficulties in completing the instrument, it is one step closer to being ready for production. Here is the site that we have for it:
I would like to note that our intention in producing this instrument is to enable a global network of aerosol measurements, and collaborate in some way with the task of understanding and fighting climate change. We started this as a school project and have developed this with our spare time and budget, so lots of bugs are still present. Which brings me to the point of this post, a bootloader!
Background of bootloaders
Bootloaders are the workhorses of all embedded devices. A bootloader is one of several pieces of code that are used to load the target application into the final device. In our case, we want to be able to change the program that the instrument is using without having to open the device and connect a FET programmer. We have several options for doing this, and each has its own benefits:
- Write our own bootloader from scratch. Writing a bootloader from scratch requires lots of knowledge of the target architecture and chip and lots of careful planning on memory real estate on the target chip. The benefit of doing this from scratch is that the target application can load the program from any location that we want. We could write a bootloader that reads packets from a TCP socket and then writes the image to flash. Doing this means that the booloader that we write will be the first application that the processor runs when turned on. The booloader will verify that a valid application is stored in flash and then proceeds to execute it. The target application needs to be linked in such a way that would allow execution starting from a non 0 address. Also, there needs to be a way to enter bootloader mode to change the application in normal use.
- Use a boot ROM. Most microcontrollers and microprocessors nowadays have some sort of built in bootloader that is stored in a ROM, or a special protected region in flash. The Texas Instruments MSPF5438 microcontroller we are using thankfully falls in this category, so if we are able to figure out what the engineers over at TI did in the boot rom we can use the built in bootloader for our purposes.
For the SHADE instrument, we went with the second option. Building a bootloader from scratch requires maintaining two separate projects, and given the limited ammount of time we can put into the project, it made more sense to understand and work with TI instead of reinventing the wheel. The folks at TI call their bootloader the MSP Boot Strap Loader (BSL). The BSL on the F5438 requires a special “entry sequence”, in other words, a specific sequence of transitions on the JTAG programming pins to enter the BSL programming mode. This is what the documentation says that we need to do:
Ok, so we need to pulse the TCK pin twice and pull the RST line high while we are in the middle of the second pulse. Note: Not all MSPF5438A devices can actually enter BSL mode. Take a look at the MSPF5438A SYS10 errata entry which says the following:
The BSL entry sequence requires that the low phase of the TEST/SBWTCK pin does not exceed 15us. This timing requirement is faster than most PC serial ports can provide, as shown in the following picture. If this requirement is not met, the entry sequence fails and the SYSBSLIND is not set.
If you have an MSPF5438A device, make sure it is a revision F or H, or a non -A variant. Any other version will make it almost impossible to enter BSL mode reliably.
We want to program the device using though a standard USB to serial com port converter chip. We are using Sillicon Labs CP2102 VCP chip. So how do we actually create these pulses though a serial port? Well.. we use the RTS and DTR signals of course! We have no need for flow control in the protocol. So instead of letting these pins go to waste, we actually connect these pins to the RST and TCK lines.This falls mostly in line with what TI wanted us to do anyway (implied by actually using the RST and TCK signal names in the above timing diagram). Ok, we get it TI, let’s do it that way.
But wait.. if we try to hard wire the outputs of the CP2102 to the chip to the RST and TCK lines, that would mess up a lot of things. First off.. the RST is the reset line! We want to be able to pull the reset line low whenever we want to. We also don’t want to lose the ability to use the FET programmer to debug right? The solution, use tristate buffers! By using these buffers we can let the USB port take control of the RST and TCK lines when the USB is connected, and let the RST and TCK lines be controlled normally when the USB is disconnected. The diagram looks like this then:
Lets say that we manage to pulse the pins correctly then, what’s next? TI’s BSL uses two pins to communicate via serial port to a pc that runs the BSL procotol. TI provides a BSL_scripter application that runs a script and transmits the required commands via serial port. We connected the output of the CP2102’s serial port to both the BSL pins and the regular UART port used for communication in normal operation.
A special note here: some of the documents of the F5XXX family say that you should use pins 1.0 and 1.1.. always check the specific datasheet of the device, not the family, to check where the BSL lines are. For the MSPF5438 you should use pins 1.1 and 1.2.
So the schematic looks like this:
The BSL_scripter is quite simple to use. Basically, it requires a few commands that instruct it to read a special password register and then transmit this password to unlock the flash in the microcontroller. This scheme ensures that even if BSL mode is somehow entered accidentally, no data is overwritten unless we truly intentionally want to change the flash. Once the flash is unlocked, a command transmits a binary image to the microcontroller overwriting the previous flash image. The whole process is wrapped up by a reset which causes the chip to exit BSL mode and run the new binary image. The system performs checksums all along the way, so it is quite safe. Even if the download process in interrupted, the BSL flash region is protected and can always be entered by triggering the BSL entry sequence again.
The SHADE Bootloader
In order to simplify the download process for an end user, we did a small wrapper that uses the BSL scripter. This GUI generates a custom script file that is fed to the BSL scripter. This way, the GUI is independent of the actual serial processes that occur, and makes uploading new flash images very simple.
We will make the SHADE bootloader available soon on the official website. Feel free run the GUI application to inspect the syntax of the generated script files and how you can modify one of these scripts to load your own binary images to an MSPF5xxx device.
Since I had a hard time finding the source code of TI’s BSL scripter, I am leaving the link here:
Happy MSP bootloading!