Flashing custom firmware onto SKRV1.4 Board

Hi @maxgerhardt, just an update after attempting to flash the LPC1768 on the SKRV1.4 Board with the LED Blink firmware you provided. So the firmware compiles all fine into a binary file. I converted this to a .hex file for flashing via flashmagic. So then I powered on my SKR board via usb, connected an external LED to Pin0.1 as per the SKR Board’s schematic with a resistor looping back to ground and then attempted to flash the mcu with the firmware. I did this by connecting the SKR board to a USB-UART Serial adapter and putting the board in ISP mode as instructed in this manual I found on GitHub: BTT_SKR_13_14_14T_SD-DFU-Bootloader/bootloader_bin/backed_up_original_bootloaders/SKR V1.4/Guide UART Flash SKR V1.3 or SKR V1.4 or SKR V1.4 TURBO using Windows 10.pdf at main · GadgetAngel/BTT_SKR_13_14_14T_SD-DFU-Bootloader · GitHub. After making sure all my connections were in properly and assigned correctly and watching the flashmagic firmware export load up successfully after putting the board into ISP mode, the LED just never blinked even after I made sure to power cycle it. I then tried uploading the code via the board’s SD card slot, but same issue. I then checked the firmware file on the SD card to see if it had flashed and it remained as a binary file instead of changing to a .CUR file. Although, initially I was getting a .CUR file after attempting to flash an LED blink firmware using the mbed framework on PlatformIO, but still no LED blinking. I suspect why my firmware file is not flashing this time round may have to do with not addressing the firmware correctly to the flash memory of the mcu, as I never applied an offset and it most likely has overridden the custom bootloader at 0x0. Do you reckon that is a plausible conclusion for why it may have not worked on the SD card? However, shouldn’t it still work regardless if you go through the ISP mode? Any insight and suggestions will be greatly appreciated.

You can decide whether you want to keep this SD card bootloader at 0x0 or not.

