Forum: Mikrocontroller und Digitale Elektronik Problem bei Funktionsaufruf und unsigned long Übergabeparameter (SiLabs F500)


von Mr Bean (Gast)


Lesenswert?

Hallo Ich habe folgende Funktion um eine Zahl in einen String 
umzuwandeln:
1
int8_t num2string(unsigned int num, int size, char *retbuffer){
2
  int i;
3
      
4
  switch (size){
5
    case OBJ_UNSIGNED32:      
6
      // Zeichenkette erzeugen
7
      sprintf(retbuffer, "%2x%2x%2x%2x", (unsigned int) ((num& 0xff)),(unsigned int) ((num& 0xff00) >> 8),(unsigned int) ((num& 0xff0000) >> 16),(unsigned int) ((num& 0xff000000) >> 24) );
8
      break;
9
    case OBJ_UNSIGNED16 | OBJ_INDEX:      
10
      // Zeichenkette erzeugen
11
      sprintf(retbuffer, "%2x%2x", (unsigned int)((num& 0xff)), (unsigned int)((num& 0xff00) >> 8));
12
      break;           
13
    case OBJ_UNSIGNED8 | OBJ_SUBINDEX:      
14
      // Zeichenkette erzeugen
15
      sprintf(retbuffer, "%2x",(unsigned int) (num & 0xff) );
16
      break;
17
        default:
18
            return -1;       
19
  }
20
  
21
  for ( i = 0; i < strlends(retbuffer); i++)
22
  {
23
    if (retbuffer[i] == ' ')
24
    {
25
      retbuffer[i] = '0';
26
    }
27
  }   
28
  return SUCCESS;
29
}

wenn ich nun eine unsigned long Variable in eine String wandeln möchte, 
macht mir natürlich der Übergabeparameter (unsigned int) Probleme. Nun 
wollte ich den Aufruf der Funktion einfach in:
1
int8_t num2string(unsigned long num, int size, char *retbuffer){
ändern. Dann läuft mein Controller aber nichteinmal mehr los. Alle 
angeschlossenen LED`s sowie jedliche Kommunikation bleiben/bleibt aus.

Könnt ihr mir sagen woran das lieg? Oder mir einen anderen 
Lösungsvorschlag geben?

Grüße

Bean

von Karl H. (kbuchegg)


Lesenswert?

Mr Bean schrieb:

> wollte ich den Aufruf der Funktion einfach in:
>
1
> int8_t num2string(unsigned long num, int size, char *retbuffer){
2
>
> ändern.

Und alles erneut durchcompilieren.

> Dann läuft mein Controller aber nichteinmal mehr los.

Dann musst du rauskriegen woran das liegt.
Speicher voll?
An der Funktion selbst liegt es erst mal nicht.

> Alle angeschlossenen LED`s sowie jedliche Kommunikation
> bleiben/bleibt aus.

Das ist zwar ein eindeutiges Symptom, allerdings zur Fehlerdiagnose 
nicht ausreichend. Da musst du schon ein wenig mehr Aufwand reinstecken, 
bis aus dieser Symptombeschreibung die Diagnose 'Controller läuft nicht 
mehr los' abgeleitet werden kann. Was passiert denn am Anfan des 
Programms? Lass doch mal am Anfang des Programms eine LED aufleuchten, 
gleich als allererstes, noch ehe irgendwas anderes passiert. Wenn die 
auch nicht mehr kommt, dann kann man darüber nachdenken warum dein 
'Controller nicht mehr losläuft'.


PS:
Den Teil hier
1
  for ( i = 0; i < strlends(retbuffer); i++)
2
  {
3
    if (retbuffer[i] == ' ')
4
    {
5
      retbuffer[i] = '0';
6
    }
7
  }
kannst du dir sparen.
1) ist der strlends in der Abbruchbedingung nicht so glücklich, denn
   strlends wird dadurch bei jedem Schleifendurchlauf erneut
   aufgerufen. Die Länge des Strings ändert sich aber in der
   Schleife gar nicht.

2) kann die beabsichtigte Funktionalität (führende 0-en) auch das
   jeweilige sprintf übernehmen. Man muss es ihm im Formatstring nur
   sagen, dass es das tun soll:
1
      sprintf(retbuffer, "%02x",(unsigned int) (num & 0xff) );
   und schon macht sprintf anstelle der Leerzeichen da führende 0-en
   rein

von g457 (Gast)


Lesenswert?

> Könnt ihr mir sagen woran das lieg?

Ich vermute Programmierstil..

> Oder mir einen anderen Lösungsvorschlag geben?

Übergib die Daten per Adresse (vorzugsweise als void*), dann ersparst Du 
Dir die unanständigen Sachen.

