USB-MSD and UART boot loader for Teensy 3.1

uTasker

Well-known member
Hi All

I have configured a USB-MSD boot loader (also with UART SREC loading) for the Teensy 3.1.
Anyone interested can download it from http://www.utasker.com/SW_Demos.html#K20

This video shows it in operation https://www.youtube.com/watch?v=XVlCisUmJMI&feature=youtu.be (not on a Teensy but otherwise equivalent) and it is fully described here: http://www.utasker.com/docs/uTasker/uTaskerSerialLoader.PDF

The boot loader allows the loaded software to be displayed (name, date etc.) but protects the content with a password. This is shown here (again not on the Teensy but otherwise identical) https://www.youtube.com/watch?v=e4oFBn_M5wo

There is a test application there too which, once loaded via the boot loader, will appear as USB-CDC with various menu items to play with.

Regards

Mark
 
Hi All

I have configured a USB-MSD boot loader (also with UART SREC loading) for the Teensy 3.1.
Anyone interested can download it from http://www.utasker.com/SW_Demos.html#K20

This video shows it in operation https://www.youtube.com/watch?v=XVlCisUmJMI&feature=youtu.be (not on a Teensy but otherwise equivalent) and it is fully described here: http://www.utasker.com/docs/uTasker/uTaskerSerialLoader.PDF

The boot loader allows the loaded software to be displayed (name, date etc.) but protects the content with a password. This is shown here (again not on the Teensy but otherwise identical) https://www.youtube.com/watch?v=e4oFBn_M5wo

There is a test application there too which, once loaded via the boot loader, will appear as USB-CDC with various menu items to play with.

Hi Mark, what process did you go about to actually program the Teensy 3.1 with this bootloader? I've tried programming it through the teensy loader, and then when I try to put a SREC file on it doesn't work.
 
Hi

The file "uTaskerSerialLoader_Teensy_3_1.hex" can be programmed using the Teensy loader and then you should then see the red LED on the board blinking at 5Hz.
This is what I do with it on my Teensy3.1 and it works as expected - there is no other way without physically adding a parallel JTAG debugger connection and using other tools.

Regards

Mark
 
Hi Mark, I've tried this and it seems to work, creating a USB storage and also getting the correct reply via Teraterm. The problem I am having is that I can't find a reliable way to turn the .hex files generated by compiling Teensy Arduino into .srec for copy over serial. I've tried creating a batch file with srec_cat.exe (http://srecord.sourceforge.net/windows.html) inside:

srec_cat Release\_Camera.hex -intel -o _Camera.srec
PAUSE
-address-length=4

However, when I try copying this via teraterm, I get .......... *** ......... instead of all .................................

What is your process to create the .srec file?

Thanks again!
 
Hi

