[cortex-m3] startup-code/booten

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • DizzyVacation
  • Registratie: November 2006
  • Niet online
Ik ben bezig met een Olimex lpc-1766stk bordje. Hierop zit een arm cortex-m3 microcontroller. Deze probeer ik dus aan de gang te krijgen.
Nu heb ik dus een simpel stukje c code welke alleen een ledje aanzet en een startup file in assembly. Deze compile ik met yagarto naar een elf file. Deze elf file converteer ik naar een binair bestand waarin ik in een hex-editor de benodigde checksum inzet.
Deze file zet ik via jtag (Olimex ARM-USB-TINY/openocd) in de microcontroller.
Tot zover gaat het allemaal goed.

Maar wanneer ik nu de microcontroller reset komt deze meteen in de HardFault handler.
code:
1
2
3
4
5
6
7
> reset
JTAG tap: lpc1766.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)
Invalid ACK 0x6 in JTAG-DP transaction
lpc17xx -- clearing lockup after double fault
target state: halted
target halted due to debug-request, current mode: Handler HardFault
xPSR: 0x60000003 pc: 0x000000ea msp: 0x10007fe0


Het rare is echter dat het wel werkt wanneer ik de microcontroller reset-halt en zelf het geheugen map en het pc-register instel op het start adres. Normaal gesproken zou de ingebouwde bootloader dit doen.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
> reset halt
JTAG tap: lpc1766.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)
target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x1fff0080 msp: 0x10001ffc
// Map het geheugen, zodat de flash op adres 0 begint.
> mww 0x400fc040 1
> mdw 0x4
0x00000004: 000000cc
// Zet het pc-register naar het begin van de code.
> reg pc 0xcc
pc (/32): 0x000000CC
> resume
// Hier gaat het ledje branden zoals de bedoeling is.


Wanneer ik een breakpoint op de eerste paar instructies zet komt hij al bij de fout voordat een breakpoint bereikt is. Dit deed mij vermoeden dat de fout bij de eerste instructie optreed, als ik het juist begrepen heb bevestigd de volgende log dit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
> reset
JTAG tap: lpc1766.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)
Invalid ACK 0x6 in JTAG-DP transaction
lpc17xx -- clearing lockup after double fault
target state: halted
target halted due to debug-request, current mode: Handler HardFault
xPSR: 0x60000003 pc: 0x000000ea msp: 0x10007fe0
> reg
===== arm v7m registers
(0) r0 (/32): 0x00000000
-- knip --
(12) r12 (/32): 0xEEEC2880
(13) sp (/32): 0x10007FE0
(14) lr (/32): 0xFFFFFFF9
(15) pc (/32): 0x000000EA
(16) xPSR (/32): 0x60000003
(17) msp (/32): 0x10007FE0
(18) psp (/32): 0x26F2704C
-- knip --
> mdw 0x10007FE0 8
0x10007fe0: 00000000 000000cc 00000000 00000000 eeec2880 1fff0d5f 000000cc 60000000
// De een-na-laatste waarde zou hier het pc-register aangeven welke de fout veroorzaakt.
// Oftewel het begin van de code, zie vorige log.


Nu is de vraag waarom boot hij niet normaal? De dingen die ik handmatig doe wanneer het wel werkt zouden normaal gesproken door de hardware/bootloader gedaan moeten worden. Of zie ik hier iets over het hoofd?

helloworld.elf listing
LPC17xx user manual

Acties:
  • 0 Henk 'm!

  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

ik heb 0 verstand van microcontrollers, maar ik ga even captain obvious doen:
target halted due to debug-request

-niks-


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 11-09 12:01
Invalid ACK 0x6 in JTAG-DP transaction
Lijkt me dat dat de oorzaak is van je HardFault?

Waarom ondersteunt jouw IDE eigenlijk geen build+download? Waarom zo vreselijk low-level?

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • Wolf87
  • Registratie: Juli 2004
  • Laatst online: 19:32
Hoe heb je de elf file geconverteerd naar een binary file?

Kan je het is proberen met arm-elf-objcopy van yagarto:

arm-elf-objcopy -O binary infile outfile.bin

Acties:
  • 0 Henk 'm!

  • DizzyVacation
  • Registratie: November 2006
  • Niet online
@MLM
Dat komt omdat hij in die fout springt, want anders zou hij dit ook doen wanneer ik hem handmatig goedzet.

