I got the code USB secondary ISP bootloader for LPC23xx from NXP working fine with none RTX kernel but It does not working with RTX kernel. If anyone know more detail please help.
Thank you.
Hi noom noise, I had the same problem on lpc2378. I've made my project work with non-RTX bootloader and my RTX project. I'll try to explain what I've donne:
1. Bootloader project is the one from NXP site: www.standardics.nxp.com/.../an10759.zip
All values in the bootloader project are at their default. Just unpack USBMem folder. Leave the other one. Alas, no RTX there. Compile, Flash->Erase, Flash->Download. A window displaying your device as mass storage device under windows should appear at your screen.
2. In my RTX project I've changed following:
A) Project->Options for target->Target: IROM1 start:0x2000 size:0x7E000. (from 0x0 to 0x1FFF is bootloader) (size = IROM1_size - 0x2000)
IRAM1 start:0x40001000 size:0x7000 (I was playing with bootloader IRAM1_size. And in my case, bootloader needs somewhere around 0xDFF of RAM. So in order not to overlap it's area, my IRAM1 starts at 0x40001000. Moshe Tal suggested 0x40000100 for his lpc2368 - not enough in my case. Try playing with IRAM1_size in bootloader project to determine your minimum...)
B) Project->Options for target->Linker: Misc.controls: --entry 0x2000 (that is of course, where your IROM1 starts)
C) Project->Options for target->User: Run user programs after build/rebuild: fromelf --bin .\out\my_project.axf -o .\out\firmware.bin (that way firmware.bin will be created, which you can copy to the device from PC over USB)
D)Project->Options for target->Output: check create hex file
E) Right click on your startup file: options->Asm->ConditionalAssembyControSymbols: RAM_INTVEC REMAP RAM_MODE ( This is Keil's description of what should happen: ; * RAM_INTVEC: when set the startup code copies exception vectors ; * from on-chip Flash to on-chip RAM. ; * ; * REMAP: when set the startup code initializes the register MEMMAP ; * which overwrites the settings of the CPU configuration pins. The ; * startup and interrupt vectors are remapped from: ; * 0x00000000 default setting (not remapped) ; * 0x40000000 when RAM_MODE is used ; * 0x80000000 when EXTMEM_MODE is used ; * ; * EXTMEM_MODE: when set the device is configured for code execution ; * from external memory starting at address 0x80000000. ; * ; * RAM_MODE: when set the device is configured for code execution ; * from on-chip RAM starting at address 0x40000000. )
F) Finally, I had to Copy my interupt vector table from declared beginning of my application's IROM1 to the actuall beginning of IROM1: Put this at the beginning of your RTX's main(): memcpy((char *)0x00000000, (char *)(0x00002000), 64);
(it seems that even though I used remapping (step E), code always jumps to IVT of the bootloader, that is, from 0x0..., so not exactly what you may expect after remaping to RAM... And thats why I had to copy my IVT from 0x2000 to 0x0).
G) I also had some problems with interrupts which were happening before my RTX-application's main(). I was debugging something with interrupt driven UART before the main(). When I cleared those printf functions, everything worked well. So maybe it would be wise to disable interrupts before your main()...
Also, just to mention, as RTX uses SWIs, I have SWI_Table.s file included in my RTX project.
And that's all I had to do. My RTX application works perfectly with non-RTX bootloader that NXP supplied.
NOTE: Here I have one MCB2300 board whith lpc2378 revision '-' on it. There was no chance to make the bootloader work with it. Not even with MAM disabled. I made it work only on my prototype which uses revision 'B' of lpc2378... So if you are not using revision 'B', maybe that could be the problem... Although I'm not quite shure...
I hope this helps...
Just to make this easier, I uploaded this bootloader packed with simple RTX application which uses serial port 1 at baud rate 115200.
It prints some test messages, and then loops in "init_task" to echo input from keyboard...
Here is rapidshare link: rapidshare.com/.../non_RTX_bootloader_with_RTX_application_for_lpc2378.rar
Link will be active for 90 days from now as I understood from rapidshare...
Predrag,
I almost never do this, but I had a look at the code you posted. I am afraid that I do not understand why your application does this:
memcpy((char *)0x00000000, (char *)(0x00002000), 64);
maybe I missed something, but are you not trying to write into internal flash here...? if you are trying to remap interrupt vectors, well, then you can use the facilities of the startup file of the RTX application by the macros
RAM_INTVEC REMAP RAM_MODE
or do this in the bootloader:
<code to disable interrupts> memcpy((char *)0x40000000, (char *)(0x00002000), 64); MEMMAP = 2 ; <code to enable interrupts>
now I have a small question: what will you do if your bootloader needs to jump to a software components that remaps the vectors, which then jumps to your RTX application...?
You don't need the file SWI_Table.s in your project at all. you only need it if you want to implement your own SWIs.
Thanks Tamir,
I quite agree that instead of
there should be
memcpy((char *)0x40000000, (char *)(0x00002000), 64);
That was leftover after experimenting a milion times :)....
But this is what I don't understand: You said that I should use either:
or:
But in my case, I do use
but I also have to copy vectors manually. Nothing works if i do not copy IVT manually.
In other words, "RAM_INTVEC REMAP RAM_MODE" does the remapping, but doesn't copy the interupt vector table as I would expect it...
Or are you saying that "RAM_INTVEC REMAP RAM_MODE" should move IVT and there is no need to do this manually?
that is exactly what I am saying. an application that uses these macros, makes its startup file copy the vectors and set MEMMAP for it (have a look in the startup file - search for 'memmap'). this should be done in the application. however, you can do the mapping manually in the bootloader instead - using memcpy and MEMMAP. about my question: if you have a piece of code (bootloader) than jumps to software that is intended to handle interrupts, that jumps in its turn to an RTX application (no interrupts handling intended here), then the handling will be a little different: the mid section will use the macros to remap the interrupt vectors, but the startup file of the application must do something like this:
LDR R0,=RAM_BASE+0x28 LDR R1, =SWI_Handler STR R1, [R0]
to copy the SWI handler of application to the internal memory - otherwise RTX will not start. this arrangement makes sure all interrupts but the SWI will be handled in the mid section software. just one more comment: too bad you posted and never correct code that is clearly misleading...
Corrected version of above file is: rapidshare.com/.../non_RTX_bootloader_with_RTX_application_for_lpc2378.rar (This works with new RTX (from v3.40) of uVision). Old version is deleted from rapidshare.
Please note that in my case (in this example)
ASM option for startup file does not remap IVT as Tamir Michael suggested. I have to say
(see __rt_entry...)
This is part of startup file that has to do with those macros:
; Memory Mapping (when Interrupt Vectors are in RAM) MEMMAP EQU 0xE01FC040 ; Memory Mapping Control IF :DEF:REMAP LDR R0, =MEMMAP IF :DEF:RAM_MODE MOV R1, #2 ELSE MOV R1, #1 ENDIF STR R1, [R0] ENDIF
So uVision generated REMAP and RAM_MODE, but not a RAM_INTVEC part... And I guess that this is the reason why vectors are not remapped as in Tamir's case, but have to be copied manually in my case...
wait a minute. the following instructions should reside in your startup file, just above the code you quoted:
; Copy Exception Vectors to Internal RAM --------------------------------------- IF :DEF:RAM_INTVEC ADR R8, Vectors ; Source LDR R9, =RAM_BASE ; Destination LDMIA R8!, {R0-R7} ; Load Vectors STMIA R9!, {R0-R7} ; Store Vectors LDMIA R8!, {R0-R7} ; Load Handler Addresses STMIA R9!, {R0-R7} ; Store Handler Addresses ENDIF
I am using the remapping macros without a problem.
Exactly, that is missing! I copied this file from Keil... RAM_BASE, is undefined in my project. Can you please tell me from where did you copy your .s file? This one is Keil's, but is obviously missing something...
if you look at the lastest released LPC2400.s, line 61 looks like this:
RAM_BASE EQU 0x40000000
don't forget to bless your "rapidshare" clients with your findings :-)
Ave, Tamir!
This gave me a lot of headache! Startup file when I started my project was 20k. Today it is 37k. I jus needeed to copy .s file from "Keil\ARM\Startup\Philips\" to my project over old one and now everything is defined. I've read a bunch of documents searching why those macros won't work :)
Thanks once more!
You're welcome.
This is the final version of the example, all works as it should:
rapidshare.com/.../non_RTX_bootloader_with_RTX_application_for_lpc2378.rar
(all other links from above are deleted...)
I found more problem with startup file when running after bootloader, that required workaround. In startup file (LPC2300.S) there is code that setup stacks for each ARM mode. To do that the program is trying to enter each mode with MSR instruction and changing the value of SP (stack) register.
But, after bootloader this code will not work, and all special mode stacks will remain as setup by the boot loader, and probably will overwrite program memory every time the ARM enter to special mode (For example - every IRQ call and every task switching).
This problem seem to occurs because MSR instruction (switch ARM mode) doesn't work when ARM is in User mode, only when ARM in special (supervisor) mode.
After ARM reset the MCU run in Supervisor mode, so this code run well. but after bootloader the ARM run in User mode.
My solution was to force ARM to enter supervisor mode before running stacks setup code by calling to SWI. This require changing of SWI vector, that was easy after remapping vector table to RAM.
Here the updated code:
; Setup Stack for each mode ---------------------------------------------------- ; Stack setup code will not run when MCU in User mode ; as occur when this code run after secondary boot loader ; The following code will do fake calling to Software interrupt to enter Supervisor mode ; so stacks init code will work properly. SWI_RAM_ADDR EQU 0x40000028 LDR R8, =SWI_RAM_ADDR ; LDR R7, [R8] ;Save SWI_Handler address LDR R9, =Stack_Set_Addr STR R9, [R8] ;Replace SWI_Handler (for next command) with Stack_Set_Addr SWI 11 ;Just jump to Stack_Set_Addr in Supervisor mode Stack_Set_Addr DCD Stack_Setup Stack_Setup STR R7, [R8] ;Restore SWI_Handler address ;End of edit LDR R0, =Stack_Top
yes you are right - of the jump to the application can be done in a SWI function.