Typically GCC Objcopy is used (--output-target=srec) but it looks to be OK as it is.
A . is displayed for each correct line of SREC received.
There are 2 x * when a buffer full of code has been received and programmed to Flash. This means that a buffer (eg. 4k or 8k in size) is first collected - then an XOFF is sent to the terminal emulator so that it stops sending more data. The programming is done and XON sent so that the transfer continues. (First * shows pause starting and the second * shows transfer continuing.
The reason for pausing during programming is that interrupts have to be disabled and so it is simplest to stop so that no UART receptions can be lost. If thsi is not done and each line programmed at a time it is found that there are often UART Rx overruns (and so corruption) when loading speeds greater than 56k are used; the reason is that it takes about one character period at this speed for a flash byte to be programmed. At 115kBaud Rx overrun would otherwise almost certainly take place.

Regards

Mark
 
Hi,

I tried to use your bootloader. It works fine with your examples but it did not work when I tried to load another program. I tried with the example Blink. I converted it with arm-nano-eabi-objcopy using this command line:
arm-none-eabi-objcopy.exe --output-target=srec --change-start=0x8080 --change-addresses=0x8080 Blink.cpp.elf Blink.S19
it converts well in S19 format and it changes the address start. When i send it to the teensy it writes "Terminated-restarting" but it the led never blinks.
Could you give more detail about the creation of the srec file?

Regards
 
Hi

I don't think that you can use a command like --change-start since that will probably just move the code to a different address and make it inoperable.
You need to link the application code to the correct start address when it is built. If it is linked to the normal reset addres (0x00000000) but loaded to another it can't operate.

Regards

Mark

P.S. The latest version of the uTasker Serial Loader (compatible with the Teensy) contains UART loading (SREC or Freescale KBOOT compatible), SD card, USB (Freescale KBOOT compatible and/or USB-MSD - composite device allows both options at the same time), as well as Ethernet web server (for parts with Ethernet) - can be built for most Kinetis KE, KL and K parts
 
Hi,

Thks for your fast answer!
Ok I have changed the address in the linker. I wrote 0x8080 as the origin of flash.
I did: arm-none-eabi-objcopt.exe --output-target=srec Blink.cpp.elf Blink.S19
My S19 starts at 8080 address but once programmed in teensy with your bootloader it still does not work.

I tried with your k_256_64.ld but compilation error many undefined references

Regards
 
Last edited:
Hi

These are to be considered to ensure that an application can run from an offset address:
- 1. If you are using interrupts you can either copy them to SRAM or have them hardcoded in the interrupt vector space after the reset vector. In case of SRAM there is nothing to do - in the case of hard coded the Vector Table Offset register must be set to match (it will default to 0 which suits the vectors after the reset vector but will need to be changed to 0x8080 to match in this case - it needs to be on a 0x80 boundary due to the offset register's address line limitation).
- 2. Ensure that the first two long words in the file are as expected: the first must be the stack pointer value and the second the program's entry address. These can be seen by viewing either the binary or SREC file content. If they don't have expect values the reset vector has been 'lost' or moved to a different location which then can't work.
- 3. The loader will typically enable and start the watchodg. If your application runs for only 1..2s before resetting it is probably because it is not either disabling or retriggering the watchdog.

I use a linker script called K_256_64_BM.ld for the boot loader (K_256_64.ld is for a standalone application).

Below are the relevant details (the first 488 bytes of SRAM are reserved for interrupt vector use in SRAM)

Regards

Mark


MEMORY
{
FLASH (rx) : ORIGIN = 0x00008080, LENGTH = 0x00040000-0x8080 /* 256k Flash */
SRAM (wx) : ORIGIN = 0x1fff81f0, LENGTH = 0x00010000-0x1f0 /* 64k RAM with vector size 0x1f0 (488 bytes - maximum for all processors) */
}

SECTIONS
{
__SRAM_segment_start__ = 0x1fff81f0;
__SRAM_segment_end__ = 0x20007fff;
__Vector_segment_start__ = 0x00008080;
__Vector_segment_end__ = 0x00008087;
__FLASH_segment_start__ = 0x00008088;
__FLASH_segment_end__ = 0x0003ffff;
..
..
 
Hi,

thks a lot for your answers.
sorry, I really don't understand what I must change in my ld file.
I don't understand why you have SRAM, there isn't any SRAM in original ld file and I have no idea where to write FLASH start in this file.
if we change only flash origin, should it work?
I don't know the value of thestack pointer, my S19 file starts like that:
S01A00004F707469626C7565494D554669726D776172652E5331398E
S1138080107E00203D82000059C0000059C000004D

I see 8080 and it increments in the next lines so it seems the address is good.

how do you disable the watchdog?

regards
 
Hi

>>I don't understand why you have SRAM
Maybe it is names RAM in your .ld file but it doesn't matter how it is called, it matters just which address raneg it has and that variables are assigned to its area.
I don't know how your .ld file looks so it would be best to post it.

>>S1138080107E00203D82000059C0000059C000004D
This looks good.
107E0020 is the address 0x20007e10 which is a realistic value for the SP (towards the top of the RAM area).
3D820000 is the adress 0x000082ed which is a thumb address near to the start of the program area.

This looks to be able to boot correctly.

Then the values 59C0000059C00000 (addresses 0x0000c059) look to be interrupt vector addresses (probaly handling undefined interrupts since they are pointing to the same address) so I expect that you have fixed interrupt vectors. In this case you will have to add something like
VECTOR_TABLE_OFFSET_REG = 0x00008080; in your initialisation code so that interrupts are correctly used.

To disable the watchog (as long as it hasn't been configured to not allow changes) the following code serves as reference:
UNLOCK_WDOG(); // open a window to write to watchdog
WDOG_STCTRLH = (WDOG_STCTRLH_STNDBYEN | WDOG_STCTRLH_WAITEN | WDOG_STCTRLH_STOPEN | WDOG_STCTRLH_ALLOWUPDATE | WDOG_STCTRLH_CLKSRC); // disable watchdog


where UNLOCK_WDOG() is
WDOG_UNLOCK = WDOG_UNLOCK_SEQUENCE_1; WDOG_UNLOCK = WDOG_UNLOCK_SEQUENCE_2; [write 0xc520 followed by 0xd928]


To retrigger the watchog your application can regularly call
uDisable_Interrupt(); // protect the refresh sequence from interrupts
REFRESH_WDOG();
uEnable_Interrupt();


where REFRESH_WDOG() is
WDOG_REFRESH = WDOG_REFRESH_SEQUENCE_1; WDOG_REFRESH = WDOG_REFRESH_SEQUENCE_2; [write 0xa602 followed by 0xd928]

There is a thread about the watchdog somewhere and I expect that the framework you are using has such functions. Generally all applications should have a watchdog operating to ensure recovery in case of errors.

Regards

Mark
 
Hi,

this is my ld file:

/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2013 PJRC.COM, LLC.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* 1. The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* 2. If the Software is incorporated into a build system that allows
* selection among a list of target devices, then similar target
* devices manufactured by PJRC.COM must be included in the list of
* target devices and selectable in the same manner.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

MEMORY
{
FLASH (rx) : ORIGIN = 0x8080, LENGTH = 0x00040000-0x8080 /* 256k Flash */
RAM (rwx) : ORIGIN = 0x1fff8000, LENGTH = 0x00010000 /* 64k RAM with vector size 0x1f0 (488 bytes - maximum for all processors) */
}


/* INCLUDE common.ld */


/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2013 PJRC.COM, LLC.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* 1. The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* 2. If the Software is incorporated into a build system that allows
* selection among a list of target devices, then similar target
* devices manufactured by PJRC.COM must be included in the list of
* target devices and selectable in the same manner.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/



SECTIONS
{
__RAM_segment_start__ = 0x1fff81f0;
__RAM_segment_end__ = 0x20007fff;
__Vector_segment_start__ = 0x00008080;
__Vector_segment_end__ = 0x0000847F;
__FLASH_segment_start__ = 0x00008480;
__FLASH_segment_end__ = 0x0003ffff;

.text : {
. = 0;
KEEP(*(.vectors))
*(.startup*)
/* TODO: does linker detect startup overflow onto flashconfig? */
. = 0x400;
KEEP(*(.flashconfig*))
*(.text*)
*(.rodata*)
. = ALIGN(4);
KEEP(*(.init))
. = ALIGN(4);
__preinit_array_start = .;
KEEP (*(.preinit_array))
__preinit_array_end = .;
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
} > FLASH = 0xFF

.ARM.exidx : {
__exidx_start = .;
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
__exidx_end = .;
} > FLASH
_etext = .;

.usbdescriptortable (NOLOAD) : {
/* . = ORIGIN(RAM); */
. = ALIGN(512);
*(.usbdescriptortable*)
} > RAM

.dmabuffers (NOLOAD) : {
. = ALIGN(4);
*(.dmabuffers*)
} > RAM

.usbbuffers (NOLOAD) : {
. = ALIGN(4);
*(.usbbuffers*)
} > RAM

.data : AT (_etext) {
. = ALIGN(4);
_sdata = .;
*(.data*)
. = ALIGN(4);
_edata = .;
} > RAM

.noinit (NOLOAD) : {
*(.noinit*)
} > RAM

.bss : {
. = ALIGN(4);
_sbss = .;
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .;
__bss_end = .;
} > RAM

_estack = ORIGIN(RAM) + LENGTH(RAM);
}


From what I understand, the vector table should be from 8080 to 8480 thanks to this ld file and for me it should work

regards

Benoit
 
Hi

It looks basically OK to me.

Although probably not important, the address of the .vectors could also be set to the link address and the .flashconfig can be removed since it doesn't serve any purpose (the boot loader defines these values)

.text : {
. = 0x8080;
KEEP(*(.vectors))
*(.startup*)
/* TODO: does linker detect startup overflow onto flashconfig? */
. = 0x400;
KEEP(*(.flashconfig*))


Did you check that the interrupt vector offset is being set by code to match the new locations?

Regards

Mark
 
Hi,

Actually I tried to write 0x8080 in .text but it fills in 0xFF the flash so I decided to write 0.
The phenomenom is still the same, once uploaded, the board has the led ON and it never boots on the program

what do you mean by interrupt vector set in the code? I have not checked
have you changed the file mk20dx128.c to make it work?

regards

Benoit
 
Hi

>>what do you mean by interrupt vector set in the code?

As I wrote earlier;:
"Then the values 59C0000059C00000 (addresses 0x0000c059) look to be interrupt vector addresses (probaly handling undefined interrupts since they are pointing to the same address) so I expect that you have fixed interrupt vectors. In this case you will have to add something like
VECTOR_TABLE_OFFSET_REG = 0x00008080; in your initialisation code so that interrupts are correctly used."

>>have you changed the file mk20dx128.c to make it work?
I don't use this file since I use the uTasker project. But it is possible to use the loader with any project as long as its code allows the vectors to be relocated. Since it looks like it is using fixed interrupt vectors you will HAVE to at least set up the vector table offset register to match (assuming you are using interrupts) - search the project code to see whether it is being written to with 0x00000000 (often the case) or it may not be set at all (defaults to 0) and then set it accordingly.

I prefer to work with interrupt vectors in RAM since it is generally more flexible but if the project doesn't support this it would be a bigger change. Often there is a configuration option (eg. MQX based projects) which allows the style to be chosen.

Regards

Mark
 
Hi,

the solution may be to use the utasker project.
If we take a licence, could you help us in configuring the files of teensy project?

regards,

Benoit
 
Hi Benoit

I am not sure whether you are referring to the complete uTasker project or the uTasker serial loader project?
The serial loader project includes various boot loader features (presently UART [SREC or Freescale KBOOT compatible], USB-MSD, SD card, USB-HID [Freescale KBOOT compatible), Ethernet web server] which works on all KE, KL and K devices that have the required peripherals (and space) - often they can work in parallel as alternative methods.

The complete uTasker project includes the serial loader plus full application support (TCP/IP stack, utFAT, USB device stack, drivers for most peripherals and a complete applcation framework). Again it supports most KE, KL and K devices and boards and allows (approx) real-time simulation of the chips and boards (of course including the Teensy3.1)

The projects are free for use in non-commercial projects, including support in various forums.

For commercial use the projects can be licensed which includes personal support for a period of time (6 months or 1 year) so email and telephone cooperation is available whenever needed in case of any urgency, or if more detailed help is required.

If your work is not purely hobby and has need for additional support it would be no problem to solve any issues that are blocking your progress by sending me the code in question. You can contact me on the uTasker web site in this case.
If you are doing hobby work you can still post your binary (or SREC) file here and I can load it to my board. Possibly I can see with a debugger what the issue is - it is normally fairly obvious when an application doesn't start or crashes early on in its operation.

Regards

Mark
 
Hi,

My work is not for hobby, we will take a licence.
ok I sent you an email, we will continue the discussion by email and I will publish the solution here after, I think that's better

regards

Benoit
 
Hi All

The serial loader for the Teensy 3.1 has been updated to include Freescale KBOOT support as option (KBOOT is detailed at the Freescale web site: http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=KBOOT).

The following offers alternative binaries that include SREC loading on UART-0 and a composite USB mode with both KBOOT mode (for the Freescale PC tool) and USB-MSD for drag-and-drop when the Teensy appears as a hard-drive.

http://www.utasker.com/kinetis/TEENSY_3.1.html

The USB-MSD is the best mode to use at the moment because the Freescael tools is "really" slow - I have been complaining to Freescale about it and hope that their next release will be somewhat improved in this respect....

There is an application to load that operates the Teensy 3.1 as composite USB-CDC and HID keyboard, with a command line menu on the USB virtual COM port and the ability to move to a USB-CDC<->UART-0 brige with end-to-end flow control.

Regards

Mark
 
Back
Top