WinARM + fichier assembleur

Forum sur tous les autres logiciels : AVR Studio, AVR Assembleur, AVR ISP, Ponyprog, BASCOM-AVR, ICC AVR etc

Modérateur : Modérateur

bunn_rath
NOUVEAU
NOUVEAU
Messages : 13
Inscription : 29 mai 2008 15:40

WinARM + fichier assembleur

Message par bunn_rath »

Bonjour tout le monde,

Je travaille avec WinARM pour flasher une carte. J'ai essayé de m'inspirer du fichier assembleur du lpc2106 crt0.s pour ma carte (processeur ARM7 TDMI).
Mais j'ai du mal à comprendre ce que ce fichier fait exactement. J'ai juste compris que c'est pour initialiser les interruptions, les différents modes du micro.

Quelqu'un pourrait il m'expliquer plus en détail le code assembleur suivant :
.global main // int main(void)

.global _etext // -> .data initial values in ROM
.global _data // -> .data area in RAM
.global _edata // end of .data area
.global __bss_start // -> .bss area in RAM
.global __bss_end__ // end of .bss area
.global _stack // top of stack

// Stack Sizes
.set UND_STACK_SIZE, 0x00000004
.set ABT_STACK_SIZE, 0x00000004
.set FIQ_STACK_SIZE, 0x00000004
.set IRQ_STACK_SIZE, 0X00000080
.set SVC_STACK_SIZE, 0x00000004

// Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs
.set MODE_USR, 0x10 // User Mode
.set MODE_FIQ, 0x11 // FIQ Mode
.set MODE_IRQ, 0x12 // IRQ Mode
.set MODE_SVC, 0x13 // Supervisor Mode
.set MODE_ABT, 0x17 // Abort Mode
.set MODE_UND, 0x1B // Undefined Mode
.set MODE_SYS, 0x1F // System Mode

.equ I_BIT, 0x80 // when I bit is set, IRQ is disabled
.equ F_BIT, 0x40 // when F bit is set, FIQ is disabled

.text
.code 32
.align 2

.global _boot
.func _boot
_boot:

