Hello, I'm trying deeply understand the mechanism of remapping on AT91SAM7 chips and it's concerned the ARM assembly language. Basically what I wish to perceive is the way C-startup is implemented. As far as I understand, it strongly depends on a board involved and purpose of the firmware. But there are some common parts of startup code as well, for example the vector table: some examples I explored use "B .." instructions, while others do various variations of "LDR pc ...". To my understanding, the first one is doing PC-relative jump, and "LDR pc, ..." populate PC with an absolute address. So when is is preferable to use the first method (via 'B' instructions) and whe the second one with absolute addresses? Are there any rules or common practises for that? Thanks.
Roman Mashak wrote: > But there are some common parts of startup code as well, for example the > vector table: some examples I explored use "B .." instructions, while > others do various variations of "LDR pc ...". To my understanding, the > first > one is doing PC-relative jump, and "LDR pc, ..." populate PC with an > absolute address. [skip] After researching this question I got more familiar with the addressing modes used by various ARM instructions. But the main question that forced me to start the thread is when should I use this or that kind of vector table representation and what are the main benefits/downsides of these approaches. For example, this is the first (1) style: B reset B undef B swi B prefabt B dataabt B . B irq B fiq ... [Atmel's example exploits this method with all handlers in a one single section] (2) This is another way I encountered: reset_vector: ldr pc, =reset_handler undef_vector: b undef_vector /* Undefined Instruction */ swi_vector: b swi_vector /* Software Interrupt */ pabt_vector: ldr pc, =pabt_handler /* Prefetch Abort */ dabt_vector: ldr pc, =dabt_handler /* Data Abort */ rsvd_vector: b rsvd_vector /* reserved */ irq_vector: b irq_handler /* IRQ : read the AIC */ fiq_vector: ..... (2) And this is one more style: LDR PC, ResetAddr /* Reset */ LDR PC, UndefAddr /* Undefined instruction */ LDR PC, SWIAddr /* Software interrupt */ LDR PC, PAbortAddr /* Prefetch abort */ LDR PC, DAbortAddr /* Data abort */ NOP /* Reserved */ LDR PC, IRQAddr /* IRQ interrupt */ LDR PC, FIQAddr /* FIQ interrupt */ ResetAddr: .word ResetHandler UndefAddr: .word UndefHandler SWIAddr: .word SWIHandler PAbortAddr: .word PAbortHandler DAbortAddr: .word DAbortHandler IRQAddr: .word IRQHandler FIQAddr: .word FIQHandler .... I assume the (2) and (3) styles I described above are directly related to re-mapping procedure, but this is just my guess. Looking forward to hearing some comments from you. Thanks!
> reset_vector: > ldr pc, =reset_handler Jumps to reset_handler when a reset occurs, wheras: > undef_vector: > b undef_vector /* Undefined Instruction */ loops indefinitely when an undefined instruction occurs. It all depends upon whether you are going to handle the exception/interrupt or not. So the examples you posted are all variations of none, some, or all vectors explicitly handled. It is also possible that a system hooks the handlers at runtime (after C-startup), for this to happen the vectors must be in RAM, so it requires that the micro-controller support remapping of RAM to zero. If you are going to do this you might simply have the "loop indefinitely" mechanism as an initial ROM vector table, on the basis that it will be modified later when re-mapped to RAM. It is quite simple. When an exception/irq/reset occurs, the instruction at that address is executed. For obvious reasons (because there is only room for one instruction), that instruction is normally a branch or jump. Clifford
... sorry to keep posting, this is good too: http://www.hitex.co.uk/arm/lpc2000book/ If you are not using an LPC2000, it is still useful for the ARM7 specific parts (which is most of it). Clifford