Aloittelua ARM LPC1768 alustalla

Tämä kirjoitus käsittelee omia kokemuksiani robomaasta hankittusta blueboard LPC1768-H:sta sekä CP210 pohjaisesta USB to TTL muuntimesta. Tämän kirjoituksen tarkoitus on lähinnä täydentää ruuvipenkin ARM-kontrolleritutoriaalia, bootloaderin sekä softapuolen osalta.

[size=150]Piuhat kiinni[/size]
Tarina alkaa viime viikonlopusta, jolloin vihdoin oli aikaa säätää ruuvipenkistä voittamaani ja robomaasta hankkimiani rojuja.

http://www.robomaa.com/index.php?main_page=product_info&cPath=106&products_id=745

http://www.robomaa.com/index.php?main_page=product_info&cPath=70_73&products_id=602

Ensin varmistin USB-UART muuntimen toimivuuden yhdistämällä hyppylangalla RXD ja TXD linjat ja kytkemällä muuntimen PC:hen. dmesg osoitti että laite tunnistui, kun kernelistä sattui löytymään tuki sarjaporttilaitteille. muuntimen toimivuuden osoittaminen käy vaikka minicom:lla. Tai ehkä helpommin pythoninpätkällä

# -*- coding: iso-8859-1 -*-
import serial
ser = serial.Serial("/dev/ttyUSB3",9600)
print ser.portstr
ser.write("?\n")
while(1):
	line = ser.readline()
	print "luettiin "+line
ser.close()

Control+C lopettaa, ruudulle pit√§isi tulla luettiin ‚Äú?‚ÄĚ

Muunnin toimi, loistavaa. Muistutuksena, että kyseinen muunnin käyttää +5V:n jännitetasoja, onneksi LPC1768:n UART0 on +5V tolerantti.

Sitten blueboard kiinni usb-mini johdolla PC:hen, valot syttyivät, hyvä ja jokin demosofta alkoi pyörimään. Muistaakseni USB-liitäntä esitti jotain HID laitetta. Oma blueboardini nyt sattui olemaan sellaista erää, että USB bootloaderi ei siihen jostainsyystä oltu asennetu. Manuaalin mukaan uudemmissa levyissä sellainen pitäisi olla asennettuna Siispä perinteinen USB-loaderi käyttöön.

Bootloaderi tarkoittaa suomeksi sellaista koodinpätkää, joka kyttää käynnistyksessä jonkinaikaa jonkin tietyn pinnin tilaa. Jos linjaa kiskotaan kontrollerin käynnistyksenaikana alas, bootloaderi tietää että kontrolleri on tarkoitus uudellenohjelmoida tai käyttää debuggaustilassa. Tällöin bootloaderi jää odottamaan ohjeita USB:stä,UART linjasta tai ethernet liitännästä. Atmelin atmega U2 ja U4 sarjan kontrollereissa bootloaderi muuttaa kontrollerin näyttämään USB:n kannalta DFU-laitteelta. Tällöin kontrolleriin saa ohjelmoitua dfu-programmer nimisellä ohjelmalla.

Kuitenkin LPC1768:n tapauksessa kontrollerin natiivi bootloaderi haluaa jutella uart0:n kanssa, ei USB:n.LPC1768:lle on kuitenkin tarjolla erillinen bootloaderi, joka muuttaa LPC1768:n näyttämään USB-levyasemalta eli erillistä poltto-ohjelmaa ei tarvita. Siispä keksimään, miten Blueboard lankun saa kiinni USB-UART muuntimeen.

Kurotin käden romulootaani ja sieltä löytyi CD-rom aseman ja äänikortin välillemenevä nelilinjainen piuha, mikä sopii myös piikkirimaan. RX ja TX linjat ovat blueboardilla näppärästi riman päissä, joten sen puolen sai helposti kiinni. Irroitin blueboardin puoleisesta liittimestä yhden piuhan ja varmuuden vuoksi erikseen yhdistin sen läheiseen GND pinniin. Vaikka kortti saakin maata varsin hyvin varsinaisen USB liittimen kautta.
usbuartkytkenta.png
USB-uart muuntimen puolella tarvitiin kolvia. kolvasin kaksi piikkirimaa vastakkain, jotta johdon saisi naaraspuoleiseen liittimeen kiinni. Pinoutti usb-uart muuntimelle on

  • GND
  • +5V
  • RTS
  • TXD
  • RXD
  • NC
  • NC

