Firmware loader for Teensy 3

Status
Not open for further replies.

rbrockman

Active member
I would like input into the feasibility of using Teensy 3 in a product that allows end users i.e. "consumers" to update the firmware through an application.

I understand that you can force Teensy 3 into the bootloader mode through the PROG line.
How is the .hex file then loaded into Teensy? I assume that something like avrdude could be called in the background from a product update application?
After the upload is complete, must Teensy 3 be Reset in order to run the new firmware?

Example:
Teensy 3 is embedded into a consumer product, and the product gets shipped to 100 customers. I'm looking for a way to easily allow these customers to update the firmware in the product as it evolves and new features are introduced. These would be non-technical customers.

Ideal customer use case:
* user plugs a usb cable between product (with embedded Teensy 3) and PC
* user runs product update software (company branded user interface)
* user selects appropriate firmware file (pre-compiled code) and clicks "update".
* New firmware is loaded onto the Teensy 3.

Appreciate any insights and advice!
 
To get started on this, please look at the makefile in hardware/teensy/cores/teensy3. It demonstrates how to control the Teensy Loader from a script using a couple utility programs.

Currently the loader always shows the GUI window. Perhaps an option could be added for displaying different images, or maybe an option for no display at all?
 
Thanks Paul. Would you mind commenting on these executables to clarify their purpose, usage and any parameters involved?

Yes - an option to run teensy.exe without any UI would be great for integration with other applications. Duly requested :)

* teensy.exe (Teensy loader)
* teensy_gateway.exe -
* teensy_reboot.exe
* teensy_restart.exe
* teensy_post_compile.exe - this looks straightforward as below


teensy_post_compile -file=<file> -path=<path> -tools=<tools>
<file> - The code to program (without .hex) to your Teensy board
<path> - The directory where <file.hex> is located
<toolspath> - The directory where the Teensy Loader is located
 
Last edited:
teensy_reboot sends a request to reboot into bootloader mode.

teensy_restart sends a request to emulate an Arduno Uno style reboot, starting the application over. Teensy 3.0 currently does not support this, but it will be added in the future. The intent is to run this when the Arduino Serial Monitor opens.

teensy_gateway listens for emulated serial and makes the data available to the Arduino Serial Monitor. This is used when Tools > USB Type selects a non-serial option. The emulated serial allows Serial.print() to work with the Arduino Serial Monitor, even when Teensy is not a serial port.

teensy_post_compile communicates with the teensy loader, launching it if it's not already running, and informs it of the file and directory to use, and set the auto mode to on. The intent is to run this right after compiling code, but before teensy_reboot, or before manually pressing the button.
 
Thank you Paul. That answered some of my questions!

What is your policy on releasing code? Is it: "Hell no"?
 
The general policy is to release code to facilitate your use of Teensy, even for commercial use. I do indeed publish a LOT of code! I want you and your project or product to be successful.

However, the one commercial use that isn't supported is making a direct clone of Teensy. The problem isn't you. It's Sparkfun, Seeed Studios, iTead and numerous other companies whose business model is making and selling "open" hardware with minimal engineering investment. Arduino can survive such cloning (through it's causing them a lot of trouble), but PJRC can not.

Back to your product, which obviously isn't a Teensy clone, you're obviously going to create your own board when/if the volume is high enough. At very low volumes, the most sensible approach is to just solder or plug a Teensy into sockets on whatever you're making. How you run your business is, well, your business, but for anyone reading this, I've seen numerous attempts focus all these energy on minimizing hardware cost rather than building customer relationships and ultimately selling their product. That's not usually a path for success. Rarely does a new product immediately sell in high volume, so a successful approach usually involves trying to make sales first, then optimize for low cost when doing so actually saves real money.

For Teensy 2.0, we started selling a pre-programmed 32u4 chip, to support people making the transition from using a $16 PCB to designing their own. The $8 chip is still relatively expensive (you are buying software, and also a physical product which we handle in low volume), but the pre-programmed chip lets you take the step of making your own PCB without also needing to take the difficult step of transitioning to different software at the same time.

