C in ASM einbinden | ASM in C einbinden?

btw: Tabs nach Text, sowohl innerhalb, als auch außerhalb von Codeboxen ist ein Krampf.
Gibt's da 'ne einfache Möglichkeit, die ich nicht gefunden habe?
Nicht dass ich wüsste, ich schau mal ob ich eine Lösung hinbekomme.
 
Nicht dass ich wüsste, ich schau mal ob ich eine Lösung hinbekomme.
Danke.

In Codeboxen mit Blanks solange hin und herschieben, bis die Kommentare untereinanderstehen ist zeitraubend. Man muß immer wieder die Vorschau aufrufen und sehen ob's paßt.
Außerhalb werden alle Blanks und Tabs gefressen,
da geht's nur mit irgend ein Müll.←sieht man nur im BBC-Editor.
 
Wenn Du C-Funktionen aufrufen willst, muß er vorher initialisiert sein.
Richtig, ABER wie gesagt:
Den Stack brauch ich meist nicht zu initialisieren
Genau genommen ist der Stack in jedem AVR mit dem Reset bereits initialisiert. In ururalten AVR ohne SRAM über den 3-level-Stack; in allen AVR mit SRAM und Stackpointer (in den SRAM) wird der Stack während des Reset initialisiert. Immer. Bei den Dinosauriern auf 0x0000, bei "moderneren" auf RAMEND. Deswegen "meist";). Dinos setz ich selten ein.
So, Schritt für Schritt. Erstmal die einfachere Version: Asm von C aus aufrufen.
Etwas C-Syntax mußt Du sowieso lernen, wenn Du C-Funktionen aufrufen willst und wenn Du den Präprozessor schon benutzt hast, wird Dir einiges bekannt vorkommen
Naja, 'n bisschen lesen kann ich C auch (wegen TurboPascal und Delphi ? ) - jedenfalls hab ich irgendwie die .h vernachlässigt. Den Rest geh ich morgen nochmal durch...

Danke bisher...
Letztendlich ist die "kompliziertere Variante" natürlich mein Ziel...
 
Letztendlich ist die "kompliziertere Variante" natürlich mein Ziel...
Letztendlich ist es auch nicht komplizierter...
(Diesmal ohne Kommentare)
test.c


CodeBox C
#include <avr/io.h>

#define INC

uint8_t summe = 0;
uint8_t summand = 0;

uint8_t addiere(uint8_t var)
{
   return summe += var;
}

void nacktfrosch(void)
{
#ifdef INC
   summand++;
#else
   summand--;
#endif
}

test.S


CodeBox Assembler
.extern summe
.extern summand
.extern addiere
.extern nacktfrosch

.func main
.global main
main:
   lds r24, summe
0: rcall addiere
   rcall nacktfrosch
   rjmp 0b
.endfunc
 
Danke, hatte inzwischen selbst diesen Schritt geschafft. Der wesentliche Hinweis war:
File → Move test.S into _________ <Projektname>
Danach war die "invalid reference to main" weg...
So...
Mit 'ner leeren ".c" und 'ner leeren ".s" (abgesehen von der .global-Direktive und dem main-Label) werden beim Tiny44A 56 Bytes (28 Words) Code erzeugt.
  • 1 - Sprung vom 0x0000 direkt hinter die IVT (*)
  • 16 - Sprünge aus der IVT nach (**)
  • 1 - (*) Clear R1 (setzt "Z")
  • 1 - 0x00 nach SREG schreiben (löscht "Z")
  • 4 - Stackpointer von 0x015F auf 0x015F reinitialisieren
  • 1 - Call nach (***)
  • 1 - Sprung nach (***) - wird nie erreicht
  • 1 - (**) hier landen die IVT-Sprünge. Sprung nach 0x0000
  • 1 - (***) Interrupts werden global gesperrt
  • 1 - leere Endlosschleife
Das sind 1,4% des Flash, ohne daß irgendwas implementiert wurde.
Also:
Wenn die main im Assemblerquelltext steht, mußt Du Dich um fast alles selbst kümmern, Stack initialisieren, IRQ-Tabelle etc.
Nö!
Zwischen (**) und (***) würde mein ASM-Programm erscheinen, auf die Flashadressen bis dahin habe ich keinen Zugriff (.org greift da nicht korrekt). Wie komme ich an die IVT ran?