Tarkoitus oli kytkeä liitin TDX,RXD,NC ja NC paikkoihin. NC linjat olivat nimenomaan not connected…hmm… miksiköhän, joten samantien yhdistin ne lyhyellä hyppylangalla maahan, jotta saisin maahankytkentyn piuhan muuntimen GND:hen LPC:n RX tulee muuntimen TX:ään ja LPC:n TX ->RX.

blueboardKytkenta.png

[size=150]USB-Bootloaderin poltto[/size]

Natiivi-bootloaderi kyttää 2.10 linjaa eli bsl-linjaa. Virallinen USB bootloader taas 2.12 linjaa. Ja blueboardilla olisi kytkin 2.10:iin liitettynä. Satuin löytämään googlatessani ongelmaan ratkaisun
Blogi:
http://gvworks.blogspot.com/2010/10/usb-bootloader-for-blueboard.html
Ja kasa esimerkkejä
http://code.google.com/p/cortex-m3-tutorials/
http://code.google.com/p/embeddedhobby/downloads/list

Sieltä
LPC1700 Secondary USB bootloader for NGX BlueBoard.rar
En tässävaiheessa jaksanut alkaa miettimään kääntämistä… Joten luotin että kukaan ei ole bootloaderibinin sijaan kirjoittanut koodia joka saa blueboardin muuttumaan usb näppäimistöksi joka hmm… joko windows käyttäjien riesaksi painaa win+r näppäintä painaa backspacea kirjoittaa cmd ja perään enter, ja tämän jälkeen antaa muutaman hassun komennon. (tai vaihtoehtoisesti toivoo, että käyttäjä on roottina sisällä, sulkee X-ikkunoinnin ja antaa muutaman komennon)

Seuraavaksi piti löytää pätevä uart-ohjelmointisofta. Sellainen on flash magic…
http://www.flashmagictool.com/
Joka toimii vain windowsissa… :frowning: Ja tietenkin winessä. :sunglasses:

Heti tulee mieleen… miksiköhän kukaan ei ole tehnyt open source-versiota… pitäisiköhän sitä itse vaivautua? Sehän on vaan sarjaporttiin kirjoittelua ja lukemista :smiley:

Asennus-exe:n kopiointi ~/.wine/drive_c/ asennusohjelman ajo, pari klikkausta ja flashmagic asennettu ongelmitta. Seuraava ongelma ‚Äúmiten saan linuxin sarjaporttilaitteen n√§kym√§√§n winelle‚ÄĚ. Ratkaisu: tehd√§√§n hakemistoon
~/.wine/dosdevices/
linkki

ln -s /dev/ttyUSB3 com10

missä ttyUSB3 oli usb-sarja muuntimelle tuleva portti. com10 taas voi olla mikätahansa vapaa com-portti

flashmagic.png
Flash magic päälle
Deviceksi LPC1768, COM10, 9600,erase blocks ja verify päälle.Valitaan heksa.
Painetaan blueboardin resetti ja BSL nappi alas, vapautetaan reset ja sen jälkeen BSL. Lankulla olevan yksi lankun ledeistä pitäisi hehkua himmeänä. Ja painetaan flash magickistä start.

Allekirjoittaneella oli pieniä vaikeuksia :mrgreen: , johtuen huolimattomasta johtoviritelmästä. Kun törmäätte ongelmiin, kannattaa vianhaku aloittaa

  • Ottamalla LPC:n puoleiset piuhat irti ja oikosulkemalla RX ja TX linjat, l√§hetet√§√§n terminalilla jotain ja katsotaan ett√§ merkit tulee l√§pi
    (puttyn ajaminen winellä, että wine käsittelee porttia oikein. Tosin luultavasti fonttiongelmien takia jotkin merkit tulostuvat C kirjaimina)
  • LPC:n bootloaderin pit√§isi vastata Syncronized, jos sille heitt√§√§ terminaalilla kysymysmerkki√§ (kts python-testikoodi)

