Hallo, ich arbeite mich gerade in die STM32 ein. Konkret beginne ich mit dem STM32F100RB auf dem STM32VLDiscovery. Nach längerer Suche bin ich nun im Bilde, dass es von ARM eine CMSIS-Schnittstelle gibt, die einheitlich für alle ARM-Controller definiert wurde. Ebenso bietet STM eine StdPeriph-Lib mit höheren Funktionen sowie eine HAL an, welche nach meinen Informationen langsam die StdPeriph-Lib ablösen soll. Hier blicke ich aber noch nicht durch. Ich würde mich gerne möglichst wenig an STM binden, sondern mich mit den ARMs generell auseinandersetzten. Daher würde ich gerne auf CMSIS-Ebene bleiben wollen. Nach Recherche scheint es so, dass ARM eine wesentliche Komponente liefert, die core_cm3*.h, in welcher Defines für interne Komponenten wie NVIC bereitgestellt werden. Der Chiphersteller liefert hierzu eine Datei, hier die stm32f10x.h, in welcher Defines für die Hersteller-Peripehierie enthalten ist. Hier werden auch erste Strukturen definiert wie z.B. GPIO_TypeDef, in der die definierten Register für die GPIO in einen Zusammenhang gebracht werden. Nun setzt die StdPeriph offenbar hier an und definiert spezifische Namen, um die Register aus der CMSIS mit konkreten Werten zu versorgen. Z.B. GPIO_Mode_Out_PP = 0x10. Ich habe jetzt nich jede stm32f10x_*.h Datei durchgesehen. Aber ist das der gesamte Umfang dieser StdPeriph-Lib, die Vergabe von Namen für Registeradressen und deren Addition? Übersehe ich da etwas? Ich habe versucht, Literatur zu finden, die nur auf der Basis der CMSIS einen Einstieg in die Programmierung bietet. Leider mischen sich jedoch fast immer wieder Elemente der StdPeriph-Lib mit hinein oder es kommt zur Programmierung auf Registerebene wie z.B. GPIOA->MODER |= (1 << 1); Die genanten Structs werden also ausgelassen. Wo verläuft die genaue Trennlinie zwischen CMSIS und STM32-StdPeriph? Habt Ihr evtl. Literatur, in der konsequent nur die CMSIS für einen Programmiereinstieg verwendet wird? Mit Gruß Schmidt
>Wo verläuft die genaue Trennlinie zwischen CMSIS und STM32-StdPeriph? Logischerweise genau da, wo hardwaremässig die Trennlinie zwischen ARMv7M und der controller-spezifischen Peripherie verläuft. >Habt Ihr evtl. Literatur, in der konsequent nur die CMSIS für einen >Programmiereinstieg verwendet wird? Wozu? Da reichen die Header aus, um das zu erkennen.
Schmidt schrieb: > Nun setzt die StdPeriph offenbar hier an und definiert spezifische > Namen, um die Register aus der CMSIS mit konkreten Werten zu versorgen. > Z.B. GPIO_Mode_Out_PP = 0x10. Nein das sind schon spezielle Defines die nur für die Standard Peripheral Library interessant sind. Die kann man so meist nicht direkt in Register vom µC schreiben. Schmidt schrieb: > oder es kommt > zur Programmierung auf Registerebene wie z.B. GPIOA->MODER |= (1 << 1); So muss man es nunmal machen wenn man keine HAL Library verwenden möchte. Oder meinst du die Magic Numbers wie (1 << 1)? Dafür gibt es in der stm32f10x.h Datei auch schon Defines. Gerade bei den GPIO Registern sind die aber nicht besonders praktisch wenn man ein Define hat was effektiv nur ein Bit gesetzt hat und das dann 16mal für alle Pins eines GPIO Ports. Bei anderen Registern macht das dann schon mehr Sinn. Schmidt schrieb: > Die genanten Structs werden also ausgelassen. Welches Struct? Du hast nur das GPIO_TypeDef genannt aber genau GPIOA ist doch ein Pointer auf dieses Struct.
:
Bearbeitet durch User
Schau Dir einfach die Lizenzzeile oben in den Headern an. Die von ARM CMSIS sagen dass sie von ARM (aka ARM LIMITED) sind:
1 | /**************************************************************************//**
|
2 | * @file core_cm4.h
|
3 | * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File
|
4 | * @version V4.30
|
5 | * @date 20. October 2015
|
6 | ******************************************************************************/
|
7 | /* Copyright (c) 2009 - 2015 ARM LIMITED
|
8 | ...
|
9 | */
|
Die von ST haben Copyright von ST.
> Daher würde ich gerne auf CMSIS-Ebene bleiben wollen. Schau mal hier: https://github.com/prof7bit/bare_metal_stm32f401xe Das ist zwar für einen stm32f401 aber Du kannst daraus sehen wie ich diese Sache angehen würde, welche Header essentiell sind, welche zu ARM gehören, welche von STM kommen und welche man nicht braucht (nämlich alle die welche Du in dem obigen Projekt nicht findest). Du könntest Dir zur Übung ja mal den Spaß machen das obige Projekt auf Deine CPU zu portieren indem Du: * Die entsprechenden Header findest und austauscht * Den Startup code anpasst * Das Linkerscript anpasst * Pfadnamen im Makefile anpasst * Die LED auf Deinem Board wieder zum Blinken bringst. Wenn Du Dich da durchgebissen hast (das schaffst Du) wirst Du einiges von dem was Du wissen wolltest (und noch viel mehr) gelernt haben und ein ganz anderes und viel engeres Verhältnis zu dieser ganzen Materie haben.
Schmidt schrieb: > oder es kommt > zur Programmierung auf Registerebene wie z.B. GPIOA->MODER |= (1 << 1); > Die genanten Structs werden also ausgelassen. Ja, genau so eben. Du mußt dich schon selbst entscheiden, ob du dich tatsächlich mit dem µC befassen willst, oder dich lieber mit dem Zeug der jeweiligen Hersteller abgeben willst. Normalerweise hat man auf einem µC kein Betriebssystem, was die HW am Laufen hält und auf Kommando oder Skript oder sonstwie mal eben die eine oder andere Anwendung laufen läßt. Sondern man hat eben eine Firmware, die man selbst schreibt, die man auch selbst strukturiert und die eben auf die Hardware direkt zugreift. Beispiel: Es gibt keinen - ja wirklich KEINEN - sinnvollen Grund, irgend ein Pin des Chips über eine Bibliotheksfunktion anzusprechen a la "SetMyPin(Port3,Pin7,High)" oder so, denn eben genau DAS ist ein Krampf an der falschen Stelle, den die Erfinder der HW so nicht vorgesehen haben. Wer sich die entsprechenden Referenzmanuals mal durchgesehen hat, weiß daß die Konstrukteure der Chips sich alle Mühe gegeben haben, eine gute Funktionalität einzubauen. Da gibt es beispielsweise eben HW-Register, die WriteOnly sind und die nur dazu dienen, ausgewählte Pins zu setzen oder zu löschen oder zu toggeln - und das alles möglichst mit einem einzigen Befehl. Wer sowas in falsch verstandenem Bemühen um Abstraktion in eine "SetMyPin(..)" quetschen will, vergeigt einen wesentlichen Teil der vorhandenen Funktionalität. Das solltst du dir sehr gut merken und skeptisch sein gegenüber allen Bibliotheken, die angeblich dich von der Bürde der Hardware-Kenntnis fernhalten wollen. Zum großen Teil gehört auch CMSIS dazu, also auch dort nie unkritisch sein. W.S.
Den gegebenen Antworten möchte ich nur noch einen kurzen Hinweis hinzufügen: ST baut alle paar Jahre mal Ihre Bibliotheken um. Das was aktuell unter dem Namen HAL kursiert, ist IMHO genauso benutzerfreundlich, wie der gleichnamige Computer gegen Ende des Films. Allerdings findet man direkt bei ST, manchmal etwas versteckt, für jeden STM32 (zumindest für F0,F1,F4) aktuelle Bibliotheken, die nicht auf HAL aufbauen. Diese, zusammen mit den Datenblättern und der reichhaltigen Doku, ermöglichen eine effiziente Programmierung und Codepflege.
Bitte nicht schon wieder die HAL Diskussion :-) Was mich an den SPL (Standard Peripheral Lib) defines auch genervt hat waren genau diese fehlenden Definitionen. Im Refmanual zu der Serie sind sie drin, aber es gibt keinen passenden definierten symbolischen Namen für die entsprechende Bitkombination. Das hat Atmel zumindest bei den AVRs wesentlich besser gemacht, dort gibt es genau die Werte aus dem Datenblatt als Definitionen. Das Problem was ich sehe, ob man nun ohne SPL, mit SPL oder mit HAL programmiert: Man bindet sich zwangsläufig an die Hardware, da man bestimmte Funktionen (oder Funktionsweisen) voraussetzt. Und ein universeller Ansatz steht meistens auch im Gegensatz zu einem performanten Ansatz. Will man z.B. nur ein I/O Pin periodisch ein/ausschalten und es kommt auf ein paar µs nicht an, kann man die HAL (oder auch ein OS wie chibios etc.) verwenden und hat die Sache sauber in eine handvoll Funktionen gekapselt. Um einen Ansatz zu haben der auch wirklich die Hardwareeigenschaften ausnutzt, muss man z.B. schon wissen wie die PWM funktioniert etc. Das kann man kaum in eine universelle Library packen die man einfach auf andere Plattformen umziehen kann. Tja, es ist schon ein Dilemma...
W.S. schrieb: > Beispiel: Es gibt keinen - ja wirklich KEINEN - sinnvollen Grund, irgend > ein Pin des Chips über eine Bibliotheksfunktion anzusprechen a la > "SetMyPin(Port3,Pin7,High)" oder so, denn eben genau DAS ist ein Krampf > an der falschen Stelle, den die Erfinder der HW so nicht vorgesehen > haben. Das ist natürlich wieder mal schreiender Unfug. Es spricht nichts dagegen immer wiederkehrendes unleserliches Registergewurschtel in simple wrapper zu packen: (Beispiel für Kinetis)
1 | void set_pin(FGPIO_Type* fpt, uint8_t number, bool state) { |
2 | if(state) { |
3 | fpt->PSOR = (1 << number); |
4 | } else { |
5 | fpt->PCOR = (1 << number); |
6 | }
|
7 | }
|
8 | |
9 | int main(void) { |
10 | while(1) { |
11 | set_pin(FPTA, 3, false); |
12 | set_pin(FPTA, 4, true); |
13 | set_pin(FPTB, 5, false); |
14 | set_pin(FPTA, 4, false); |
15 | set_pin(FPTA, 3, true); |
16 | set_pin(FPTB, 5, true); |
17 | }
|
18 | }
|
implodiert bei der Kompilation zu folgendem:
1 | 00000410 <main>: |
2 | 410: b510 push {r4, lr} |
3 | 412: 2008 movs r0, #8 |
4 | 414: 2410 movs r4, #16 |
5 | 416: 4b05 ldr r3, [pc, #20] ; (42c <main+0x1c>) |
6 | 418: 2120 movs r1, #32 |
7 | 41a: 4a05 ldr r2, [pc, #20] ; (430 <main+0x20>) |
8 | 41c: 6098 str r0, [r3, #8] |
9 | 41e: 605c str r4, [r3, #4] |
10 | 420: 6091 str r1, [r2, #8] |
11 | 422: 609c str r4, [r3, #8] |
12 | 424: 6058 str r0, [r3, #4] |
13 | 426: 6051 str r1, [r2, #4] |
14 | 428: e7f6 b.n 418 <main+0x8> |
15 | 42a: 46c0 nop ; (mov r8, r8) |
16 | 42c: f80ff000 .word 0xf80ff000 |
17 | 430: f80ff040 .word 0xf80ff040 |
Und auch die folgende überaus umständlich wirkende zweischichtige Abstraktion:
1 | /*
|
2 | * GPIO abstraction and pin definitions
|
3 | */
|
4 | |
5 | typedef struct { |
6 | FGPIO_Type* fpt; |
7 | uint8_t number; |
8 | } pin_t; |
9 | |
10 | typedef enum { |
11 | LOW, |
12 | HIGH
|
13 | } pin_state_t; |
14 | |
15 | const pin_t DEFLECTOR_SHIELD = {FPTA, 3}; |
16 | const pin_t INERTIAL_DAMPENERS = {FPTA, 4}; |
17 | const pin_t PULSE_DRIVE = {FPTB, 5}; |
18 | |
19 | void set_pin(pin_t pin, pin_state_t state) { |
20 | if(state == HIGH) { |
21 | pin.fpt->PSOR = (1 << pin.number); |
22 | } else { |
23 | pin.fpt->PCOR = (1 << pin.number); |
24 | }
|
25 | }
|
26 | |
27 | /*
|
28 | * NCC-1701 Engine control
|
29 | */
|
30 | |
31 | typedef enum { |
32 | DISABLE, |
33 | ENABLE
|
34 | } control_state_t; |
35 | |
36 | |
37 | void engine_control(pin_t pin, control_state_t state) { |
38 | if(state == ENABLE) { |
39 | set_pin(pin, LOW); |
40 | } else { |
41 | set_pin(pin, HIGH); |
42 | }
|
43 | }
|
44 | |
45 | |
46 | /*
|
47 | * application
|
48 | */
|
49 | |
50 | int main(void) { |
51 | |
52 | // self destruction sequence
|
53 | while(1) { |
54 | engine_control(DEFLECTOR_SHIELD, ENABLE); |
55 | engine_control(INERTIAL_DAMPENERS, DISABLE); |
56 | engine_control(PULSE_DRIVE, ENABLE); |
57 | engine_control(INERTIAL_DAMPENERS, ENABLE); |
58 | engine_control(DEFLECTOR_SHIELD, DISABLE); |
59 | engine_control(PULSE_DRIVE, DISABLE); |
60 | }
|
61 | }
|
implodiert bei der Kompilierung ebenfalls zu
1 | 00000410 <main>: |
2 | 410: b510 push {r4, lr} |
3 | 412: 2008 movs r0, #8 |
4 | 414: 2410 movs r4, #16 |
5 | 416: 4b05 ldr r3, [pc, #20] ; (42c <main+0x1c>) |
6 | 418: 2120 movs r1, #32 |
7 | 41a: 4a05 ldr r2, [pc, #20] ; (430 <main+0x20>) |
8 | 41c: 6098 str r0, [r3, #8] |
9 | 41e: 605c str r4, [r3, #4] |
10 | 420: 6091 str r1, [r2, #8] |
11 | 422: 609c str r4, [r3, #8] |
12 | 424: 6058 str r0, [r3, #4] |
13 | 426: 6051 str r1, [r2, #4] |
14 | 428: e7f6 b.n 418 <main+0x8> |
15 | 42a: 46c0 nop ; (mov r8, r8) |
16 | 42c: f80ff000 .word 0xf80ff000 |
17 | 430: f80ff040 .word 0xf80ff040 |
Also möcht ich mal wissen was der Blödsinn bedeuten soll vom wegen die Erfinder hätten nicht gewollt daß man Abstraktionen verwendet um den Code leserlicher und wartbarer zu machen. Langsamer oder größer wird er dadurch jedenfalls offensichtlich nicht, denn eine gut durchdachte Abstraktion implodiert üblicherweise beim Optimierelauf zu null oder beinahe null. Und so simple Sachen wie oben lösen sich garantiert immer in ein Wölkchen aus nichts auf.
Endlich mal einer, der auch das Kompilat anschaut :-) Lass die Anderen ruhig mal reden, da mit Argumenten zu kommen ist bekanntermaßen Zeitverschwendung...
Wenn du dich nicht an die peri libs binden willst, nimm nur das CMSIS Peripheral Headerfile. Ggf. auch aufgeteilt auf mehrere files bei STM. Das CMSIS Headerfile und die core_cm files (functions NVIC_, SysTick_) sind die ursprüngliche CMSIS. Dann kamen später RTOS und die Peri Driver hinzu, um den Peri Zugriff für Middleware zu standardisieren. Hier führen die Wege aber meisst wieder durch die Peri Libs der Hersteller. Ganz kompakt bekommst es, wenn du dir mit SVDConv.exe (>v3.3, neue Architektur und besserer Codegenerator) aus dem .SVD file für deinen Chip selbst ein Headerfile baust:
1 | > SVDConv.exe STM32F103.svd --generate=header |
stehst du auf Bitfelder, dann:
1 | > SVDConv.exe STM32F103.svd --generate=header --fields=struct |
:
Bearbeitet durch User
Holger schrieb: > Endlich mal einer, der auch das Kompilat anschaut :-) Was ja sehr gut aussieht, warum ich es auch gleich probieren mußte ;-) Allerdings ergeben sich (bei mir STM32+IAR) in anderem Zusammenspiel zwei Befehle pro set/clear, und das auch erst dann, wenn set_pin() als inline deklariert wird: // set_pin(GPIOE, TDC_SCLK,0); // SCLK auf '0' 00000016 0x2108 MOVS R1,#+8 00000018 0x8361 STRH R1,[R4, #+26] Aber auch beim obigen Code muß man die Optimierungen von 412: 2008 movs r0, #8 414: 2410 movs r4, #16 418: 2120 movs r1, #32 dem eigentlichen set/clear hinzurechnen. Möchte man jedoch mehrere Bits in einem IO-Register nicht sequentiell sondern gleichzeitig setzen/löschen, muß man doch wieder direkt die Register ansprechen. Egal. Es ist immer gut, sich bei zeitkritischem Code das Kompilat anzusehen.
Bernd K. schrieb: > Schau mal hier: > > https://github.com/prof7bit/bare_metal_stm32f401xe Schaut gut aus! > Du könntest Dir zur Übung ja mal den Spaß machen das obige Projekt auf > Deine CPU zu portieren indem Du: > > * Die entsprechenden Header findest und austauscht Und an der Stelle wird es schon schwierig. Wo finde ich die für einen anderen Chip? Oder meinetwegen auch die svd-Files, falls da alle Register-Definitionen drin sind? > * Den Startup code anpasst > * Das Linkerscript anpasst > * Pfadnamen im Makefile anpasst > * Die LED auf Deinem Board wieder zum Blinken bringst. > > Wenn Du Dich da durchgebissen hast (das schaffst Du)... Für den STM32F205 hab' ich es geschafft, weil ich damals das stm32f205xx.h gefunden habe. Für neuere Chips ist das schwieriger. Selbst wenn ich eine IDE kaufen würde, wäre es ja Glückssache, ob die Header für einen bestimmten Chip dabei sind. Natürlich könnte ich die selber schreiben, aber das kann's doch nicht sein. Wo bekommt ihr diese Files her?
> Glückssache, ob die > Header für einen bestimmten Chip dabei sind. Natürlich könnte ich die > selber schreiben, aber das kann's doch nicht sein. Wo bekommt ihr diese > Files her? Lade Dir Mal das aktuelle CubeMX ZIP runter und entpack es irgendwohin. Dort drin irgendwo vergraben sind für alle STM32 die CMSIS Header mit den Registerdefinitionen. Aber das kniffligste wird die Taktkonfiguration werden, mit dem RefMan alleine gehts, aber die SystemInit()-Funktion als Starthilfe aus einem existierenden Beispielprojekt zu entleihen und zu studieren mit dem aufgeklappten RefMan daneben ist auch hilfreich.
Bernd K. schrieb: > Lade Dir Mal das aktuelle CubeMX ZIP runter und entpack es irgendwohin. > Dort drin irgendwo vergraben sind für alle STM32 die CMSIS Header mit > den Registerdefinitionen. Danke. Das gibt's nur für registrierte Benutzer und ich verstehe die Lizenz nicht. Wenn man einen einzelnen Header im Internet findet, enthält die Datei eine BSD-Lizenz (also hab' die damals einfach benutzt). Die Lizenz für das komplette Paket ist aber restriktiver. Was gilt jetzt? Die einzelne Datei im Internet ist wahrscheinlich eine Raubkopie, gilt die BSD-Lizenz trotzdem? > Aber das kniffligste wird die Taktkonfiguration werden, mit dem RefMan > alleine gehts, aber die SystemInit()-Funktion als Starthilfe aus einem > existierenden Beispielprojekt zu entleihen und zu studieren mit dem > aufgeklappten RefMan daneben ist auch hilfreich. Wenn man erstmal gemerkt hat, dass man jedes Modul einzeln einschalten muss, ist der Takt doch nicht knifflig. Zu der ausführlichen Beschreibung gibt's im RefMan ein Blockschaltbild mit (fast?) allen Taktsignalen. Wenn das nicht reicht, hilft sowas wie SystemInit() auch nicht.
eagle user schrieb: > Die einzelne Datei im Internet ist wahrscheinlich eine > Raubkopie, gilt die BSD-Lizenz trotzdem? Wenn du eine Datei benutzen darfst, dann darfst du sie auch benutzen, egal wo du sie her hast. Natürlich nicht den Rest des Paketes.
eagle user schrieb: > Die Lizenz für das komplette Paket ist aber restriktiver. Was > gilt jetzt? Ohne die Lizenzen zu kennen: Die Header darfst du ja in deiner Software verwenden und proprietaer und kommerziell vertreiben. Das gilt sicherlich nicht fuer die im Cube-Packet enthaltenen Entwicklumgsprogramme, bzw. das gesamte Cube.
eagle user schrieb: > Wenn man erstmal gemerkt hat, dass man jedes Modul einzeln einschalten > muss, ist der Takt doch nicht knifflig. Nein, ich meine die Konfiguration der PLL und den ganzen Vorteilern für die verschiedenen Bustakte, das was in der SystemInit()-Funktion passiert (bei mir in der gcc_startup_system.c) wenn man sich das von Null an aus den Fingern saugen will muss man schon ein paar Stunden lang mit dem RefMan meditieren. Je nachdem was Du für einen Quarz dran hast musst Du da schon an einigen Schrauben drehen um alle Taktfrequenzen richtig einzustellen und auch die Reihenfolge der Initialisierung beachten. Da hilft es dann evtl doch mal notfalls sich vom Konfigurationstool helfen zu lassen diesen Code zu generieren und dann zu versuchen nachzuvollziehen welche Register es da warum und in welcher Reihenfolge konfiguriert hat.
Ganz schön aus einer Quelle bekommt man die SVDs/Header bei ARM direkt aka Keil: https://www.keil.com/dd2/pack/ Das sind einfach zip's oder ein anderes sehr einfach zu entpackendes Format, das weiß ich gerade nicht mehr.
Bernd K. schrieb: > Konfiguration der PLL Auch die ist beim STM32L4 zum Beispiel wesentlich einfacher und übersichtlicher als zum Beispiel das UART-Peripheral. Mehr als eine Stunde sollte man da im RefMan nicht lesen müssen, um die korrekten Einstellungen zu finden. Und immer dran denken, die Wait-States mit einzustellen! Davon steht im RCC-Abschnitt nichts, aber wenn man es vergisst, passieren die komischsten Sachen und man weiß nicht warum.
eagle user schrieb: > Selbst wenn ich eine IDE kaufen würde, wäre es ja Glückssache, ob die > Header für einen bestimmten Chip dabei sind. Natürlich könnte ich die > selber schreiben, aber das kann's doch nicht sein. Wo bekommt ihr diese > Files her? "Das kann's doch nicht sein" ?? Doch, das kann's sein. Man braucht dazu bloß das Referenzmanual, einen PDF-Reader, einen Editor und die Zeit, sich das RefMan mal durchzugucken. Das hat seine Meriten: man hat dabei nicht nur sich sein .h selber gemacht, sondern auch einen ersten Eindruck vom Chip gewonnen. Aber ich sehe ein, daß sowas nix ist für Leute, die den festen Willen haben, sich fern ihrer Hardware zu halten. Bernd K. schrieb: > Nein, ich meine die Konfiguration der PLL und den ganzen Vorteilern für > die verschiedenen Bustakte, das was in der SystemInit()-Funktion > passiert... Gerade das ist doch ausgeprochen übersichtlich und bequem bei den STM32. W.S.
W.S. schrieb: > man hat dabei nicht nur sich sein > .h selber gemacht, sondern auch einen ersten Eindruck vom Chip gewonnen. Durch das sinnlose Kopieren von mehreren 100 Registeradressen hat man also automatisch ein Verständnis für den Chip? Ich bin da eigentlich ganz froh, dass einem diese doch sehr eintönige Arbeit von den Chipherstellen üblicherweise abgenommen wird.
:
Bearbeitet durch User
Horst schrieb: > Ganz schön aus einer Quelle bekommt man die SVDs/Header bei ARM direkt > aka Keil: > https://www.keil.com/dd2/pack/ Was wäre der Vorteil gegenüber direkt von st.com? Die Lizenz ist jedenfalls noch abschreckender :( W.S. schrieb: > eagle user schrieb: > > Natürlich könnte ich die (Header) selber schreiben, aber > > das kann's doch nicht sein. > > "Das kann's doch nicht sein" ?? > > Doch, das kann's sein. > > Man braucht dazu bloß das Referenzmanual, einen > PDF-Reader, einen Editor und die Zeit, sich das RefMan mal > durchzugucken. Das hat seine Meriten: man hat dabei nicht nur sich sein > .h selber gemacht, sondern auch einen ersten Eindruck vom Chip gewonnen. Blöd, dass ich das Manual schon vorher gelesen hab ;) Aber gut, überredet. Großer Nachteil vom selber schreiben: ich kann Bitfelder statt #defines verwenden und ich weiß garnicht, was die Leute daran schlecht finden.
eagle user schrieb: > Großer Nachteil vom selber schreiben: ich kann Bitfelder statt #defines > verwenden und ich weiß garnicht, was die Leute daran schlecht finden. Solange Du sicherstellst, daß der von Dir verwendete Compiler die tatsächlich so herum implementiert, wie Du denkst, ist das ja OK. Zumindest, solange Du Dir beim Schreiben stets im Klaren bist, daß der Zugriff nicht atomar sein wird, auch wenn's nur eine Zeile ist. Vergißt man das, kann man sehr unterhaltsame Fehler bekommen. Darfste halt nicht die Toolchain wechseln, weil ein anderer Compiler das wieder anders handhaben kann. Im Grunde darfste nichtmal updaten, weil auch dabei die Implementierung sich ändern darf, aber das dürfte praktisch kaum vorkommen. Die Plattform wechseln geht natürlich auch nicht, aber das ist bei der untersten Treiberschicht ohnehin so.
eagle user schrieb: > Großer Nachteil vom selber schreiben: Der für mich größte Nachteil am selber schreiben ist, dass sich da wunderbar kleine Fehler einschleichen können, die man nicht bemerkt, bis man die entsprechende Hardware auch benutzen möchte. Andererseits sind auch die Header vom Hersteller bei weitem nicht immer fehlerfrei...
Hallo, vielen Dank für die zahlreichen Antworten. Ich hatte die letzten Tage viel zu tun. Daher komme ich erst jetzt dazu, alle Beiträge zu lesen. @Sebastian V.O. Ich glaube, dass ich hier einen Denkfehler hatte. Soweit ich das sehe, ist GPIOx über die herstellerspezifische Definition stm32f10x.h innerhalb des CMSIS-Teils als Adresse der Peripherie und des spezifischen Ports definiert (GPIOx_BASE). Dazu existiert eine Struct-Definition, welche Variablendeklarationen beinhaltet, die für die unterschiedlichen Funktionen der GPIOx_Registeranteile stehen, z.B. MODE, TYPE, SPEED und Inhaltsregister. Der übliche Aufruf GPIOx führt dann einen Typecast aus, so dass über die Peripherieadresse direkt auf die Strukturmember von GPIO_TypeDef geschrieben werden kann. Der Teil ist damit CMSIS und dem ensprechend ist ein Arbeiten auf der hier definierten Registerebene damit konform. Gut. @Bernd K. Vielen Dank für deinen Hinweis. Ich habe es mir gleich überflogen es scheint meiner obigen Bemerkung zu entsprechen. Die weitergehenden Punte von dir werde ich mir über das WE ansehen. Gerade auch die von dir angesprochenen Frequenzteile. Was deinen Kompilationseinwand belangt: darum würde ich mich gerne in einem zweiten Schritt erst kümmern. Es geht mir gerade darum, mit möglichst wenig Overhead erste Projekte umsetzen zu können und mich damit möglichst wenig an einen spezifischen Anbieter zu binden. Vielleicht brauche ich ja bald NXP oder Kinetis oder... Daher würde ich gerne Bibliotheken oder Kapselungen möglichst zunächst vermeiden wollen. Auch wenn diese ggf. sinnvoll sind. @ W.S. darum ja meine Anfrage. Wie oft ich mich wieder und wieder in Neuerungen einarbeiten musste in der letzten Zeit, nur weil Firmen plötzlich die! Innovation hatten oder Projekte "gewachsen" waren. Zum Schluss gab es dann mitunter 5 standardisierte Methoden, die alle das gleiche erbrachten aber stets aus einer anderen Bibliotheksgeneration stammten. Software ändert sich da schneller als Hardware. Und auf Registerebene fühle ich mich wohl und es bedarf meist nur weniger Zeichen um etwas zu erreichen. Ich stimme dir bei "SetMyPin" hinsichtlich der flexibilität und Softwareunabhängigkeit zu. Möglichst wenig Bibliotheken, möglichst knapper Code. Ob das effizient ist gerade auch mit Blick auf die Wartbarkeit, mürde ich zunächst gerne vernachlässigen. @Marcus H. Guten Morgen Dave... "Allerdings findet man direkt bei ST, manchmal etwas versteckt, für jeden STM32 (zumindest für F0,F1,F4) aktuelle Bibliotheken, die nicht auf HAL aufbauen. Diese, zusammen mit den Datenblättern und der reichhaltigen Doku, ermöglichen eine effiziente Programmierung und Codepflege." Welche Bibliotheken meinst du damit genau? Welche reichhaltige Dokumentation meinst du (Die Reference Manuals?) @Markus M. Ja, das fand ich bei den AVRs auch gut gelöst. Der Umstieg wird einem da etwas erschwert. Es geht mir nicht um Pros oder Kons zu den unterschiedlichen Bibliotheken. Ich wollte nur abstecken, wo die rudimentärste Definition endet. @ Random Das mit den Peripherie-Libs wird ja schon bei der STM32f10x.h deutlich. Das mit dem SVDConv werde ich mir mal ansehen, danke. ---- Dann werde ich mich die nächsten Tage weiter mit dem Thema beschäftigen. Mit Gruß und vielem Dank. Schmidt
Schmidt schrieb: > @Marcus H. > "Allerdings findet man direkt bei ST, manchmal etwas versteckt, für > jeden STM32 (zumindest für F0,F1,F4) aktuelle Bibliotheken, die nicht > auf HAL aufbauen. Sorry, das war ein Tipp für Fortgeschrittene. Mir ging es hier um USB und Ethernet Libs ohne HAL. Stell das erstmal hinten an. > Diese, zusammen mit den Datenblättern und der reichhaltigen Doku, > ermöglichen eine effiziente Programmierung und Codepflege." > > Welche Bibliotheken meinst du damit genau? Welche reichhaltige > Dokumentation meinst du (Die Reference Manuals?) Datasheet PMxxxx RMxxxx Errata und dann die jeweilige Peripheriebeschreibungen. Wie Du schon gemerkt hast, sind die ARM-MCUs eine andere Kampfklasse als AVRs. Für die Einarbeitung würde ich eine Peripherie angehen. Das wird und die verfügbare Information ist deutlich besser als 2009... Als IDE würde ich Atollic True Studio empfehlen - da bekommst Du ein lauffähiges System serviert, nah an der CMSIS, ohne HAL. Ich vermute, dass ATS sogar Dein Evalboard kennt... Wobei das nur meine Sicht der Dinge ist - ich bin Hardwareentwickler, der auch programmiert. Falls mein Deutsch gerade etwas holprig ist - es ist spät und ich habe die letzten paar Stunden Japanisch gelesen und geschrieben. ;)
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.