Forum: Mikrocontroller und Digitale Elektronik stm32 link, bare metal examples?


von merciMerci (Gast)


Lesenswert?

huhu,
we hat diesen link rumliegen, finde diesen nicht mehr?

war aus/von frankreich/bildungseinrichtung über stm32 bare metal 
examples.
ich glaube, der wurde hier auch mal erwähnt und hatte viele gute 
beispiele, bzgl. der gesamten hw periphery dma,adc,tmr, ...


merci!

von Stefan F. (Gast)


Lesenswert?


von mr. mo (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> http://www.pomad.fr/node/2

Danke für en Link, kannte ich noch nicht.

von Jim M. (turboj)


Lesenswert?

Stefan ⛄ F. schrieb:
> http://www.pomad.fr/node/2

Hui, das ist ja mal fürchterlicher Code!

Hier mal ein relevanter Ausschnitt aus dem allerersten "Tutorial":
1
/* Main program */
2
int main(void)
3
{
4
  int i;
5
6
  *(int *)0x40021014 |=  (0x01 <<17U);
7
  *(int *)0x48000000 &= ~(0xC00);
8
  *(int *)0x48000000 |=  (0x01 <<10U);
9
10
  while(1)
11
  {
12
      *(int *)0x48000014 ^= 0x00000020U;
13
      for (i=0; i<PERIOD; i++);
14
  }
15
}

Lauter magische Zahlen. Genau so sollte man nicht programmieren, da 
gehören die Definitionen (und Macros) vom Hersteller rein. Denn nur dann 
wäre das für einen Menschen auch lesbar.

Hint: Wie lange würde es dauern, hier einen Zahlendreher zu finden..? 
Eben.

von Stefan F. (Gast)


Lesenswert?

Jim M. schrieb:
> Hui, das ist ja mal fürchterlicher Code!

Du wolltest bare-metal, du bekommst bare-metal. Ich glaube, in diesem 
Beispiel ging es allerdings nur darum, die IDE und die HW mit möglichst 
wenig Abhängigkeiten ans Laufen zu bekommen.

Vielleicht gefallen Dir meine Beispiele besser: 
http://stefanfrings.de/stm32/index.html

Sie basieren auf CMSIS, sind aber nicht aus Frankreich.

In den folgenden Kapiteln nutzt der Professor übrigens ebenfalls die 
CMSIS.

von merciMerci (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> http://www.pomad.fr/node/2

genau der, danke!

selbst mit google und eingeschränkt auf fr, polytechnique, ... kam nur 
schrott raus.

von Stefan F. (Gast)


Lesenswert?

Ich weiß, die Seite ist schwer zu finden. Was ich seltsam finde, denn 
dieses Tutorial ist wesentlich umfangreicher als meine Seite und meine 
Seite findet man sehr leicht.

Ich schätze, dass er da irgend eine techniche Besonderheit auf der Seite 
hat, der Google ganz viele Minuspunkte gibt.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

Stefan ⛄ F. schrieb:
> In den folgenden Kapiteln nutzt der Professor übrigens ebenfalls die
> CMSIS.

Ja, aber die Pins werden immernoch mit Magic Numbers eingestellt.
Da hätte er im Kapitel GPIO ruhig eine schöne Pin Init Funktion 
schreiben können.

Beispiel aus meinen Treibern:
1
// 4 Bits per Alternate Function
2
#define AFR_BITS 4U
3
#define AFR_MSK  0xFU
4
5
// 2 Bits per Function
6
#define DUALBIT_MSK 0b11U
7
#define BITSPERPIN  2U
8
9
// coding of mode Register from enum PioPinMode
10
#define ENUM_REGMODER_MSK 0b11000U
11
#define ENUM_REGMODER_POS 3U
12
// coding of MODE Bits
13
#define ENUM_BITMODER_MSK 0b11U
14
#define ENUM_BITMODER_POS 0U
15
// coding of slewrate
16
#define ENUM_OTYPE_MSK 0b100U
17
#define ENUM_OTYPE_POS 2U
18
// coding of pull resistors
19
#define ENUM_PUPDR_MSK 0b11
20
#define ENUM_PUPDR_POS 0
21
22
// how many pins in one AFR Register
23
#define AFR_PINS_PER_REG 8
24
25
// 2 part Register BSRR for SET/RESET
26
#define BSSR_SET_POS 0U
27
#define BSSR_RES_POS 16U
28
29
void gpio_init(const struct gpio_pin* pin){
30
31
  uint32_t pin_nbr = pin->nbr;
32
  uint32_t bitPosDualBit = pin->nbr * BITSPERPIN;
33
  if (pin_nbr >= 16U){
34
    return;
35
  }
36
  
37
  GPIO_TypeDef* gpio = pin->port;
38
  enum gpio_mode mode = pin->mode;
39
    
40
  // Mode (Input, GP Out, Alternate function, Analog)
41
  uint32_t regMode = (mode & ENUM_REGMODER_MSK) >> ENUM_REGMODER_POS;
42
  gpio->MODER &= ~(ENUM_BITMODER_MSK << (bitPosDualBit));
43
  gpio->MODER |= (regMode << (bitPosDualBit));
44
    
45
  // output type (Pushpull, Opendrain)
46
  uint32_t regPpod = (mode & ENUM_OTYPE_MSK) >> ENUM_OTYPE_POS;
47
  gpio->OTYPER &= ~(1 << pin_nbr);
48
  gpio->OTYPER |= (regPpod << pin_nbr);
49
    
50
  // Slewrate (Lowspeed, Mediumspeed, Fastspeed, Highspeed)
51
  gpio->OSPEEDR &= ~(DUALBIT_MSK << (bitPosDualBit));
52
  gpio->OSPEEDR |= (pin->speed << (bitPosDualBit));
53
    
54
  // Pullup, Pulldown
55
  uint32_t regPull = mode & ENUM_PUPDR_MSK;
56
  gpio->PUPDR &= ~(ENUM_PUPDR_MSK << (bitPosDualBit));
57
  gpio->PUPDR |= (regPull << (bitPosDualBit));
58
    
59
  // Altfunc 
60
  volatile uint32_t *afr = &(gpio->AFR[0U]);
61
    
62
  // search for fitting AFR Register
63
  if (pin_nbr >= AFR_PINS_PER_REG){
64
    afr = &(gpio->AFR[1U]);
65
    pin_nbr -= AFR_PINS_PER_REG;
66
  }
67
    
68
  *afr &= ~(AFR_MSK << (pin_nbr*AFR_BITS));
69
  *afr |=  (pin->alt_func << (pin_nbr*AFR_BITS));
70
}

Das struct gpio_pin sieht dann so aus:
1
#include <stdint.h>
2
3
#include "cmsis_includer.h"
4
5
//! \brief enum of possible Pin Modes
6
enum gpio_mode {
7
  GPO_PP =    0b01000, //!< out pushpull
8
  GPO_PP_PU =    0b01001, //!< out pushpull + pullup
9
  GPO_PP_PD =    0b01010, //!< out pushpull + pulldown
10
  GPO_OD =    0b01100, //!< out opendrain
11
  GPO_OD_PU =    0b01101, //!< out opendrain + pullup
12
  GPO_OD_PD =    0b01110, //!< out opendrain + pulldown
13
  AF_PP =      0b10000, //!< altfunc pushpull
14
  AF_PP_PU =    0b10001, //!< altfunc pushpull + pullup
15
  AF_PP_PD =    0b10010, //!< altfunc pushpull + pulldown
16
  AF_OD =      0b10100, //!< altfunc opendrain  
17
  AF_OD_PU =    0b10101, //!< altfunc opendrain + pullup
18
  AF_OD_PD =    0b10110, //!< altfunc opendrain + pulldown
19
  GPI_FLOAT =    0b00000, //!< in floating
20
  GPI_PU =    0b00001, //!< in + pullup
21
  GPI_PD =    0b00010, //!< in + pulldown
22
  GP_ANALOG =    0b11000, //!< analog -> input is switched off
23
};
24
25
//! \brief enum of possible Pin Speeds
26
enum gpio_speed {
27
  GPIO_LS = 0b00, //!< low speed
28
  GPIO_MS = 0b01, //!< medium speed
29
  GPIO_FS = 0b10, //!< full speed
30
  GPIO_HS = 0b11, //!< high speed
31
};
32
33
//! \brief structure for one PIO pin 
34
struct gpio_pin {
35
  GPIO_TypeDef* port;    //!< port of pin
36
  uint8_t nbr;      //!< pin Number (0 - 15)
37
  enum gpio_mode mode;  //!< pin mode @ref gpio_pin_mode
38
  enum gpio_speed speed;  //!< pin speed @ref PioPinSpeed
39
  uint8_t alt_func;    //!< alternate function, see datasheet
40
};

Das funktioniert bisher ohne Änderungen auf: G0, L0, F0, F2, F4, L4

von merciMerci (Gast)


Lesenswert?

Mw E. schrieb:
> Beispiel aus meinen Treibern:

sieht auch interessant aus!
gibt es da noch mehr zum bewundern, github, homepage, ...

von Bauform B. (bauformb)


Lesenswert?

Stefan ⛄ F. schrieb:
> Ich weiß, die Seite ist schwer zu finden. Was ich seltsam finde,
> denn
> dieses Tutorial ist wesentlich umfangreicher als meine Seite und meine
> Seite findet man sehr leicht.
>
> Ich schätze, dass er da irgend eine techniche Besonderheit auf der Seite
> hat, der Google ganz viele Minuspunkte gibt.

<Traum>Google bewertet den Inhalt und ein Tutorial mit so vielen magic 
numbers bekommt berechtigterweise Minuspunkte</Traum>

<VT>Google muss in Frankreich Steuern zahlen</VT>

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

Jedenfalls habe ich mal gemerkt, dass Google unsichtbare 
Stichwort-Listen ganz übel abstraft.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


Lesenswert?

merciMerci schrieb:
> sieht auch interessant aus!
> gibt es da noch mehr zum bewundern, github, homepage,

Bisher nur hier:
Beitrag "ARM Cortex-M3/4/7 Faulthandler"

Auf meiner HP sind nur die alten AVR Projekte, da muss ich mal die 
ganzen neuen Projekte mit STMs nachpflegen, aber Faulheit siegt immer!

Github hab ich nicht, meine Projekte liegen nicht auf Drittservern, 
sondern bei mir.
Das ist aus historischen Gründen noch ein SVN.
Auch hier siegt die Faulheit bei der Umstellung auf Gitlab.
Weil: es funktioniert ja!

von Stefan F. (Gast)


Lesenswert?

Mw E. schrieb:
> Das ist aus historischen Gründen noch ein SVN.
> Auch hier siegt die Faulheit bei der Umstellung auf Gitlab.
> Weil: es funktioniert ja!

Nicht nur Faulheit. Jedes neue Arbeitsmittel bringt potentiell neue 
Probleme mit sich. Auf jeden Fall neuen Aufwand für die Migration und 
den Umgang damit zu lernen. Und für was?

Ich hab's zu Hause als Übung durchgezogen, weil ich der Vorarbeiter bin, 
der das bald seinen Kollegen im Büro erklären muss. Wenn man mich 
gefragt hätte: ich wäre bei Mercurial (oder SVN) geblieben. Aber die 
strategischen Entscheidungen fällen letztendlich andere. Wenn der ganze 
Nachwuchs GitHub will, nur die beiden Oldies nicht, dann ist klar, was 
gemacht wird.

von merciMerci (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> ich wäre bei Mercurial (oder SVN) geblieben. Aber die
> strategischen Entscheidungen fällen letztendlich andere. Wenn der ganze
> Nachwuchs GitHub will, nur die beiden Oldies nicht, dann ist klar, was
> gemacht wird.

ich habe auch erst mit mercurial für meine privaten projekte rumgemacht, 
bin dann aber doch auf git umgestiegen weil, da gibt es tonnenweise lit. 
und quasi jede ide unterstützt git. ausserdem wenn ich irgendwas aus 
opensource will, dann muss ich git können. ich denke, für mercurial ist 
zug eher weg.
ich steige auch gerade zu gitlab um ... und will dann auch dort mal eine 
statische homepage bauen, aber noch blick ich nicht richtig durch.

von Stefan F. (Gast)


Lesenswert?

SVN und Mercurial werden auch von fast allen IDEs unterstützt. Und 
selbst wenn nicht, man braucht es nicht. Man hat ja noch die 
Kommandozeile und zudem zahlreiche GUIs zur Wahl. Ich sehe keinen großen 
Vorteil darin, alles krampfhaft in die IDE integrieren zu wollen. Je 
mehr man sich darauf verlässt, umso abhängiger macht man sich.

Abhängigkeit von einer bestimmten IDE (egal welcher) ist schlimm. Das 
steht in meiner No-Go Liste ganz weit oben.

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.