Jste zde

Praktické zkušenosti s procesory ARM Cortex M3

Článek popisuje praktické zkušenosti s návrhem aplikace s procesorem ARM Cortex M3 a vývojovým kitem firmy Luminary Micro a uvádí výhody a nevýhody těchto procesorů ve srovnání s 8bitovými procesory.

Úvod

 Jako dlouholetý vývojář aplikací zejména s 8bitovými procesory a 16bitovými DSP jsem již delší dobu sledoval bouřlivý vývoj v oblasti 32bitových procesorů pro embedded aplikace. Prakticky každý výrobce mikrokontrolerů nabízí i 32 bitové verze, např. AVR32  fy Atmel, PIC32 od fy Microchip, ColdFire fy Freescale atd. Od jejich využití mne však odrazovalo několik skutečností: není zde žádné široce používané jádro jako např. 8051 u 8bitových uP,  špatná dostupnost  a  vysoká cena potřebných vývojových nástrojů – in circuit debugger je podle mého názoru pro vývoj rozsáhlejší aplikace nezbytností.

Situace se začala zvolna měnit s nástupem procesorů ARM7, se kterými se začaly objevovat i dostupnější vývojová prostředí, při troše snahy dostupná i zcela zdarma pod GNU licencí, a cenově přístupné JTAG debuggery. Zřejmě nejlevnější jsou JTAG debuggery od firmy Olimex [2], která nabízí USB/JTAG adaptéry v ceně od 40 EUR a k tomu zdarma GNU programové vybavení. Přesto se mi tyto procesory nezdály úplně ideální pro použití jako mikrokontroléry pro některé své vlastnosti jako např. dlouhá doba odezvy na přerušení a pomalá práce s periferiemi. 

Procesory ARM Cortex M3

Nedostatky procesorů ARM7  byly do značné míry eliminovány novým jádrem ARM Cortex M3, jejichž základní vlastnosti jsou popsány v [1]. Oproti ARM7 nabízejí zejména vyšší výpočetní výkon při stejné frekvenci hodin, rychlejší odezvu na přerušení, až 240 úrovní přerušení, výkonnější a paměťově úspornější instrukční soubor atd.

Jako první nabídla vlastní čipy s tímto jádrem firma Luminary Micro [3] s frekvencí jádra až 50 MHz, v současnosti  nabízí cca 130 obvodů. V letošním roce  přichází s novou vylepšenou řadou procesorů s frekvencí 80 MHz. Dalším velkým výrobcem je  firma ST s řadou STM32 [4] s frekvencí 72 MHz  (vzhledem ke 2 waitstavům na této frekvenci je jejich výkon zhruba srovnatelný s Luminary Micro), jejich další výhodou je 12bitový AD převodník na čipu, celkem nabízejí cca 60 variant obvodů. Začátkem roku 2009 ohlásila procesory s Cortex M3 jádrem i firma Actel a NXP slibuje Cortex M3 čipy s frekvencí 100 MHz.


 

Celkově je tedy k dispozici několik set variant procesorů s tímto jádrem s nejrůznějšími periferiemi a je patrné, že nabídka se bude dále rozšiřovat a výkon stále poroste. ARM Cortex M3 má tedy velmi dobrou šanci stát se standardem mezi 32bitovými kontroléry.

Vzhledem k šíři nabídky a rychlosti změn není úplně snadné se rozhodnout, kterého výrobce si zvolit.Já jsem si vybral Luminary Micro z těchto důvodů:

  1. jako jediný nabízí procesory s Ethernet rozhraním 100 Mbit/s včetně fyzické vrstvy,
  2. jeho vývojové desky jsou cenově  dostupné a mohou zároveň sloužit i jako JTAG debugger pro ladění vlastních aplikací.

Zkušenosti s vývojovým kitem Luminary Micro

Za cca 70 USD jsem si pořídil u českého distributora HTEurep [5] vývojový kit pro LM3S6965, dále jsou popsány praktické zkušenosti s jeho používáním a vývojem první vlastní aplikace.

