Forum: Mikrocontroller und Digitale Elektronik STM32F407: HardFault


von Floid F. (Gast)


Lesenswert?

Guten Abend Forum,
Ich habe folgenden Code auf einem STM32F407-Discovery-Board:
1
#include "main.h"
2
#include "stm32f4xx_i2c.h"
3
4
GPIO_InitTypeDef GPIO_InitStructure;
5
6
void init(void)
7
{
8
//Quelle: Elia's Electronics Blog
9
    GPIO_InitTypeDef GPIO_InitStruct;
10
    I2C_InitTypeDef I2C_InitStruct;
11
    
12
    // enable APB1 peripheral clock for I2C1
13
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
14
    // enable clock for SCL and SDA pins
15
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
16
    
17
    /* setup SCL and SDA pins
18
     * You can connect the I2C1 functions to two different
19
     * pins:
20
     * 1. SCL on PB6 or PB8  
21
     * 2. SDA on PB7 or PB9
22
     */
23
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8; // we are going to use PB6 and PB9
24
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;      // set pins to alternate function
25
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;    // set GPIO speed
26
    GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;      // set output to open drain --> the line has to be only pulled low, not driven high
27
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;      // enable pull up resistors
28
    GPIO_Init(GPIOB, &GPIO_InitStruct);          // init GPIOB
29
30
    // Connect I2C1 pins to AF  
31
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_I2C1);  // SCL
32
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1); // SDA
33
    
34
    // configure I2C1 
35
    I2C_InitStruct.I2C_ClockSpeed = 10000;     // 10kHz
36
    I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;      // I2C mode
37
    I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;  // 50% duty cycle --> standard
38
    I2C_InitStruct.I2C_OwnAddress1 = 0x00;      // own address, not relevant in master mode
39
    I2C_InitStruct.I2C_Ack = I2C_Ack_Disable;    // disable acknowledge when reading (can be changed later on)
40
    I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; // set address length to 7 bit addresses
41
    I2C_Init(I2C1, &I2C_InitStruct);        // init I2C1
42
43
    // enable I2C1
44
    I2C_Cmd(I2C1, ENABLE);
45
}
46
47
int main(void)
48
{
49
  uint8_t feld1[1000];
50
  uint16_t m;
51
  init();
52
  for(m=0; m<1000; m++)
53
  {
54
    feld1[m]=0x00;
55
  }
56
  while (1)
57
  {
58
  }
59
}
Entwicklungsumgebung ist KEIL µVision.
Das Problem ist, dass in I2C_Init(I2C1, &I2C_InitStruct) der 
HardFault_Handler aufgerufen wird.
Woran liegt das? Wenn ich feld1 nur mit einer Länge von 100 anlege 
passiert dieser Fehler nicht. Läuft da der Speicher für Variablen über 
und überschreibt die i2c-init-Funktion? Wie groß ist denn dieser 
Speicherbereich?
Floid

von Hans (Gast)


Lesenswert?

Zeig mal Dein Startup-File.

von Jörn K. (joern)


Lesenswert?

Häng einen HardFault Handler ein, damit kannst du herausfinden an 
welcher Adresse der Fehler auftritt.

Ein Beispiel gibt es hier:

http://blog.frankvh.com/2011/12/07/cortex-m3-m4-hard-fault-handler/

von Furth (Gast)


Lesenswert?

Tritt das Problem auch beim Simulieren auf?

von Floid (Gast)


Lesenswert?

danke für eure Hilfe.
Ich habe mir mal das Startup-File angeschaut. Dieses habe ich von einem 
Peripheral Example übernommen gehabt.
Ausschnitt davon:
1
; Amount of memory (in bytes) allocated for Stack
2
; Tailor this value to your application needs
3
; <h> Stack Configuration
4
;   <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
5
; </h>
6
7
Stack_Size      EQU     0x00000400
8
9
                AREA    STACK, NOINIT, READWRITE, ALIGN=3
10
Stack_Mem       SPACE   Stack_Size
11
__initial_sp
12
13
14
; <h> Heap Configuration
15
;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
16
; </h>
17
18
Heap_Size       EQU     0x00000200
19
20
                AREA    HEAP, NOINIT, READWRITE, ALIGN=3
21
__heap_base
22
Heap_Mem        SPACE   Heap_Size
23
__heap_limit
24
25
                PRESERVE8
26
                THUMB

Wenn ich die Stacksize erhöhe passiert der Fehler nichtmehr.
1
Stack_Size      EQU     0x00001000
Kann der zu kleine Stack die Ursache für den HardFault sein?

Wie kann ich denn abschätzen wie groß dieser sein muss?

von (prx) A. K. (prx)


Lesenswert?

Floid schrieb:
> Stack_Size      EQU     0x00000400

1000 Bytes in einen Stack zu legen, der nur 1024 Bytes gross ist ...

von Dr. Sommer (Gast)


Lesenswert?

Floid F. schrieb:
> uint8_t feld1[1000];
Wenn du dieses Feld während der gesamten Ausführungszeit benötigst, 
macht es keinen Sinn das auf den Stack zu legen; definiere es als static 
oder globale Variable, damit der Compiler das in die 
gesamt-Speicher-Aufteilung (.data) mit einrechnen kann.

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.