STM32 komisches Verhalten bei include und leerer Funktion

Gast #4734640
Lesenswert?

Hallo Leute,

ich brauch mal Hilfe. Ich hab hier einen STM32F107VCT6 und folgendes 
Programm mit CoIDE (1.7.5, 20130927-3279-1526) draufgeladen: Die main.c 
sieht so aus:
1
#include <stm32f10x.h>
2
#include <stm32f10x_conf.h>
3
#include <stm32f10x_rcc.h>
4
#include <stm32f10x_gpio.h>
5

6
#include <stm32_time.h>
7
//#include <stm32_serial.h>   // <= PROBLEM
8

9
//**************************************************
10
void     Cyclic_1ms     (void)
11
{
12
  static  uint16_t  Count;
13
  //-----------------------------
14
  if ( ++Count >= 1000 )
15
  {
16
    Count = 0;
17
    GPIOE->ODR ^= GPIO_ODR_ODR15;
18
  }
19
  //-------------------------------
20
  GPIOE->ODR ^= GPIO_ODR_ODR14;
21
  return;
22
}
23

24
//**************************************************
25
int main(void)
26
{
27
  //-- System initialisieren ------
28
  SystemInit();
29
  //-- Treiber initialisieren -----
30
  stm32_time_init();
31
  stm32_time_addfct_1ms  ( (void*) &Cyclic_1ms );  // 1ms
32
//  stm32_serial_init();    // <= PROBLEM
33
  //-- Testpins -------------------
34
  GPIO_InitTypeDef GPIO_InitStructure;
35
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);
36
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);
37
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO,ENABLE);
38
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_AFIO,ENABLE);
39
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE|RCC_APB2Periph_AFIO,ENABLE);
40
  GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_All;   // TEST Status LEDs
41
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
42
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
43
  GPIO_Init( GPIOE , &GPIO_InitStructure);
44
  //-- Hauptschleife --------------
45
  while (1)
46
  {
47
    GPIOE->ODR ^= GPIO_ODR_ODR13;
48
  }
49
  //-------------------------------
50
  return 0;
51
}
Mit dem Oszi sehe ich jetzt am Port E an folgende Pins korrekterweise 
folgendes:
Pin15: 0.5Hz
Pin14: 500Hz
Pin13: ca 3.3MHz

Kommentiere ich die zwei mit //Problem markierten Zeilen ein, so 
funktioniert nur noch der Pin13 der main-while-Schleife. Der Timer macht 
irgendwelchen Mist. Warum? Die neue Funktion ist leer:
stm32_serial.h
1
#ifndef  STM32_SERIAL_H
2
#define  STM32_SERIAL_H
3
//**************************************************
4
void     stm32_serial_init( void );
5
#endif

stm32_serial.c
1
//**************************************************
2
#include "stm32_serial.h"
3
//**************************************************
4
void               stm32_serial_init( void )
5
{
6
  return;
7
}

Im Anhang das komplette Projekt als rar.

Ich vermute, das Problem hängt mit dem Einbinden der h-Datei zusammen. 
Aber warum? Die andere (stm32_time.h) scheint doch auch zu 
funktionieren...

Kann sich das bitte mal jemand ansehen und mir helfen?

Thx schonmal
Angehängte Dateien:
Gast #4734684
Lesenswert?

Hm.. besagte Zeilen sehen beide so aus:
1
uint8_t u8Max = (uint8_t) (   sizeof(scEsc_SysTick.apfct)
2
                            / sizeof(scEsc_SysTick.apfct[0]) );
mit:
1
volatile
2
struct
3
{
4
  void  ( *apfct[8] ) (void);
5
}
6
scEsc_SysTick;
Ich habs geändert zu;
1
#define       MAX_COUNT1MS   (  8  )
2
...
3
uint8_t u8Max = (uint8_t) ( MAX_COUNT1MS );


Ändert leider nichts am Problem...
Gast #4734718
Lesenswert?

OK, also ich hab da mal das Hexfile mit dem Mapfile abgeglichen, der 
Systick-Handler steht korrekt in der Vektortabelle. Das ist schonmal 
gut.

Versuch doch mal im ersten Schritt, das LED-Wackeln direkt hart im 
Systick-Handler zu codieren. Wenn das geht, deklarier die 
cyclic-Funktion als extern in der Time-Datei und ruf die hart aus dem 
Systick-Handler auf.

Wenn das geht, weiß man schonmal, das System geht, wie es soll. Dann 
kann das nur noch was mit der Liste aus den FUnktionspointern sein, daß 
sich da was verschluckt.
Gast #4734749
Lesenswert?

>Versuch doch mal im ersten Schritt, das LED-Wackeln direkt hart im
>Systick-Handler zu codieren.


Kein Unterschied wo ich das mache.


TEK0000 zeigt das Bild ohne den AUfruf der Leerfunktion. Die gelbe Linie 
springt alle 1s zwischen HI und LO hin und her. Die blaue sind 500Hz. 
Die untere ist das main-while. Dort sieht man, wielange er etwa im 
TimerInt ist.

Die anderen zeigen das Fehlverhalten. Es sieht irgendwie so aus, als ob 
der Test-pin beim Beenden des TimerInts wieder gelöscht wird...

Aber warum?
Angehängte Dateien:
Gast #4734786
Lesenswert?