Luminary Micro nabízí uvedený vývojový kit s vývojovými prostředími  několika firem, konkrétně Keil, IAR, CodeSourcery  a Code Red, já jsem si vybral  EWARM od IAR, protože nabízí limit 32 kByte pro velikost kódu. Vývojový kit je velmi slušně vybaven, má USB, Ethernet 100 Mbit, OLED displej a slot pro microSD kartu – bližší popis viz web výrobce. Instalace a zprovoznění modulu proběhlo bez problémů a během několika minut je možno přistoupit k vlastním experimentům. Zároveň s objednáním modulu jsem se pustil do stahování a studia dokumentace a zde je třeba říci, že to není nic snadného. Pro představu: Architecture a Technical reference manual k ARM jádru celkem 920 stran, data sheet k LM3S6911  500 stran, manuál k C knihovně Stellaris Ware značně usnadňující obsluhu periferií  320 stran, manuál k IDE, C překladači a assembleru 1100 stran. Celkem tedy přes 2800 stran manuálů. Navíc dokumentace na sebe příliš nenavazuje – popis jádra je obecný popis Cortex M3 architektury od firmy ARM, popis vlastního obvodu a Stellaris Ware je od Luminary Micro, IDE a překladač je od IAR, takže propojit to vše dohromady  a správně aplikovat na daný konkrétní odvod je poměrně náročné.

Při podrobném studiu datasheetu procesoru jsem zjistil první nepříjemnou věc: i když se jedná o 32bitový procesor, IO porty jsou organizovány po 8 bitech, takže rychlou komunikaci s 16 nebo 32bitovými ext. periferiemi  nelze očekávat.

Kit je dodáván s řadou názorných příkladů demonstrujících možnosti procesoru i vývojového kitu, od nejjednodušších jako je ovládání IO portů, sériových portů, čítačů, až po http server s kompletním TCP/IP stackem či souborový systém FAT16/32 pro SD kartu.

V průběhu praktických experimentů jsem zjistil, že jedna z uváděných hlavních výhod Cortex M3 procesorů – přímá manipulace s jednotlivými bity sice hezky vypadá ale  praktická využitelnost této možnosti je diskutabilní, přímý zápis není o nic rychlejší než „klasická“ manipulace pomocí masky a instrukcí AND či OR. To bylo dalším nepříjemným překvapením – změna stavu jediného pinu trvá 7 hodinových cyklů. Pro srovnání: můj oblíbený klon 8051 od SiLabs [6] to zvládá za 2 hodinové cykly.

Když jsem pátral po příčině tak špatného výsledku, zjistil jsem, že se jedná o instrukci typu read-modify-write, při které čtení a zápis probíhá přes pomalejší sběrnici APB vkládající jeden wait stav. Výsledkem je tak paradoxní situace, kdy nastavení jednoho bitu na portu trvá 7x déle než vynásobení dvou 32bitových čísel. Nejrychlejším způsobem zápisu jediného bitu na port je přímý zápis s využitím masky programovatelné pro každý port - věc u 8bitových procesorů neznámá. Na zdánlivě triviální úloze - obsluze portů lze názorně demonstrovat flexibilitu a zároveň složitost práce s periferiemi u tohoto procesoru: každý 8bitový port je obsluhován pomocí sady 20! registrů, takže nastavení a obsluha portů zvláště napoprvé není snadná záležitost.

Ethernet a TCP/IP stack

Moje plánovaná aplikace předpokládá přenos většího množství dat přes Ethernet rozhraní, a proto jsem v dalším kroku prozkoumal možnosti v této oblasti. Modul je dodáván s kompletními zdrojovými kódy dvou TCP/IP implementací: uiP a lwIP. uiP implementace je jednodušší, s menšími paměťovými nároky, s řadou srozumitelných příkladů a proto jsem ji začal testovat jako první. Fungovala korektně, ovšem se základním omezením vyplývajícím přímo z principu TCP/IP komunikace. Tato komunikace totiž funguje standardně tak, že pokud je vyslán jen jeden paket, není přijímací  stranou potvrzen ihned, ale až za cca 200 ms (Nagle algoritmus). Tímto algoritmem jsou eliminována zbytečně častá potvrzení zatěžující nadměrně síť. Důsledkem je žalostná přenosová rychlost řádu jednotek kByte/s. Uvedeným neduhem ovšem trpí prakticky každý jednodušší TCP/IP stack, i když u mnohých to není uvedeno. Pro dosažení vyšších přenosových rychlostí je nutno vyslat nejméně dva pakety a teprve pak čekat potvrzení, což je  výpočetně a paměťově mnohem náročnější.

LwIP implementace je o poznání dokonalejší a výše uvedeným neduhem netrpí. Jedná se o velmi propracované řešení, o jehož rozsahu svědčí fakt, že dodávaná dokumentace o rozsahu 168 stran je pouhý soupis dostupných funkcí a datových struktur s maximálně dvouřádkovým popisem.  Hlavním zdrojem informací je tak dodaný demo příklad http serveru, jehož pečlivým studiem a opatrnou editací lze dospět k požadovanému výsledku.