@farlane
Die melding weet ik idd niet waar die vandaan komt. Maar als ik de demo-firmware er weer op flash en een breakpoint zet op de eerste instructie en een reset geef, dan komt deze melding ook. Ik vermoed hier dat de bootloader dit veroorzaakt, is er misschien een manier waarop ik dit kan bevestigen?
Verder gebruiken we hier allemaal losse tools (openocd, gnu toolchain), deze ben ik nu een beetje aan het samenvoegen. Uiteindelijk gebruiken we eclipse, maar het builden+downloaden gaat goed, alleen bij het booten/runnen gaat het fout.

@Wolf87
Ik heb hem via dat commando geconverteerd, waarna ik met een hexeditor de checksum erin heb gezet. Anders doet hij helemaal niks en blijft hij in de bootloader hangen, omdat hij dan denkt dat er ongeldige code in de flash staat.

Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 20:28
Misschien een open deur, maar als het enige verschil is dat je in de handmatige versie zelf de ALU initialiseert (blijkbaar door 1 te schrijven naar 0x400fc040, wat schijnbaar het adres van een control register ofzo is?) dan lijkt me de conclusie dat de bootloader dat níet doet. Het kan natuurlijk ook zijn dat de bootloader je binary standaard op een andere locatie inlaadt maar dat het entry point verkeerd ingesteld is.

Klopt het trouwens dat de PC normaliter geüpdatet wordt vóór de instructie uitgevoerd wordt? Zo ja, dan zou dat betekenen dat die hele instructie niet gefetcht is, en dat zou consistent zijn met het idee dat 'ie niet op de goede plek in het geheugen gemapt is. Kun je de inhoud van adres 0xcc wel printen met OpenOCD?

Acties:
  • 0 Henk 'm!

  • DizzyVacation
  • Registratie: November 2006
  • Niet online
Bij een reset staat de bootloader op adres 0 gemapt, dit zodat deze automatisch start. Door dat register (0x400fc040) op 1 te zetten maak je deze map ongedaan zodat je user-flash weer op 0 staat gemapt. Hiermee skip ik dus in principe de bootloader. Normaal gesproken zou de bootloader deze dingen moeten doen.

Ik kan over het updaten van het pc register zo snel niks vinden in de datasheet, maar ik ga er vanuit van wel, want bij een reset wordt de waarde van adres 0x4 in het pc register geladen en daarna word dat adres uitgevoerd.
De inhoud van 0xcc:
code:
1
2
3
4
5
6
7
8
9
10
> reset
JTAG tap: lpc1766.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)
Invalid ACK 0x6 in JTAG-DP transaction
lpc17xx -- clearing lockup after double fault
target state: halted
target halted due to debug-request, current mode: Handler HardFault
xPSR: 0x60000003 pc: 0x000000ea msp: 0x10007fe0
> mdw 0xcc 8
0x000000cc: 47004800 000000d5 af00b480 0323f24c 0309f2c2 0202f04f e7fe601a e7fee7fe
>


Deze komt dus overeen met de listing.

Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 20:28
D'oh, ik zie nu dat je de manual al gelinkt had in je eerste post. Had me een hoop Googlen (en domme vragen stellen) kunnen besparen. :P

Maar ok, geheugen lijkt dus correct gemapt te zijn. Volgens de stack trace treedt er een exceptie op op locatie 0xcc, vervolgens kom je in de HardFault handler, die waarschijnlijk om dezelfde reden niet uitgevoerd kan worden, en heb je een double fault.

Wat ik me afvraag, is of die hard fault direct gegenereerd wordt, of dat een andere fault geëscaleerd wordt naar hard fault. Is het mogelijk om breakpoints te zetten op al die exception handlers om te zien welke het eerst getriggert wordt? Of zou dat niet werken omdat geen daarvan daadwerkelijk uitgevoerd wordt?

edit:
Een andere optie is die bootloader code te dumpen vóór je 'm unmapt om te zien wat 'ie doet, maar dat is potentieel veel code en veel uitzoekwerk, wat vervelend is...

[ Voor 11% gewijzigd door Soultaker op 03-03-2010 11:03 ]


Acties:
  • 0 Henk 'm!

  • DizzyVacation
  • Registratie: November 2006
  • Niet online
