Attiny-Entwicklungsumgebung rott?

OP #5345719
Lesenswert?

/*
Problem AVR-Programmierung

Seit zwei Tagen beiße ich mir die Zähne aus an meinem 
AVR-Entwicklungssystem,
das anscheinend keinen lauffähigen code mehr erzeugt.
Wird im angehängten Code-Beispiel die Zeile 6 auskommentiert, dann 
funktioniert die Portausgabe im Hauptprogramm nicht mehr.
Der adressierte port ist dann zwar auf Ausgang programmiert, liefert 
jedoch low.
Offenbar kann man den Fehler auch mit x-beliebigen anderen eingefügten 
dummy-code herbeiführen.

Meine Entwicklungsumgebung besteht aus

Kernel
$ uname -a
Linux pc4 3.16.0-5-amd64 #1 SMP Debian 3.16.51-3+deb8u1 (2018-01-08) 
x86_64 GNU/Linux

Distribution
$ lsb_release -a
No LSB modules are available.
Distributor ID:  LinuxMint
Description:  LMDE 2 Betsy
Release:  2
Codename:  betsy

IDE
Codeblocks aus SVN build 04.Feb.2018
AVR-gcc V4.8.1
AVRdude V6.1
SPI-programmer USBtiny (Lady Ada)
Attiny 25

Anzumerken ist dass ich verschiedene AVR Projekte in den letzten Jahren 
zum Laufen gebracht habe und bis vor wenigen Wochen auf diesem System 
lauffähigen Code generieren konnte.
Sowohl der Programmer als auch das Zielsystem wurden getauscht, jedoch 
ohne Erfolg.
Irgendwie riecht es nach einem ganz dämlichen Trivialfehler, aber ich 
komme einfach nicht drauf.
Es wäre schön, wenn jemand dazu eine zündende Idee haben könnte.

Dies ist der Minimalcode, bei dem der Fehler reproduzierbar auftritt.
*/

#include <stdlib.h>
#include <avr/io.h>

void PowerUp(void) {
    DDRB            = (1<<PB2);
    //DDRB            = (1<<PB2);    //!!!
}
//++++++++ Main Program

int main(void) {
    for (;;) {
    PowerUp();
    PORTB |= (1<<PB2);
    }
}
OP #5345724
Lesenswert?

bin/Release/TPA325xPowerManager.elf:     file format elf32-avr

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         00000044  00000000  00000000  00000094  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00000000  00800060  00000044  000000d8  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  2 .fuse         00000003  00820000  00820000  000000d8  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  3 .comment      00000011  00000000  00000000  000000db  2**0
                  CONTENTS, READONLY

Disassembly of section .text:

00000000 <__vectors>:
   0:  0e c0         rjmp  .+28       ; 0x1e <__ctors_end>
   2:  15 c0         rjmp  .+42       ; 0x2e <__bad_interrupt>
   4:  14 c0         rjmp  .+40       ; 0x2e <__bad_interrupt>
   6:  13 c0         rjmp  .+38       ; 0x2e <__bad_interrupt>
   8:  12 c0         rjmp  .+36       ; 0x2e <__bad_interrupt>
   a:  11 c0         rjmp  .+34       ; 0x2e <__bad_interrupt>
   c:  10 c0         rjmp  .+32       ; 0x2e <__bad_interrupt>
   e:  0f c0         rjmp  .+30       ; 0x2e <__bad_interrupt>
  10:  0e c0         rjmp  .+28       ; 0x2e <__bad_interrupt>
  12:  0d c0         rjmp  .+26       ; 0x2e <__bad_interrupt>
  14:  0c c0         rjmp  .+24       ; 0x2e <__bad_interrupt>
  16:  0b c0         rjmp  .+22       ; 0x2e <__bad_interrupt>
  18:  0a c0         rjmp  .+20       ; 0x2e <__bad_interrupt>
  1a:  09 c0         rjmp  .+18       ; 0x2e <__bad_interrupt>
  1c:  08 c0         rjmp  .+16       ; 0x2e <__bad_interrupt>