Tato implementace je velmi efektivní, při použití optimalizované procedury pro výpočet kontrolního součtu bylo dosaženo přenosové rychlosti 4.9 Mbyte/s. Zde se naplno projevuje síla 32bitové architektury – implementace lwip stacku na 8bitovém AVR je cca o řád pomalejší. Navíc díky integraci budiče fyzické vrstvy Ethernet rozhraní na čip stačí připojit jen konektor s transformátorem a kompletní Ethernet zařízení je hotovo. Jedinou nepříjemností pro případnou výrobu je tak nutnost zakoupit unikátní MAC adresu.

Návrh vlastní aplikace

Po ověření základních vlastností procesoru pomocí vývojového kitu jsem přistoupil k návrhu své aplikace - měřicího modulu 14bitů/400 kS/s připojenému přes Ethernet. Již při kreslení schématu jsem zjistil, že výrobce rozmístil vývody obvodu poněkud nešťastně – ani jeden port nemá všech osm pinů vedle sebe, nýbrž zpravidla na různých stranách obvodu, občas i protilehlých. Obvod používá dvě napájecí napětí: 3.3 V pro periferie a 2.5 V pro jádro, hodinový kmitočet je generován z interního PLL o frekvenci 400 MHz,  takže  pro dodržení zásad správného návrhu  plošného spoje z hlediska EMC je podle mého názoru nutný čtyřvrstvý plošný spoj.

Výsledný prototyp používající LM3S6911 jako hlavní procesor a C8051F206 pro řízení AD převodu spolu s vývojovou deskou sloužící jako JTAG debugger
Výsledný prototyp používající LM3S6911 jako hlavní procesor a C8051F206 pro řízení AD převodu spolu s vývojovou deskou sloužící jako JTAG debugger
 

Vývojovou desku lze skutečně použít i jako plnohodnotný JTAG/USB debugger pro ladění vlastní aplikace, v průběhu psaní programu pro prototyp se ukázalo, že JTAG rozhraní lze nepříjemně snadno zablokovat. JTAG totiž sdílí piny spolu s IO portem a stačí jedna chyba při ovládání zbývajících pinů portu a procesor přestane komunikovat. Doporučuji proto na úplný začátek programu umístit test stavu jednoho pinu a nekonečnou smyčku při jeho nulové hodnotě, zkratovací propojka na zem pak umožní včasné zacyklení programu ještě před případnou chybou a zachování komunikace přes JTAG.

 Závěr

ARM Cortex M3  procesory jsou skutečně výkonné a často i levnější než 8bitové procesory s odpovídající velikostí pamětí FLASH a RAM. Rovněž hardware i software pro plnohodnotný vývoj je možno pořídit za velmi příznivé ceny. Nabízejí výkonné periferie jako např. 100 Mbit Ethernet, a dostatečnou kapacitu paměti i pro rozsáhlejší programy. Pokud uvažujete o použití 32bitových procesorů, pak je uvedená architektura jedním z nejperspektivnějších  řešení. Přesto se mi zdá tvrzení výrobce, že jsou univerzální náhradou 8bitových procesorů poněkud nadnesené. Jejich zvládnutí rozhodně není triviální záležitost a i proto se domnívám, že pro jednodušší aplikace, zvláště pokud vyžadují rychlou manipulaci s porty, zůstávají 8bitové procesory stále nejjednodušší a mnohdy i výkonnější alternativou zpravidla i s nižším příkonem.

Download a odkazy

[1] http://www.arm.com/pdfs/IntroToCortex-M3.pdf
[2]  www.olimex.com
[3] www.luminarymicro.com
[4] http://www.st.com/mcu/inchtml-pages-stm32.html
[5] www.hte.cz
[6] www.silabs.com

Hodnocení článku: 

Komentáře

Diky za zajimavy clanek.

Nejak ale nechapu souvislost frekvence interniho PLL a z toho vyplyvajici potreby 4-vrstveho PCB
(cituji: ... hodinový kmitočet je generován z interního PLL o frekvenci 400 MHz, takže pro dodržení zásad správného návrhu plošného spoje z hlediska EMC je podle mého názoru nutný čtyřvrstvý plošný spoj).

Tech 400 MHz prece nikde neopusti vlastni chip, casovani je odvozeno z krystalu 3.57-8.192 MHz a rychlost I/O portu take neni nijak zavratna (jak jste nakonec sam uvadel).

Nebo to bylo mysleno nejak uplne jinak ?

Diky.
rollfree