Bootloaderi ohjelmoitui. Modifioitu USB bootloaderi aktivoidaan siten, että

  • Resetoidaan blueboard
  • Kun ledi alkaa vilkkua (aikaa vajaa pari sekunttia), painetaan sen aikana BSL nappia.
    Jos halutaan että natiivi uart0-bootloaderi aktivoituu, tällöin tietysti pidetään BSL nappia pohjassa resetin aikana.

[size=150]USB-Bootloader juttelemaan linuxin kanssa[/size]

LPC1768 ilmestyi näkymään /dev/sdb-laitteena. Ja sen sai mountattua. Levyltä löytyi sen kokonaan täyttämä firmware.bin, joka tietenkin pitää poistaa ennenkuin sinne voi kopioida oman .bin tiedoston.

26521.450134] scsi 10:0:0:0: Direct-Access Keil LPC1700 Disk 1.0 PQ: 0 ANSI: 0 CCS
[26521.450332] sd 10:0:0:0: Attached scsi generic sg3 type 0
[26521.450750] usb-storage: device scan complete
[26521.456085] sd 10:0:0:0: [sdb] 1012 512-byte logical blocks: (518 kB/506 KiB)
[26521.459091] sd 10:0:0:0: [sdb] Write Protect is off

S√§√§t√§misest√§ huolimatta, bootloaderi ei tuntunut suostunut p√§ivitt√§m√§√§n firmist√§. Ja kyll√§‚Ķ juu, kokeilin kaikki mahdolliset ‚Äúsync‚ÄĚ komennon antamisen mounttauksen j√§lkeen, kopioinnin j√§lkeen‚Ķ umountin tekemisen yms. mountin -o optiolla remountit, useri dev sync nosync yms yritelm√§t.
http://mbed.org/handbook/Mounting-with-sync

Meinasin jo heittää blueboardilla rauhoitettua vesilintua, kunnes nöyrryin tarpeeksi ja buuttasin windowsiin…Siellä se toimi… WTF!!!

Syy loppupeleissä oli se että usb bootloaderi on vaan niin keharisti ja standardia rikkoen toteutettu, että se ei kykene juttelemaan linuxin ajureiden kanssa, wintöötissä se toimii… Niinkuin hurrit sanovat, Lika barn leker best, eli samanlaiset ladot leikkivät parhaiten.

Googlailu tuotti tulosta… AH-HAA!!! :bulb:
http://www.gnu.org/software/mtools/

Ilman mitään mounttauksia, kun tarvittavilla oikeuksilla (roottina) käskee

mdel -i /dev/sdb ::/firmware.bin
mcopy -i /dev/sdb main.bin ::/

ja painaa odottelun jälkeen resettiä (olettaen että kontrolleri ajettiin ohjelmointimoodiin)

Ja homma pelittää. ARM:in ohjelmointiongelma ratkaistu, seuraavaksi mietitään miten omia .bin tiedostoja pitäisi tuottaa.

[size=150]Ohjelmanvääntö[/size]

Laiskanmiehen ratkaisu toolchainiksi on ruuvipenkin artikkeleissa esitelty code sourcery, minkä saa syntisesti binääripakettina ilman ylimääräistä häslinkiä asennettua. (johon allekirjoittanutkin sortui)
http://www.gnuarm.com/
http://www.yagarto.de
ja muut gcc pohjaiset.
http://www.gentoo.org/proj/en/base/embedded/handbook

Paras tapa aloittaa on mallikoodi

http://code.google.com/p/cortex-m3-tutorials/downloads/detail?name=LPC1700%20Secondary%20USB%20bootloader%20for%20NGX%20BlueBoard.rar

Esimerkit k√§ytt√§v√§t CMSIS:i√§ eli ‚ÄúARM¬ģ Cortex‚ĄĘ Microcontroller Software Interface Standard‚ÄĚ:ia.
Eli abstraktiolayeri, jotta sama koodi pyörisi kaikissa cortex-M sarjan kontrollereissa ja kääntäjissä.
Periaatteessa hyvä asia, tällöin kääntäjävalmistajat eivät tee omia matalan tason rutiineitaan ja rekistereiden uudelleennimeämisiä. Standardit auttavat lasta. Jos valmista koodikirjastoa tai modulia katselette, valitkaa aina CMSIS:iä käyttävä.