You just have to be aware of,

  • if you want to keep the bootloader (at 0x0) then you have to know the offset to where the bootloader expects the firmware to live, e.g. 0x4000 (aka 16 kByte), to then use that offset in the linker script of your firmware (or make sure it’s being respected9 as well as flashing the resulting binary to that offset (otherwise you’ll overwrite the bootloader)
  • if you don’t want to keep the bootloader (you can reflash it via ISP at a later time), you can flash the firmware to offset 0x0 while also compiling it for flash offset 0x0.

When you compile the firmware using the

https://github.com/maxgerhardt/pio-nxp-lpc1769-arduino

repo, then you can see through project task → Advanced → Verbose Build, the final linker invocation is

arm-none-eabi-g++ -o .pio\build\nxp_lpc1769\firmware.elf -mthumb --specs=nano.specs --specs=nosys.specs -u_printf_float -flto -mcpu=cortex-m3 -Wl,-TC:\Users\Max\.platformio\packages\framework-arduino-lpc176x\system\CMSIS/system/LPC1768.ld,--gc-sections,--relax .pio\build\nxp_lpc1769\src\main.cpp.o -L.pio\build\nxp_lpc1769 -LC:\Users\Max\.platformio\packages\framework-arduino-lpc176x\system\CMSIS\bin -Wl,--start-group .pio\build\nxp_lpc1769\libCMSIS.a .pio\build\nxp_lpc1769\liblpc176x.a .pio\build\nxp_lpc1769\libFrameworkArduino.a -lc -lgcc -lm -Wl,--end-group

Which uses the linker script

C:\Users\Max\.platformio\packages\framework-arduino-lpc176x\system\CMSIS/system/LPC1768.ld

which says

indeed that the FLASH origin is 16K (0x4000).

So with a firmware compiled this way, your board must have the bootloader flashed at 0x0 and must have the firmware.bin flashed to 0x4000, otherwise it will not work.

If you overwrote the firmware, you should be able to reflash it from the backup .bin or .hex file:

https://github.com/GadgetAngel/BTT_SKR_13_14_14T_SD-DFU-Bootloader/blob/main/bootloader_bin/backed_up_original_bootloaders/SKR%20V1.4/Bootloader/SKRV1.4-Bootloader.zip

When you use the mbed framework with

[env:lpc1768]
platform = nxplpc
board = lpc1768
framework = mbed

You can see that its linker script

C:/Users/Max/temp/pio-nxp-mbed-test/.pio/build/lpc1768/LPC1768.ld.link_script.ld

uses a flash offset

{
  FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 512K
  RAM (rwx) : ORIGIN = 0x100000C8, LENGTH = (32K - 0xC8 - 32)
  USB_RAM(rwx) : ORIGIN = 0x2007C000, LENGTH = 16K
  ETH_RAM(rwx) : ORIGIN = 0x20080000, LENGTH = 16K
}

of 0. Accordingly, you would need to flash the firwmare to 0x0, overwriting the bootloader.

To change that in mbedos, you can create a file mbed_app.json in your project, in which you define (docs, example)

{
    "requires": ["bare-metal"],
    "target_overrides": {
      "*": {
        "target.c_lib": "small",
        "target.printf_lib": "minimal-printf",
        "platform.minimal-printf-enable-floating-point": false,
        "platform.stdio-minimal-console-only": true,
        "target.mbed_app_start": "0x4000"
      }
    }
}

(This also speeds up compilation significantly by not compiling the network stack etc).

Then the generated linker script should look like

MEMORY
{
  FLASH (rx) : ORIGIN = 0x4000, LENGTH = 0x7c000
  RAM (rwx) : ORIGIN = 0x100000C8, LENGTH = (32K - 0xC8 - 32)
  USB_RAM(rwx) : ORIGIN = 0x2007C000, LENGTH = 16K
  ETH_RAM(rwx) : ORIGIN = 0x20080000, LENGTH = 16K
}

Thus you could flash that firmware again to 0x4000 with the bootloader present.

Thanks so much for this amazing insight, really appreciated! This makes sense, as I had initially used the mbed framework and had not modified the linker script as you have mentioned and so I most likely have overridden my board’s bootloader at 0x0 with the firmware I tried flashing also at 0x0. I will give the arduino and mbed frameworks a go by applying the linker script and flashing address offsets and fingers crossed it works.

I did want to just clarify one thing though. You said that if I did not want to keep the bootloader, I could flash the firmware to offset 0x0 while also compiling it for flash offset 0x0. However, how can a firmware be flashed to the mcu without having a bootloader present? My understanding this is only possible through the ISP mode? Please correct me if I’m wrong.

Cheers.

The “ISP” mode of the LPC1768 microcontroller is completely independent of whatever is programmed into flash. It is engrained into the chip itself. The entire flash of the microcontroller can be erased, and you will still be able to program it via the ISP mode, as well as over JTAG / SWD.

The “bootloader” in flash is essentially just a mini application that accepts a firmware via some mean and loads it.

Great thanks for clarifying. Unfortunately, after tying to reflash the .hex file of the SKR board’s bootloader to 0x0 using FlashMagic and then loading your compiled Arduino based LED Blink firmware onto the board with SD card, I have been unsuccessful at getting the externally wired LED to blink. I have made sure to power cycle the board by holding the Reset button after inserting the SD card and I just don’t see any response and still not seeing the firmware.bin file change to a firmware.CUR file as it would initially do when I first tried flashing firmware onto the board. My LED is on fine so the circuit should be all fine and seems to be a firmware issue.

I then went on to try flashing the firmware via flashmagic to see if that might work but still nothing executes. The booting finishes loading and you can see it loads from start to end address but it just doesn’t blink after your power off and back on. For this I made sure the start address to load the firmware onto was 0x00004000 and end was 0x0007BFFF. Likewise, when I flashed the bootloader onto the board using flashmagic, I made sure to select erase for sectors used by file only and even specified the start address as being 0x00000000 and end being 0x00003FFF as specified in the board’s bootloader documentation. I haven’t moved onto try the mbed framework as it seems pointless and I’m either clearly doing something wrong using flashmagic or the board is damaged. I have been using a FT232RL USB to Serial UART Module and wired it to my board and followed the steps exactly how the manual shows in this github page: BTT_SKR_13_14_14T_SD-DFU-Bootloader/Guide UART Flash SKR V1.3 or SKR V1.4 or SKR V1.4 TURBO using Windows 10.pdf at main · GadgetAngel/BTT_SKR_13_14_14T_SD-DFU-Bootloader · GitHub

One thing to note is my SKR board doesn’t get recognised by my laptop’s USB drivers whenever I plug it in. Could this perhaps have anything got to do with my firmware execution issues? I have seen in tutorials online that whenever the board is plugged, it will at least make some sort of sound and appear in the board’s com ports. This is even the case when I have set the power jumper to USB instead of VDD, where the board is able to be powered by my PC but doesn’t get recognised by the driver.

Appreciating the help,
Cheers.

Mhm. I think it’s best to get a debugging probe like an ST-Link or CMSIS-DAP connected to the NXP chip’s SWDIO + SWCLK to see the firmware execution instruction by instruction. It could be something trivial like a wrong clock initialization in the Arduino core (which may not be present in the mbed code) or something else that is not immediately apparent.

Thanks for the suggestion @maxgerhardt, I’ll give that a go then and may also just give the mbed framework and modify its linker script to include a flash offset considering you suspect there could be a wrong clock initialisation in the Arduino core that may not be present in the mbed code. However, just confirming, my board not being recognised by any USB driver doesn’t suggest there is anything wrong with the board right and my firmware should still be flashing regardless?