// Runtime Interrupt Vectors
// -------------------------
Vectors:
b _start // reset - _start
ldr pc,_undf // undefined - _undf
ldr pc,_swi // SWI - _swi
ldr pc,_pabt // program abort - _pabt
ldr pc,_dabt // data abort - _dabt
nop // reserved
ldr pc,[pc,#-0xFF0] // IRQ - read the VIC
ldr pc,_fiq // FIQ - _fiq

#if 0
// Use this group for production
_undf: .word _reset // undefined - _reset
_swi: .word _reset // SWI - _reset
_pabt: .word _reset // program abort - _reset
_dabt: .word _reset // data abort - _reset
_irq: .word _reset // IRQ - _reset
_fiq: .word _reset // FIQ - _reset

#else
// Use this group for development
_undf: .word __undf // undefined
_swi: .word __swi // SWI
_pabt: .word __pabt // program abort
_dabt: .word __dabt // data abort
_irq: .word __irq // IRQ
_fiq: .word __fiq // FIQ

__undf: b . // undefined
__swi: b . // SWI
__pabt: b . // program abort
__dabt: b . // data abort
__irq: b . // IRQ
__fiq: b . // FIQ
#endif
.size _boot, . - _boot
.endfunc


// Setup the operating mode & stack.
// ---------------------------------
.global _start, start, _mainCRTStartup
.func _start

_start:
start:
_mainCRTStartup:

// Initialize Interrupt System
// - Set stack location for each mode
// - Leave in System Mode with Interrupts Disabled
// -----------------------------------------------
ldr r0,=_stack
msr CPSR_c,#MODE_UND|I_BIT|F_BIT // Undefined Instruction Mode
mov sp,r0
sub r0,r0,#UND_STACK_SIZE
msr CPSR_c,#MODE_ABT|I_BIT|F_BIT // Abort Mode
mov sp,r0
sub r0,r0,#ABT_STACK_SIZE
msr CPSR_c,#MODE_FIQ|I_BIT|F_BIT // FIQ Mode
mov sp,r0
sub r0,r0,#FIQ_STACK_SIZE
msr CPSR_c,#MODE_IRQ|I_BIT|F_BIT // IRQ Mode
mov sp,r0
sub r0,r0,#IRQ_STACK_SIZE
msr CPSR_c,#MODE_SVC|I_BIT|F_BIT // Supervisor Mode
mov sp,r0
sub r0,r0,#SVC_STACK_SIZE
msr CPSR_c,#MODE_SYS|I_BIT|F_BIT // System Mode
mov sp,r0

// Copy initialized data to its execution address in RAM
// -----------------------------------------------------
#ifdef ROM_RUN
ldr r1,=_etext // -> ROM data start
ldr r2,=_data // -> data start
ldr r3,=_edata // -> end of data
1: cmp r2,r3 // check if data to move
ldrlo r0,[r1],#4 // copy it
strlo r0,[r2],#4
blo 1b // loop until done
#endif
// Clear .bss
// ----------
mov r0,#0 // get a zero
ldr r1,=__bss_start // -> bss start
ldr r2,=__bss_end__ // -> bss end
2: cmp r1,r2 // check if data to clear
strlo r0,[r1],#4 // clear 4 bytes
blo 2b // loop until done

// Call main program: main(0)
// --------------------------
mov r0,#0 // no arguments (argc = 0)
mov r1,r0
mov r2,r0
mov fp,r0 // null frame pointer
mov r7,r0 // null frame pointer for thumb
ldr r10,=main
mov lr,pc
bx r10 // enter main()

.size _start, . - _start
.endfunc

.global _reset, reset, exit, abort
.func _reset
_reset:
reset:
exit:
abort:
#if 0
// Disable interrupts, then force a hardware reset by driving P23 low
// -------------------------------------------------------------------
mrs r0,cpsr // get PSR
orr r0,r0,#I_BIT|F_BIT // disable IRQ and FIQ
msr cpsr,r0 // set up status register

ldr r1,=(PS_BASE) // PS Base Address
ldr r0,=(PS_PIO) // PIO Module
str r0,[r1,#PS_PCER_OFF] // enable its clock
ldr r1,=(PIO_BASE) // PIO Base Address
ldr r0,=(1<<23) // P23
str r0,[r1,#PIO_PER_OFF] // make sure pin is contolled by PIO
str r0,[r1,#PIO_CODR_OFF] // set the pin low
str r0,[r1,#PIO_OER_OFF] // make it an output
#endif
b . // loop until reset

.size _reset, . - _reset
.endfunc

.end
En espérant que quelqu'un réponde à mon appel en détresse.
Je vous souhaite de passer un excellent 14 juillet.
Et merci d'avance.

@++

thm
REGULIER
REGULIER
Messages : 97
Inscription : 17 juin 2005 15:45

Re: WinARM + fichier assembleur

Message par thm »

Bonjour, Bunn

Si il y a bien une chose à ne pas toucher dans les projets GCC, ce sont bien les routines de bas niveau (qui sont exécutées directement après un "hard reset")

Ton exemple montre ce qu'elles font, par exemple :
- Initialiser le compteur programme
- initialiser le pointeur de pile
- définir les adresses de base de la Ram et de la Flash
- Initialiser les variables RAM à 0
- charger les vecteurs de d'exception (interruptions)
- copier les constantes de la Flash vers la Ram
Et encore souvent plein d'autre chose

Bref, c'est assez spécifique au processeur utilisé, mais elles sont indispensables au démarrage (boot)

thierry

bunn_rath
NOUVEAU
NOUVEAU
Messages : 13
Inscription : 29 mai 2008 15:40

Re: WinARM + fichier assembleur

Message par bunn_rath »

Salut Thierry,

Merci de m'avoir répondu ! :-D
Si il y a bien une chose à ne pas toucher dans les projets GCC, ce sont bien les routines de bas niveau (qui sont exécutées directement après un "hard reset")
Bref, c'est assez spécifique au processeur utilisé, mais elles sont indispensables au démarrage (boot)
Je travaille sur la TMS470 (processeur ARM7 TDMI). J'ai récupéré ces exemples de routines (voir plus haut) qui sont destinés au LPC2106. Je n'en ai pas trouvé pour la TMS470
Est-ce que c'est compatible avec la TMS470 ?
D'autre part, j'ai vu d'autres exemples de routines boot pour la LPC2106, donc il arrive parfois qu'on doive le modifier...

En fait mon problème, c'est que j'ai pu avec OpenOCD modifier les registres de la TMS470 pour tester le fonctionnement des I/O, LED, etc, mais après flashage du fichier .bin (écriture a marché), ces mêmes tests ne marche pas. Et la première chose, à laquelle j'ai pensé, était le fichier *.S que je n'ai pas bien compris.

Voici ce que je comprends de ces routines (corrigez moi si je me trompe) :
_ on commence à _boot
_ branchement à _start
_ on initialise la pile avec une taille réservé pour chaque mode (mais j'ai pas compris comment on fait le lien entre CPSR et la pile)
_ ensuite si ROM_RUN est défini, on charge le contenu .data de la ROM en RAM (comprends pas tout)
_ on appelle le programme main, on sort de _start, on retourne dans _boot
_ et là je comprends plus rien. On charge le pc aux différentes étiquettes _undf, _swi...

Ce que je ne comprends pas :
_ Que fait l'instruction .word ?
_ Que fait l'instruction b. ?
_ if 0 ne sera jamais vrai. Donc les instructions qui suivent ne servent à rien non ?
_ Qu'entends-tu par initialiser le compteur programme ?
_ Qu'est ce qu'il y a dans la pile ?
_ A quel moment on défini les adresses de base de la RAM et de la ROM ? Je pensais que c'était fait dans le fichier *.ld.

Il y a encore des petites choses que je ne comprends pas mais c'est déjà bien si tu pouvais me répondre sur ces questions.

Merci à tous !
@++

Répondre