Esimerkiksi FreeRTOS käyttää CMSIS:iä, tai vaikkapa CMSIS:in USB ajurin päälle tehdyt USB laiteluokka-ajurit.
http://support.code-red-tech.com/CodeRedWiki/RDB1768cmsisExampleProjects
(viittaus tuohon, latauslinkki palauttaa meikäläiselle jostain syystä rikkinäisen zip-tiedoston)

Oleelliset tiedostot tässä ledivilkuttelussa ovat:

  • core_cm3.h ja core_cm3.c
  • system_LPC17xx.h ja system_LPC17xx.c
  • LPC17xx.h ja startup_LPC17xx.c
  • LPC17xx.ld
  • main.c
  • makefile

main.c
Itsestäänselvä

core_cm3.h ja core_cm3.c
debuggaus, ja matalantason funktioita

system_LPC17xx.h system_LPC17xx.c

system_LPC17xx.c modulissa on SystemInit. Siinä asetetaan muun muassa kiteestä CPU kelloksi muuttavan PLL kertoja&jakaja yhdistelmän asetukset. On makuasia, mutta minä en kyseiseen moduliin menisi koskemaan. Jos ja kun CPU:n ja oheislaitteiden kelloihin pitää mennä tekemään muutoksi, niin tehdään ne main() rutiinissa tai sen kutsumissa aliohjelmissa. Tällöin kellotaajuudet tulevat itse-dokumentoiduksi koodiksi omaan koodiin, eikä muutoksia tarvitse etsiä kissojen ja koirien kanssa jostain vakiokirjastosta.

system_LPC17xx.h headeri sisältää kasan strukteja, joilla kuvataan muistiosoitteisiin mäpätyt rekisterit
Ja struktipointterit osoittamaan vastaaviin muistipaikkoihin esim.
LPC_SC
LPC_GPIO0 yms…

startup_LPC17xx.c:st√§ taas l√∂ytyy ‚ÄúExternal interrupt vector handler‚ÄĚ:it, joidenka nimi√§ kannattaa katsella kun tekee keskeytysrutiineja.

Vihje:

#pragma weak TIMER0_IRQHandler = Default_Handler

tarkoittaa tässätapauksessa sitä että Defaut_Handler:iä asetetaan jos TIMER0_IRQHandler funktio on määritelty

makefilu:

Ei kannata pelästyä, makefilut ovat varsin sekavaa luettavaa.
Rivit johin kannattaa ehkä kannattaa puuttua ovat ehkä jotkin flagit, optimointitaso -O2 ? yms…
Ja
CSRC+= main.c, mihin lisätään käännettävät c-tiedostot

Ja muistutetaan, että bootloaderille kopioidaan .bin tiedosto.
(ei elf, ei hex)

Pieniss√§ projekteissa koodin voi nykykoneilla k√§√§nt√§√§ sekunneissa aina ‚Äúpuhtaalta p√∂yd√§lt√§‚ÄĚ, suuremmissa (512k rajana?) ajans√§√§st√∂ voi olla makefilen s√§√§t√§misen arvoinen.

LPC17xx.ld

Linkkeriskripti, sekaisin ja hankalin tiedosto, pakko myöntää, kun se ei ole C:tä :-/
Linkkeriskriptin tarkoitus on kuvata mihinkohtaa muistiavaruutta minkäkinlaiset muistialueet sijoittuvat.

Aloittelijoiden kannalta huomionarvoisin rivi linkkeriskriptissä on

IROM (rx) : ORIGIN = 0x00002000, LENGTH = 512k

Käytettäessä usb-bootloaderia, rom-ohjelma alkaa osoitteesta 0x2000

Henk. koht en aiemmin joutunut muokkaamaan linkkeriskriptejä, joten tämän pätevämpiä neuvoja en osaa vielä antaa.

Näistä tiedostoista (ja datalehdestä) ja lunttaamaan kun pitää keksiä miten prossua ja sen toimilaitteita käskytetään.