For Teensy 3.0, we'll certainly offer a pre-programmed Mini54 chip at some point. It will be in the larger TQFP package. In fact, I recently purchased the ZIF socket we'll use for programming these chips, but I haven't built the board and a version of the test fixture to program just the chip. There's still a lot of software work to do on 3.0, so this is near the bottom of my priority list... but also it's a low priority because so far nobody has really needed it. I'm sure that will change over the next few months.

Ultimately, if you're selling a product in high volume, you'll want to make your own board without buying anything from PJRC. For Teensy 3.0, you've got every last line of source code for everything on the MK20 chip. This was one of the goals of 3.0... to let you transition from a Teensy board to your own board, without having to program a bootloader onto the MK20 chip. There are companies that make programming hardware meant for using Freescale's chips in high volume. P&E Micro is the main one. You'll probably buy something from them? I can't help you select a P&E Micro product, but I'm sure their sales people will be more than happy to help!

I want to help you with using Teensy to at least get your commercial product started. Really, I do. I there's something you need, just ask me. I'm reasonable. I put an incredible amount of work into Teensy, and ultimately make far less than before I left my professional engineering job, because I really do want to make a platform you can use to be successful.

But please do understand I get a LOT of these questions about transitioning from an idea to a high volume product when they're very early in the idea stage. In fact the contact often happens as a phone call before even buying a single $16 Teensy and trying to physically build a first proof-of-concept prototype (and rarely do those lengthy conversations turn into a single $16 sale). I'm usually happy to help, but Teensy is ultimately about a platform that helps you to help yourself.

Also, keep in mind PJRC's business model is based on much more engineering work than most companies in this market. Honestly, it's not a great way to be profitable.... the "open hardware" money is in distribution of parts and sale of other people's designs, where minimal engineering effort is needed. Even Arduino primarily aggregates 3rd party contributions, though only recently they've finally hired a full time programmer (Christian Maglie) now that they've grown so much. PJRC is not even a tiny fraction of Arduino's size. In the market of Arduino-compatible boards, there is massive cloning. For an example, look at Sparkfun's "Pro Micro" board, which is amazingly similar to Teensy 2.0. The Arduino first announced Leonardo and published beta test code which they clearly said was not ready (and they weren't selling Leonardo boards), Sparkfun took that code, made a PCB from the pinout map, and started selling it with the buggy bootloader. Adafruit did the same, only briefly, but quickly discontinued using the buggy bootloader and offered to replace the boards for people without ISP programmers. Sparkfun kept selling the board and aggressively marketed it on their website, selling many hundreds (at considerably higher price than Teensy 2.0, by the way), even though they were well aware it had problems and their web page at the time specifically said to expect bootloader bugs. Had Teensy 2.0's very stable bootloader code been available, you can be sure Sparkfun would have been selling a Teensy board long ago, and PJRC would probably never have been able to make Teensy 3.0, nor the numerous Arduino contributions and other code I published.

So please understand releasing code to permits cloning is a sensitive issue. I really wish it were possible, but the commercial reality of this market is what it is. I try to do the best I can, and I really do want to help you to make your project a huge success.
 
Last edited:
Really great, well argued answer, Paul.

One thing occurred to me while reading, and that is to question the need for making one's own board for medium-volume production. For low volume, obviously just buy Teensies from PJRC. For really high volume (tens of thousands of units and up) where shaving 10% off the hardware cost does save a couple of thousand dollars/euro/pounds then fine (although I suspect people under-estimate the QA costs, they are probably not going to build the bed-of-nails testbed that you have, for example).

But for medium volume? I think (and this is just my idea, not trying to tell you how to run your business) that you could promote the idea of 'better to buy from PJRC'. I understand from your Teensy 3.0 kickstarter that one of the reasons to raise money was to finance a decent sized parts order and production run, which gives you economies of scale. Customers who have prototyped using Teensy and are now selling a product based on Teensy could be seen as having the same interests as you. If you were to offer them a modest discount on 100 Teensies, a bigger discount on 1000 and again on 10,000 this would benefit the customer, encourage them to buy built and tested Teensies from you, and also help you because your next batch of Teensies would be larger and so you would get a better price.

Anyway as I said, just something to consider.

Insert "Teensy inside" logo here.
 
I didn't mean the boot loader code... I saw the pro micro, and it broke my heart... I remember reading some thing from you, and about you. I like supporting small business, and local business. My friend lives down where you do, and man is it gorgeous. It leaves a better taste in your mouth, better then buying by boat!

