MCPcopy Index your code
hub / github.com/cpq/bare-metal-programming-guide

github.com/cpq/bare-metal-programming-guide @main

Chat with this repo
repository ↗ · DeepWiki ↗ · + Follow
2,830 symbols 6,564 edges 99 files 366 documented · 13%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Sıfırdan programlamaya başlangıç rehberi

Lisans: MIT Build Status

English | 中文 | Türkçe

Bu rehber herhangi bir framework kullanmadan sadece GCC derleyicisi ve datasheet kullanarak mikrodenetleyici programlamayı arzulayan geliştiriciler için yazılmıştır. Rehber, Cuce, Keil, Arduino gibi araçların temelinde nasıl çalıştığını ana hatlarıyla açıklamayı amaçlamaktadır.

Bu rehberdeki her bölüm, işlevsellik ve eksiksizlik açısından kademeli olarak ilerleyen kaynakları içerir. Özetle, farklı mimarilerdeki projeleri sıfırdan anlatacağız.

  • blinky - En klasiklerden biri olan LED yakma ve düzenli olarak debug mesajı yazmak
  • cli - UART komut satırı arayüzü. LED durumunu ve RAM'in hexdump'ını alan komutları implemente eder.
  • lfs - Flash memory'nin üst bölümüne littlefs kullanarak mkdir(),readdir(),fopen() gibi fonksiyonları implemente eder. Cihaz boot sayısını bir dosyada tutar, her boot'ta arttırır ve düzenli olarak yazdırır.
  • webui - mongoose library sayesinde profesyönel bir cihaz arayüzü sunan gömülü web sunucusu
Kart Arch MCU datasheet Board datasheet Örnek proje
STM32 Nucleo-F429ZI Cortex-M4 mcu datasheet board datasheet blinky, cli, webui
STM32 Nucleo-F303K8 Cortex-M4 mcu datasheet board datasheet lfs
STM32 Nucleo-L432KC Cortex-M4 mcu datasheet board datasheet blinky, cli, lfs
TI EK-TM4C1294XL Cortex-M4F mcu datasheet board datasheet webui
RP2040 Pico-W5500 Cortex-M0+ mcu datasheet board datasheet webui
ESP32-C3 RISCV mcu datasheet blinky

Bu öğreticide Nucleo-F429ZI geliştirme kartını kullanacağız bu yüzden mikrodenetleyicinin ve kartın datasheet'lerini indirmeyi unutmayın.

Hakkımda

Ben Sergey Lyubka, mühendis ve girişimciyim. Ukrayna Kyiv State üniversitesinde fizik lisansı yapıyorum . İrlanda Dublin merkezli Cesanata teknoloji şirketinin kurucu ortağı ve yöneticisiyim. Cesanata'nın geliştirdiği bazı gömülü çözümler:

  • https://mongoose.ws - açık kaynaklı HTTP/MQTT/Websocket ağ kütüphanesi
  • https://vcon.io - uzaktan firmware güncelleme ve serial monitoring framework'ü

Gömülü ağ programlama konusundaki ücretsiz web seminerime davetlisiniz.

Araçların kurulumu

Çalışmalara devam edebilmek için şunlar gereklidir :

  • ARM GCC, https://launchpad.net/gcc-arm-embedded - derleme ve link'leme için
  • GNU make, http://www.gnu.org/software/make/ - derlemeyi otomatik hale getirmek için
  • ST link, https://github.com/stlink-org/stlink - Flash'lama için
  • Git, https://git-scm.com/ - Kodları indirmek ve versiyon kontrolü için

Mac için kurulum aşamaları

Terminalinizi açın ve şu komutu çalıştırın:

$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
$ brew install gcc-arm-embedded make stlink git

Linux (Ubuntu) için kurulum aşamaları

Terminalinizi açın ve şu komutu çalıştırın:

$ sudo apt -y update
$ sudo apt -y install gcc-arm-none-eabi make stlink-tools git

Windows için kurulum aşamaları

  • İndirin ve kurun gcc-arm-none-eabi-10.3-2021.10-win32.exe. Kurulum sırasında "Path ekle" seçeneğini aktifleştirin.
  • c:\tools klasörünü oluşturun.
  • stlink-1.7.0-x86_64-w64-mingw32.zip indirin ve bin/st-flash.exe dosyasını c:\tools içine çıkartın.
  • make-4.4-without-guile-w32-bin.zip indirin ve bin/make.exe dosyasını c:\tools içine çıkartın.
  • c:\tools klasörünü Path ortam değişkenine ekleyin.
  • Windows 10/11 için "Geliştirici Ayarları"ndan "Simbiyotik link ekleme" özelliğini açın.
  • Git'i https://git-scm.com/download/win adresinden indirin. "symlink aktifleştir / Enable symlink" seçeneğini işaretleyin.

