Mega32: Program hängt.

OP #1461399
Hallo !

Ich habe ein lange funktionierendes Programm für einen Mega32 erweitert. 
Nun läuft das Ding zwar an, aber es bleibt an einer bestimmten Stelle 
hängen. Das hatte ich früher schon mal - zu viel Speicher benötigt.

Derzeit sieht die Ausgabe des avr-gcc so aus:
1
Linking: psuctrl.elf
2
avr-gcc -mmcu=atmega32 -I. -gdwarf-2 -DF_CPU=8000000UL  -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=controller.o -I/Users/frgo/gnc//avr/gaul -std=gnu99 -MD -MP -MF .dep/psuctrl.elf.d controller.o --output psuctrl.elf -Wl,-Map=psuctrl.map,--cref   /Users/frgo/gnc//avr/gaul/libgaul.a -Wl,-u,vfprintf -lprintf_flt  -lm
3

4
Creating load file for Flash: psuctrl.hex
5
avr-objcopy -O ihex -R .eeprom psuctrl.elf psuctrl.hex
6

7
Creating load file for EEPROM: psuctrl.eep
8
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \
9
  --change-section-lma .eeprom=0 -O ihex psuctrl.elf psuctrl.eep
10
avr-objcopy: --change-section-lma .eeprom=0x00000000 never used
11

12
Creating Extended Listing: psuctrl.lss
13
avr-objdump -h -S psuctrl.elf > psuctrl.lss
14

15
Creating Symbol Table: psuctrl.sym
16
avr-nm -n psuctrl.elf > psuctrl.sym
17

18
Size after:
19
psuctrl.elf  :
20
section             size      addr
21
.text              22422         0
22
.data                692   8388704
23
.bss                 863   8389396
24
.stab               1632         0
25
.stabstr             198         0
26
.debug_aranges       512         0
27
.debug_pubnames     4201         0
28
.debug_info        24239         0
29
.debug_abbrev       6788         0
30
.debug_line        19513         0
31
.debug_frame        3104         0
32
.debug_str          5322         0
33
.debug_loc         13478         0
34
.debug_ranges       1104         0
35
Total             104068
36

37
AVR Memory Usage:
38
-----------------
39
Device: atmega32
40

41
Program:   23114 bytes (70,5% Full)
42
(.text + .data + .bootloader)
43

44
Data:       1555 bytes (75,9% Full)
45
(.data + .bss + .noinit)
46

47
-------- end --------

Angehängte Dateien:
controller.c/.h: Der eigentliche Source Code.
libgaul.tar: TAR Datei mit Utility Library (wird auch in anderen 
Projekten erfolgreich eingesetzt)
Makefile: ...

Sieht also doch gut aus, oder?

Bin für jeden Hinweis dankbar !!!

Viele Grüße

  Frank DG1SBG
Angehängte Dateien:
hier sind ein paar stellen die mir merkwürdig vorkommen:

> tRelayID get_relay_id( tRelayID nID )
> {
>   return (tRelayID) nID;
> }

der sinn des cast bzw der gesamten funktion ist mir nicht ganz klar

> uint8_t  nTmpSREG = SREG;      // Save status
dafür ist der compiler da, das macht man doch nicht selber

damit könntest du schon etwas sparen.
OP
Marcus Kunze schrieb:
> hier sind ein paar stellen die mir merkwürdig vorkommen:
>
>> tRelayID get_relay_id( tRelayID nID )
>> {
>>   return (tRelayID) nID;
>> }
>
> der sinn des cast bzw der gesamten funktion ist mir nicht ganz klar

Reine Abstraktion. Das könnte ein paar Byte sparen, wenn dies 
weggelassen würde. Aber: Meine Frage ist ein wenig anders gelagert.

Lt. Compiler habe ich noch Platz ...

>> uint8_t  nTmpSREG = SREG;      // Save status
> dafür ist der compiler da, das macht man doch nicht selber

Aha. Und wie?

>
> damit könntest du schon etwas sparen.

Muss ich denn???

Danke!

Frank
OP
gast schrieb:
>> tRelayID get_relay_id( tRelayID nID )
>> {
>>   return (tRelayID) nID;
>> }
>
>
> das ist echt witzig ^^

Nicht unbedingt. Das ist die Umsetzung zwischen Software-Ebene und 
Hardware-Ebene. Wenn  ich die Relays anders beschalte bzw. verdrahte, 
kann ich hier die Addressierung zentral ändern. Zur Zeit bedeutet die 
Funktion: Die Relays sind so mit Nummern versehen, dass diese sich 
direkt als das Bit des Ports nehmen lassen. Das muss nicht immer so 
sein, v.a. wenn das selbe Grund-Programm für mehrere ähnliche Projekte 
verwendet wird.

Das ist einfach eine Abstraktionsebene (mehr).

Gruß,
  Frank

P.S. Ich lach auch gerne - nur gerade eben nicht mehr. Das Programm 
läuft immer noch nicht. ;-)
OP
Marcus Kunze schrieb:
>>> uint8_t  nTmpSREG = SREG;      // Save status
>> dafür ist der compiler da, das macht man doch nicht selber
>
> Aha. Und wie?
>
> einfach weglassen, damit sparst du schon mal 1byte ram

???
Äh - wie kann denn der Compiler ahnen, dass ich das SREG sichern 
will/muss ?

Es gibt da wohl inzwischen ein Makro, ja, aber weglassen ? (Ich bin nur 
Gelegenheits-µC-Programmierer - ich komm einfach nicht drauf, wie der 
Compiler das ohne irgendwas hinbekommt).

Danke!

Gruß,
  Frank
Gast
Was ist besser zu lesen?
1
rc_t switch_it( tComponentClassID nObjectClassID, char **ppcTokens, uint16_t nTokenIndex )
2
{
3
  rc_t              nRC            = RC_OK;
4
  tComponentClassID nClassID       = OBJECT_CLASS_ID_INVALID_ID;
5
  uint16_t          nCurTokenIndex = nTokenIndex;
6
  char             *pcCurToken     = ppcTokens[ ++nCurTokenIndex ];
7

8
  nRC = get_key_value_pair( pcCurToken, acKey, acValue );
9

10
  if( nRC == RC_OK )
11
  {
12
    // Value -> Component Class
13
      
14
    nClassID = get_component_class_id( acKey );
15
    if( nClassID == nObjectClassID )
16
    {
17
      tIOID nIOID 
18
        = get_io_id_from_darc_value( nObjectClassID, acValue );
19
          
20
      if( nIOID != NO_IO )
21
      {
22
        // Next token = Key/value pair for mode
23
            
24
        pcCurToken = ppcTokens[ ++nCurTokenIndex ];
25

26
        nRC = get_key_value_pair( pcCurToken, &acKey, &acValue );
27
        if( nRC == RC_OK )
28
        {
29
          tIOStatus nMode = get_mode( acValue );
30
          switch_io( nObjectClassID, nIOID, nMode );
31
        }
32
        else
33
        {
34
          nRC = DARC_CAT_CMD_FC_INVALID_PARAMETER;
35
        }
36
      }
37
      else
38
      {
39
        nRC = DARC_CAT_CMD_FC_INVALID_PARAMETER;
40
      }
41
    }
42
    else
43
    {
44
      nRC = DARC_CAT_CMD_FC_INVALID_PARAMETER;
45
    }
46
  }
47
  else
48
  {
49
    nRC = DARC_CAT_CMD_FC_INVALID_PARAMETER;
50
  }
51
 
52
  return nRC;
53
}

