Programmierung moderner Mikrocontroller: Vorlesung 1

Zusammenfassung der ersten Vorlesung zur Programmierung moderner Mikrocontroller am Beispiel von STM32 und dem Betriebssystem RIOT. Die Vorlesungen werden samstags ab 12:50 Uhr im MIREA-Institut fĂŒr Informationstechnologie im Auditorium im 4. Stock des GebĂ€udes D gehalten. Die Vorlesungen selbst dauern 1,5 Stunden und die praktischen Vorlesungen im IoT-Labor der Samsung Academy zum Thema der Vorlesung 3 Stunden.

Hallo Giktayms! Wie versprochen, beginnen wir mit der Veröffentlichung von Vorlesungsunterlagen, die am MIREA IT Institute geliefert werden. Nach den Ergebnissen der ersten EinfĂŒhrungsvorlesung haben wir beschlossen, die Struktur des Kurses leicht zu Ă€ndern - anstelle der geplanten zwei Ströme mit 5 Lektionen wird es einen Strom fĂŒr 7 Lektionen geben. Dies wird es ermöglichen, eine Reihe von unterstĂŒtzenden Fragen in einem entspannteren Tempo zu klĂ€ren, und abstrakte Artikel werden jede Woche im MĂ€rz und April auf dem GT erscheinen und nicht wie zuvor geplant in einer Woche.

Trotzdem ist es unmöglich, ein so umfangreiches Thema in sieben Vorlesungen vollstÀndig zu behandeln, so dass die PrÀsentation an einigen Stellen eine These sein wird. Um dies zu kompensieren, werden wir versuchen, anzugeben, in welche Richtung diejenigen schauen werden, die dieses oder jenes Thema unabhÀngig genauer untersuchen möchten.

Der Kurs richtet sich an Studierende des zweiten und dritten Studienjahres, die mit der C-Sprache und den Grundkonzepten der Elektronik und Elektrotechnik vertraut sind. Eine vorherige Kenntnis der Mikrocontroller ist nicht erforderlich.

Der Zweck des Kurses ist die Entwicklung von FĂ€higkeiten, die es Ihnen ermöglichen, auf moderner Ebene frei mit Mikrocontrollern am ARM Cortex-M-Kern zu arbeiten und, falls dies gewĂŒnscht wird, Ihr Wissen weiter zu vertiefen.



Die heutige Vorlesung ist die erste, damit allgemeine Konzepte verstanden werden: Was ist ein Mikrocontroller im Allgemeinen und warum wird er benötigt, was ist Firmware und wie wird er erhalten, warum benötigen wir ein Betriebssystem und schließlich, wie man mit Git arbeitet. Das Ergebnis dieser Lektion ist Ihr eigenes GitHub-Repository mit Betriebssystem-Quellcodes sowie eine erfolgreich konfigurierte Build-Umgebung auf dem lokalen Computer.

Mikrocontroller


Kurz gesagt, der Mikrocontroller ist ein klassisches Beispiel fĂŒr ein „System auf einem Chip“, das sowohl den Prozessorkern als auch eine Reihe von Hilfs- und PeripheriegerĂ€ten umfasst, wodurch der Mikrocontroller in vielen FĂ€llen völlig autark ist.



In einem typischen Mikroprozessor, Ă€hnlich wie auf jedem PC oder Smartphone, werden fast alle Module, die Hilfsmodulen zugeordnet werden können (Stromversorgung, Taktung, sogar grundlegende PeripheriegerĂ€te), außerhalb des Chips selbst bewegt, obwohl der Mikroprozessor ohne sie arbeitet kann nicht.

Im Mikrocontroller hingegen sind auf demselben Chip mit dem Kern nicht nur die fĂŒr seinen Betrieb erforderlichen Subsysteme implementiert, sondern auch eine Vielzahl von PeripheriegerĂ€ten, die fĂŒr verschiedene praktische Aufgaben erforderlich sein können. DarĂŒber hinaus konkurrieren viele Hersteller von Mikrocontrollern nicht in Bezug auf Kernleistung oder SpeicherkapazitĂ€t miteinander, sondern in Bezug auf die FĂŒlle und Funktionen von PeripheriegerĂ€ten.

