volání subrutin v AVRASM

Neznáte náhodou někdo způsob, jak v AVRA, resp. AVRASM zavolat z mainloopu subrutinu, která je uložena v *.inc souboru ? Díky za jakoukoli inspiraci.

Já takto vkládám vlastní knihovny. Každá knihovna je rozdělena na *.inc soubor (definice paměťových míst, proměnných a konstant atd.) a *.asm soubor, kde je napsán vlastní kód. Soubor(y) *.inc nakopíruju do adresáře k projektu, protože je v něm(nich) i konfigurace pro použití třeba jen některých funkcí (definice pro podmíněný překlad) z knihovny a pro každý projekt může být (nebo spíš je) konfigurace jiná. Ve vlastním souboru jej pak vkládám hned na začátku takto :

#include <M8Adef.inc> // Soubor AVR studia pro definici použitého mcu. #include "nazev_knihovny1.inc" // Soubor s definicí konstant knihovny a její konfigurací #include "nazev_knihovny2.inc" // Soubor s definicí konstant knihovny a její konfigurací

Ve vlastním programu pak vložení kódu knihovny vypadá takto :

    .
    .
Hlavni_smycka:
    .
    .
    .
    .
   rcall knihovni_funkce
    .
    .
    .
    rjmp Hlavni_smycka

;----------------------------
; Oblast podprogramů
;----------------------------

Podprogram1:
    .
    .
    .
    ret

Podprogram2:
    .
    .
    .
    ret

#include <nazev_knihovny1.asm>
#include <nazev_knihovny2.asm>

Podprogram3:
    .
    .
    .
    ret
    .
    .

V AVR Studiu pak nastavím v “Project” -> “Assembler Options” do položky “Additional include path” vložím cestu k adresáři, kde jsou tyto knihovny uloženy.

Používám AVR Studio 4.

Takhle nějak jsi to myslel ?

OK, asi jsem se trošku blbě zeptal, nicméně to řešíš podobně jako já, s tím rozdílem, že Tobě to funguje a mě ne.
Abych Ti trošku vysvětlil svoji situaci. Pracuju v Debianu, k psaní kódu používám textový editor a pro překlad do strojového kódu používám Avra ovládaný z příkazového řádku. Symulátor nepoužívám.

Jde mi o to, že mám knihovnu s inicializačními makry (inicializace displeje, A/D převodníku, TCNT, atd); součástí jednoho makra je subrutina, na kterou se potřebuju odkázat z mainloopu. …dozvím se, že jméno subrutiny neexistuje.

Tenhle problém jsem řešil už ve svých začátcích, když jsem začínal programovat ještě ve Winech s AVRstudiem 4; vložit z externího souboru makro nebyl problém, ale odkázat se na subrutinu, uloženou v tom samém souboru , nebylo možné. Není mi jasné, kde dělám chybu.

Pokud do kódu napíšu RJMP knihovni_funkce, tak se dozvím: Found no label/variable/constant named knihovni_funkce, pokud je ale knihovní funkcí makro a napíšu jeho název, pak vše funguje. Podotýkám, že to není zřejmě nezpůsobuje AVRA, protože ve Winech s AVRASM jsem řešil totéž.

Možná Tě pořád špatně chápu, ale .inc soubory jsou v podstatě totéž, co v Cčku .h soubory - tedy hlavičkové. Ty se vkládají na začátku. Pokud v něm máš makro, pak ho nemůžeš použít dřív, než ho definuješ. Proto se dávají na začátku. Vlastní kód je třeba vložit někam do oblasti programu. Tedy #include tohoto kódu je potřeba provést až v části s kódem. Pokud tedy do hlavního souboru dáš na začátku #include s definicema (.inc) a někde dál pak soubor s kódem (.asm), bude vše fungovat OK. Pokud máš v *.inc souboru i kód, pak jej musíš vkládat nejdříve za tabulkou vektorů přerušení, aby Ti to fungovalo. Kód se totiž vloží do místa, kam jsi napsal #include jako by tam byl fyzicky napsaný. Abys tedy neodsunul vektory přerušení, musel bys mít tento soubor vložený tam. Pak by Ti to mělo fungovat i v případě, že budeš mít definice i kód v jednom souboru.