Bylo to myšleno tak, že vzhledem k této frekvenci je velmi vhodné použít souvislou zemní plochu pod obvodem a jeho okolím, blokovací kondenzátory co nejtěsněji k napájecím pinům, obě napájecí napětí by měly být také rozvedeny co nejširšími vodiči - ideálně opět souvislou plochou. A pokud k takto ošetřenému obvodu chcete ještě připojit na piny "něco svého", zjistíte, že ve dvou vrstvách to jde velmi špatně, obzvláště proto, že piny jednoho portu nejsou fyzicky vedle sebe.

Mohl byste uvést odkaz, kde je popsáno, že nastavení trvá 7 cyklů CPU?
I tak si myslím, že výhody oproti "klasickému" způsobu existují. Podle The Definitive Guide to the ARM Cortex-M3 je operace nepřerušitelná, dále je výhoda oproti tradičnímu přístupu, pokud interrupt handler sdílí proměnnou spolu s hlavním programem. Tímto způsobem(bitband) lze nastavit i jednotlivé piny na portech.

Právě že to není popsáno nikde, to jsem si vyzkoušel na demo kitu a potvrdil v diskusi na Luminary Micro, viz téma "Bitband writes slower than direct writes?", navíc je zde komická zkušenost popsaná účastníkem diskuse: "Když se zeptám Luminary Micro na délu trvání instrukce odpoví mi, že se mám zeptat autora jádra - fy ARM, ARM mi odpoví, že je to záležitost časování APB a mám se obrátit na Luminary Micro." Pro nastavování jednotlivých bitů na portech je asi lepší přímý zápis s maskou. Operace AND a OR jsou také nepřerušitelné, takže použitelné v kritických úsecích kódu, osobně považuji bitbanding z větší části za marketingový žvást i když v principu fungující.

Domnívám, se, že nemáte pravdu - operaci s maskou nelze v kombinaci s přerušením používat. Dám jednoduchý příklad. Uživatelský program modifikuje bit 0 slova 0 RAM a přerušovací rutina modifikuje bit 1 stejn0ho slova....

LDR R0,=0x2000000 ;setup adresa
LDR R1,[R0] ;read
ORR.W R1, #0x04 ;modify bit
..... a tady prijde preruseni, ktere modifikuje stejne slovo, pouze bit 1
STR R1, [R0] ; zapis data zpet zniči modifikaci z preruseni

Bitové operace jsou vždy o instrukci kratší, pokud je bitová adresa známa a jejich použití na bitových polích - bitové přesuny a pod - jsou nesmírně výhodné a účinné.

Literatura říká, že READ-MODIFY-WRITE operace na bitech je aplikována pouze na datový přístup a ne na instrukci, takže pokud modifikovaná data nejsou potřebná v další instrukci k žádnému zpomalení nedojde.

S pozdravem

I. Pokorný

Děkuji za vysvětlení, zřejmě máte pravdu, v tomto případě mají bitové manipulace smysl, při práci s RAM by měly trvat jen 1 cyklus, stejně se mi ale nelíbí, že překladač C (alespoň od IAR) operace s bity nijak nepodporuje a výpočet bitové adresy je složitý.
Janásek

Děkuji za vysvětlení, zřejmě máte pravdu, v tomto případě mají bitové operace smysl, při práci s RAM by měly navíc trvat jen jeden cyklus, stejně mi se mi ale nelíbí, že C překladač práci s bity nijak nepodporuje (alespoň IAR), určení adresy v bitové oblasti je složité. Janásek

Taky se mi mikrokontroléry ARM od Luminary Micro líbí, uvažuji o nich. Rozhoduji se mezi nějakým ARM a nebo AVR 32.
Nesouhlasím s názorem v úvodu "špatná dostupnost a vysoká cena potřebných vývojových nástrojů"

Obvod AVR32: (nejvýkonější verze) cca 10$
Develop tools:- AVR Studio= Zdarma, Překladač C,C++ GCC = zdarma,
HW debugger cca 300$
S pozdravem Krátký

Procesory AVR32 vypadají velmi dobře a vycházejí cenově příznivě ale přesto mi Cortex M3 připadají perspektivnější, zvláště teď, kdy Luminary přišlo s novou rychlejší řadou, která má i interface pro připojení externích periferií nebo paměti (moje hlavní výhrada k minulým typům) a konečně se rozhoupaly i NXP a ATMEL.

Na druhou stranu lze tyto procesory velice snadno zlikvidovat i programově.
Např. Když nastavíte vnitřní oscilátor, JTAG přestane fungovat. Když změníte nastavení pinů PC.0 - PC3, JTAG přestane fungovat a na další "programové destruktory" jsem zatím nenarazil.