Mikrocontroller werden seit geraumer Zeit parallel zu Mikroprozessoren entwickelt - beispielsweise wurde die Intel 8051-Architektur, die noch in Industrieprodukten zu finden ist, 1980 entwickelt. An einigen Stellen beginnen sich ihre Entwicklungslinien mit Mikroprozessoren zu ĂŒberschneiden. Beispielsweise verfĂŒgen Ă€ltere Modelle von Mikrocontrollern ĂŒber Schnittstellen fĂŒr externes RAM, und Hersteller von Mikroprozessoren integrieren immer mehr PeripheriegerĂ€te auf den Chip (es reicht aus, sich daran zu erinnern, dass zu Beginn der „Personal Computer“ sogar ein externer Cache gewĂ€hlt wurde Mikroschaltungen) - aber auf jeden Fall bleiben sie zwei signifikant unterschiedliche Entwicklungszweige.

TatsĂ€chlich bestand das Ziel der Entwicklung von Mikrocontrollern darin, die Kosten und die Miniaturisierung verschiedener GerĂ€te zu reduzieren, die eine geringe Rechenleistung erfordern: Die Verwendung eines einzelnen Chips, fĂŒr den die Stromversorgung fĂŒr den Betrieb ausreicht, vereinfacht das Design und die Herstellung einer Leiterplatte im Vergleich zu einem Satz von 4 bis 5 separaten Chips erheblich .

NatĂŒrlich hat der Mikrocontroller seine eigenen EinschrĂ€nkungen - es ist technisch unmöglich, in einen Chip zu packen, was in einem großen PC eine halbe, ziemlich große Platine belegt.

  • Betriebsfrequenzen ĂŒberschreiten selten 200 MHz und liegen hĂ€ufiger im Bereich von zehn Megahertz.
  • Die RAM-GrĂ¶ĂŸe liegt innerhalb von Megabyte und hĂ€ufiger im Bereich von mehreren zehn Kilobyte.
  • Die GrĂ¶ĂŸe des Programmspeichers liegt innerhalb von Megabyte und hĂ€ufiger im Bereich von zehn bis Hunderten von Kilobyte.

Im Rahmen des Kurses werden wir mit STM32L151CC-Mikrocontrollern arbeiten, die ĂŒber 32 KB RAM, 256 KB ROM und eine maximale Betriebsfrequenz von 32 MHz verfĂŒgen (auf den Nucleo-L152RE-Karten befinden sich etwas schwerwiegendere Chips - 80 KB RAM und 512 KB ROM).

Die Erinnerung


Im Allgemeinen kann es in einem Mikrocontroller vier Arten von Speicher geben:

  1. Der permanente Speicher (Flash-Speicher) wird zum Speichern von Benutzerprogrammen und manchmal einiger Einstellungen des Mikrocontrollers selbst verwendet. Wenn sie bei der Angabe der Eigenschaften des Mikrocontrollers die Speichermenge schreiben, ohne anzugeben, welche - in der Regel handelt es sich um Flash. Der Inhalt des Blitzes wird nicht zurĂŒckgesetzt, wenn die Stromversorgung ausfĂ€llt. Die Speicherdauer der darin enthaltenen Informationen betrĂ€gt unter normalen Bedingungen normalerweise mindestens 10 Jahre.
  2. RAM wird verwendet, um ein Benutzerprogramm auszufĂŒhren und "momentane" Daten zu speichern. Der Arbeitsspeicher wird beim Neustart oder Ausschalten immer zurĂŒckgesetzt und möglicherweise auch nicht gespeichert, wenn Sie in den Ruhemodus wechseln. In Mikrocontrollern gibt es oft keine klare Trennung zwischen Programmspeicher und Datenspeicher - daher kann der Begriff "AusfĂŒhrung aus dem RAM" gefunden werden, was bedeutet, dass im RAM nicht nur Daten, sondern auch das Programm selbst vorhanden sind; Dies sind jedoch ziemlich exotische FĂ€lle.
  3. EEPROM . Es bezieht sich auch auf Nur-Lese-Speicher, unterscheidet sich jedoch in seinen Eigenschaften erheblich vom Flash-Speicher. Der Flash hat zwei große Nachteile, die es sehr unpraktisch machen, einige aktuelle Daten aus dem Programm zu speichern: Erstens hat der Flash eine begrenzte Anzahl von Überschreibungen derselben Zelle, und zweitens ist es oft möglich, mit dem Flash nur auf ganzen Seiten zu arbeiten sind Hunderte von Bytes groß, auch wenn Sie nur ein Byte ĂŒberschreiben mĂŒssen. Das EEPROM weist diese Nachteile nicht auf - seine Lebensdauer ist normalerweise zehnmal so lang (von 100.000 bis 1 Million Überschreibungen), und Sie können mit jedem Byte einzeln damit arbeiten. Aus diesem Grund wird das EEPROM zur dauerhaften Speicherung von Daten verwendet, die vom Programm selbst generiert wurden (Messarchive, Programmeinstellungen usw.). Das typische Volumen betrĂ€gt Einheiten von Kilobyte, ist jedoch nicht in allen Controllern enthalten.
  4. Systemspeicher Bereiche des Nur-Lese-Speichers, auf die der Benutzer fĂŒr die Aufzeichnung nicht zugreifen kann, die jedoch bei der Herstellung des Mikrocontrollers aufgezeichnet wurden. Normalerweise enthalten sie den ausfĂŒhrbaren Code des Bootloaders (dazu weiter unten), aber einige Kalibrierungskonstanten, Seriennummern oder sogar Hilfsbibliotheken fĂŒr die Arbeit mit PeripheriegerĂ€ten können ebenfalls gespeichert werden

