Tom,
Thanks for the reply. My original question was probably way too broad
and maybe I didn't ask it correctly?
The current setup (see below) uses a startup file written in ARM
assembly (something I'm not well versed in). It sets up various basic
things (like chip settings and sys stack) and then jumps into the C
main function. What I'd like to do is leave the jump to main intact,
but also check nvram for a var and optionally jump to RAM resident FW
update C code.
I don't think this sort thing requires disclosure of anything
proprietary as it should be pretty basic.
Regards,
Jay
Chip:
LPC213x
Build environment:
Keil uVision
Runtime:
Home grown RTOS written in C
RAM:
"C" FW update code (complied in ARM mode).
Gets FW image via i2c (once started this trashes RTOS RAM space)
ARM Startup:
Jump to C main() function.
--- In l..., Tom Walsh wrote:
>
> jaybrinkmeyer wrote:
>
> > Can someone point me at sample /open source code for lpc213x
> > bootloader that branches to FW update or normal C main at startup? I
> > found lots of discussion in the archives, but no example code.
> >
> > Thanks,
> > Jay
> > Yes, and it probably will remain that way, as a discussion and not as
> examples. Mainly due to the unique nature of projects / applications
> and the hardware available / strategy for the loader.
>
> I have a loader which is multipurpose, it can be run from a command
line
> to do the initial programming of the loader into the
LPC2136 and
LPC2138
> chips (host processors). The same source is compiled
under arm-elf-gcc
> (#ifdef __ARM__) to become the resident loader itself. This loader
uses
> the RDCF2 filesystem and SD / miniSD SPI cards to
pull in the images.
> One project only has an LPC2136, another has both an LP2138 and
> LPC2106. In the dual core situation, the resident loader uses the ISP
> calls to program the LPC2106, and IAP to program the host (LPC2138).
> IAP calls are used on the LPC2136 variation.
>
> The loader looks at a memory location in the Application Flash area to
> find a signature, if the signature is there, it simply boots the app.
> With a missing signature, or, a pin grounded to force the programming
> cycle, the resident loader goes through the necessary motions to
program
> the system. The main application within the LPC2136
/ LPC2138 hosts
> will erase their Flash memory block containing the signature bytes,
then
> force a hard reset of the system, when the system
comes up, the
resident
> loader programs the Flash as the signatures are now
missing.
>
> Some (most?) of the people on this list are hobbyists and are eager to
> share their code with you, perhaps one of them would do so. Myself, I
> am a consultant and sell what I write to customers, I am not so
eager to
> dump entire bodies of code I've spend months
perfecting for public
> view. Especially since a Dallas DS2505 security device is integrated
> into that Bootloader...
>
> I would suggest that you sit down, grab a pencil and start mapping out
> where what resides. For my system, the resident bootloader is the
first
> body of code in Flash, it also has 3 4K Flash block
within it for param
> storage, etc. The boot loader occupies 96K, from 0x0..0x17FFF, the
main
> application runs from 0x18000..top of flash.
>
> Concentrate on programming the application area of flash via IAP calls,
> you will probably need an SD card or some other resource for the
image.
> You will need to study and change your linker script
to locate the
> various code sections into their proper areas. You will be writing two
> entirely seperate, autonomous programs for this: bootloader and
> application. For example, this is my linker scripts for one of the
> projects:
>
> ======================= begin RESIDENT.ld =====================>
/***********************************************************************/
> /*
*/
> /* ROM.ld: Linker Script File
*/
> /*
*/
>
/***********************************************************************/
> SEARCH_DIR( ../libs )
> SEARCH_DIR( ./)
>
> ENTRY(_boot)
>
> /* Memory Definitions */
> /* */
> /* Although Flash memory may move up / down, depending, */
> /* the RAM is fixed as to allocation. */
> /* ISP uses: 0x40000120-0x400001ff */
> /* IAP uses: 0x40007fe0-0x40007fff */
> /* IAP also uses up to 128bytes of user stack space. */
> /* */
> /* */
> MEMORY
> {
> BOOTROM (rx) : ORIGIN = 0x00000000, LENGTH = 0x00000fff
> FLASHMEM (wi) : ORIGIN = 0x00001000, LENGTH = 0x00001fff
> ROM (rx) : ORIGIN = 0x00003000, LENGTH = 0x00014fff
> USERROM (rx) : ORIGIN = 0x00018000, LENGTH = 0x100
> RAM (rw) : ORIGIN = 0x40002200, LENGTH = 0x00005D6F
> STACKRAM (rw) : ORIGIN = 0x40007E80, LENGTH = 4
> }
>
> /* Section Definitions */
> SECTIONS
> {
> /* first section is .text which is used for code */
> BOOTCODE :
> {
> crt0.o (.text)
> } > BOOTROM
>
> . = ALIGN(4);
>
> CONFIGS :
> {
> PROVIDE (_usereeprom = .);
> } > FLASHMEM
>
> . = ALIGN(4);
>
> .text :
> {
> PROVIDE (_usereepromend = .);
> *(.text) /* remaining code */
> *(.rodata) /* read-only data (constants) */
> *(.rodata*)
> *(.glue_7)
> *(.glue_7t)
> } > ROM
>
> . = ALIGN(1024);
> _etext = . ;
> PROVIDE (etext = .);
> . = ALIGN(4);
>
> /* .data section which is used for initialized data */
> .data : AT (_etext)
> {
> _data = .;
> *(.data)
> } > RAM
>
> . = ALIGN(4);
> _edata = . ;
> PROVIDE (edata = .);
> . = ALIGN(4);
>
> /* .bss section which is used for uninitialized data */
> .bss (NOLOAD) :
> {
> __bss_start = . ;
> __bss_start__ = . ;
> *(.bss)
> *(COMMON)
> . = ALIGN(4);
> } > RAM
>
> . = ALIGN(4);
> __bss_end__ = . ;
> PROVIDE (__bss_end = .);
>
> _end = . ;
> PROVIDE (end = .);
>
> .stack :
> {
> PROVIDE (_stack = .);
> } > STACKRAM
>
> .usercode :
> {
> PROVIDE (_userboot = .);
> . += 0x20;
> PROVIDE (_usersignature = .);
> . += 0x10;
> PROVIDE (_userchecksum = .);
> . += 4;
> PROVIDE (_userimagelen = .);
> } > USERROM
>
> /* Stabs debugging sections. */
> .stab 0 : { *(.stab) }
> .stabstr 0 : { *(.stabstr) }
> .stab.excl 0 : { *(.stab.excl) }
> .stab.exclstr 0 : { *(.stab.exclstr) }
> .stab.index 0 : { *(.stab.index) }
> .stab.indexstr 0 : { *(.stab.indexstr) }
> .comment 0 : { *(.comment) }
> /* DWARF debug sections.
> Symbols in the DWARF debugging sections are relative to the
beginning
> of the section so we begin them at 0. */
> /* DWARF 1 */
> .debug 0 : { *(.debug) }
> .line 0 : { *(.line) }
> /* GNU DWARF 1 extensions */
> .debug_srcinfo 0 : { *(.debug_srcinfo) }
> .debug_sfnames 0 : { *(.debug_sfnames) }
> /* DWARF 1.1 and DWARF 2 */
> .debug_aranges 0 : { *(.debug_aranges) }
> .debug_pubnames 0 : { *(.debug_pubnames) }
> /* DWARF 2 */
> .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
> .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) }
> .debug_macinfo 0 : { *(.debug_macinfo) }
> /* SGI/MIPS DWARF 2 extensions */
> .debug_weaknames 0 : { *(.debug_weaknames) }
> .debug_funcnames 0 : { *(.debug_funcnames) }
> .debug_typenames 0 : { *(.debug_typenames) }
> .debug_varnames 0 : { *(.debug_varnames) }
> }
> /* Libraries to link against. */
> INPUT( -lc -lstdc -lgcc );
> ============================ snip =========================>
> The above loader is "aware" of the location of the main application
code
> (.usercode) via the way the memory map is described.
That script is
> totally aware of the full system mapping.
>
> ======================== begin APPLICATION.ld ==================>
/***********************************************************************/
> /*
*/
> /* ROM.ld: Linker Script File
*/
> /*
*/
>
/***********************************************************************/
> SEARCH_DIR( ./)
> SEARCH_DIR( ../libs )
>
> ENTRY(_boot)
>
> /* Memory Definitions */
> MEMORY
> {
> ROM (rx) : ORIGIN = 0x00018000, LENGTH = 0x00027fff
> RAM (rw) : ORIGIN = 0x40000210, LENGTH = 0x00007d6f
> STACKRAM (rw) : ORIGIN = 0x40007f80, LENGTH = 4
> }
>
> /* Section Definitions */
> SECTIONS
> {
> /* first section is .text which is used for code */
> .text :
> {
> crt0.o (.text)
> *(.rodata) /* read-only data (constants) */
> *(.rodata*)
> *(.glue_7)
> *(.glue_7t)
> *(.text) /* remaining code */
> } > ROM
>
> . = ALIGN(4);
> _etext = . ;
> PROVIDE (etext = .);
>
> /* .data section which is used for initialized data */
> .data : AT (_etext)
> {
> _data = .;
> *(.data)
> } > RAM
>
> . = ALIGN(4);
> _edata = . ;
> PROVIDE (edata = .);
>
> /* .bss section which is used for uninitialized data */
> .bss (NOLOAD) :
> {
> __bss_start = . ;
> __bss_start__ = . ;
> *(.bss)
> *(COMMON)
> . = ALIGN(4);
> } > RAM
>
> . = ALIGN(4);
> __bss_end__ = . ;
> PROVIDE (__bss_end = .);
>
> _end = . ;
> PROVIDE (end = .);
>
> .stack :
> {
> PROVIDE (_stack = .);
> } > STACKRAM
>
> /* Stabs debugging sections. */
> .stab 0 : { *(.stab) }
> .stabstr 0 : { *(.stabstr) }
> .stab.excl 0 : { *(.stab.excl) }
> .stab.exclstr 0 : { *(.stab.exclstr) }
> .stab.index 0 : { *(.stab.index) }
> .stab.indexstr 0 : { *(.stab.indexstr) }
> .comment 0 : { *(.comment) }
> /* DWARF debug sections.
> Symbols in the DWARF debugging sections are relative to the
beginning
> of the section so we begin them at 0. */
> /* DWARF 1 */
> .debug 0 : { *(.debug) }
> .line 0 : { *(.line) }
> /* GNU DWARF 1 extensions */
> .debug_srcinfo 0 : { *(.debug_srcinfo) }
> .debug_sfnames 0 : { *(.debug_sfnames) }
> /* DWARF 1.1 and DWARF 2 */
> .debug_aranges 0 : { *(.debug_aranges) }
> .debug_pubnames 0 : { *(.debug_pubnames) }
> /* DWARF 2 */
> .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
> .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) }
> .debug_macinfo 0 : { *(.debug_macinfo) }
> /* SGI/MIPS DWARF 2 extensions */
> .debug_weaknames 0 : { *(.debug_weaknames) }
> .debug_funcnames 0 : { *(.debug_funcnames) }
> .debug_typenames 0 : { *(.debug_typenames) }
> .debug_varnames 0 : { *(.debug_varnames) }
> }
> /* Libraries to link against. */
> INPUT( -lc -lstdc -lgcc );
> ======================== snip =============================>
> The application script has a narrow view of the memory map. It does
not
> know about the Flash memory below 0x18000.
>
> FWIW, the linker scripts are the key to building a resident bootloader.
> You have to describe how the memory map structured for you to take
> control of your build process.
> Regards,
>
> TomW
> --
> Tom Walsh - WN3L - Embedded Systems Consultant
> http://openhardware.net, http://cyberiansoftware.com
> "Windows? No thanks, I have work to do..."
> ----------------
>