Hm, Du verwendest eine recht alte Version der CoIDE - der Compiler wird 
vermutlich auch nicht der aktuellste sein? Mach außerdem mal die 
Optimierung auf Größe raus und geh auf O0.

Hast Du nach dem Einblenden der beiden Zeilen das komplette Projekt mit 
Rebuild neu gemacht? Ich würde IDEs da nie vertrauen.
Gast #4735126
Lesenswert?

der Stack ist 0x100 gross und liegt direkt hinter dem .bss. Ich sehe 
jetzt zwar keine Funktion die viel Stack braucht, lag da beim Testen 
evtl. ein grosser Buffer auf dem Stack? Mit der CoIde hast du ja auch 
einen Debugger, wie sieht der Stack da aus vor/nach dem 
stm32_serial_init() ?

Dann wird SystemInint() im Startup schon vor main() aufgerufen, der 
Aufruf in main() ist also überflüssig.

Die Pointeraktionen sehen ok aus, habe ich mal im VS angesehen. Für den 
Funktionspointer würde ich ein typedef verwenden, siehe Anhang.
In der Pointertabelle hast du ja schon einen Füllstand, im SysTick muss 
die Schleife dann auch nur bis zum max. Anzahl fnPtr laufen.
Angehängte Dateien:
Gast #4744252
Lesenswert?

>Hm, Du verwendest eine recht alte Version der CoIDE - der Compiler wird
>vermutlich auch nicht der aktuellste sein?

CoIDE 1.7.5
GNU  5.4 2016q2


>Hast Du nach dem Einblenden der beiden Zeilen das komplette Projekt mit
>Rebuild neu gemacht? Ich würde IDEs da nie vertrauen.

Mache ich immer.


>Mach außerdem mal die Optimierung auf Größe raus und geh auf O0.

Yup. Mit O0, O1 und O2 gehts. Mit O3 und Os nicht. Warum?
Gast #4744386
Lesenswert?

Ok, den Compiler habe ich auch, die Version ist OK. Mit dem Q3-Update 
wird sich vermutlich nichts ändern, ich bekomme damit jedenfalls 
dieselben Binaries wie mit Q2 bei meinen Projekten. Vermutlich ist die 
Leerfunktion auch gar nicht die Ursache, sondern nur ein Symptom. Das 
wird etwas Herumgestochere.

Stackgröße glaube ich nicht als Ursache; die ist im Startfile zwar mit 
0x100 definiert, also 256, aber vom Typ unsigned long int, mithin sind 
das auf STM32 immerhin 1kB.

Erstmal vielleicht den überflüssigen SystemInit()-Aufruf aus der Main 
nehmen, wie Johannes schon gesagt hat. Das wird im Default-Resethandler 
schon gemacht.

Dann in cyclic_1ms mal den Blinker für den Sekundentakt rausnehmen und 
nur den 500Hz drinlassen. Einfach mal gucken, was passiert mit O3. 
Cyclic_1ms direkt ohne die Pointertabelle aus dem SysTick aufzurufen 
hattest Du ja schon gemacht?

Eine weitere Idee ist, den Compiler Stück für Stück mit 
Compiler-Optionen auf O3 anzufüttern und zu testen, ob eine davon was 
bringt - das kann bei der ziemlich vertrackten Fehlersuche helfen. Ich 
würde es Stück für Stück mit denen hier versuchen:

-fno-gcse -fno-unsafe-loop-optimizations -fno-inline 
-fno-delete-null-pointer-checks -fno-strict-aliasing 
-fno-strict-overflow -fno-isolate-erroneous-paths-dereference

Wenn das nichts hilft, dann als nächstes mal so compilieren, daß Du 
jeweils alle Dateien bis auf eine mit O2 compilierst, und die eine mit 
O3. Dann sieht man immerhin schonmal, für welche Datei das einen 
Unterschied macht. Kann ja auch in dem Sumpf der ST-Software begründet 
liegen.

Wie das aus CoIDE geht, weiß ich nicht, ich nutze 
Batchfiles/Shellscripte. Allerdings kann man sich den Compiler-Aufruf 
aus dem Statusfenster bei CoIDE in ein Batchfile kopieren.

Ich würde auch ein Update der CoIDE auf 1.78 andenken. Keine Ahnung, was 
sich da geändert hat, aber immerhin hast Du ja im Moment kein eigenes 
Linkerfile.
Gast #4744613
Lesenswert?

Nochwas.. ich weiß nicht, was auf Deiner Hardware alles an Port E hängt, 
aber ich würde testhalber mal
GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_All;
durch
GPIO_InitStructure.GPIO_Pin   = (GPIO_Pin_13 | GPIO_Pin_14 | 
GPIO_Pin_15);
ersetzen. Oder so ähnlich, irgendwie so heißt das bei der ST-Lib aber.
Gast #4749157
Lesenswert?

Ich habe noch bischen rumprobiert. Keine logische Erklärung gefunden, 
wanns geht und wann nicht. Meist ists so, wenn ich einen leeren 
Fkt-aufruf mache, geht der Timer nicht mehr richtig..

Ich habe vor zwei Jahren mal ein Projekt mit CoIDE realisiert. Dort 
hatte ich solche Probleme bei demselben Evalboard nicht.

Zwischenzeitlich habe ich avon Win7 auf Win10 umgestellt und CoIDE/gcc 
neu installiert..

Ob das was damit zutun hast?

Mich kotzt das hier an..

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