0000001e <__ctors_end>:
  1e:  11 24         eor  r1, r1
  20:  1f be         out  0x3f, r1  ; 63
  22:  cf e5         ldi  r28, 0x5F  ; 95
  24:  d2 e0         ldi  r29, 0x02  ; 2
  26:  de bf         out  0x3e, r29  ; 62
  28:  cd bf         out  0x3d, r28  ; 61
  2a:  06 d0         rcall  .+12       ; 0x38 <main>
  2c:  09 c0         rjmp  .+18       ; 0x40 <_exit>

0000002e <__bad_interrupt>:
  2e:  e8 cf         rjmp  .-48       ; 0x0 <__vectors>

00000030 <PowerUp>:
  30:  8c e0         ldi  r24, 0x0C  ; 12
  32:  87 bb         out  0x17, r24  ; 23
  34:  87 bb         out  0x17, r24  ; 23
  36:  08 95         ret

00000038 <main>:
  38:  cc e0         ldi  r28, 0x0C  ; 12
  3a:  fa df         rcall  .-12       ; 0x30 <PowerUp>
  3c:  c8 bb         out  0x18, r28  ; 24
  3e:  fd cf         rjmp  .-6        ; 0x3a <main+0x2>

00000040 <_exit>:
  40:  f8 94         cli

00000042 <__stop_program>:
  42:  ff cf         rjmp  .-2        ; 0x42 <__stop_program>
#5345784
Lesenswert?

MWS schrieb:
> Es sollte auffallen, dass 1<<x niemals 2 Bits setzen kann, wie es bei
> 0x0C geschieht.
> Ergo: Compiler kaputt.

Also "Compiler kaputt" ist es doch in etwa 101% aller Fälle nicht. 
Insbesondere nicht bei so einem offensichtlichen Fehler.

Der CPP scheint aus 1<<PB2 den Wert 0x0C zu generieren. Muss also was in 
den entsprechenden Header Files mit den Definitionen kaputt sein. Schau 
doch mal wie PB2 definiert ist.
Gast #5345811
Lesenswert?

Und was macht PINB2 statt PB2?

Edit:
ok, sollte nix bringen, sind zumindest in meinem alten gcc gleich 
definiert. Ist schon komisch das der Compiler aus einem zweit Bits 
macht. Aber das richtige ist doch trotzdem dabei, nach dem disassembly 
müsste nur noch PB3 zusätzlich als Ausgang gesetzt werden?
OP #5345859
Lesenswert?

ich bin nun nicht so der disassembly-Versteher.
Vlt liegt der Fehler aber hier - Bildschirmausgabe vom 
CodeBlocks-Compiler-Lauf. Gleich in der ersten Zeile, wieso steht da an 
einer Stelle mmcu=attiny85, obwohl in den settings nur Attiny25 angehakt 
ist?
In früheren Läufen hatte ich in der Tat den Attiny85 programmiert, was 
ja auch noch vor wenigen Wochen funktionierte.




-------------- Build: Release in TPA325xPowerManager (compiler: GNU GCC 
Compiler for AVR)---------------