Sie können die Speicherorganisation eines bestimmten Controllers in seinem Datenblatt anzeigen. Hier ist zum Beispiel ein Datenblatt zum STM32L151CC , auf dem Seite 51 eine Speicherkarte dieser Familie vorgestellt wird.

Es ist leicht zu bemerken, dass alle vier Arten von Speicher, ĂŒber die wir gesprochen haben, einen sehr kleinen Teil der Karte belegen - und auf dem grĂ¶ĂŸten Teil des Bildes ist eine Liste aller PeripheriegerĂ€te im Controller verfĂŒgbar.

Register


Tatsache ist, dass alles - im Allgemeinen alles - die Kommunikation mit allen PeripheriegerĂ€ten des Mikrocontrollers und all seinen Einstellungen mit nur zwei Operationen ausgefĂŒhrt wird:

  • Lesen Sie den Wert an der angegebenen Adresse
  • Schreiben Sie den Wert an die angegebene Adresse

Alles, was sich im Mikrocontroller befindet, ist notwendigerweise einer Adresse zugeordnet. Diese Adressen werden als Register bezeichnet (nicht mit Prozessorregistern verwechseln - die Register der Prozessoren enthalten Daten, an denen der Prozessor Operationen ausfĂŒhrt; die Register, ĂŒber die wir sprechen, enthalten einige spezielle Daten, die speziell dem Zustand verschiedener Hardwareeinheiten des Mikrocontrollers zugeordnet sind).

Wenn zum Beispiel "1" auf dem dritten Zweig von Port A des Mikrocontrollers erscheinen soll (PA2, Nummerierung von Grund auf neu), mĂŒssen wir "1" in das dritte Bit des Registers bei 0x4002014 schreiben. Und wenn dieser Zweig als Eingang konfiguriert ist und wir im Gegenteil herausfinden möchten, welcher Wert darauf ist, mĂŒssen wir das dritte Bit des Registers unter der Adresse 0x40020010 lesen.

Ja, um dem Controller anzuzeigen, dass dieser Zweig der Ein- oder Ausgang ist, mĂŒssen Sie die entsprechenden Werte in die entsprechenden Bits unter der Adresse 0x40020000 schreiben.

Dies ist ein wichtiger Punkt fĂŒr das VerstĂ€ndnis der Funktionsweise des Mikrocontrollers: Absolut alles, was keine Rechenoperationen sind, fĂŒr die der Prozessorkern verantwortlich ist, erfolgt durch Schreiben oder Lesen dieses oder jenes Registers. Welche Bibliotheken auch immer von oben in Ihr Programm hineingelockt werden - am Ende kommt es auf die Register an.

Das Arbeiten mit numerischen Adressen ist natĂŒrlich ziemlich unpraktisch, daher gibt es fĂŒr jeden Mikrocontroller auf dem Cortex-M-Kern eine CMSIS-Bibliothek (Cortex Microcontroller Software Interface Standard), deren wichtigste Komponente fĂŒr uns die Header-Datei ist, die die in einem bestimmten Controller verfĂŒgbaren Register beschreibt und sie relativ lesbar macht Namen.

Unter Verwendung von CMSIS sehen die oben beschriebenen VorgĂ€nge mit dem PA-Fuß folgendermaßen aus:

int pin_num = 2; /* PA2*/
GPIOA->MODER &= ~(0b11 << (pin_num*2)); /*     PA2    */
GPIOA->MODER |= 0b01 << (pin_num*2); /*     PA2  01 —  */
GPIOA->ODR |= 1 << pin_num; /*   PA2  1 */

GPIOA->MODER &= ~(0b11 << (pin_num*2)); /*     PA2,    */
uint32_t pa2_value = GPIOA->IDR & (1 << pin_num); /*    PA2 */

