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-