avr-gcc -mmcu=attiny85 -Wall -DF_CPU=1000000UL -Os -mmcu=attiny25  -c 
main.c -o obj/Release/main.o
avr-g++  -o bin/Release/TPA325xPowerManager.elf obj/Release/fuse.o 
obj/Release/main.o  -mmcu=attiny85 
-Wl,-Map=bin/Release/TPA325xPowerManager.map,--cref
Output file is bin/Release/TPA325xPowerManager.elf with size 1.98 KB
Running project post-build steps
avr-objdump -h -S bin/Release/TPA325xPowerManager.elf > 
bin/Release/TPA325xPowerManager.lss
avr-objcopy -R .eeprom -R .fuse -R .lock -R .signature -O ihex 
bin/Release/TPA325xPowerManager.elf bin/Release/TPA325xPowerManager.hex
avr-objcopy --no-change-warnings -j .eeprom --change-section-lma 
.eeprom=0 -O ihex bin/Release/TPA325xPowerManager.elf 
bin/Release/TPA325xPowerManager.eep
avr-objcopy --no-change-warnings -j .lock --change-section-lma .lock=0 
-O ihex bin/Release/TPA325xPowerManager.elf 
bin/Release/TPA325xPowerManager.lock
avr-objcopy --no-change-warnings -j .signature --change-section-lma 
.signature=0 -O ihex bin/Release/TPA325xPowerManager.elf 
bin/Release/TPA325xPowerManager.sig
avr-objcopy --no-change-warnings -j .fuse --change-section-lma .fuse=0 
-O ihex bin/Release/TPA325xPowerManager.elf 
bin/Release/TPA325xPowerManager.fuse
srec_cat bin/Release/TPA325xPowerManager.fuse -Intel -crop 0x00 0x01 
-offset  0x00 -O bin/Release/TPA325xPowerManager.lfs -Intel
srec_cat bin/Release/TPA325xPowerManager.fuse -Intel -crop 0x01 0x02 
-offset -0x01 -O bin/Release/TPA325xPowerManager.hfs -Intel
/bin/sh: 1: srec_cat: not found
Process terminated with status 127 (0 minute(s), 0 second(s))
0 error(s), 0 warning(s) (0 minute(s), 0 second(s))
Gast #5345865
Lesenswert?

mein altes AtmelStudio mit gcc 3.4 macht es richtiger:
1
0000002c <PowerUp>:
2

3
#include <stdlib.h>
4
#include <avr/io.h>
5

6
void PowerUp(void) {
7
  DDRB            = (1<<PB2);
8
  2c:  84 e0         ldi  r24, 0x04  ; 4
9
  2e:  87 bb         out  0x17, r24  ; 23
10
  DDRB            = (1<<PB2);    //!!!
11
  30:  87 bb         out  0x17, r24  ; 23
12
  32:  08 95         ret
13

14
00000034 <main>:
15
}
16
//++++++++ Main Program
17

