PlatformIO Community

How do I set my start offset(Bootloader)


#1

So my development board’s original guide is for keil.
it says to make it start at 0x00001FF and set NO_CPR as conditional assembly symbols.

any idea how to do that in this software? it looks so confusing i just installed it…


#2

What exact board, where is the manual, where is your code?


#3

I have no code in mind right now. I just want to get started with a blinky perhaps. it’s been 2 years since I last coded. the board is an Iranian custom made board from an electronics shop. stm baords are insanely expensive here. it came with the schematics and all. since it’s in persian if you’re intrested in any spicific thing I can translate it but honestly that’s all it says. it included a lot of example keil projects but again nothing on how to use it in other IDEs


#4

If it’s an STM chip I suggest using any of the available normal frameworks (Arduino, STM32HAL, mbed-os) instead trying to do a bare-metal project. I’ve never heard of a NO_CPR register or something and google yields 0 results for "NO_CPR" stm32.

What chip does the board have? Are you programming it via SWD and a ST-Link probe? Can you upload the schematics?


#5

when I plug the board to my PC it reads as a USB flash drive. I paste the .hex there and unplug it. maybe I should save for a proper stm board. they’re very expensive sadly :frowning: any recommendations? I think an m3 is enough for a noob like me :slight_smile:


#6

If it’s a flash drive it probably has a DAP-Link debug probe on board or the chip opens up a file system. I think your board is fine, you just have to show me the board schematics and I can tell you what how to create a project for it.


#7

Sure! thank you for helping me :slight_smile: here are both the schematic files I found on the drive. I think the (REV_C) file is the optional board that it plugs into that has all sorts of buttons LCD inputs etc. BUt I uploaded it just in case. it functions just as well without that board (I didn’t have it at first in fact)

Schematic
rev_c file


#8

Do you use PlatformIO from Visual Studio Code or from the commandline?


#9

Anways your board has a LPC1768 and a LED on pin P1.18. PlatformIO supports this board as the lpc1768 / NXP mbed LPC1768 board.

You should create a new project (see here) for the ‘NXP mbed LPC1768’, then create the src\main.cpp file and write

#include <mbed.h>
#include <PinNames.h>

DigitalOut led(P1_18);

int main() {
	while(1) {
		led = !led;
		wait_ms(500);
	}
	return 0;
}

You can also set the macro NO_CRP as this manual says by adding

build_flags = -D NO_CRP

at the end of the platformio.ini.

But we also need to change the RAM ( IRAM1) and FLASH (IROM1) offsets according to the manual (why is this necessary? no idea…) This is done by a custom linker script found at the bottom. Save it to some path on your computer.

The whole platformio.ini is then:

[env:lpc1768]
platform = nxplpc
board = lpc1768
framework = mbed
build_flags =
	-D NO_CRP
	-Wl,-TC:/Users/Maxi/Desktop/lpc/custom_lpc1768.ld

You need to change the path C:/Users/... to the path where you have downloaded the linker script. It must be an absolute path.

You should then try to just press the upload the button, it will try CMSIS-DAP. If that doesn’t work try adding upload_protocol = mbed to make it place the firmware.bin on the microcontroller. If that still doesn’t work, you can go into your project folder under .pioenvs\lpc1768\firmware.bin, there is the firmware file which you can drag on the USB drive.

custom_lpc1768.ld