I wrote an HTML5 editor for the Teensy3. I see it less as a competition, and more of a moral issue. I feel so good hollding this Teensy in my hand! Knowing who worked so hard to make it, knowing who shipped it!

If I wanted to release something large scale, I'd design it myself, and not use the Teensy. That is the fun of it, for me though.

I hope I didn't offend you paul!
 
To get started on this, please look at the makefile in hardware/teensy/cores/teensy3. It demonstrates how to control the Teensy Loader from a script using a couple utility programs.

Currently the loader always shows the GUI window. Perhaps an option could be added for displaying different images, or maybe an option for no display at all?

What would be helpful is a loader for the teensy3 that has no GUI guts at all. My teensy is connected to a 'headless' linux box and Id like to be able to load a hex file remotely.

$ ./teensy
./teensy: error while loading shared libraries: libgtk-x11-2.0.so.0: cannot open shared object file: no such file or directory

Thanks for the great product, I am looking forword to more adventures with the teensy3.

Don
 
The command-line loader works exactly as advertised (on my openSuSE 11.3 system, and I'm sure plenty of other Linux systems too).

Upon downloading the beta source, it compiled cleanly. The compilation command line that I used produces a conveniently named executable named "lxload". It was a test compilation, there are no optimizations or other fancy stuff.

Code:
cc -DUSE_LIBUSB -lusb -o lxload load_linux_only.c

Running the loader is equally straightforward. The following command line loaded a modified version of the blinky example:

Code:
./lxload -mmcu=mk20dx128 -w -v /tmp/build920612358029283211.tmp/Blink.cpp.hex

There are lots of ways to learn where the hex file lands after the Arduino IDE has completed the build process. I look for a subdirectory of /tmp whose path name has the form "/tmp/buildNNNNN.tmp"; the string of "NN..NN" is probably 1-10 digits on a 32-bit system and 18-20 digits on a 64-bit system. I looked for the directory with latest modification date. It's also possible to learn from the GUI loader that is automoatically started by the Arduino IDE, by using its "help -> verbose info" option. Look for 'remote cmd: "file:xxxxx"' and 'remote cmd: "dir: /tmp/buildNNNNN.tmp/"' lines.

I appreciate this facility because it will facilitate automated test capabilities as we use the Teensy 3.0 in a prototype system to help decide on a product direction.
 
Nice to see this!

This is still "experimental", but it works well on Linux. The Mac, Windows and FreeBSD sections are NOT yet updated for Teensy3.

http://www.pjrc.com/teensy/beta/load_linux_only.c

This is awesome. We are still in the early stages of a project (it's a pretty complex multi-board design which has to work in the field for 5+ years with no service) where we would have up to 12 Teensy3 modules, each with its own array of sensors, small touchscreen display, and driven devices, all connected by BACnet MS/TP (the 'TP' indicates half-duplex serial via RS485, but baud rate can be 115k or higher) to a BeagleBone Black board. If the BBB can update the Teensy modules in the field, that would be really sweet! We talk one at a time from the BBB to the Teensy modules.

The bootloader is actually in the MINI54TAN Cortex M0 controller but the USB signals only connect to the MK20D, so how exactly does the bootloader work, and how might we get it to work over something other than USB? We could figure a way to drive the reset signal into the MIN54 if that would help trigger a reload. There's a Prog input into the MINI54, but where is that on the Teensy3 module?

We are planning to have the serial comm for BACnet work over the UART signals from Teensy3, not try to adapt the USB data path for that.

If we must use USB then we have the problem of one Linux board trying to multiplex to 12 Teensy3 modules...

I hope we can make this work over Teensy's serial port and not just USB... which would also require ability to access the Teensy loader over something other than USB. Is that even possible? Any thoughts on that?

Thanks
Bruce
 
Last edited:
I'll try to answer all the questions....

The bootloader is actually in the MINI54TAN Cortex M0 controller but the USB signals only connect to the MK20D, so how exactly does the bootloader work,

When you drive the PROG signal low, or when it detects a request to enter bootloader mode, the MINI54 resets the MK20 and copies a tiny bootloader program into RAM, which then enumerates the USB as the HID device Teensy Loader expects. The code is uploaded and programmed into the flash memory.

and how might we get it to work over something other than USB?

It only supports USB.

We could figure a way to drive the reset signal into the MIN54 if that would help trigger a reload.

You need the PROG signal.

There's a Prog input into the MINI54, but where is that on the Teensy3 module?

It's on the right hand side of the board (opposite the USB). It's labeled on the pinout reference card that came with the board, which is also available at this page.


If we must use USB then we have the problem of one Linux board trying to multiplex to 12 Teensy3 modules...

The most reliable solution is to use a 13th Teensy, dedicated to pulsing one of the 12 other PROG pins.

You might also be able to use 12 I/O pins from the Beaglebone board.


I hope we can make this work over Teensy's serial port and not just USB... which would also require ability to access the Teensy loader over something other than USB. Is that even possible?

No, I'm sorry, it's designed only for USB.
 
The other less reliable approach is have your program detect a request to reboot and call _teensyduino_reboot_(), which requests the bootloader take over. I'd recommend calling that function, rather than copying the code, since the mechanism may change slightly in future versions.

Of course, this method depends on your firmware always being able to detect a request and call that function. If you ever upload a bad firmware which can't call the reboot function, then the board becomes unable to do further upgrades. But if you test your code reasonably well on other boards first, maybe this is an acceptable risk?
 
OK, I was looking at a Teensy2 pinout... doh, and now with the right one I see the Prog pin on Teensy3.

So are you saying we can tie all the Teensy USB connections together (or do we have to use USB hubs - yuck if so, that's four USB hubs per rack plus a pile of USB cables which don't latch) and just hit one Prog line on one of the 12 Teensy3 and then the linux board can talk just to that one and the other 11 will have their USB lines in a high-Z state and won't load the USB down?

If we are using the command line loader, then we aren't using the PC-side Teensy Loader, right? We'd have to change the linux CLI to use a UART as well (the same one it uses for BACnet).

Another idea: could we pay you to make a custom version of the bootloader which would permit loading code over a serial port? That would be then a custom MINI54 which we could use with a blank MK20...

This is starting to sound complicated but hopefully there is a way to make it as simple and reliable as we can.

Thanks
Bruce
 
If we have to USB-hub 12 Teensy 3 modules together, into a BeagleBone Black, we would need to cycle through all available devices. If one wasn't reachable (non-latching USB cable comes unplugged, or ??) then we wouldn't know which of the 12 devices it was... hmmm. Also we would not want to have the hub powered 24/7, just when we want to do a remote update. There is a Satechi 12-port hub but it gets mixed reviews on Amazon.

How do you test Teensy modules as they go out the door? Plug a bunch into a hub and run some automatic test?

Thanks
Bruce
 
How do you test Teensy modules as they go out the door? Plug a bunch into a hub and run some automatic test?

We use 2 different mostly automated tests. Each tests just a single board.

Test #1 uses a bed of nails that touches every I/O pin. Almost all of the testing is done on test #1. You can see some photos here:

http://www.kickstarter.com/projects...rm-cortex-m4-usable-in-arduino-a/posts/305527

Test #2 uses a small linux-based PC with a USB port. The USB feeds through a custom-built circuit that lets the tester measure current consumption (which checks for the extra 3 mA when the LED turns on and other current measurement tests). The circuity also use red & green LEDs to report fail or pass. It also can disconnect the data lines and do other tricks which the test uses. Test #2 checks to make sure the USB connector really works. The LED blink example is loaded during test #2, so if the LED is blinking, we know for sure the board worked here through the actual USB connector. The final step in test #2 involves the operator pushing the button. The green LED turns on when test is completed with all steps passed.

Both tests are designed to run very quickly. There's no need to use a big hub.

Regarding USB hubs, I believe you'll find the ones with many ports are actually 2 or more hubs inside 1 box. All the actual USB hub chips I've seen (TI, Cypress, others) are only 4 or 7 ports. Even some 7 port hubs, including one I have on my desk, are actually a pair of 4 port chips where 3 of the ports are from the chip connected to your PC, and the other 4 are from the chip wired into the 4th's port of the main chip. You can discover this using Linux "lsusb -v" or Mac's USB Prober (from Apple's Xcode) or the Windows device manager.
 
Short update relevant to BeagleBone Black users. I was doing some BBB maintenance this morning, and on a lark tried compiling the linux loader. It compiled and loaded a test hex file just fine.

Context: This morning's BBB maintenance was to install the latest 2013-09-04 flasher image. That image has a recent libusb. Upon copying my installed libusb header file to the BBB creating a properly named symlink to the library, compilation worked:

Code:
# mv /tmp/usb.h /usr/include/.
# cd /lib
# ls libusb*
libusb-0.1.so.4  libusb-0.1.so.4.4.4  libusb-1.0.so.0  libusb-1.0.so.0.1.0
# ln -s libusb-0.1.so.4 libusb.so
# gcc -O2 -o lxloader -DUSE_LIBUSB -lusb load_linux_only.c
# /lxloader -w -v -mmcu=mk20dx128 /tmp/Blink.cpp.hex  
Teensy Loader, Command Line, Version 2.0
Read "/tmp/Blink.cpp.hex": 14908 bytes, 11.4% usage
Found HalfKay Bootloader
Programming...............
Booting

Note that I needed to fix libusb naming to make compiling a bit easier. I'll try to suggest an upstream mod to the Angstrom folks to keep it simple and standard.

The BBB kernel supports USB gadget serial and the default image has screen. It works as expected.

Code:
screen /dev/ttyACM0

It's possible to fully control a Teensy 3.0 from a BBB, including firmware update. Having said that (my day job being F/W development of mesh radio stuff)... Beyond prototype development which the Teensy 3.0 does nearly perfectly, applications have diverse OTA firmware upgrade requirements and I would not expect PJRC to support such broad diversity at this price point and form factor. I just purchased a few SPI flash chips from Sparkfun, and preparing to implement (as nearly as possible :) ) bulletproof OTA firmware upgrade for my remote access project.
 
If we have to USB-hub 12 Teensy 3 modules together, into a BeagleBone Black, we would need to cycle through all available devices. If one wasn't reachable (non-latching USB cable comes unplugged, or ??) then we wouldn't know which of the 12 devices it was...
What I do to identify modules, in the face of varying USB ids, is read the MAC on the teensy3s using software that's already loaded into the teensy. This doesn't help if you're loading from scratch, but you could do something like "look for serial port".. "try to talk", if it doesn't talk back, load software in; if it does talk back, ask it what MAC it has (which is a defacto serial number).
I am still periodically cursed by USB serial ports coming and going. I don't know why it happens.. I think it's a USB hub/power supply/phase of the moon thing.
 
Along these lines, do you publish the interface between the MK20DX and the Mini54AT. Specifically I would be interested in being able have the MK20DX transfer control to an internal RAM program that would write a sector of its own Flash using the Mini54AT.
 
Just want to say thanks man.

You and your product (teency ++ 2.0 in particular) have been a fantastic introduction tool and made possible some amazing results. I am very grateful for your time and perseverance in such a fickle market.

Sincerely,
Scott
 
Hi Paul,

I'm pretty blown away by Teensy 3.x. If I succeed in basing our new products on Teensy, we will certainly buy directly from PJRC. Can I expect to be able to buy these for a good number of years, say 5-10 or even longer? Our products tend to have a long life, and we want to be able to repair and replace over that time frame.

Best regards,

Joe
 
Can't answer for Paul given I'm a random denzin of the forum in no way representing PJRC, but he is on record in various threads here for planning ahead to keep parts in stock with big buys when production ceases. Note he still keeps the Teensy2 in production so you can sorta bench mark on that for how long he is prepared to keep something on the shelf. That of course doesn't help if a company merger or something suddenly disappears the product line, but process to date has kept the Teensy3.x line alive through various changes of actual ICs.
 
Old thread I know, but this seems to be the one to use...if not please let me know admins.

I have a commercial product based on the teensy 3.6 and am looking to implement a branded firmware updater package. I have had a good scour looking around (and I have tried to discretely message you Paul, though I totally understand that I probably got lost in filters and hundreds of messages).

So my question is this, does anyone have any updates on a custom firmware loader? If not I will try and start to put something together.

Any input on how people would approach this would be welcome and of course I will open source this.
 
Status
Not open for further replies.
Back
Top