Hi All
The uTasker project now supports also the popular Teensy 4.0 (i.MX RT 1062).
The following is a boot loader that can be installed on the Teensy 4.0:
https://www.utasker.com/iMX/Teensy_4.html
to allows it to load new code via USB-MSD, serial SREC (on LPUART3), using NXP's Kboot USB-HID tool or from an SD card.
It is AES256 encrypted in QSPI flash and also the new code loaded via the loading methods can be AES256 encrypted so that no one can reverse engineer it by reading it from the QSP flash.
There is a reference application that can be tested (in plain text and AES256 encrypted forms, whereby the loader accepts both) that demonstrates USB-MSD and USB-CDC composite HW USB device and SD card operation (when there is an SD card socket mounted) allowing the Teensy 4 to operate as a pen drive to a USB host with access to the SD card. Furthermore it always appears as a second hard drive to the PC with emulated FAT content that shows snap shots of the complete QSPI flash content, the instruction RAM content and the data RAM content.
On the USB-CDC interface (and on LPUART3 at 115'200Baud) there is a command line menu which supports various commands, such as a DOS like command line interface to the SD card, commands to view, write and erase data in the QSPI flash, command ports and save parameters to an area of QSPI flash. It allows commanding a LPUART3 to USB-CDC bridge, etc. etc.
The loader is usable with Teensyduino or SDK projects by linking the project code to the address 0x00000300 (for execution in instruction RAM) - interrupt vectors are to be copied by the code to the instruction RAM area beginning at 0x00000000. The image can be optionally AES256 encrypted by using the uTaskerConvert utility at https://www.utasker.com/forum/index.php?topic=1445.0 to securely protect it when distributing new firmware versions.
The boot loader also dynamically partitions the FlexRAM in the i.MX RT 1062 to suit the application size (allocating just enough banks to fit the application in instruction memory and allocating all remaining ones to data memory). This achieves maximum performance since code and data are accessed at full speed without wait states. The QSPI flash is powered down when not used by parameters or file system and so optimal power consumption, with no radiation due to external QSPI code accesses once running.
Regards
Mark
[uTasker project developer for Kinetis and i.MX RT]
Hi Mark
Many thanks for access to the dev repo. We're having a little difficulty using with the Teensy 4.0 that you might be able to shed some light on.
TLDR; Cannot load a regular teensy file to the bootloader
Background: The project is using two i.MX RTs - one a the main control and user interface processor and the second controlling four TI DSPs. The design goal for uTasker if to provide bootloader with highly secure field upgradeability - first processor with USB HOST capability, the second bootloader running over i2c. For test and prototyping purposes, we're using two teensy 4.0s.
We have successfully built all parts of the repo but as we encountered difficulties we have simplified until the problem is resolved. Setup is now a single teensy 4.0, programmed with the bootloader linked in your post above, using the USB-MSD to 'drag&drop' a compiled teensy hex file (Blinky of course!). From the code and docs, we believe this is a valid use case. Obviously, the real aim is for target id and encryption - baby steps!
The teensy code is linked with the following script:
MEMORY
{
VITCM (rwx): ORIGIN = 0x0, LENGTH = 0x2FF
ITCM (rwx): ORIGIN = 0x300, LENGTH = 0x80000-0x300
DTCM (rwx): ORIGIN = 0x20000000, LENGTH = 512K
RAM (rwx): ORIGIN = 0x20200000, LENGTH = 512K
FLASH (rwx): ORIGIN = 0x60000000, LENGTH = 1984K
}
ENTRY(ImageVectorTable)
SECTIONS
{
.vectorsram : {
. = ALIGN(1024);
} > VITCM
.text.progmem : {
KEEP(*(.flashconfig))
FILL(0xFF)
. = ORIGIN(FLASH) + 0x1000;
KEEP(*(.ivt))
KEEP(*(.bootdata))
KEEP(*(.vectors))
KEEP(*(.startup))
*(.flashmem*)
*(.progmem*)
. = ALIGN(4);
KEEP(*(.init))
__preinit_array_start = .;
KEEP (*(.preinit_array))
__preinit_array_end = .;
__init_array_start = .;
KEEP (*(.init_array))
__init_array_end = .;
. = ALIGN(16);
} > FLASH
.text.itcm : {
. = . + 32; /* MPU to trap NULL pointer deref */
*(.fastrun)
*(.text*)
. = ALIGN(16);
} > ITCM AT> FLASH
.ARM.exidx : {
__exidx_start = .;
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
__exidx_end = .;
} > ITCM AT> FLASH
.text.itcm.padding (NOLOAD) : {
. = ALIGN(32768);
} > ITCM
.data : {
*(.rodata*)
*(.data*)
. = ALIGN(16);
} > DTCM AT> FLASH
.bss ALIGN(4) : {
*(.bss*)
*(COMMON)
. = ALIGN(32);
. = . + 32; /* MPU to trap stack overflow */
} > DTCM
.bss.dma (NOLOAD) : {
*(.dmabuffers)
. = ALIGN(32);
} > RAM
_stext = ADDR(.text.itcm);
_etext = ADDR(.text.itcm) + SIZEOF(.text.itcm) + SIZEOF(.ARM.exidx);
_stextload = LOADADDR(.text.itcm);
_sdata = ADDR(.data);
_edata = ADDR(.data) + SIZEOF(.data);
_sdataload = LOADADDR(.data);
_sbss = ADDR(.bss);
_ebss = ADDR(.bss) + SIZEOF(.bss);
_heap_start = ADDR(.bss.dma) + SIZEOF(.bss.dma);
_heap_end = ORIGIN(RAM) + LENGTH(RAM);
_itcm_block_count = (SIZEOF(.text.itcm) + SIZEOF(.ARM.exidx) + 0x7FFF) >> 15;
_flexram_bank_config = 0xAAAAAAAA | ((1 << (_itcm_block_count * 2)) - 1);
_estack = ORIGIN(DTCM) + ((16 - _itcm_block_count) << 15);
_flashimagelen = SIZEOF(.text.progmem) + SIZEOF(.text.itcm) + SIZEOF(.ARM.exidx) + SIZEOF(.data);
_teensy_model_identifier = 0x24;
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
}
This places code from 0x300 and the ram interrupt vector table at 0x00 - the startup code then copies the ivt from flash to ram. We think this is what you were indicating in your post above.
Link output:
'Building target: Blink'
'Printing size:'
"C:/Program Files (x86)/Arduino/hardware/teensy/../tools/arm/bin/arm-none-eabi-size" -A Blink.elf
Blink.elf :
section size addr
.vectorsram 704 0
.text.progmem 5920 1610612736
.text.itcm 5136 768 <== 0x300
.fini 4 5904
.text.itcm.padding 26860 5908
.data 800 536870912
.bss 8096 536871712
.bss.dma 12384 538968064
.ARM.attributes 46 0
.comment 110 0
.debug_info 92343 0
.debug_abbrev 12628 0
.debug_line 14508 0
.debug_frame 3532 0
.debug_str 22807 0
.debug_loc 17327 0
.debug_aranges 1544 0
.debug_ranges 2008 0
Total 226757
Top of memory map:
.vectorsram 0x00000000 0x2c0
0x00000000 . = ALIGN (0x400)
.vectorsram 0x00000000 0x2c0 /arduino.ar(startup.c.o)
0x00000000 _VectorsRam
.text.progmem 0x60000000 0x1720
*(.flashconfig)
.flashconfig 0x60000000 0x200 /arduino.ar(bootdata.c.o)
0x60000000 FlexSPI_NOR_Config
FILL mask 0xff
0x60001000 . = (ORIGIN (FLASH) + 0x1000)
*fill* 0x60000200 0xe00 ff
*(.ivt)
.ivt 0x60001000 0x20 /arduino.ar(bootdata.c.o)
0x60001000 ImageVectorTable
*(.bootdata)
.bootdata 0x60001020 0xc /arduino.ar(bootdata.c.o)
0x60001020 BootData
*(.vectors)
.vectors 0x6000102c 0x8 /arduino.ar(bootdata.c.o)
0x6000102c vector_table
*(.startup)
.startup 0x60001034 0x234 /arduino.ar(startup.c.o)
0x60001034 ResetHandler
|
.text.itcm 0x00000300 0x1410 load address 0x60001720
0x00000320 . = (. + 0x20)
*fill* 0x00000300 0x20
*(.fastrun)
*(.text*)
.text 0x00000320 0x5c /armv7e-m/fpu/fpv5-d16/crtbegin.o
So the questions: Have we correctly setup the linker to comply with the uTasker bootloader requirements. When we try to upload the code (dropping it onto the upload 'drive') it just sits there and is ignored by the loader. The code, if prgrammed as usual, runs perfectly. We have tried outputting srec and then using the uTaskerConvert tool to tag the file with application magic number and key but no joy.
Any advice gratefully received. We'd like to see this work prior to licencing to confirm it will meet our needs.
Many thanks
Pablo-
Hi Pablo
I see that you want to run your code in XiP mode (directly from QSPI flash) but I see that you are linking it to the start of the QSPI flash, where the boot loader resides. Since this is an illegal address the code that you copy is being ignored.
Therefore you need to link the code to 0x60020200 rather than 0x60000000 to resolve this issue.
Use the linker script file \Applications\uTaskerV1.4\GNU_iMX\iMX_RT_10XX_FlexSPI_NOR_XIP.ld as a general reference to this setup.
Also use \Applications\uTaskerV1.4\GNU_iMX\Build_iMX_RT.bat as a reference to creating authentication headers, encrypting your application and combining your application with the loaders for single-step production programming (just remove the call to make and adjust paths to suit).
Note that the step of interest for non-encrypted XiP is
uTaskerConvert.exe uTaskerV1.4.bin Objects/uTaskerV1.4_XiP_%iMX_RT%.bin +boot_header.txt -0x2%MAGIC% -%AUTHENTICATION%
(replacing with a Teensy reference and expanded it is something like uTaskerConvert.exe TeensyApplication.bin Objects/TeensyApp_Uploadable.bin +boot_header.txt -0x2234 -a748b6531124)
I would use the loaders that you built with the latest repository since the linked ones are older versions that don't support full features and may not be fully compatible with the latest guides. They work with the references application that go with them but are not maintained as the repository is.
For full details use https://www.utasker.com/docs/iMX/MCUXpresso.pdf and https://www.utasker.com/docs/iMX/GCC.pdf which both are GCC based, as is TeenysDuino.
Use a copy of \Applications\uTaskerV1.4\GNU_iMX\boot_header.txt (it is used to ensure that code is padded correctly to allow correct operation with all GCC libraries and applications, irrespective of their use of interrupt vectors and code alignments).
Good luck
Regards
Mark
Thanks for your sharing!
Hi All
Also the Teensy 4.1 (adding SD card and Ethernet, via Ethernet Kit, to the Teensy 4.0) is now supported:
https://www.utasker.com/iMX/Teensy_4_1.html
The demonstration hex file allows USB and Ethernet operations (Telnet, FTP, Web server, IGMP, etc.) and includes secure OTA (Ethernet) and serial loading (USB-MSD) and Teens 4.1 users can simply make use of the loader concept for reliable field uploading, with clone and IP protection to simply run existing Teensy 4.1 project code in XiP or on-the-fly decrypted XiP with no additional effort.
Regards
Mark
[uTasker project developer for Kinetis and i.MX RT]
Contact me by personal message or on the uTasker web site to discuss professional training, solutions to problems or rapid product development requirements
For professionals searching for faster, problem-free Kinetis and i.MX RT 10xx developments the uTasker project holds the key: https://www.utasker.com/Teensy_4_1.html