18
int main(void) {
19
  for (;;) {
20
    PowerUp();
21
  34:  fb df         rcall  .-10       ; 0x2c <PowerUp>
22
    PORTB |= (1<<PB2);
23
  36:  c2 9a         sbi  0x18, 2  ; 24
24
  38:  fd cf         rjmp  .-6        ; 0x34 <main>
25

26
0000003a <_exit>:
27
  3a:  f8 94         cli
28

29
0000003c <__stop_program>:
30
  3c:  ff cf         rjmp  .-2        ; 0x3c <__stop_program>

wenn ich die //!!! Zeile auskommentiere wird auch nur ein out generiert.
Gast #5345897
Lesenswert?

ohne das jetzt im Detail geprüft zu haben: ich vermute die falsche mcu 
definition führt dazu das der Stackpointer falsch initialisiert wird 
(tiny85 hat 512 Byte RAM, tiny24 nur 128 Bytes) und dann der Rücksprung 
aus PowerUp() nicht mehr im main() landet. Damit wird der Port 
initialisiert, aber das Bit in main nicht mehr gesetzt.
Das passiert vielleicht wenn man das CodeBlocks Projekt kopiert und die 
mcu Einstellung verändert, dann muss die IDE ja die alte Einstellung 
erkennen und ändern. Das hat sie wohl nicht und den tiny25 hinzugefügt. 
Vielleicht korrigiert die IDE das wenn man noch andere 
Compilereinstellungen ändert.
Aber eigentlich wollte ich mir die AVR gar nicht mehr ansehen...
Persönliche Seite #5345969
Lesenswert?

Johannes S. schrieb:
> ich vermute die falsche mcu definition führt dazu das der Stackpointer
> falsch initialisiert wird (tiny85 hat 512 Byte RAM, tiny24
> nur 128 Bytes)

Was aber nicht das 0xC für 1<<PB2 erklärt.

Tatsächlich wird der Startcode für ATtiny85 verwendet:
1
COLLECT_GCC_OPTIONS='-mmcu=attiny85' '-mmcu=attiny25' '-Os' '-save-temps' '-v' '-fverbose-asm'
2
collect2 version 4.8.0 20130306 (experimental)
3
.../avr/bin/ld -m avr25 .../avr/lib/avr25/crttn85.o ...
4
GNU ld (GNU Binutils) 2.23.52.20130301
5

6
0000001e <__ctors_end>:
7
  1e:  11 24         eor  r1, r1
8
  20:  1f be         out  0x3f, r1  ; 63
9
  22:  cf e5         ldi  r28, 0x5F  ; 95
10
  24:  d2 e0         ldi  r29, 0x02  ; 2
11
  26:  de bf         out  0x3e, r29  ; 62
12
  28:  cd bf         out  0x3d, r28  ; 61
13
  2a:  06 d0         rcall  .+12       ; 0x38 <main>
14
  2c:  08 c0         rjmp  .+16       ; 0x3e <_exit>
Gast #5346071
Lesenswert?

Bernd S. schrieb:
> MWS schrieb:
>> Es sollte auffallen, dass 1<<x niemals 2 Bits setzen kann, wie es bei
>> 0x0C geschieht.
>> Ergo: Compiler kaputt.
>
> Also "Compiler kaputt" ist es doch in etwa 101% aller Fälle nicht.
> Insbesondere nicht bei so einem offensichtlichen Fehler.
>
> Der CPP scheint aus 1<<PB2 den Wert 0x0C zu generieren. Muss also was in
> den entsprechenden Header Files mit den Definitionen kaputt sein. Schau
> doch mal wie PB2 definiert ist.

Spannender Fehler. denn 1<<x kann eigentlich nicht mehr als ein Bit 
gesetzt haben, egal welchen Wert x hat, also egal wie PB2 definiert ist. 
Tut es aber sowohl in der Funktion PowerUp als auch in der main, beide 
Male 0x0c

Mein avr-gcc-4.9.2 macht das auch (erstmal) richtig:
1
ldi r24,lo8(4)
2
out 0x17,r24

Der eigentliche, beobachtete Fehler scheint aber tatsächlich der falsche 
Startup-Code zu sein, der den Stack-Pointer falsch initialisiert. Ist 
auch kein Wunder, denn der Linker-Aufruf (avr-g++) bekommt nur 
-mmcu=attiny85 mit.

Da scheint die IDE die korrekten Einstellungen noch nicht in alle 
Build-Schritte übertragen zu haben.

Kann es sein, dass auch die Disassembly-Ausgabe alt ist und du 
irgendwann mal PB2 und PB3 benutzt hast?

MfG, Arno
OP #5346087
Lesenswert?

Johannes S. schrieb:
> ohne das jetzt im Detail geprüft zu haben: ich vermute die falsche mcu
> definition führt dazu das der Stackpointer falsch initialisiert wird
> (tiny85 hat 512 Byte RAM, tiny24 nur 128 Bytes) und dann der Rücksprung
> aus PowerUp() nicht mehr im main() landet. Damit wird der Port
> initialisiert, aber das Bit in main nicht mehr gesetzt.
> Das passiert vielleicht wenn man das CodeBlocks Projekt kopiert und die
> mcu Einstellung verändert, dann muss die IDE ja die alte Einstellung
> erkennen und ändern. Das hat sie wohl nicht und den tiny25 hinzugefügt.
> Vielleicht korrigiert die IDE das wenn man noch andere
> Compilereinstellungen ändert.
> Aber eigentlich wollte ich mir die AVR gar nicht mehr ansehen...

So in der Richtung denke ich auch. Ich hatte im laufenden Projekt das 
target geändert. Werde das Projekt neu aufsetzen, das könnte schon die 
Lösung sein.
Dazu komme ich aber im Augenblick nicht (Gartenarbeit ist hat eben den 
höheren Prioritätslevel).
OP #5346434
Lesenswert?

Für die vielen hilfreichen Beiträge möchte ich mich hier mal herzlich 
bedanken. Innerhalb von CodeBlocks konnte ich keine Einstellungen 
finden, die das falsche Target korrigiert hätten. Also habe ich ein 
neues Attiny25-Projekt geöffnet - und voilà - nun läuft es wieder 
erwartungsgemäß.
Und ja, es ist für mich nachvollziehbar, dass der Code, gelinkt für den 
größeren RAM-Bereich des Attiny85 im Attiny25 wohl nicht funktionieren 
wird.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren