1. Boot Diyagramı
Aşağıda belirtilen akış şeması Gemstone O1 geliştirme kartı için olmakla birlikte bir çok ARM mimarili gömülü Linux geliştirme kartlarında benzer bir yapı bulunmaktadır.1.1. ROM Bootloader (RBL)
Üreticiler tarafından çoğu zaman kaynak kodları verilmeden sadece derlenmiş program olarak dağıtılan RBL (Room Bootloader)‘in temel amacı; karta ilk enerji verildiğinde donanım sağlık kontrolleri ve ilklendirme vb. işlemleri yaparak, kaynak kodları değiştirilebilir olan SBL (Secondary Bootloader) isimli ikinci Bootloader’a geçiş yapmaktır. SBL’in nereden okunarak başlatılacağı ise RBL tarafından Bootmode switchlerinden tespit edilir.1.2. Secondary Bootloader (SBL)
Secondary Boot Loader’un T3-GEM-O1 geliştirme kartlarındaki kullanım amacı U-Boot isimli daha gelişmiş Bootloader’ı başlatmak ve Gemstone Imager isimli uygulama aracılığıyla imajların eMMC’ye yazılmasını sağlamaktır. Linux Kernel içeren gömülü kartlarda çoğunlukla U-Boot tercih edilmektedir. SBL gibi ön yükleyiciler daha temel seviyede ilklendirme işlemleri yapabilirken, U-Boot çok daha gelişmiş özelliklere sahiptir. Örneğin U-Boot kendi Terminal/Konsol arayüzüne ve SBL’de mümkün olmayan bir çok sürücüye sahip olduğu için daha gelişmiş özelleştirmelere imkan sağlar.1.3. U-Boot
SBL sonrası geliştirme kartının kontrolünü devralan U-Boot, Device Tree’de tanımlanmış olan konfigürasyonlara göre ilgili donanımların sürücülerini aktifleştirir ve ön tanımlı bir takım komutları çalıştırarak Linux Kernel, Initrd gibi bileşenleri RAM’e yükleyerek kontrolü Linux Kernel’e devreder.1.3.1. U-Boot Konsol Alıştırmaları

U-Boot Konsolu
1.4. Linux Kernel
Device Tree’de tanımlanan donanımların sürücülerini yükler. Ardından varsa initrd’yi/initramfs’i başlatır ve rootfs’te bulunaninit programını çalıştırır.
1.5. Initial RAM Disk (Initrd)
Rootfs başlatılmadan önce çeşitli kernel modüllerini yükleme, disk şifresini çözme, yazılım güncellemesi yapma gibi ara işlemleri gerçekleştirmeyi sağlayan ve RAM üzerinde bulunan geçici dosya sistemidir.1.6. Root Filesystem (Rootfs)
Initrd, işlemlerini bitirdikten sonra rootfs olarak adlandırılan; sistem ve kullanıcı programlarını, kütüphaneleri ve çeşitli konfigürasyon dosyalarını içeren dosya sistemini/ dizinine bağlar.
Ardından kernel, rootfs’te /init, /sbin/init ya da benzeri bir dizinde bulunan init programını çalıştırır.
Bu program, bazı donanımların sürücülerini yükler (kernel modüllerini), sistem servislerini
(ağ bağlantısı, saat senkronizasyonu, paket güncelleme ve bluetooth gibi servisleri) ve masaüstü ortamını
başlatır (gnome, kde, xfce).
2. MCU Yazılım Geliştirme
MCU projelerini derleyebilmek için gerekli araçlar aşağıda listelenmiştir.- Texas Instruments Processor SDK RTOS J722S
- Texas Instruments Sysconfig
- Texas Instruments Code Generation Tools C7000
- Texas Instruments Code Generation Tools ARM LLVM
2.1. Git clone işlemi ile örnek projeleri indir
2.2. Derleme için gerekli araçları ve kütüphaneleri kur
2.3. Taslak proje oluştur
t3gemstone/examples reposunda yer alanmcu projesinde iki R5F gerçek zamanlı
çekirdek ve iki C7x DSP çekirdeğinde çalışan örnek projeler bulunmaktadır. Bunlara benzer örnekler
build/ti/ti-processor-sdk-rtos-j722s-evm-10_01_00_04/mcu_plus_sdk_j722s_10_01_00_22/examples dizininde yer
almaktadır. Amacınıza uygun bir örnek proje bulup mcu proje dizinine kopyalamanız ve onun üzerinde geliştirme yapmanız
tavsiye edilir.
Her bir örnek projenin altında farklı çekirdekler için alt dizinler bulunmaktadır.
Örneğin hello_world projesinde aşağıdaki dizinler mevcuttur.
c75ss0-0_freertosc75ss1-0_freertosmain-r5fss0-0_freertosmcu-r5fss0-0_freertos
.env dosyasında MCU_TARGETS değişkeni olarak tanımlanmıştır. Derlemek istediğiniz
projenin makefile dizininin mutlak veya göreli yolunu MCU_TARGETS değişkenine ekleyin. Aşağıda hello_world
projesinin mcu-r5fss0-0_freertos çekirdeği için örnek gösterilmiştir.
2.4. SysConfig ile çevre birimleri yapılandır
SysConfig, Texas Instruments (TI) tarafından geliştirilen bir yapılandırma aracı (configuration tool)’dur. TI’nin mikrodenetleyici (MCU) ve işlemci tabanlı geliştirme ortamlarında kullanılır. Temel amacı donanım ve yazılım ayarlarını görsel olarak yapılandırılmasını sağlar. Yani doğrudan karmaşık başlatma kodları yazmak yerine, bir GUI üzerinden seçenekleri tıklayarak sistem yapılandırmasına imkan sağlar. Başlıca özellikleri:- Pin Muxing (Pin Yönlendirme): Hangi pinin hangi fonksiyonu üstleneceğini (UART, SPI, GPIO vb.) belirler.
- Peripheral Ayarları: UART, I2C, Timer, ADC gibi donanımların konfigürasyonunu yapar.
- Driver ve RTOS yapılandırması: TI-Drivers veya FreeRTOS bileşenlerini etkinleştirir.
- Otomatik Kod Üretimi: Yapılan ayarların C kaynak dosyalarını (.c, .h) otomatik oluşturur.
- Hata önleme: Uygun olmayan pin veya modül kombinasyonlarını algılayıp uyarır.
.syscfg dosyasında
tanımlanmıştır. Yeni çevre birimler eklemek veya mevcut olanların Pin Mux ayarlarını değiştirmek için SysConfig
GUI aracı kullanılır.
Bir MCU projesinde SysConfig’i başlatmak için:
SYSCONFIG_TARGETdeğişkenini istenen proje olarak değiştirin.- Bu değişkeni
.envdosyası içinde düzenleyebilir veya taskprogramına ortam değişkeni olarak iletebilirsiniz.
- Bu değişkeni
Ctrl + S kısayol tuşuyla kaydettikten sonra SysConfig arayüzünü kapatabilirsiniz.
2.5. Projeyi derle
2.6. Derlenmiş projeyi geliştirme kartına yükle
2.7. Derlenmiş projeyi çalıştır
Remoteproc ile çekirdeklere yüklenecek.out dosyaları /lib/firmware dizini altına önceden tanımlı isimlerde
kopyalanmalıdır. Her bir çekirdek için firmware ismi aşağıdaki tabloda verilmiştir.
| Core | Firmware |
|---|---|
| mcu-r5fss0-0 | j722s-mcu-r5f0_0-fw |
| main-r5fss0-0 | j722s-main-r5f0_0-fw |
| c7xss0-0 | j722s-c71_0-fw |
| c7xss1-0 | j722s-c71_1-fw |
head /sys/class/remoteproc/remoteproc*/firmware komutu ile erişilebilir. Her boot sonrasında çekirdekler
farklı remoteproc cihazlarına karşılık gelebildiği için kontrol edilmesi gerekmektedir.
2.8. Derlenmiş projenin U-Boot aşamasında çalıştırılması
Boot Diyagramı bölümündeki şekilde görüldüğü gibi bir önceki bölümde anlatılan çalıştırma yöntemi kullanıldığında MCU uygulamasının çalışabilmesi için Linux’un başlama sürecini tamamlayıp çekirdeklerin yazılımlarını yükleyip başlatması gerekir. Bu süreç bazı uygulamalarda istenmeyen gecikmelere neden olabilir. Bu gecikme uzak çekirdekler bootloader (U-Boot) aşamasında başlatılarak önlenebilir.- Öncelikle derlenen uygulama
/boot/mcu-fw/dizinine kopyalanır. /boot/uEnv.txtdosyasında derlenen uygulama hangi çekirdeğe aitse aşağıdaki tablo kullanılarak gerekli parametre tanımlanır.
| Çekirdek | Değişken Adı |
|---|---|
| main-r5fss0-0 | main_r5f_firmware_name |
| mcu-r5fss0-0 | mcu_r5f_firmware_name |
| wkup-r5fss0-0 | wkup_r5f_firmware_name |
| c7xss0-0 | c7x0_dsp_firmware_name |
| c7xss1-0 | c7x1_dsp_firmware_name |
blink_main_r5 isimli bir uygulama U-Boot aşamasında main-r5fss0-0 çekirdeğinde çalıştırılmak istendiğinde
öncelikle uygulama aşağıda görüldüğü gibi /boot/mcu-fw dizinine kopyalanır.
/boot/uEnv.txt dosyasına aşağıdaki satır eklenir.
blink_main_r5 uygulaması Linux’un başlamasını beklemek yerine doğrudan bootloader aşamasında başlatılacaktır.
3. Kaynakların Çekirdekler Arasında Paylaştırılması
AM67’nin çok çekirdekli bir işlemci olması dolayısıyla, sahip olduğu kaynakların bu çekirdekler arasında paylaştırılması gerekmektedir. Örneğinmain_uart1 uart çevre birimi hem Linux (A53 çekirdekler) tarafından hem de
main-r5fss0-0 çekirdeği tarafından aynı anda kullanılamaz. Eğer bu UART çevre birimi MCU tarafından kullanılacaksa
Linux tarafından bu birimin kullanılmadığının belirtilmesi gerekmektedir.
3.1. Varsayılan Kaynak Dağılımı Tablosu
Aşağıda verilen tabloda HAT’a çıkan pinlerin SOC’de hangi pinlere denk geldiği, hangi çevre birim olarak kullanılabilecekleri (Pinmux), Linux tarafından varsayılan olarak kullanılıp kullanılmadığı, kullanılıyorsa hangi amaçla kullanıldığı ve bunun nasıl devre dışı bırakılabileceği gibi bilgiler bulunabilir.Kaynak Tablosu
Kaynak Tablosu
| HAT Pin Adı | SOC Pin Adı | Pinmux | Linux Varsayılan Olarak Kullanıyor mu? | Linux’ta Kullanım Amacı | Devre Dışı Bırakmak için |
|---|---|---|---|---|---|
| GPIO-0 | D11 | 0 -> WKUP_I2C0_SDA 7 -> MCU_GPIO0_20 | Evet | EEPROM, RTC ve PMIC ile haberleşmek üzere I2C SDA | Device-tree ile devre dışı bırakılmalı (wkup_i2c0). |
| GPIO-1 | B9 | 0 -> WKUP_I2C0_SCL 7 -> MCU_GPIO0_19 | Evet | EEPROM, RTC ve PMIC ile haberleşmek üzere I2C SCL | Device-tree ile devre dışı bırakılmalı (wkup_i2c0). |
| GPIO-2 | E11 | 0 -> MCU_I2C0_SDA 7 -> MCU_GPIO0_18 | Hayır | Waveshare Dokunmatik Ekran için I2C SDA | - k3-am67a-t3-gem-o1-dsi-waveshare-7inch-h-panel.dtbo - k3-am67a-t3-gem-o1-dsi-waveshare-7inch-panel.dtbo |
| GPIO-3 | B13 | 0 -> MCU_I2C0_SCL 7 -> MCU_GPIO0_17 | Hayır | Waveshare Dokunmatik Ekran için I2C SCL | - k3-am67a-t3-gem-o1-dsi-waveshare-7inch-h-panel.dtbo - k3-am67a-t3-gem-o1-dsi-waveshare-7inch-panel.dtbo |
| GPIO-4 | W26 | 0 -> GPMC0_WAIT1 1 -> VOUT0_EXTPCLKIN 2 -> GPMC0_A21 3 -> UART6_RXD 4 -> AUDIO_EXT_REFCLK2 7 -> GPIO0_38 8 -> EQEP2_I | Evet | Bluetooth için UART RX | - k3-am67a-t3-gem-o1-uart-ttys6.dtbo - Device-tree ile devre dışı bırakılmalı (main_uart6) |
| GPIO-5 | B20 | 0 -> SPI0_CS0 2 -> EHRPWM0_A 7 -> GPIO1_15 | Hayır | Genel amaçlı PWM | - k3-am67a-t3-gem-o1-pwm-epwm0-gpio5.dtbo - k3-am67a-t3-gem-o1-pwm-epwm0-gpio14.dtbo - k3-am67a-t3-gem-o1-pwm-epwm0-gpio5-gpio14.dtbo |
| GPIO-6 | D20 | 0 -> SPI0_CLK 1 -> CP_GEMAC_CPTS0_TS_SYNC 2 -> EHRPWM1_A 7 -> GPIO1_17 | Evet | Genel amaçlı PWM | - k3-am67a-t3-gem-o1-pwm-epwm1-gpio6.dtbo - k3-am67a-t3-gem-o1-pwm-epwm1-gpio13.dtbo - k3-am67a-t3-gem-o1-pwm-epwm1-gpio6-gpio13.dtbo |
| GPIO-7 | B3 | 0 -> WKUP_UART0_RXD 2 -> MCU_SPI0_CS2 7 -> MCU_GPIO0_9 | Evet | - Linux spidev ile kullanmak üzere SPI Chip select 2 - Wakeup domain UART0 Rx | - k3-am67a-t3-gem-o1-spidev0-1cs.dtbo - k3-am67a-t3-gem-o1-spidev0-2cs.dtbo - k3-am67a-t3-gem-o1-uart-ttys0.dtbo |
| GPIO-8 | C12 | 0 -> MCU_SPI0_CS0 4 -> WKUP_TIMER_IO1 7 -> MCU_GPIO0_0 | Evet | Linux spidev ile kullanmak üzere SPI Chip select 0 | - k3-am67a-t3-gem-o1-spidev0-1cs.dtbo - k3-am67a-t3-gem-o1-spidev0-2cs.dtbo |
| GPIO-9 | C11 | 0 -> MCU_SPI0_D1 7 -> MCU_GPIO0_4 | Evet | - BMP390 basınç ve icm20948 imu spi data1 - Linux spidev ile kullanmak üzere SPI DATA1 (MOSI veya MISO olarak atanabilir) | Device-tree ile devre dışı bırakılmalı. (mcu_spi0) |
| GPIO-10 | B12 | 0 -> MCU_SPI0_D0 7 -> MCU_GPIO0_3 | Evet | - BMP390 basınç ve icm20948 imu spi data0 - Linux spidev ile kullanmak üzere SPI DATA0 (MOSI veya MISO olarak atanabilir) | Device-tree ile devre dışı bırakılmalı. (mcu_spi0) |
| GPIO-11 | A9 | 0 -> MCU_SPI0_CLK 7 -> MCU_GPIO0_2 | Hayır | Linux spidev ile kullanmak üzere SPI Clock | Device-tree ile devre dışı bırakılmalı. (mcu_spi0) |
| GPIO-12 | C20 | 0 -> SPI0_CS1 1 -> CP_GEMAC_CPTS0_TS_COMP 2 -> EHRPWM0_B 3 -> ECAP0_IN_APWM_OUT 5 -> MAIN_ERRORn 7 -> GPIO1_16 9 -> EHRPWM_TZn_IN5 | Evet | Genel amaçlı PWM | - k3-am67a-t3-gem-o1-pwm-ecap0-gpio12.dtbo |
| GPIO-13 | E19 | 0 -> SPI0_D0 1 -> CP_GEMAC_CPTS0_HW1TSPUSH 2 -> EHRPWM1_B 7 -> GPIO1_18 | Evet | Genel amaçlı PWM | - k3-am67a-t3-gem-o1-pwm-epwm1-gpio13.dtbo - k3-am67a-t3-gem-o1-pwm-epwm1-gpio6-gpio13.dtbo |
| GPIO-14 | F24 | 0 -> MCASP0_ACLKR 1 -> SPI2_CLK 2 -> UART1_TXD 6 -> EHRPWM0_B 7 -> GPIO1_14 8 -> EQEP1_I | Evet | - Linux /dev/ttyS3 seri cihazı olarak kullanılıyor. - İstenirse overlay ile genel amaçlı PWM olarak ayarlanabilir | - k3-am67a-t3-gem-o1-pwm-epwm0-gpio5.dtbo - k3-am67a-t3-gem-o1-pwm-epwm0-gpio14.dtbo - k3-am67a-t3-gem-o1-pwm-epwm0-gpio5-gpio14.dtbo - Device-tree ile devre dışı bırakılmalı. (main_uart1) |
| GPIO-15 | C27 | 0 -> MCASP0_AFSR 1 -> SPI2_CS0 2 -> UART1_RXD 6 -> EHRPWM0_A 7 -> GPIO1_13 8 -> EQEP1_S | Evet | - Linux /dev/ttyS3 seri cihazı olarak | Device-tree ile devre dışı bırakılmalı. (main_uart1) |
| GPIO-16 | A25 | 0 -> MCASP0_AXR3 1 -> SPI2_D0 2 -> UART1_CTSn 3 -> UART6_RXD 5 -> ECAP1_IN_APWM_OUT 7 -> GPIO1_7 8 -> EQEP0_A | Hayır | Genel amaçlı PWM | - k3-am67a-t3-gem-o1-pwm-ecap1-gpio16.dtbo |
| GPIO-17 | A26 | 0 -> MCASP0_AXR2 1 -> SPI2_D1 2 -> UART1_RTSn 3 -> UART6_TXD 5 -> ECAP2_IN_APWM_OUT 7 -> GPIO1_8 8 -> EQEP0_B | Evet | Bluetooth için UART TX | - k3-am67a-t3-gem-o1-uart-ttys6.dtbo - Device-tree ile devre dışı bırakılmalı. (main_uart6) |
| GPIO-18 | D25 | 0 -> MCASP0_ACLKX 1 -> SPI2_CS1 2 -> ECAP2_IN_APWM_OUT 7 -> GPIO1_11 8 -> EQEP1_A | Hayır | Genel amaçlı PWM | - k3-am67a-t3-gem-o1-pwm-ecap2-gpio18.dtbo |
| GPIO-19 | C26 | 0 -> MCASP0_AFSX 1 -> SPI2_CS3 2 -> AUDIO_EXT_REFCLK1 7 -> GPIO1_12 8 -> EQEP1_B | Hayır | - | - |
| GPIO-20 | F23 | 0 -> MCASP0_AXR0 2 -> AUDIO_EXT_REFCLK0 6 -> EHRPWM1_B 7 -> GPIO1_10 8 -> EQEP0_I | Hayır | - | - |
| GPIO-21 | B25 | 0 -> MCASP0_AXR1 1 -> SPI2_CS2 2 -> ECAP1_IN_APWM_OUT 5 -> MAIN_ERRORn 6 -> EHRPWM1_A 7 -> GPIO1_9 8 -> EQEP0_S | Evet | Soğutma fanını kontrol amacıyla | - k3-am67a-t3-gem-o1-gpio-fan.dtbo |
| GPIO-22 | R27 | 0 -> GPMC0_CSn0 1 -> I2C4_SCL 3 -> MCASP2_AXR14 6 -> TRC_DATA15 7 -> GPIO0_41 | Hayır | - | - |
| GPIO-23 | B5 | 0 -> MCU_UART0_CTSn 1 -> MCU_TIMER_IO0 3 -> MCU_SPI1_D0 7 -> MCU_GPIO0_7 | Hayır | - | - |
| GPIO-24 | C8 | 0 -> WKUP_UART0_TXD 2 -> MCU_SPI1_CS2 8 -> MCU_GPIO0_10 | Hayır | Wake Up domain UART0 Tx | - k3-am67a-t3-gem-o1-uart-ttys0.dtbo |
| GPIO-25 | P21 | 0 -> GPMC0_CSn1 1 -> I2C4_SDA 3 -> MCASP2_AXR15 6 -> TRC_DATA16 7 -> GPIO0_42 | Hayır | - | - |
| GPIO-26 | P26 | 0 -> GPMC0_BE1n 3 -> MCASP2_AXR12 6 -> TRC_DATA11 7 -> GPIO0_36 | Hayır | - | - |
| GPIO-27 | N22 | 0 -> GPMC0_OEn_REn 2 -> MCASP1_AXR1 6 -> TRC_DATA8 7 -> GPIO0_33 | Hayır | - | - |
Devre Dışı Bırakmak için isimli sütununa bakılır. Bu sütunda
k3-am67a-t3-gem-o1-xxxxxx.dtbo şeklinde listelenen device-tree overlay ismi verilen dosyalar Linux’a belirtilen
çevre birimi nasıl kullanması gerektiğini bildiren ayar dosyalarıdır.
İlgili ayarları devre dışı bırakmak için /boot/uEnv.txt dosyasını açıp overlays ismi verilen değişkenden bu
dosyanın silinmesi yeterlidir. Bazı pinlerin Devre Dışı Bırakmak için sütünunda overlaylerin
haricinde Device-tree ile devre dışı bırakılmalı. (mcu_spi0) benzeri yönergeler mevcuttur. Bunları devre dışı
bırakmak için;
- https://github.com/t3gemstone/devicetrees reposu klonlanır.
src/arm64/ti/k3-am67a-t3-gem-o1.dtsdosyası açılır ve aşağıdaki kod parçası gerekli değişiklikler yapılarak eklenir.- Repo dizininde
makekomutu çalıştırılarak device-tree derlenir. - Eski device-tree
$ sudo mv /boot/k3-am67a-t3-gem-o1.dtb /boot/k3-am67a-t3-gem-o1.dtb.bakkomutu ile yedeklenir. - Derleme sonucu oluşan
src/arm64/ti/k3-am67a-t3-gem-o1.dtbdosyası/boot/altına kopyalanır. - Kart yeniden başlatılır ve çalışıp çalışmadığı test edilir.
Yukarıdaki işlemler sonucu istenmeyen bir durum oluşursa
$ sudo cp /boot/k3-am67a-t3-gem-o1.dtb.bak /boot/k3-am67a-t3-gem-o1.dtb komutu ile yedeklenen device-tree geri yüklenebilir.mcu_spi0 mcu çekirdeklerden kullanılabilir durumda olacaktır. Ancak tabloda
bulunan Linux'ta Kullanım Amacı bölümünde - BMP390 basınç ve ICM20948 imu spi için kullanıldığı belirtilmiştir.
Dolayısıyla bu çevresel birimlere Linux’ta erişim kapatılmış olacak ve MCU tarafından sürülmesi gerekecektir.
3.2. Örnek Senaryo: PWM ile MCU’dan Servo Motorun Sürülmesi
Elimizde bulunan SG90 model bir servo motoru MCU çekirdekten sürmemiz gerektiği bir senaryoda öncelikle HAT pinleri üzerinde bulunan bir PWM pinini seçmeliyiz. ÖrneğinGPIO-12 pini seçilmiş olsun. Tabloya
baktığımızda bu pinin Linux tarafından kullanımda olduğunu görebiliriz. Bu pini Linux’ta
devre dışı bırakmak için Devre Dışı Bırakmak için sütununa baktığımızda yalnızca bir overlay dosyası bulunduğu
görülür. Kapatmak için /boot/uEnv.txt dosyasını açıp overlays değişkenini kontrol ediyoruz.
k3-am67a-t3-gem-o1-pwm-ecap0-gpio12.dtbo dosyasının adını görebiliriz. Bunu siliyoruz ve
overlays değişkeni aşağıdaki şekle geliyor.

