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!
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.
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.
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.
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.
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
Mw E. schrieb: > Beispiel aus meinen Treibern: sieht auch interessant aus! gibt es da noch mehr zum bewundern, github, homepage, ...
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
Jedenfalls habe ich mal gemerkt, dass Google unsichtbare Stichwort-Listen ganz übel abstraft.
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!
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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.