jojo, pochopil jsi to správně, používám, asi trošku nešťasntý, systém, kdy mám definice i kód v jednom *.inc souboru. Je to pozůstatek dřívějších časů, kdy jsem to jinak neuměl a takhle mi to fungovalo…a do dneška jsem tak nějak neměl důvod na tom cokoli měnit.

Skusil jsem to podle Tvojí rady a jak asi tušíš, tak už mi to funguje jak má. Jen se teť teda asi chtě-nechtě, budu muset podřítit obecně zažitým zvyklostem a rozdělit si knihovny na *.inc a *.asm, protože jinak se to, za těhle okolností, ani udělat nedá.

Díky za trpělivost a dobrou radu.

Ono mít oddělenou hlavičku a vlastní kód má i svoje výhody. Tím, že k projektu vždy kopíruju jen *.inc, který nastavím podle HW a kód v *.asm includuju přímo z adresáře s knihovníma souborama, tak když pak najdu nějakou chybu v knihovně a opravím ji, tak ji de-facto opravím ve všech projektech. Totéž platí i pro rozšíření knihovny o další možnosti. Tím že jsem začal používat podmíněný překlad, tak v *.inc souboru nastavím které části kódu potřebuju a které ne (pokud nepoužiju nějakou funkci, pak ji nepotřebuji mít v mcu). Podle toho se pak z knihovního souboru pomocí #if defined(nějaký_parametr) část kódu zkompiluje nebo ne. Podobný systém používám třeba pro komunikaci se znakovým LCD displejem. V *.inc souboru jenom nastavím, jestli chci použít 4- nebo 8- bitovou komunikaci, na výběr je dále z několika variant sérivových komunikací - vše v jednom souboru a pomocí parametrů v *.inc souboru se v knihovně vybírají odpovídající části kódu. V hlavním programu jenom zavolám funkci na poslání řetězce na LCD a nestarám se o způsob komunikace. To už je prostě v knihovně. Pokud změním HW zapojení, pak jenom přenastavím hodnoty v *.inc souboru a znova zkompiluji.

Jinak držím palce, ať Ti programování jde dobře od ruky.

Je to tím, že vkládáš soubor inc mimo (před) segment CSEG.
Kód podprogramů musí být v CSEG.
Kód maker může být před nebo v CSEG.

Takže soubor inc je třeba vložit na začátek C segmentu.
Při tom je nutno ho při běhu programu obejít, aby se po resetu nevykonával kód, který obsahuje.

[code].include “m88def.inc”

.cseg
.org 0

;případná přerušení

rjmp START ; přeskoč inkludovaný soubor

.include “muj.inc”

START:
[/code]

Trochu bych Tě poopravil :

[code].include “m88def.inc”

.cseg
.org 0

rjmp START ; přeskoč inkludovaný soubor

;případná přerušení

.include “muj.inc”

START:
[/code]
rjmp START musí být VŽDY na adrese 0, pak teprve vektory přerušení.

Jinak to je samozřejmě správně. Pokud ale v *.inc souboru je použitá nějaká definice či makro, dá se použít až za tímto vložením.

Tak.
Nějak se mi podařilo ty řádky přehodit.

Jasně, díky za doplnění. Už chápu, kde jsem dělal chybu. Nastudoval jsem si stránku s názvem* The C Preprocessor* (delorie.com/gnu/docs/gcc/cpp_toc.html). Kdybych to udělal už dávno, tak bych se na to nemusel ptát tady. Já prostě jen špatně chápal, jak funguje directiva * .INCLUDE*, resp. #INCLUDE.

Teť mě docela zaujal podmíněný překlad, o kterém se pár příspěvků níž zmiňuje Balů. Myslel jsem na něj už dávno, ale nějak jsem se k němu nemohl dokopat. Možná, že teť na to přišel ten správný čas. Až mi nebude fungovvat, tak už vím, na koho se obrátit
:wink: , ještě jednou díky za podnětné rady.