Ok, danke bis hierher. Dann könnte ich mir bei Gelegenheit mal die QTouch zu Gemüte führen...
 
Wie komme ich an die IVT ran?
In C übernimmt das der Compiler
test.c


CodeBox C
#include <avr/io.h>
#include <avr/interrupt.h>

uint8_t summe = 0;
volatile uint8_t summand = 0;

ISR(TIMER2_OVF_vect)
{
   summand++;
}

void init(void)
{
   sei();
   TCCR2A = 0;
   TIMSK2 = (1 << TOIE2);
   TCCR2B = (1 << CS20);
}

uint8_t addiere(uint8_t var)
{
   return var += summand;
}
test.S


CodeBox Assembler
.extern summe
.extern summand
.extern addiere
.extern init

.func main
.global main
main:
   rcall init
   lds r24, summe
0: rcall addiere
   sts summe, r24
   rjmp 0b
.endfunc

und - Überraschung! - in Assembler natürlich auch ;)
test.c

CodeBox C
#include <avr/io.h>
#include <avr/interrupt.h>

uint8_t summe = 0;
volatile uint8_t summand = 0;

void init(void)
{
   sei();
   TCCR2A = 0;
   TIMSK2 = (1 << TOIE2); 
   TCCR2B = (1 << CS20); 
}

uint8_t addiere(uint8_t var)
{
   return var += summand;
}
test.S


CodeBox Assembler
.nolist
#include <avr/io.h>  
.list

.global TIMER2_OVF_vect
TIMER2_OVF_vect:
   lds r16, summand
   inc r16
   sts summand, r16
   reti

.extern summe
.extern summand
.extern addiere
.extern init

.func main
.global main
main:
   rcall init
   lds r24, summe
0: rcall addiere
   sts summe, r24
   rjmp 0b
.endfunc
 
Ein weiterer Punkt, der sich meiner Kontrolle entzieht...
Egal.
Die XTinies scheinen im 7er Studio erst ab Build Version 1118 integriert zu sein... Update läuft.....
 
Hmm...
irgendwie konnte der QTouch-Composer dann nur noch nonPTC-Projekte composen... die anderen Punkte ware ausgegraut... also nochmal gaanz von vorn. Alles deinstalliert, und dann:
  • ATMEL Studio frisch aus dem Netz installiert -> Version 7.0.1188
    • ASF ist auf Version 3.32.0.596
    • QTouch Composer ist auf Version 5.9.116.0
    • die XTinies sind als Devices verfügbar
    • beim Versuch eines QTouch-Projektes wird die fehlende Library bemängelt
  • QTouch-Library als Extension hinzugefügt -> Version 5.9.0.211
    • Composer verwendbar, aber der compost nur für diverse SAMs und die beiden neuen PB-Megas (ATmega324PB/328PB) - vom XTiny keine Spur)
  • für das ASF ist'n Upgrade verfügbar ->3.33.0.640 -> keine Änderung
Hmm...
The ATtiny816 PTC is supported by the Atmel QTouch Composer development tool (QTouch Library project builder and QTouch Analyzer).
Quelle

Ja wie denn??
Warum ist der Support von Micromel eigentlich JEDESMAL in Wartung wenn ich mal was von denen will???
 