Anmerken möchte ich noch folgende zwei Zeilen:

> case OBJ_UNSIGNED16 | OBJ_INDEX:
> case OBJ_UNSIGNED8 | OBJ_SUBINDEX:

Bist Du Dir bewusst, dass das binäre 'oder' hier zum umgangssprachlichen 
'und' mutiert?

von Mr Bean (Gast)


Lesenswert?

Hallo

Vielen Dank für die Tipps! Ich hab meine Funktion nun etwas 
umgeschrieben:
1
int8_t num2string(unsigned int num, int size, char *retbuffer){
2
  int i;
3
      
4
  switch (size){
5
    case OBJ_UNSIGNED32:      
6
      // Zeichenkette erzeugen
7
      sprintf(retbuffer, "%02x%02x%02x%02x", (unsigned int) ((num& 0xff)),(unsigned int) ((num& 0xff00) >> 8),(unsigned int) ((num& 0xff0000) >> 16),(unsigned int) ((num& 0xff000000) >> 24) );
8
      break;
9
    case OBJ_UNSIGNED16:
10
    case OBJ_INDEX:      
11
      // Zeichenkette erzeugen
12
      sprintf(retbuffer, "%02x%02x", (unsigned int)((num& 0xff)), (unsigned int)((num& 0xff00) >> 8));
13
      break;           
14
    case OBJ_UNSIGNED8:
15
    case OBJ_SUBINDEX:      
16
      // Zeichenkette erzeugen
17
      sprintf(retbuffer, "%02x",(unsigned int) (num & 0xff) );
18
      break;
19
        default:
20
            return -1;       
21
  }   
22
  return SUCCESS;
23
}

Allerdings hab ich das Problem mit dem nicht loslaufenden Code 
immernoch. Ich habe schon eine LED die zu allererst gesetzt wird (noch 
vor meiner whileschleife und den Initialisierungen). Auch diese LED 
macht keine Muckser.
Werde jetzt mal das mit dem void* probieren.

Grüße

Bean

von g457 (Gast)


Lesenswert?

> Ich habe schon eine LED die zu allererst gesetzt wird (noch
> vor meiner whileschleife und den Initialisierungen). Auch diese LED
> macht keine Muckser.

Setz bei der mal ein hinreichend langes sleep dazu, sodass Du 
entscheiden kannst ob die Kiste durchgehend resets macht (oder was 
anderes schief geht).

von Karl H. (kbuchegg)


Lesenswert?

Mr Bean schrieb:

> Allerdings hab ich das Problem mit dem nicht loslaufenden Code
> immernoch. Ich habe schon eine LED die zu allererst gesetzt wird (noch
> vor meiner whileschleife und den Initialisierungen). Auch diese LED
> macht keine Muckser.
> Werde jetzt mal das mit dem void* probieren.

Das wird nichts bringen.

Schau dir den Erstellprozess des Programms an.
Achte aucf Kennwerte wie Speicherauslastung. Alles was sich bedenklich 
den 90% nähert, sollte näher untersucht werden (Über 100% ist sowieso 
klar)

von Mr Bean (Gast)


Lesenswert?

Hallo Wo kann ich sowas sehen?
In der *.l51 Datei!?
Oder gibt es irgendwelche anderen Möglichkeiten die 
Codegröße/Speicherauslastung zu untersuchen? Arbeite mit dem Tasking 
Compiler und der Tasking EDE.

Grüße

Bean

von Karl H. (kbuchegg)


Lesenswert?

Mr Bean schrieb:
> Hallo Wo kann ich sowas sehen?
> In der *.l51 Datei!?
> Oder gibt es irgendwelche anderen Möglichkeiten die
> Codegröße/Speicherauslastung zu untersuchen? Arbeite mit dem Tasking
> Compiler und der Tasking EDE.

Gibts da keine Statistik am Ende des Vorgangs?
Normalerweise wird während des Buildens auch ein 'Map-File' erzeugt, in 
dem die interne Struktur des Programms genauer aufgeschlüsselt ist.

Da musst du jetzt suchen gehen.

von g457 (Gast)


Lesenswert?

..üblicherweise(tm) [1] gibts auch einen extra (Kommandozeilen)Befehl à 
la 'size', der zu einer hex-/elf-/bin-/..datei deren Zusammensetzung 
ausspuckt.

[1] auf anständigen(tm) Systemen

von Pieter (Gast)


Lesenswert?

moin moin,

hole dir mal bei Silabs das Config-Tool.
Bei Dir wird der Watschen-Hund zubeissen;-)

Mit Gruß
Pieter

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.