Skip to content

Releases: lupyuen/pinetime-rust-mynewt

MCUBoot with Vector Table Relocation (Official PineTime Preload)

21 May 09:22
Compare
Choose a tag to compare

Final release of MCUBoot Bootloader for PineTime Preload yay!

Previous Notes

Tested OK with FreeRTOS yay!

Demo video: https://github.com/lupyuen/pinetime-rust-mynewt/releases/download/v4.1.7/mcuboot-freertos.mp4

Set flash-app.ocd to...

program /Users/Luppy/Downloads/jf.bin verify 0x00008000

FreeRTOS firmware jf.bin may be found here: https://github.com/lupyuen/pinetime-rust-mynewt/releases/tag/v4.1.5

Stub Bootloader for Debugging MCUBoot

21 May 00:20
Compare
Choose a tag to compare
Pre-release
v4.1.6

Added semihosting compiler flag

Debugging FreeRTOS + MCUBoot on PineTime

20 May 20:14
Compare
Choose a tag to compare

Download the video here

  1. Generate the disassembly pinetime-app.S from the executable pinetime-app.out...

    arm-none-eabi-objdump -t -S --demangle --line-numbers --wide pinetime-app.out >pinetime-app.S 2>&1
    
  2. Flash the Stub Bootloader boot_stub.elf.bin to address 0x0: https://github.com/lupyuen/pinetime-rust-mynewt/releases/tag/v4.1.6

    This allows the debugger to jump to the application firmware properly, even when the firmware doesn't have a valid MCUBoot Image Header.

  3. For VSCode Debugger, edit .vscode/launch.json and set the executable to be debugged...

    {
        "version": "0.2.0",
        "configurations": [
            {
                "executable": "/Users/Luppy/Downloads/pinetime-app.out",
    
  4. Start the VSCode debugger

  5. Watch the debug video

  6. Function vPortStartFirstTask() in FreeRTOS is executing the Arm instruction SVC 0 (System Call) and it fails

  7. Is it because SCB VTOR Register is pointing to the wrong Interrupt Vector Table?

    See "Special Note to Arm Cortex-M Users": https://www.freertos.org/FAQHelp.html

  8. What is the Interrupt Vector Table? It's a table of pointers to exception and interrupt handlers...

    See http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/BABIFJFG.html

    Usually the table is stored at the start of ROM, at addresses 0x0. Now with the MCUBoot Bootloader we allow each operating system to set their own vector table. Which could be the problem here.

  9. The SCB VTOR Register should point to the Interrupt Vector Table: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0552a/Ciheijba.html

    VTOR Register is located at 0xE000ED08:
    http://infocenter.arm.com/help/topic/com.arm.doc.100166_0001_04_en/ric1417011873697.html

  10. Our VTOR Register at 0xE000ED08 points to 0x20000000, which is the start of RAM:

    x/x 0xE000ED08
    0xe000ed08:	0x20000000
    

    See https://github.com/lupyuen/pinetime-rust-mynewt/releases/download/v4.1.5/Screenshot.2020-05-21.at.4.59.08.AM.png

  11. What's at 0x20000000? Looks like garbage, not an Interrupt Vector Table...

    x/40x 0x20000000
    0x20000000:	0x00000000	0x20000008	0x00000000	0x0004894c
    0x20000010 <impure_data+8>:	0x0004896c	0x0004892c	0x00000000	0x00000000
    0x20000020 <impure_data+24>:	0x00000000	0x00000000	0x00000000	0x00000000
    0x20000030 <impure_data+40>:	0x00000000	0x00000000	0x00000000	0x00000000
    0x20000040 <impure_data+56>:	0x2000bde0	0x00000000	0x00000000	0x00000000
    0x20000050 <impure_data+72>:	0x00000000	0x00000000	0x00000000	0x00000000
    0x20000060 <impure_data+88>:	0x00000000	0x00000000	0x03d09000	0x00000000
    0x20000070 <log_backend_cb_rtt_log_backend+4>:	0x00000100	0x00045a78	0x00043d0c	0x00043d14
    0x20000080 <_ZN8Pinetime12Applications7Screens5Clock10DaysStringE+12>:	0x00043d1c	0x00043d28	0x00043d34	0x00043d3c
    0x20000090 <_ZN8Pinetime12Applications7Screens5Clock10DaysStringE+28>:	0x00043d48	0x00045a78	0x00043cdc	0x00043ce0
    

    See https://github.com/lupyuen/pinetime-rust-mynewt/releases/download/v4.1.5/Screenshot.2020-05-21.at.5.07.27.AM.png

  12. MCUBoot set the VTOR to 0x20000000 at startup, but FreeRTOS doesn't set VTOR. Hence the conflict.

  13. Let's fix VTOR and the Interrupt Vector Table. There is a valid Interrupt Vector Table for FreeRTOS at 0x8020, aliased to __isr_vector...

    x/40x 0x8020
    0x8020 <__isr_vector>:	0x20010000	0x0000870d	0x00008735	0x00008737
    0x8030 <__isr_vector+16>:	0x00008739	0x0000873b	0x0000873d	0x00000000
    0x8040 <__isr_vector+32>:	0x00000000	0x00000000	0x00000000	0x000143bd
    0x8050 <__isr_vector+48>:	0x00008741	0x00000000	0x000143dd	0x00008745
    0x8060 <__isr_vector+64>:	0x00008935	0x00010d91	0x00008747	0x00010d2d
    0x8070 <__isr_vector+80>:	0x0000edf1	0x00008747	0x00008c55	0x00009255
    0x8080 <__isr_vector+96>:	0x00008747	0x00008747	0x00008747	0x00010da9
    0x8090 <__isr_vector+112>:	0x00008747	0x00010d9d	0x00008747	0x00008747
    0x80a0 <__isr_vector+128>:	0x00010db5	0x0001443d	0x00008747	0x00008747
    0x80b0 <__isr_vector+144>:	0x00008747	0x00008747	0x00008747	0x00008747
    

    See https://github.com/lupyuen/pinetime-rust-mynewt/releases/download/v4.1.5/Screenshot.2020-05-21.at.5.59.09.AM.png

  14. Can we just set VTOR to 0x8020? Apparently not, since 0x8020 is not a page-aligned address.

  15. Thus we should set VTOR to 0x20000000

    SCB->VTOR = 0x20000000;

    Then reserve 0xD8 bytes at 0x20000000 for the Interrupt Vector Table, and we should manually copy 0xD8 bytes from 0x8020 to 0x20000000

    memcpy((void *) 0x20000000, (void *) 0x8020, 0xd8);
  16. 0x20000000 is already used by other variables, see https://github.com/lupyuen/pinetime-rust-mynewt/releases/download/v4.1.5/Screenshot.2020-05-21.at.8.08.29.AM.png

    So we need to edit the Linker Script to reserve 0xD8 bytes for a section named .vector_relocation at 0x20000000...

    ...
    __etext = .;
    
    .vector_relocation :
    {
        . = ALIGN(4);
        __vector_tbl_reloc__ = .;
        . = . + (__isr_vector_end - __isr_vector_start);
        . = ALIGN(4);
    } > RAM
    
    .data :
    {
        __data_start__ = .;
        *(vtable)
        *(.data*)
    ...
    

    From https://github.com/apache/mynewt-core/blob/master/hw/mcu/nordic/nrf52xxx/nrf52.ld

    Note that .vector_relocation MUST be the first thing in RAM (0x20000000). It should appear before .data.

  17. For reference, check the vector table relocation code in https://github.com/apache/mynewt-core/blob/master/hw/cmsis-core/src/cmsis_nvic.c

    extern char __isr_vector[];
    extern char __vector_tbl_reloc__[];
    
    void
    NVIC_Relocate(void)
    {
        uint32_t *current_location;
        uint32_t *new_location;
        int i;
    
        /*
         * Relocate the vector table from its current position to the position
         * designated in the linker script.
         */
        current_location = (uint32_t *)&__isr_vector;
        new_location = (uint32_t *)&__vector_tbl_reloc__;
    
        if (new_location != current_location) {
            for (i = 0; i < NVIC_NUM_VECTORS; i++) {
                new_location[i] = current_location[i];
            }
        }
    
        /* Set VTOR except for M0 */
        SCB->VTOR = (uint32_t)&__vector_tbl_reloc__;
    }

MCUBoot with Semihosting Disabled

19 May 19:37
Compare
Choose a tag to compare

PineTime Firmware Update Video

19 May 04:19
Compare
Choose a tag to compare
Pre-release

To download the video, scroll to the end of this page, click Assets then pinetime-dfu.mp4

Refer to the article:
Wireless Firmware Update In Action on PineTime Smart Watch (nRF52)

Mynewt Firmware Update Test

18 May 13:50
Compare
Choose a tag to compare
Pre-release

Testing Firmware Update with 2 versions of Mynewt Firmware: 1.1.0 and 1.2.0

Refer to the articles...

  1. MCUBoot Bootloader for PineTime Smart Watch (nRF52)

  2. Wireless Firmware Update In Action on PineTime Smart Watch (nRF52)

MCUBoot with Firmware Update over Bluetooth

16 May 07:57
Compare
Choose a tag to compare

Contents:

  • mynewt.*: Enhanced Build of MCUBoot Bootloader 1.5.0, supports Boot Graphic and SPI Flash

  • my_sensor_app.*: Application Firmware that supports firmware upgrade over Bluetooth.

  • boot-graphic.bin: Boot Graphic in RGB565 format (Hand-drawn PineTime Logo)

  • pinetime-rust-mynewt.7z: Complete set of build files generated on macOS

Refer to the articles...

  1. MCUBoot Bootloader for PineTime Smart Watch (nRF52)

  2. Wireless Firmware Update In Action on PineTime Smart Watch (nRF52)

Log:

Starting Bootloader...
Displaying image...
Image displayed
Button: 0
[INF] Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
[INF] Scratch: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
[INF] Boot source: primary slot
[INF] Swap type: none
Button: 0
Button: 0
Bootloader done
TMP create temp_stub_0
NET hwid 4a f8 cf 95 6a be c1 f6 89 ba 12 1a 
NET standalone node 
Testing flash...
Read Internal Flash ROM...
Read 0x0 + 20
  0x0000: 0x00 0x00 0x01 0x20 0xd9 0x00 0x00 0x00 
  0x0008: 0x35 0x01 0x00 0x00 0x37 0x01 0x00 0x00 
  0x0010: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 
  0x0018: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 
Read External SPI Flash...
Read 0x0 + 20
  0x0000: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 
  0x0008: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 
  0x0010: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 
  0x0018: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 
Flash OK
Rust test display

MCUBoot with Firmware Update over Bluetooth (Work In Progress)

08 May 13:31
Compare
Choose a tag to compare

Work In Progress: Build of MCUBoot Bootloader 1.5.0 (mynewt.*) and Application Firmware (my_sensor_app.*) that supports firmware upgrade over Bluetooth. Boots OK. Firmware upgrade not tested yet.

pinetime-rust-mynewt.7z contains the complete set of build files generated on macOS

See https://lupyuen.github.io/pinetime-rust-mynewt/articles/dfu

PineTime Firmware with Visual Rust and Mynewt (Raspberry Pi Build)

17 Feb 12:32
Compare
Choose a tag to compare

PineTime Firmware with Visual Rust and Mynewt (macOS Build)

17 Feb 12:34
Compare
Choose a tag to compare