EmbDev.net

Forum: ARM programming with GCC/GNU tools C-startups


von Roman M. (romez777)


Rate this post
useful
not useful
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.

von Roman M. (romez777)


Rate this post
useful
not useful
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!

von Clifford S. (clifford)


Rate this post
useful
not useful
> 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

von Clifford S. (clifford)


Rate this post
useful
not useful

von Clifford S. (clifford)


Rate this post
useful
not useful
... 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

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.