Volgens mij zet ik op de volgende manier op elke vector een breakpoint. Hij geeft iig niet meer die melding over die dubbele fout.
log:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
> cortex_m3 vector_catch all
 hard_err: catch
  int_err: catch
  bus_err: catch
state_err: catch
  chk_err: catch
 nocp_err: catch
   mm_err: catch
    reset: catch
> reset
JTAG tap: lpc1766.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)
target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x1fff0080 msp: 0x10001ffc
> mdw 0 2
0x00000000: 10001ffc 1fff0081
>


Hij heeft blijkbaar dus wel al die memory map gedaan. Maar hij crashed dus nog in de code van de bootloader die zich nog in de ram bevindt.
Ik weet niet precies hoe ik hiermee verder moet, ik kan idd de bootloader dumpen en disassemblen, maar dit is idd veel werk.

Iets wat me nu trouwens opvalt is dat als ik vaker achter elkaar reset hij om en om voor en in de fout word gehalt (let op het pc-register).
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
> reset
JTAG tap: lpc1766.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)
target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x1fff0080 msp: 0x10001ffc
> reset
JTAG tap: lpc1766.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)
Invalid ACK 0x6 in JTAG-DP transaction
target state: halted
target halted due to debug-request, current mode: Handler HardFault
xPSR: 0x60000003 pc: 0x000000ea msp: 0x10007fe0
> reset
JTAG tap: lpc1766.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)
target state: halted
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0x1fff0080 msp: 0x10001ffc
> reset
JTAG tap: lpc1766.cpu tap/device found: 0x4ba00477 (mfg: 0x23b, part: 0xba00, ver: 0x4)
Invalid ACK 0x6 in JTAG-DP transaction
target state: halted
target halted due to debug-request, current mode: Handler HardFault
xPSR: 0x60000003 pc: 0x000000ea msp: 0x10007fe0
>


Je ziet ook dat die ACK fout alleen optreedt wanneer hij in de hardfault word gehalt.

Acties:
  • 0 Henk 'm!

  • DizzyVacation
  • Registratie: November 2006
  • Niet online
Ik heb uiteindelijk de oplossing gevonden door toch nog eens goed de binaire dump van de demo-firmware te bekijken en daar stukjes in te veranderen in een hex-editor.
De waarde van adres 0x4 moet je 1 bij optellen.

Bit 0 van het pc register is altijd 0 omdat de cortex-m3 met 16-bit en 32-bit instructies werkt, dus altijd een even aantal bytes. Ook je code staat mooi uitgelijnd per 16-bits.
Nu blijkt dat bij het zetten van het pc register bit 0 wordt gebruikt om de instructie set aan te geven. Een 0 staat dan voor de ARM(?) instructie set en een 1 voor de thumb set. Echter ondersteunt de cortex-m3 alleen thumb.
Weer eens een aantal uren aan een bitje besteed. 8)7

Staat ook lekker handig vermeld onder de instructie set in de datasheet.

Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 20:28
Ahh... maar waarom werkte het met de hand dan wel? Daar zette je toch juist de PC op 0xcc (wat even is) terwijl je 0xcd had moet doen? Of bedoel je dat de bootloader naar het eerste bit van het startadres kijkt, en op basis daarvan de processor instelt op thumb dan wel standaard mode? Of wellicht gaat het om de laagste bit van het argument van een call instructie, die je omzeilt met de handmatige code?

(In dat geval wordt de eerste bit bij het zetten van de PC juist genegeerd, lijkt me, want anders zou je met 0xcc juist de cpu in normale mode instellen terwijl je thumb instructies gebruikt.)

In ieder geval mooi dat je 't hebt weten op te lossen. :)

[ Voor 77% gewijzigd door Soultaker op 04-03-2010 18:22 ]


Acties:
  • 0 Henk 'm!

  • DizzyVacation
  • Registratie: November 2006
  • Niet online
Uit de datasheet:
Remark: Bit[0] of any address you write to the PC with a BX, BLX, LDM, LDR, or POP instruction
must be 1 for correct execution, because this bit indicates the required instruction set, and
the Cortex-M3 processor only supports Thumb instructions.
Ik weet dus niet hoe het pc register via jtag wordt gezet, maar de bootloader zal dus een van deze instructies gebruiken en jtag niet.

[ Voor 3% gewijzigd door DizzyVacation op 04-03-2010 19:17 ]


Acties:
  • 0 Henk 'm!

Verwijderd

Goed bezig!
Pagina: 1