STACK_SIZE = 4096;
MEMORY
{
  FLASH (rx) : ORIGIN = 0x00002000, LENGTH = 512K
  RAM (rwx) : ORIGIN = 0x10000000, LENGTH = (32K - 32)
  USB_RAM(rwx) : ORIGIN = 0x2007C000, LENGTH = 16K
  ETH_RAM(rwx) : ORIGIN = 0x20080000, LENGTH = 16K
}
ENTRY(Reset_Handler)
SECTIONS
{
    .text :
    {
        KEEP(*(.isr_vector))
        . = 0x000002FC ;
        KEEP(*(.CRPSection))
        *(.text*)
        KEEP(*(.init))
        KEEP(*(.fini))
        *crtbegin.o(.ctors)
        *crtbegin?.o(.ctors)
        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
        *(SORT(.ctors.*))
        *(.ctors)
        *crtbegin.o(.dtors)
        *crtbegin?.o(.dtors)
        *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
        *(SORT(.dtors.*))
        *(.dtors)
        *(.rodata*)
        KEEP(*(.eh_frame*))
    } > FLASH
    .ARM.extab :
    {
        *(.ARM.extab* .gnu.linkonce.armextab.*)
    } > FLASH
    __exidx_start = .;
    .ARM.exidx :
    {
        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
    } > FLASH
    __exidx_end = .;
    __etext = .;
    .data : AT (__etext)
    {
        __data_start__ = .;
        Image$$RW_IRAM1$$Base = .;
        *(vtable)
        *(.data*)
        . = ALIGN(8);
        PROVIDE (__preinit_array_start = .);
        KEEP(*(.preinit_array))
        PROVIDE (__preinit_array_end = .);
        . = ALIGN(8);
        PROVIDE (__init_array_start = .);
        KEEP(*(SORT(.init_array.*)))
        KEEP(*(.init_array))
        PROVIDE (__init_array_end = .);
        . = ALIGN(8);
        PROVIDE (__fini_array_start = .);
        KEEP(*(SORT(.fini_array.*)))
        KEEP(*(.fini_array))
        PROVIDE (__fini_array_end = .);
        . = ALIGN(8);
        __data_end__ = .;
    } > RAM
    .bss :
    {
        __bss_start__ = .;
        *(.bss*)
        *(COMMON)
        __bss_end__ = .;
        Image$$RW_IRAM1$$ZI$$Limit = . ;
    } > RAM
    .heap :
    {
        __end__ = .;
        end = __end__;
        *(.heap*)
        . = ORIGIN(RAM) + LENGTH(RAM) - STACK_SIZE;
        __HeapLimit = .;
    } > RAM
    .stack_dummy :
    {
        *(.stack)
    } > RAM
    __StackTop = ORIGIN(RAM) + LENGTH(RAM);
    __StackLimit = __StackTop - STACK_SIZE;
    PROVIDE(__stack = __StackTop);
    ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
    .AHBSRAM0 (NOLOAD):
    {
        Image$$RW_IRAM2$$Base = . ;
        *(AHBSRAM0)
        Image$$RW_IRAM2$$ZI$$Limit = .;
    } > USB_RAM
    .AHBSRAM1 (NOLOAD):
    {
        Image$$RW_IRAM3$$Base = . ;
        *(AHBSRAM1)
        Image$$RW_IRAM3$$ZI$$Limit = .;
    } > ETH_RAM
}

#10

The reason for the changed start offset is very likely that the chip has been programmed with its own custom bootloader (at 0x0), so we should not overwrite it if we want to keep programing the board via USB. See http://www.keil.com/support/docs/3876.htm. The problem is that the startup file in the mbed Framework doesn’t use the NO_CRP macro, it doesn’t touch CRP. Some other startup files do (example). So it could be that the device can be programmed only once via USB. I would just buy a JTAG programmer (example J-Link) and progarm the board normally without a special bootloader or changed offsets.


#11

This is very late but THANKS IT WORKS :slight_smile:
Is there a way I can avoid the mbed and use just native code or cmsis or whatever? i ahve no idea what to choose as a beginner. MBED seems to be spicific to a spicific board.


#12

there’s this cheap segger (probably a fake) v8 jlink. would that be good enough? can’t find much info…


#13

I sent you a ebay link above for a JLink programmer. Although, when I think about it, the chip should be capable of being programmed via SWD, so you might even be able to use a ST-Link to do it? (It’s not restricted to STM32 chips, I’ve also programmed a Realtek and a Nordic nRF52 chip with it)