Hmm...
The ATtiny816 PTC is supported by the Atmel QTouch Composer development tool (QTouch Library project builder and QTouch Analyzer).
Quelle
Heute die Antwort vom Support:
Please note that QTouch project builder support for ATtiny817/816/814 is available in Atmel START (not in Atmel Studio). The latest QTouch Modular Library is used for implementing QTouch support in ATtiny816. This modular library is part of Atmel START. Therefore, you need to use Atmel START (http://start.atmel.com/) for QTouch in ATtiny816.
"Start" ist irgendwie sowas wie ein Online-C-Code-Zusammenklick-Generator. (Womit wir mal wieder beim Online-Zwang wären)
Zum QTML-PTC gibts 'n User Guide (atmel-42805a) - allerdings scheint da der Tiny816 doch noch nicht unterstützt zu werden. Die QTML läßt sich (noch ? ) nicht "dazuklicken"...

Support Case reopened...

(nebenbei: den DataVisualizer scheint man auch als standalone laufen lassen zu können...)
 
Achtung!!! Böse Falle:
Verwendet man auf diese Art eine Assembler-Datei innerhalb eines GCC-Executable-Projektes, stimmen die unteren 0x40 I/O-Adressen nicht (wie man das in ASM gewohnt ist). Ich hab schon schier an meinen Fähigkeiten gezweifelt, 'ne LED am STK leuchten zu lassen...

CodeBox Assembler
ldi r17, lustigeBitmaske
out PORTC, r17   ;landet in OCR0B
out DDRC, r17   ;landet in OCR0A

Bis ich das rausgefunden hatte...:mad:
Ok, also bei in/out immer 0x20 abziehen...

Erstellt man ein Assembler-Projekt, ist alles beim Alten - will man ein konventionelles I/O wie SRAM adressieren (LDS/STS/LD/ST), muß man wie gehabt 0x20 addieren

So, die LEDs kann ich also endlich ansteuern... der UART spuckt auch das Testbyte aus, aber irgendwas mach ich beim EmpfangsIRQ immer noch falsch... schau ich morgen drüber.
Was muß ich für den USART Rx complete IRQ vom Mega88 als "xxxxxxx_vect" nehmen? (Flashadresse wäre ja 0x0024)
(Bzw wo finde ich Infos über die vordefinierten "vects"? in ASM hat man ja einfach ans Ende der automatisch inkludierten Definitionsdatei geschaut, wo die Equations der Interrupt-Einsprungadressen definiert waren...)
 
Da Du ja C mit Assembler mischst, hast Du ein C-Projekt, auch wenn die main im Assemblercode steht, also empfiehlt es sich statt der .inc die .h Datei einzubinden. Das macht #include <avr/io.h> automatisch richtig.

Irgendwo im Datenblatt oder einer App-Note steht sinngemäß, daß die 32 Arbeits-Register (0x20) in Assembler vor den I/O-Registern stehen und in C ausgeblendet werden. Erkennt man im Register Summary daran, daß bei den ersten Adressen 0x00 - 0x3F und 0x20 - 0x5F nebeneinander stehen.

Für den mega 88 heißt die Include-Datei iom88.h oder iom88a.h bzw. pa oder pb.
Da steht übrigens auch der USART_RX_vect (Nr. 18 (dezimal) bzw. Adresse 0x24) drin. Ziemlich weit hinten.
 
empfiehlt es sich statt der .inc die .h Datei einzubinden. Das macht #include <avr/io.h> automatisch richtig.
Die Sache ist die, daß ich die Definitionsdatei unter ASM gar nicht (selbst) einbinde. Ich lege den zu verwendenden Controller als Device fest, dann wird beim Compilieren automatisch die zu verwendende Definitionsdatei eingebunden, und erscheint im Solution Explorer auch bei den Dependencies. Auf der Hauptprojektseite kann man den Controller dann auch mit Change Device ändern.
Hier mische ich eigentlich nicht C mit ASM - die automatisch erstellte C-Datei ist leer, die ASM-Datei enthällt allen von mir erstellten Code (inklusive des öffentlichen main-labels.
Genau genommen erstelle ich natürlich so ein C-Projekt mit Inline-Assembler (in Form einer eingebundenen ASM-Datei). Und natürlich ist die io.h eingebunden, hattest Du ja bereits mehrfach gezeigt...
Für den mega 88 heißt die Include-Datei iom88.h oder iom88a.h bzw. pa oder pb.
Da steht übrigens auch der USART_RX_vect
Jain. Wie gehabt, nach dem compilieren erscheint unter anderem die iom88.h - die Vektoren stehen aber nicht da drin, sondern in der iomx8.h .
Für den Mega88 ist das beim USART-RX-C-IRQ dann "USART_RX_vect" (wie man auch auf addi's Link mit etwas suchen findet).
Irgendwo im Datenblatt oder einer App-Note steht sinngemäß, daß die 32 Arbeits-Register (0x20) in Assembler vor den I/O-Registern stehen und in C ausgeblendet werden. Erkennt man im Register Summary daran, daß bei den ersten Adressen 0x00 - 0x3F und 0x20 - 0x5F nebeneinander stehen.
Eben. Eigentlich bei allen normalen 8bit-AVR. Bei den TPI und/oder UPDI-Tinies meine ich Abweichungen gesehen zu haben.
Auch in der derzeit aktuellen Version (W) des Mega88-Datenblattes findet sich hierzu als Fußnote unter den Register Descriptions:
When using the I/O specific commands IN and OUT, the I/O addresses 0x00 - 0x3F must be used.
When addressing I/O Registers as data space using LD and ST instructions, 0x20 must be added
to these addresses. The ATmega48/V/ 88/V /168/V is a complex microcontroller with more
peripheral units than can be supported within the 64 location reserved in Opcode for the IN and
OUT instructions. For the Extended I/O space from 0x60 - 0xFF in SRAM, only the ST/STS/STD
and LD/LDS/LDD instructions can be used.
In den jeweiligen inkludierten ASM-Definitionsdateien sind für die konventionellen I/Os entsprechend die 0x00..0x3F-Adressen definiert, in den C-Definitionsdateien die von 0x20..0x5F.

Wie gesagt, 'ne böse Falle, wenn man's andersrum gewohnt ist... egal...

Nachdem ich jetzt auch noch die Interrupt.h inkludiert hatte, läuft das UART-Echo, und die sechs LEDs an PORTC zählen die Bytes rauf.
Vielleicht komme ich ja dann morgen doch noch dazu, mal'n Sägezahn und'n Sinus (Funktion in der C-Datei(*)) draus zu machen...

(*) die relevanten ein-zwei Zeilen hab ich in der Mittagspause mal auf'n Zeitungsrand gekritzelt, muß nur noch dazu kommen, die abzutippen...
 
Ich lege den zu verwendenden Controller als Device fest
Eben. Wenn ich den 88pa auswähle (ältere benutze ich nicht), stimmt auch alles.
nach dem compilieren erscheint unter anderem die iom88.h - die Vektoren stehen aber nicht da drin, sondern in der iomx8.h
Stimmt, teilweise. Daß die Header vom 88 und 88a schon so veraltet sind, ist mir noch gar nicht aufgefallen. Hätte auch gedacht, daß Atmel die gelegentlich auf dem Laufenden hält, da hab' ich wohl falsch gedacht.

Der x8 Header muß auch schon uralt sein, da stehen neben den neuen auch noch die schon seit Jahren als deprecated klassifizierten Vektorbezeichnungen mit SIG_ drin (in p, pa und pb nur noch die neuen).

Btw: wenn ich einen 88pa benutze und ein anderes Header-File auswähle, weigert sich das Studio ihn zu programmieren. Jedenfalls bindet es den richtigen Header ein, wenn man 88pa benutzt und auswählt.
Genau genommen erstelle ich natürlich so ein C-Projekt mit Inline-Assembler
Du benutzt reine Assembler-Dateien innerhalb eines C-Projektes (auch wenn es überhaupt keinen C-Code enthält). Beim Inline-Assembler hingegen sind keinerlei Assembler-Dateien notwendig, da stehen die Assembleranweisungen direkt im C-Quelltext. Das sieht dann in etwa so aus:

CodeBox C

char data;
asm volatile (
   "ld __tmp_reg__, %a1+" "\n\t"
   "ld %0, %a1" "\n\t"
   "st %a1, __tmp_reg__" "\n\t"
   "st -%a1, %0"
      : "=&r" (data)
      : "e" (addr)
      : "memory"
);

Man kann damit längere Programmteile in Assembler schreiben, aber für mehr als ein oder zwei Befehle (wie z.B. nop, cli o.ä.) nehme ich dann doch lieber gleich ein eigenes .S-File, sonst wird mir das zu umständlich mit den In/Out-Listen und der Clobber-Liste und auch die Syntax finde ich viel zu unübersichtlich.
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)