Hi all,
I use the LPC2138 microcontroller, I programmed it with a hex file using ISP commands and it went well.
When I tried to read the contents of the flash at the address 0x0000 0000 it returns me a result different from what I expected,
I know that the first 64 bytes are re-mapped to the flash boot sector and what I got is apparently the bootloader code, but how I do so that I receive the contents of the address 0x0000 0000 of my code.?
Best Regards,
Hmissa
Solved! Go to Solution.
Hi,
I found the solution:
you must inject the code below into the RAM and execute it in ARM mode before reading the first 64 bytes of the Flash.
static unsigned char remap_code[] =
"\x0c\x00\x9f\xe5" //ldr r0, [pc, #0xc]
"\x01\x10\xa0\xe3" //mov r1, #1
"\x00\x10\x80\xe5" //str r1, [r0]
"\x0e\xe0\x81\xe1" //orr lr, r1, lr
"\x1e\xff\x2f\xe1" //bx lr
"\x40\xc0\x1f\xe0"; //ands ip, pc, r0, asr #32
Best Regards,
Hi, Thanks for your reply, but I honestly haven't figured out how to find the user application code entry point.
Please could you explain to me clearly?
Best Regards
Hi,
pls go to the link and download "
After you unzip the file, pls refer to the directory:
.....\SC_LPC213X_LPC214X_PERIPHERALS_USING_ARM_REALVIEW\RVDK\Common\src
and open the startup.s
I copy part of it.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Reset
LDR PC, ResetAddr
LDR PC, UndefinedAddr
LDR PC, SWI_Addr
LDR PC, PrefetchAddr
LDR PC, DataAbortAddr
DCD 0xb9205f80
LDR PC, [PC, #-0x0ff0]
LDR PC, FIQ_Addr
ResetAddr DCD ResetInit
UndefinedAddr DCD Undefined
SWI_Addr DCD SoftwareInterrupt
PrefetchAddr DCD PrefetchAbort
DataAbortAddr DCD DataAbort
Nouse DCD 0
IRQ_Addr DCD 0
FIQ_Addr DCD FIQ_Handler
Undefined
B Undefined
PrefetchAbort
B PrefetchAbort
DataAbort
B DataAbort
FIQ_Handler
STMFD SP!, {R0-R3, LR}
BL FIQ_Exception
LDMFD SP!, {R0-R3, LR}
SUBS PC, LR, #4
;*****************************************************************************
;* Initialize the stacks *
;* Function : void InitStack(void) *
;* Parameters *
;* input : None *
;* output : None *
;*****************************************************************************
InitStack
MOV R0, LR
;Build the SVC stack
MSR CPSR_c, #SVC32Mode
LDR SP, StackSvc
;Build the IRQ stack
MSR CPSR_c, #IRQ32Mode
LDR SP, StackIrq
;Build the FIQ stack
MSR CPSR_c, #FIQ32Mode
LDR SP, StackFiq
;Build the DATAABORT stack
MSR CPSR_c, #ABT32Mode
LDR SP, StackAbt
;Build the UDF stack
MSR CPSR_c, #UDF32Mode
LDR SP, StackUnd
;Build the SYS stack
MSR CPSR_c, #SYS32Mode
LDR SP, =StackUsr
MOV PC, R0
;******************************************************************************
;* Reset Entry *
;* Function : void ResetInit(void) *
;* Parameters *
;* input : None *
;* output : None *
;******************************************************************************
ResetInit
BL InitStack ;Initialize the stack
BL TargetResetInit ;Initialize the target board
;Jump to the entry point of C program
B __main
////////////////////////////////////////////////////////////////////////////////////////////////////////////
with the above red color code, you can track how to jump main() which is application code.
Hope it can help you
BR
XiangJun Rong
Hi,
I don't have the tools to track how to jump to the main, but in the reference manual, I found that to remap the flash I have to write 0x1 to the address 0xE01FC040 so I created a shellcode:
const static unsigned char remap_code[] =
"\x4c\xf2\x40\x03" // movw r3, #0xC040
"\xce\xf2\x1f\x03" // movt r3, #0xE01F
"\x4f\xf0\x01\x02" // mov.w r2, #1
"\x1a\x70" // strb r2, [r3]
"\x70\x47"; // bx lr
and I put it in RAM at address 0x40000200 using the ISP "W" Write to RAM command then I executed it using the Go "G" command and this last command was executed successfully but I lose the ISP command handler
I'm blocked.
Best Regards,
Hi,
I suppose that if you set up the MEMMAP(the address is 0xE01F C040) as 0x01, the interrupt vector will fetch from 0x0000_0000 address space, if the bootloader uses interrupt mode to respond the command, it will lead to error.
You said that the reading data from Flash space 0x0000_0000 was wrong, what was the reading data? how did you know that the reading data was incorrect?
BR
XiangJun Rong
Hi,
Below is a screenshot that compares the two files "original.hex" and "ReadTest.hex".
original.hex = this is the file I programmed the LPC2138
ReadTest.hex = this is the file I read from the LPC2138
you notice that there is a difference in the first 64 bytes (in yellow).
And whatever file I program it, I read always the same first 64 bytes.
BR.
Hi,
This is AE team reply:
"
customer's hex file read from chip is not correct, we may 0x00 and some other data.
so, i guess, customer not erased chip before program.
"
BR
XiangJun Rong
Hi,
I found the solution:
you must inject the code below into the RAM and execute it in ARM mode before reading the first 64 bytes of the Flash.
static unsigned char remap_code[] =
"\x0c\x00\x9f\xe5" //ldr r0, [pc, #0xc]
"\x01\x10\xa0\xe3" //mov r1, #1
"\x00\x10\x80\xe5" //str r1, [r0]
"\x0e\xe0\x81\xe1" //orr lr, r1, lr
"\x1e\xff\x2f\xe1" //bx lr
"\x40\xc0\x1f\xe0"; //ands ip, pc, r0, asr #32
Best Regards,
Hi,
This is our AE engineer reply:
"
do you mind providing binary(.bin) file compare table?
actual some of the ISP tool will add checksum value at 0x1C, i am not sure this activities will change the hex file content.
so, i hope you can provide binary file to me
"
BR
XiangJun Rong
Hi,
I have asked the AE team, I will give you a response after I get feedback from AE.
BR
XiangJun Rong
Thanks, I'm waiting for your response.
BR.
Hi,
Regarding your question, as you know that the LPC2138 is very old processor, which is based on the 16/32 bit ARM7TDMI-S CPU, the interrupt of LPC2000 family uses the VIC, it is different from the NVIC for Cortex-M0/M3/M4/M8.
For the Reset vector, the content of the reset vector in flash of 0x0000_0000 is the instruction binary code:
LDR PC, =Reset_Addr
it is a binary code. For the assembly instruction code for ARM7TDMI-S, pls download from the arm home page.
For detailed information, I suggest you download the AN10404.pdf from the link:
https://www.nxp.com.cn/docs/en/application-note/AN10404.pdf
5.1 Startup assembly code
5.1.1 Interrupt vector table
In this code section, the interrupt vectors are set up for the ARM7 core. It would be linked
to the bottom of the memory (If running from external memory this code will be run from
Bank0). Comments in the code below are preceded by “;”. This might vary depending
upon the Assembler being used.
LDR PC, =Reset_Addr
LDR PC, Undefined_Addr
LDR PC, SWI_Addr
LDR PC, Prefetch_Addr
LDR PC, Abort_Addr
; At 0x14 the user should insert a signature (checksum).
; This signature enables the bootloader to determine if
; there is valid user code in the Flash. Currently most of
; the Flash programming tools (even the Philips ISP utility
; have this feature built–in so the end user need not worry
; about it. If the tool does not provide this feature then
; the value has to be computed manually and has to be
; inserted at 0x14. Details on computation of checksum
; could be found in the Flash programming chapter in the
; device User Manual.
DCD … .
; The below instruction is the IRQ vector and it will load the
; PC with the ISR of the highest priorty interrupt from the
; VIC Vector Address Register (VICVectAddr at address 0xFFFFF030).
LDR PC, [PC, #–0xFF0]
; The ISR for FIQ can start from the below address itself.
LDR PC, FIQ_Addr
Undefined_Addr DCD Undefined_Handler
SWI_Addr DCD SWI_Handler
Hope it can help you
BR
XiangJun rong