linkkivinkit:
http://dev.frozeneskimo.com/notes/getting_started_with_cortex_m3_cmsis_and_gnu_tools
http://www.mcu-related.com/pdf/CMSIS_Doulos_Tutorial.pdf
http://msys-mv.blogspot.com/
http://gvworks.blogspot.com
http://cortex-m3-tutorials.googlecode.com
http://gandalf.arubi.uni-kl.de/avr_projects/arm_projects/index_cortex.html

[size=150]USB:n käyttäminen lpcusb, CMSIS:n USB?[/size]
Jotta Blueboard voisi näyttää joltain laitteelta (HID, sarjaportti, massamuisti yms…) se tarvitsee sitävarten ajurit. LPC:n rauta hoitaa USB:n matalan tason temput ja CMSIS näiden kutsumisen. Ajurillä tässätapauksessa tarkoitetaan tämän päälle tulevaa koodia.

USB-luokkia on useita.
http://www.usb.org/developers/devclass_docs#approved
Harrastelijan kannalta aiheellisemmat, käyttöjärjestelmien natiivisti tukevat luokat ovat

  • CDC eli Communications Device Class, ‚Äúsarjaportilta n√§ytt√§v√§t‚ÄĚ
  • Massamuistilta n√§ytt√§v√§ (kuten bootloader)
  • HID-laitteelta, kuten hiirelt√§, n√§ppikselt√§, joystikilt√§/ratilta n√§ytt√§v√§t

Erikoisempia laitteita varten tarvitaan erilliset ajurit PC-puolelle tai varsinainen ohjelma käyttämään vaikka libusb:tä http://www.libusb.org/

http://support.code-red-tech.com/CodeRedWiki/RDB1768ExampleProjects
Netti on täynnä epämääräisiä usb-kirjastoja, Mielestäni kannattaisi käyttää CMSIS:in matalan tason USB-funktioiden päälle rakennenettuja kirjastoja (zipin latauslinkin takana rikkinäinen zip-filu)
http://support.code-red-tech.com/CodeRedWiki/RDB1768cmsisExampleProjects

Bootloaderissa on toki ‚Äúmassamuistiajuri‚ÄĚ, mutta se ei k√§yt√§ CMSIS:i√§ Viel√§ kun l√∂yt√§isi (tai jaksaisi tehd√§) bootloaderin, joka k√§ytt√§isi CMSIS:i√§ ja bootloaderin massamuistiajuria (usb-hostille n√§ytt√§√§ levyasemalta) voisi kutsua omasta koodista‚Ķ niin wau‚Ķ muistins√§√§st√∂√§ kun samaa koodia ei k√§√§nnet√§ kahteen eri paikkaan.

[size=150]Käyttöjärjestelmä? No onhan meillä muistia…[/size]
http://www.freertos.org/
Kun kumminkin jossainvaiheessa rakenteluprojektia tulee tarve sille, ett√§ laite tekisi useampaa asiaa yht√§aikaa. Itsekirjoittaen ‚Äúrinnakkain‚ÄĚ ajettavaa koodia, tulee poikkeuksetta kumminkin paska scheduleri tai jokin scheduleria muistuttava ep√§varma h√§r√∂viritelm√§, mielummin sit√§ ottaa k√§ytt√∂√∂n valmiin ja testatun k√§ytt√∂j√§rjestelm√§n.

FreeRTOS:n esimerkkikoodeissa vilahtelee CMSIS ja näemmä CDC-eli sarjaporttiajurikin kuuluu pakettiin mukaan

[size=150]Loppusanat[/size]
Asiasta voisi vielä kirjoittaa lisää CMSIS:n käytöstä, saisi luotua aika kattavan kuvan LPC1768:n sielunelämästä. Tai Freertos:n, käyttöönotosta, debuggauksesta, DSP kirjastosta, ethernet-liitännän rakentamisesta tai jonkin skriptikielen (lua,python, forth ja kumppanit…) käytöstä kontrollerilla.
http://en.wikipedia.org/wiki/Lua_(programming_language)
http://en.wikipedia.org/wiki/Forth_(programming_language)

PS.

Henk. koht olen sitämieltä että kuukauden parhaan artikkelin äänestys voisi olla arvontaa parempi vaihtoehto.