Yüklenmiş araçların kontrolü

An itibariyle tüm gerekli araçlar yüklendi, terminali ya da komut istemcisini açın ve aşağıdaki komutla bu projeyi indirin ve örneği derleyin.

git clone https://github.com/cpq/bare-metal-programming-guide
cd bare-metal-programming-guide/steps/step-0-minimal
make

Giriş

mikrodenetleyiciler (uC, veya MCU) özünde küçük bilgisayarlardır. Genellikle CPU, RAM, kodun yükleneceği flash ve bir avuç pin içerirler. Bazı pinler kontrolcüye güç sağlamak için kullanılır, bunlar çoğunlukla GND (topraklama) ve VCC pini olarak işaretlenir. Diğer pinler ise yüksek(high) ve alçak(low) voltaj vererek kontrolcü ile haberleşmek için kullanılır. Haberleşmeden kastedilenlerden en basiti LED yakmaktır. LED'in bir ayağı GND'ye diğer ayağı ise akım sınırlayıcı direnciyle birlikte bir sinyal pinine takılır. Yazılım sinyal pinini low ve high yaparak LED'i yakıp söndürür.

Bellek ve register'lar

Kontrolcü 32-bit'lik adreslenebilir bölge(region)'lere bölünmüştür. Mesela bazı bellek bölümleri kontrolcünün dahili flash'ının spesifik adresleri ile eşlenmiştir. Firmware kodu bu bölgeyi kullanarak komutları okur ve çalıştırır. Diğer bir bölüm ise başka bir spesifik adresle eşlenmiş olan RAM'dir. RAM bölgesine istediğimiz herhangi bir değeri okuyup yazabiliriz.

STM32F429 datasheet'inin 2.3.1 bölümünü incelediğimizde RAM'in 0x20000000 adresinden başladığını ve 192KB genişliği bulunduğunu anlarız. 2.4 numaralı bölümde flash'ın ise 0x08000000 adresi ile eşlendiğini görebiliriz. mikrodenetleyicimiz 2MB'lık flash'a sahip olduğuna göre RAM bölgesi şöyle konumlandırılmıştır:

Datasheet'te baktığımızda bunlardan daha fazla bellek bölgesi olduğunu da fark ederiz 2.3 numaralı "Memmory Map" bölümünde bunların adres aralıkları verilmiştir. Örnek olarak "GPIOA" bölgesi 0x40020000 adresinden başlayım 1KB uzunluğa sahiptir.

Bu bellek bölgeleri, MCU içindeki farklı "çevre birimlerine" karşılık gelir

  • belirli pinlerin özel bir şekilde davranmasını sağlayan devrelerdir. Çevresel bellek bölgesi, 32 bitlik register'lardan oluşur.Her register, belirli bir adresteki 4 byte'lık hafızayla çevre biriminin belirli bir özelliği ile eşleşir Veriler bu adreslere yazılır. Bir başka deyişle verilen adres aralığına 32 bit yazarak çevre birimine istediğimizi yaptırabiliriz. Register'ları okuyarak da çevre biriminin konfigrasyonunu veya gönderdiği veriyi elde edebiliriz.

Birden fazla çevre birimi bulunmaktadır. Bunlardan en basiti MCU'nun pinlerini "output mode"(çıktı modu) olarak ayarlayıp pine high veya low voltaj vermemizi veya "input mode"(girdi modu) olarak ayarlayıp pine uygulanan voltajı okumamızı sağlayan GPIO(genen amaçlı girdi çıktı)'dur. Seri haberleşme protokolünü kullanarak sadece iki pin ile seri veri almamıza(recive) ve iletmemize(transmit) olanak sağlayan UART çevre birimi de örnek verilebilir. Bunlar dışındada birsürü birim vardır.

Sıklıkla çevre birimlerinin birden fazla örneği,varyasyonu bulunur. Mesela, GPIOA, GPIOB MCU'nun farklı pinlerini kontrol ederler. Aynı şekilde UART1, UART2 de farklı UART kanallarını implemente ederler.Nucleo-F429'de, birden fazla GPIO and UART çevre birimi bulunur.

GPIOA 0x40020000 adresinden başlar,bölüm 8.4'te GPIO register'larının açıklamalarına ulaşabilirsiniz Datasheet'in söylediğine göre GPIOA_MODER register'ının offset'i 0'dır,bunun anlamı register'ın adresi 0x40020000 + 0'dir ve register'ın formatı şu şekildedir:

