Mega32: Program hängt.

#1461399
Lesenswert?

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:
#1461432
Lesenswert?

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
#1461439
Lesenswert?

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. ;-)
#1461464
Lesenswert?

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 #1461490
Lesenswert?

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.
#1461491
Lesenswert?

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.
#1461501
Lesenswert?

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
#1461526
Lesenswert?

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
#1461530
Lesenswert?

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

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