oder
1
rc_t switch_it( tComponentClassID nObjectClassID, char **ppcTokens, uint16_t nTokenIndex )
2
{
3
  rc_t              nRC            = RC_OK;
4
  tComponentClassID nClassID       = OBJECT_CLASS_ID_INVALID_ID;
5
  uint16_t          nCurTokenIndex = nTokenIndex;
6
  char             *pcCurToken     = ppcTokens[ ++nCurTokenIndex ];
7

8
  nRC = get_key_value_pair( pcCurToken, acKey, acValue );
9
  if( nRC != RC_OK ) {
10
    return DARC_CAT_CMD_FC_INVALID_PARAMETER
11
  }
12

13
  // Value -> Component Class
14
  nClassID = get_component_class_id( acKey );
15
  if( nClassID != nObjectClassID ) {
16
     return DARC_CAT_CMD_FC_INVALID_PARAMETER
17
  }
18

19
  tIOID nIOID = get_io_id_from_darc_value( nObjectClassID, acValue );
20
  if( nIOID == NO_IO ) {
21
     return DARC_CAT_CMD_FC_INVALID_PARAMETER;
22
  }
23

24
  // Next token = Key/value pair for mode
25
  pcCurToken = ppcTokens[ ++nCurTokenIndex ];
26

27
  nRC = get_key_value_pair( pcCurToken, &acKey, &acValue );
28
  if( nRC == RC_OK ) {
29
     return DARC_CAT_CMD_FC_INVALID_PARAMETER;
30
  }
31

32
  tIOStatus nMode = get_mode( acValue );
33
  switch_io( nObjectClassID, nIOID, nMode );
34

35
  return RC_OK ;
36
}

Ja ich weiss, es gibt Leute die sagen es darf nur ein return geben, aber 
ich das ist mal ein schönes Beispiel dafür das es das ganze nicht 
lesbarer macht.
Frank Goenninger schrieb:
> Marcus Kunze schrieb:
>>>> uint8_t  nTmpSREG = SREG;      // Save status
>>> dafür ist der compiler da, das macht man doch nicht selber
>>
>> Aha. Und wie?
>>
>> einfach weglassen, damit sparst du schon mal 1byte ram
>
> ???
> Äh - wie kann denn der Compiler ahnen, dass ich das SREG sichern
> will/muss ?

Vergiss das einfach. Marcus hat nur nicht durchschaut, was du da machst. 
Ich würde an deiner Stelle allerdings <util/atomic.h> benutzen.
OP
Stefan B. schrieb:
> Du hast das SRAM zu fast 76% mit Variablen gefüllt und zusätzlich in
> einigen Funktionen ziemlich viel lokal auf dem Stack liegen.

Yep. Das ist sicherlich das Problem ...

>
> Ich würde da abspecken oder versuchsweise auf den pinkompatiblen, aber
> grösseren Atmega644P wechseln
> (http://www.atmel.com/dyn/resources/prod_documents/doc8001.pdf)

Ist bestellt ;-)

Danke!

Gruß,
  Frank
OP
Peter schrieb:

> rc_t switch_it( tComponentClassID nObjectClassID, char **ppcTokens,
> uint16_t nTokenIndex )
> {
>   ....
>   // Next token = Key/value pair for mode
>   pcCurToken = ppcTokens[ ++nCurTokenIndex ];
>
>   nRC = get_key_value_pair( pcCurToken, &acKey, &acValue );
>   if( nRC == RC_OK ) {
>      return DARC_CAT_CMD_FC_INVALID_PARAMETER;
>   }
>
>   tIOStatus nMode = get_mode( acValue );
>   switch_io( nObjectClassID, nIOID, nMode );
>
>   return RC_OK ;
> }

Stimmt. Übernommen. Nur: Programm damit auch nicht kleiner geworden ;-)

Gruß,
  Frank
OP
Stefan Ernst schrieb:
> Frank Goenninger schrieb:
>> Marcus Kunze schrieb:
>>>>> uint8_t  nTmpSREG = SREG;      // Save status
>>>> dafür ist der compiler da, das macht man doch nicht selber
>>>
>>> Aha. Und wie?
>>>
>>> einfach weglassen, damit sparst du schon mal 1byte ram
>>
>> ???
>> Äh - wie kann denn der Compiler ahnen, dass ich das SREG sichern
>> will/muss ?
>
> Vergiss das einfach. Marcus hat nur nicht durchschaut, was du da machst.
> Ich würde an deiner Stelle allerdings <util/atomic.h> benutzen.

Jau. Sicherlich. Der Ur-Quelltext stammt noch aus einer Zeit, als es 
atomic.h noch nicht gab...

Danke übrigens - ich dachte schon, ich hätte was Grundlegendes nicht 
mitbekommen.

Gruß,
  Frank

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 17 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.