, — Reference Manual (, , , RM0038, STM32L1). , 900 RM0038 —  , 1500-2000 . -, , —  .

, — . , , «» .

, , — , - ( 1 , , , 1 , , ), .

STM32 Standard Peripherals Library, StdPeriphLib, SPL. , ST LL, — , LibOpenCM3. , STM32 .

, SPL , , , GPIO_Init GPIO_Write.

, , SPL — .

, SPL «» , , STM32 CubeMX. (, , ) STM32.

, , « , - » — « , ». SPL, , , , SPL , —  SPL , . , .

, , , - , , , STM32L1 ATSAMD21 , SPL, .

SPL — , , , SPL.

, SPL —  «» . , :

  • . , (RTC), — - , ( ) (, ), . -, .
  • . , . Arduino loop() , . loop() , , . ( , ).
  • . , , — , : -, , , . - —  , , , , . , API.

—  —  .

, ( 5-20 ), , 70 % .



, , SPL. RIOT OS, STM32 —  SPL .

: , , , , SPL . , SPL , , STM32, , .


, :



  • — , ;
  • — , , : , , ;
  • —  .

, RIOT OS - (IDE) — , , IDE, (, , Arduino IDE —  ; , , ).

, , , , « , , ».

, , Arduino IDE, IDE, — .



, RIOT OS , : HAL cpu ( , , AVR PIC32), — boards, — drivers, — core, — sys, — examples.

, — , ( ) , , , , . — , , .


https://github.com/unwireddevices/RIOT/tree/mirea — RIOT OS, Unwired Devices STM32L1, , , , .

Github, «Clone/Download» «Download ZIP», . GitHub, «Fork» — , .

GitHub Git —  , .


, , - , «Hello world» :

#include <stdio.h>
int main(void)
{
    puts("Hello World!");
    printf("You are running RIOT on a(n) %s board.\n", RIOT_BOARD);
    printf("This board features a(n) %s MCU.\n", RIOT_MCU);
    return 0;
}

example/hello-world main.c ( ).

, , , . - .

1. Windows 8 . , MinGW, . . , Git/GitHub Git for Windows, MinGW. MinGW, MinGW .

, Windows 7 Windows 8, , .

2. Windows 10. Microsoft Store, Ubuntu . Ubuntu Windows, « Windows», « Windows Linux» .

Ubuntu, , MinGW.

(: 64- Linux!), Ubuntu, :

cd /opt
sudo tar xf /mnt/c/Users/vasya/Downloads/gcc-arm-none-eabi-7-2017-q4-major-linux.tar.bz2
export PATH=/opt/gcc-arm-none-eabi-7-2017-q4-major/bin/:$PATH
export PATH=/opt/gcc-arm-none-eabi-7-2017-q4-major/arm-none-eabi/bin/:$PATH
echo "export PATH=/opt/gcc-arm-none-eabi-7-2017-q4-major/bin/:\$PATH" >> ~/.bashrc
echo "export PATH=/opt/gcc-arm-none-eabi-7-2017-q4-major/arm-none-eabi/bin/:\$PATH" >> ~/.bashrc

.bashrc, Ubuntu. $ >> —  , ( ) .bashrc.

arm-none-eabi-gcc --version , , — 7.2.1 ( ).

Git ssh-keygen, ( Ubuntu Windows cat ~/.ssh/id_rsa.pub, Enter — ) GitHub. GitHub git.

NB: Linux, : , Tab ( cd /opt/gcc- cd /opt/gcc-arm-none-eabi-7-2017-q4-major). , — , . , Tab .

NB: Windows , , Windows, Documents/git/RIOT. - MinGW /c/Users/vasya/Documents/git/RIOT, - Ubuntu — /mnt/c/Users/vasya/Documents/git/RIOT. , , , Windows, Notepad++.

3. Linux. Windows 10, , Microsoft Store . gcc-arm-none-eabi — .

, RIOT examples/hello-world, make.

, , unzip ( Windows 10 ), make . Windows 10 ( ):

sudo apt-get install unzip make

make — , «make clean && make»: , . , - , —  , .

NB: RIOT hello-world native, , , x86. unwd-range-l1-r3, stm32,

Building application "mirea" for "unwd-range-l1-r3" with MCU "stm32l1".

- , make — . mirea.elf ( - ).

- :



, , , , , .

, GPIO, — , , — , .

P.S. — 360- ( : « » , , - ):



Source: https://habr.com/ru/post/de411143/


All Articles