Datasheet'te 32-bit MODER register'larının toplamda 16 olacak şekilde 2-bit'lik veriler tuttuğunu görebilirsiniz. Öyleyse bir MODER register'ı 0.pin için 0 ve 1 bitleri, 1.pin için 2 ve 3 bitleri şeklinde devam ederek 16 fiziksel pini kontrol edebilir. 2 bitlik pinin modununa göre 0 girdiyi(input), 1 çıktıyı(output), 2 özel fonksiyonu (alternate function) -başka bir yerde açıklanan özel işlev- ve 3 ise analog modu ifade eder. Pinler ise bulunduğu bölgeye uygun yani GPIOA için "A0", "A1" veya GPIOB için "B0", "B1" şeklinde adlandırılırlar.

Eğer MODER register'ına 32 bit boyunca 0 değerini yazarsak A0'dan A15'e kadar 16 pini de input moduna göre ayarlamış oluruz.

  * (volatile uint32_t *) (0x40020000 + 0) = 0;  // A0-A15 arasını input olarak ata

volatile anahtar kelimesini aklınızda tutun bunun anlamına daha sonra değineceğiz.Bitleri tek tek değiştirerek sadece istediğimiz pinlere mod atayabiliriz. Örnek olarak A3 pinini "output" olarak ayarlayalım.

  * (volatile uint32_t *) (0x40020000 + 0) &= ~(3 << 6);  // 6-7 aralığını temizle
  * (volatile uint32_t *) (0x40020000 + 0) |= 1 << 6;     // 6-7 aralığını 1 ata

Gelin bu bit işlemlerini birlikte inceleyelim. Amacımız, GPIOA çevre biriminin 3.pininden sorumlu olan bit 6-7'yi belirli bir değere (bizim durumumuzda 1) olacak şekilde atamaktır. Bu işlem iki adımda yapılır. İlk olarak, 6-7 bitlerinin mevcut değerini silmeliyiz, çünkü daha önceden içinde tuttuğu değer işimizi bozabilir. Ardından 6-7 bitlerini istediğimiz değere ayarlamalıyız.

Bundan dolayı,ilk önce 6. ve 7. bitleri 0 yapmalıyız.Peki bir sayının belirli bitlerini nasıl sıfır yaparız? Dört adımla şöyle:

İşlem İfade Bitler (32 bitin ilk 12'si)
N tane yan yana biti alın: 2^N-1, N=2 3 000000000011
O sayıyı X kere sola kaydırın (3<<6) 000011000000
Sayıyı tersleyin: Birler sıfır, sıfırlar bir olacak ~(3<<6) 111100111111
Sayıyı bitsel VE(AND) işlemine tabi tutun VAL &= ~(3<<6) xxxx00xxxxxx

Son adımı aklınızda tutun, bitsel AND işlemi X yerindeki N tane biti sıfırlar (çünkü 0 ile AND'lendi) ama geri kalan bitlere dokunmaz(çünkü 1 ile AND'lendi. Kendisi neyse yeni değeri de o kalacak). Kalan verilere dokunulmaması çok önemlidir çünkü iki veriyi değiştirmek isterken önceden atanan diğer verileri değiştirmek sistemimizi bozacaktır. Özetle

Core symbols most depended-on inside this repo

mg_error
called by 44
steps/step-7-webserver/nucleo-f429zi/mongoose.c
mg_call
called by 44
steps/step-7-webserver/pico-w5500/mongoose.c
mg_error
called by 44
steps/step-7-webserver/pico-w5500/mongoose.c
mg_error
called by 44
steps/step-7-webserver/ek-tm4c1294xl/mongoose.c
mg_call
called by 43
steps/step-7-webserver/nucleo-f429zi/mongoose.c
mg_call
called by 43
steps/step-7-webserver/ek-tm4c1294xl/mongoose.c
mg_snprintf
called by 35
steps/step-7-webserver/nucleo-f429zi/mongoose.c
mg_snprintf
called by 35
steps/step-7-webserver/ek-tm4c1294xl/mongoose.c

Shape

Function 2,298
Class 532

Languages

C70%
C++30%

Modules by API surface

steps/step-7-webserver/nucleo-f429zi/mongoose.c469 symbols
steps/step-7-webserver/ek-tm4c1294xl/mongoose.c469 symbols
steps/step-7-webserver/pico-w5500/mongoose.c462 symbols
steps/step-7-webserver/nucleo-f429zi/include/cmsis_gcc.h135 symbols
steps/step-7-webserver/ek-tm4c1294xl/include/cmsis_gcc.h135 symbols
steps/step-7-webserver/pico-w5500/mongoose.h65 symbols
steps/step-7-webserver/nucleo-f429zi/mongoose.h64 symbols
steps/step-7-webserver/ek-tm4c1294xl/mongoose.h64 symbols
templates/lfs/nucleo-l432kc/syscalls.c38 symbols
templates/lfs/nucleo-f303k8/syscalls.c37 symbols
steps/step-7-webserver/pico-w5500/hal.h34 symbols
templates/blinky/esp32-c3/hal.h33 symbols

For agents

$ claude mcp add bare-metal-programming-guide \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact