Jak na S a asm v CCS550
Josef Štengl
ok1ced na nagano.cz
Úterý Prosinec 23 20:57:10 CET 2014
No a když už jsme u toho TI kompilátoru, překládáte/píšete to v THUMB nebo v ARM? ARM procesor je v tomhle hrozný
zvěrstvo. ARM assembler (instukce) nejsou špatně navržené, jen jsou dlouhé celých 32 bitů a proto vznikl THUMB (16 bit).
No a pak se přišlo na to, že THUMB je nevýkonný a přišlo THUMB2 :-D
V dokumentu ARM DUI 0489? Kde ? je poslední nalezené písmeno (u mě G) jsou všechny instrukce i s příklady použití.
První, co si musíte určit je, ve které sadě instrukcí psát. Jsou si dost podobné, ač se detaily liší. Hlavně ty zatracené
{cond} jsou se začátku zapeklité, ač se to ukáže jako dobrá myšlenka.
Na x86 jsem ASM nepotřeboval, nemohu porovnat. Tak nízko jsem tam neprogramoval :-)
Jo, tady to mám. Příklad pro ARM s tabulkou (je to pro SWI přerušení, ale to je principiálně jedno)
;-------------------------------------------------------------------------------
.text ; určení code section
.arm ; .arm .thumb2 - styl
;---------------------------------------------------------------------------------
; Global Definitions
.ref func2 ; „import“ C funkce
.ref func3 ; „import“ C funkce
;-------------------------------------------------------------------------------
; SWI handler
;-------------------------------------------------------------------------------
.def sch_asmSvcHandler ; název funkce
.asmfunc ; tohle je pro debugger
sch_asmSvcHandler ; label funkce - počátek fukce
STMFD SP!, {R7, LR} ; store link register (don't touch others register!) - uložení návratové hodnoty do
stacku LR regist + jeden pracovní R7
LDRB R7, [LR,#-1] ; Load target function code. Only for Big Endian! - Tohle souvisí s instrukcí SVC
pro vás nepodstatné - prostě nahrát index pole. pro vás asi číslo vektoru přerušení
LDR LR, handler ; jumptable address into r14
LDR LR, [LR, R7, LSL #2] ; set address to wanted function - pointer jest 32 bitů - výpočet offsetu tabulky skoků
LDMFD SP!, {R7} ; restore contents of r7 - všimněte si, že pro načtení jednoho registru není použito
LDR. On si to překladač správně přebere a přeloží LDR :-)
BLX LR ; jump to file handler - Já nevím jestli je funkce v thumb nebo arm (to je to X na
konci BL a nutnost mít u R přerušení v ARM. Pro jednu sadu vynechte X
LDMFD SP!, {LR} ; obnovení LR (kam se má vrátit) - vrací se sem po vykonání funkce z tabulky
MOVS PC, LR ; return návrat na předchozí adresu - všiměte si, že se nic neodečítá - to je u SWI (SVC)
přerušení u IRQ, FIQ je návrat subs pc, lr, #4 (pro thumb si to ověřte je to někde v tabulce, nevím jestli tam není #2)
.endasmfunc ; konec funkce - jen info pro debugger
handler:
.word jumptable
; tady volám funkce
; Když psané v C v tomto případě všechny void FCE(void)
jumptable
.word fce1 ; asm funkce a
.word fce2 ; c fce
.word fce3 ; c fce
.word fce4 ; asm
; a tak dále
.word fcen
Starterwar neznám.
procesoru se neříká, kde je tabulka vektorů. Procesor říká, který vektor přerušení nastal a pak voláte vlastní obsluhu
daného vektoru přerušení (pro IRQ, FIQ).
Aha.
Pokud myslíte vlastní tabulku přerušení procesoru, tak jsem vám psal číslo a dokument, kde je umístěn v RAM.
Já to mám jednoduchý, mám to od 0 takže píšu jenom b <label> na začátku programu :-)
Ale zkusil bych při startu něco jako (už jsem rok nepsal v asm, tak jen idea)
LDR R0, irq_isr ; do r0 nahrát adresu irq obsluhy
LDR R1, irq_vector ; adresa vektoru v ram - najít viz předchozí maily
STR R0, [R1] ; na adresu R1 uložím obsah R0
Pak by se při přerušení měla zavolat obsluha.
uložení a obnovu registrů v přerušen inebudu psát, protože mě tam chybí dbi a nemám nested irq (R nemá data cache. Tedy
vlastně RAM je data cache (L1) ale nemá DRAM paměť :-)
Dne 23.12.2014 v 19:48 Pavel Hudeček napsal(a):
> Vlastně ani nevím, jsem z toho jelen...
>
> Už jen ten prasáckej asm. Ještě jsem dokázal pochopit, že asm pro AVR má místo MOV několik různých LDx a STx, že když to
> začalo jako práce nějakého studenta, tak si asi chtěl ušetřit práci, aby překaldač nemusel analyzovat operandy. Poněkud mě
> ovšem šokovalo, že stejně je na tom ARM, resp. hůř, neboť má místo MOV celekem asi 16 různých názvů pro různé kombinace
> operandů.
>
> Zatím jsem např. nepřišel na to, jak zapíšu obsah banální proměnné do R0.
>
> Na x86 bych použil MOV a překladač by to vyřešil.
>
> Takže: V CCS 550 jsem vytvořil "hello world" projekt, k němu přidal include s různými #define na adresy registrů a makrem
> HWREG. Následně jsem z té odkazované asm ukázky vykoukal nastavení všech registrů ohledně GPIO a přerušení. Pak jsem
> přidal ještě interrupt.h a interrupt.c ze Starterwaru a použil IntAINTCInit(); a IntRegister(SYS_INT_GPIOINT2A, pokusIsr);
> Ale stále to nefungovalo. LEDky blikaly, jak jim velela smyčka na konci mainu, když jsem udělal, aby se daly přímo ovládat
> tlačítky přes čtení portu tlačítek, tak to fungovalo, ale přerušení prostě nic...
>
> Nakonec jsem zjisitil, že:
> - V tom interrupt.h/c je pole fnRAMVectors, kam se reistrujou přerušení, ale není tam nic, co by řeklo procesoru, že tady
> je ta tabulka vektorů.
> - Odkaz na to fnRAMVectors se vyskytuje i v system.lib z dema ve Starterwaru, což jednak samo o sobě nefunguje bez
> nastavení tuny dalších věcí a jednak je to monstrum, který bych do svého projektu nerad dával. A nenašel jsem od toho
> zdroják. Stejne tak není od libc.a, co je v tom hello world projektu.
>
> PH
>
> Od: Josef Štengl <ok1ced na nagano.cz>
>
> A překládáte to arm-none-eabi kompilátorem?
>
> Abych řekl pravdu, Keilem se budu zabývat jen když mě za to budou platit.
>
> Mimochodem všiml jste si, že ty ... tentonoc používají stejnou příponu pro C a header a ASM (.h)?
>
> A ještě mám dojem, že to napsáno v THUMB2. Nikdy jsem THUMB2 kód neměl odvahu spustit v přerušení, protože je řečeno, že
> se přepíná do ARM. Ale to je u R ka, u A jsem se to asi nepřepíná, pokud si matně vzpomínám z vašeho předchozího dotazu.
>
> Dne 23.12.2014 v 18:56 Pavel Hudeček napsal(a):
> > Díky, nějak mi časem vypadla. Teď už to zas hlásí původní chybu:
> > [E0004] Coprocessor information field must be an absolute constant
> > a to hned 2x za sebou
> >
> > Jenže takhle přesně jsem to zkpíroval ze souboru init.S, který je v 3000.trivial-a8.zip
> > <http://e2e.ti.com/cfs-file.ashx/__key/communityserver-discussions-components-files/791/3000.trivial_2D00_a8.zip>
> > odkazovaném zde:
> > http://e2e.ti.com/support/arm/sitara_arm/f/791/p/360758/1268334#1268334
> >
> > stejně je to i v start.S v io-irq.tar.gz
> > <http://e2e.ti.com/cfs-file/__key/communityserver-discussions-components-files/791/io_2D00_irq.tar.gz> odkazovaném zde:
> > http://e2e.ti.com/support/arm/sitara_arm/f/791/p/389752/1376393#1376393
> >
> > jen mi zcela uniká, proč nikde před tím nevidím vložení adresy vektorů do R0. Tam je pro mě navíc naprosou záhadou celá
> > syntaxe, např. to, že je všechno deklarováno stylem "let main() -> void" wtf?
> >
> > Od: Milan B. <milan na bastl.sk>
> >
> > On 23. 12. 2014 18:08, Pavel Hudeček wrote:
> > > 3. Co dělám špatně, když mi překladač nepřeloží "MCR p15, 0 r0, c12, c0"?
> > > Píše: [E0003] Unexpected trailing operand(s)
> >
> > Nechyba tam ciarka?
>
>
>
> _______________________________________________
> HW-list mailing list - sponsored by www.HW.cz
> Hw-list na list.hw.cz
> http://list.hw.cz/mailman/listinfo/hw-list
>
Další informace o konferenci Hw-list