embedded-deck
TEKNİK REHBER GÖMÜLÜ AGL / OTOMOTİV 2026

AGL — Automotive Grade Linux
Araç içi Linux platformu.

Linux Foundation çatısı altında geliştirilen, IVI'dan ADAS'a geniş araç profili yelpazesi sunan açık kaynaklı otomotiv platformunu Yocto temelleriyle öğrenin.

00 AGL nedir?

Automotive Grade Linux (AGL), Linux Foundation bünyesinde geliştirilen, otomotiv kullanım senaryolarına özel hazırlanmış açık kaynaklı bir yazılım platformudur. Toyota, Renault, Jaguar Land Rover, Bosch ve Denso gibi dev oyuncuların aktif katkı sağladığı proje, araç içi uygulamalar için standart bir taban oluşturmayı hedefler.

GENIVI ile fark

GENIVI Alliance, otomotiv Middleware katmanını standartlaştırmaya çalışan bir ticari konsorsiyumdu; sektörde geniş kabul göremedi ve 2021'de faaliyetlerini sona erdirdi. AGL ise daha pratik bir yaklaşım benimseyerek üretim kaliteli Linux dağıtımı ve araçları doğrudan yönetir. Her iki inisiyatif de paylaşımlı bileşenler geliştirmiş olsa da AGL aktif gelişim sürdürmektedir.

Araç profilleri

ProfilAçıklamaÖrnek kullanım
IVIIn-Vehicle InfotainmentMultimedya, navigasyon, telefon entegrasyonu
ICInstrument ClusterHız göstergesi, yakıt, uyarı göstergeleri
ADASAdvanced Driver AssistanceŞerit takip, acil frenleme, kör nokta uyarı
TCUTelematic Control Unit4G/5G bağlantı, uzaktan teşhis, OTA
EVElectric VehicleBatarya yönetimi, şarj kontrolü, range hesaplama
GatewayVehicle GatewayCAN/LIN/Ethernet ağ geçidi, güvenlik duvarı
NOT

AGL, Yocto Project üzerine inşa edilmiştir. meta-agl katmanı Yocto Kirkstone/Scarthgap uyumludur. Sıfırdan AGL öğrenmek için temel Yocto bilgisi faydalıdır ancak zorunlu değildir — AGL kendi araçlarını sağlar.

01 AGL mimarisi

AGL'nin temel mimari bileşeni Application Framework (AFB / AppFW)'dır. Bu katman, uygulama izinlerini, servis bağlamalarını ve güvenlik politikalarını merkezi olarak yönetir.

Application Framework Binding

AGL'deki servisler binding adı verilen plugin yapısıyla uygulanır. Her binding, AFB microservice daemon'una dinamik olarak yüklenen ve HTTP/WebSocket/Unix-socket üzerinden JSON-RPC çağrıları kabul eden bir paylaşımlı kütüphanedir.

  Uygulama (Flutter / HTML5 / Native)
       │  JSON-RPC / WebSocket
       ▼
  ┌─────────────────────────────────────┐
  │  afb-binder (Application Framework) │
  │  • Kimlik doğrulama (token)         │
  │  • İzin denetimi (Cynara)           │
  │  • Binding yükleme / unload         │
  └──────────────┬──────────────────────┘
                 │  C API
        ┌────────┴────────┐
        ▼                 ▼
  ┌──────────┐     ┌──────────────┐
  │ media-   │     │  navigation- │
  │ binding  │     │  binding     │
  └──────────┘     └──────────────┘
    

Cynara güvenlik politikası

Cynara, AGL'nin özellik tabanlı erişim kontrol motorudur. Her uygulama başlatıldığında sistem tarafından atanan bir SMACK label alır. Binding verb'lerine erişim, /etc/cynara/ altındaki politika dosyalarıyla kontrol edilir.

afb-binderUygulama çerçevesi ana daemon'u — binding'leri yükler, API'ları dışa açar
afm-user-daemonKullanıcı oturumu yöneticisi — uygulama başlatma/durdurma/izleme
CynaraÖzellik tabanlı erişim kontrolü — "uygulama X, servis Y'nin Z verb'ini çağırabilir mi?"
SMACKKernel düzeyinde mandatory access control — her süreç ve dosya etiketlenir
westonWayland compositor — ivi-shell veya agl-compositor ile araç HMI yönetimi

Temel binding yapısı

hello-binding.c
#include <afb/afb-binding.h>

/* Verb handler — JSON-RPC isteğini karşılar */
static void hello_verb(afb_req_t req)
{
    const char *name = afb_req_value(req, "name");
    if (!name) name = "World";

    afb_req_reply(req, json_object_new_string("ok"),
                  NULL,
                  afb_req_json(req) ? name : "no-name");
}

/* Binding tanımı */
static const afb_verb_t verbs[] = {
    AFB_VERB("hello", hello_verb, NULL, "Selamla", AFB_SESSION_NONE),
    AFB_VERB_UNDEFINE
};

const afb_binding_t afbBindingExport = {
    .api     = "hello",
    .verbs   = verbs,
    .info    = "AGL merhaba örneği",
};

02 Kurulum ve build

AGL, Yocto tabanlı yapısı sayesinde agl-init-build-env betiği ve aglsetup.sh ile hızlı bir şekilde yapılandırılabilir. QEMU üzerindeki ilk çalıştırma için gerçek donanım gerekmez.

Bağımlılıkların kurulumu

# Ubuntu 22.04 / 24.04
sudo apt update && sudo apt install -y \
  gawk wget git-core diffstat unzip texinfo gcc-multilib \
  build-essential chrpath socat cpio python3 python3-pip \
  python3-pexpect xz-utils debianutils iputils-ping \
  python3-git python3-jinja2 libegl1-mesa libsdl1.2-dev \
  xterm python3-subunit mesa-common-dev zstd liblz4-tool

# repo aracı kurulumu
mkdir -p ~/.local/bin
curl https://storage.googleapis.com/git-repo-downloads/repo \
     -o ~/.local/bin/repo
chmod a+x ~/.local/bin/repo
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

AGL kaynak kodlarını çekme

mkdir -p ~/agl-workspace && cd ~/agl-workspace

# AGL manifest ile tüm katmanları çek
repo init -u https://gerrit.automotivelinux.org/gerrit/AGL/AGL-repo \
          -b master
repo sync --no-clone-bundle -j$(nproc)

ls sources/
# meta-agl  meta-agl-devel  meta-agl-demo  meta-agl-profile-*

Build ortamı kurulumu

cd ~/agl-workspace

# QEMU x86-64 için IVI profili
source meta-agl/scripts/aglsetup.sh \
    -f agl-demo agl-devel \
    -m qemux86-64 \
    agl-demo-platform

# RPi4 için:
# source meta-agl/scripts/aglsetup.sh \
#     -f agl-demo agl-devel \
#     -m raspberrypi4 \
#     agl-demo-platform

Image derleme

# Build dizinine geç (aglsetup.sh tarafından oluşturulur)
cd ~/agl-workspace/build

# Demo platform image'ını derle (ilk build 4-8 saat sürebilir)
bitbake agl-demo-platform

# Çıktılar:
# tmp/deploy/images/qemux86-64/
#   agl-demo-platform-qemux86-64.wic.xz   — disk image
#   bzImage                                — kernel
#   agl-demo-platform-qemux86-64.ext4     — rootfs

QEMU ile çalıştırma

# AGL QEMU wrapper scripti
source ~/agl-workspace/build/agl-init-build-env

runqemu qemux86-64 \
    tmp/deploy/images/qemux86-64/agl-demo-platform-qemux86-64.wic.xz \
    kvm \
    serialstdio \
    nographic

# Alternatif: grafik arayüz ile
runqemu qemux86-64 agl-demo-platform-qemux86-64.wic.xz ovmf
HIZLANMA

Shared DL_DIR ve SSTATE_DIR ayarları build süresini dramatik şekilde düşürür. conf/local.conf dosyasına DL_DIR = "/data/agl/downloads" ve SSTATE_DIR = "/data/agl/sstate" ekleyin. Ekip ortamında bu dizinleri NFS üzerinden paylaşın.

03 Flutter / HTML5 uygulama geliştirme

AGL, iki ana uygulama geliştirme yolunu destekler: Flutter (Dart tabanlı, native performans) ve HTML5/JavaScript (web teknolojileri, Chromium tabanlı). Her iki yaklaşım da Wayland compositor üzerinde çalışır.

Wayland / Waltham compositor

AGL'nin agl-compositor'u, Wayland protokolüne dayalı özel bir compositor'dür. Araç HMI'a özgü agl_shell Wayland protokolü aracılığıyla uygulamaların panel, tam ekran veya arka plan modunda görüntülenmesini sağlar. Waltham ise uzak ekran paylaşımı için kullanılan Wayland uzantısıdır.

Flutter uygulama şablonu

lib/main.dart
import 'package:flutter/material.dart';
import 'package:flutter_agl/flutter_agl.dart'; // AGL binding wrapper

void main() {
  runApp(const AGLApp());
}

class AGLApp extends StatelessWidget {
  const AGLApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'AGL Demo',
      theme: ThemeData(colorScheme: ColorScheme.dark()),
      home: const VehicleInfoScreen(),
    );
  }
}

class VehicleInfoScreen extends StatefulWidget {
  const VehicleInfoScreen({super.key});
  @override
  State<VehicleInfoScreen> createState() => _VehicleInfoScreenState();
}

class _VehicleInfoScreenState extends State<VehicleInfoScreen> {
  double _speed = 0.0;

  @override
  void initState() {
    super.initState();
    // AFB binding üzerinden araç hızını dinle
    AglBinding.subscribe('low-can', 'speed', (data) {
      setState(() => _speed = data['value'] as double);
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black,
      body: Center(
        child: Text(
          '{{_speed.toStringAsFixed(1)}} km/h',
          style: const TextStyle(fontSize: 72, color: Colors.white),
        ),
      ),
    );
  }
}

AppFW'ye uygulama kaydetme

config.xml (WGT paket manifesti)
<?xml version="1.0" encoding="UTF-8"?>
<widget xmlns="http://www.w3.org/ns/widgets"
        id="vehicle-info-app"
        version="1.0.0">

  <name>Vehicle Info</name>
  <description>AGL Flutter araç bilgi uygulaması</description>

  <author>Emirhan Pehlevan</author>

  <!-- Hangi binding'lere erişim gerekli -->
  <feature name="urn:AGL:widget:required-api">
    <param name="low-can" value="ws"/>
    <param name="navigation" value="ws"/>
  </feature>

  <!-- Hangi izinler gerekli -->
  <feature name="urn:AGL:widget:required-permission">
    <param name="urn:AGL:permission:low-can:public:read" value="required"/>
  </feature>

  <content src="index.html" type="text/html"/>
</widget>
# WGT paketi oluşturma ve kurma
wgtpkg-pack -f -o vehicle-info.wgt .
afm-util install vehicle-info.wgt

# Uygulamayı başlatma
afm-util start vehicle-info@1.0.0

# Çalışan uygulamaları listeleme
afm-util list --runnable

04 CAN / SOME-IP entegrasyonu

AGL, araç ağ verilerine erişimi standartlaştırmak için W3C Vehicle Information Service (VIS) spesifikasyonunu ve KUKSA.val projesini kullanır. CAN sinyalleri bu katman aracılığıyla uygulamalara JSON olarak sunulur.

Araç veri mimarisi

  CAN Bus (SocketCAN)
       │ can0, can1
       ▼
  ┌─────────────────────────────────┐
  │  low-can binding                │
  │  • CAN frame decode (DBC)       │
  │  • JSON sinyaller               │
  └──────────────┬──────────────────┘
                 │ AFB WebSocket API
                 ▼
  ┌─────────────────────────────────┐
  │  KUKSA.val / w3c-visserver      │
  │  • VSS (Vehicle Signal Spec)    │
  │  • JWT yetkilendirme            │
  │  • WebSocket / gRPC             │
  └──────────────┬──────────────────┘
                 │
        ┌────────┴───────────┐
        ▼                    ▼
  Flutter App          Navigation
                         Binding
    

low-can binding kurulumu

# CAN arayüzünü başlat (gerçek donanım)
ip link set can0 up type can bitrate 500000
ip link set can0 txqueuelen 1000

# Sanal CAN (test için)
modprobe vcan
ip link add dev vcan0 type vcan
ip link set vcan0 up

# low-can binding başlat
afb-binder --name=afbd-low-can \
           --binding=/usr/lib/afb/low-can-binding.so \
           --port=1234 \
           --token=MYSECRET

# CAN sinyal aboneliği (curl ile test)
curl -s "http://localhost:1234/api/low-can/subscribe?event=speed"

VSS sinyal okuma (KUKSA.val)

read_vss.py
import asyncio
import websockets
import json

KUKSA_URL = "ws://localhost:8090"
JWT_TOKEN = "your-jwt-token-here"

async def read_vehicle_speed():
    async with websockets.connect(KUKSA_URL) as ws:
        # JWT yetkilendirme
        auth_msg = {"action": "authorize", "tokens": JWT_TOKEN}
        await ws.send(json.dumps(auth_msg))
        resp = json.loads(await ws.recv())
        print(f"Auth: {resp['action']}")

        # VSS yolu üzerinden hız oku
        get_msg = {
            "action": "get",
            "path": "Vehicle.Speed",
            "requestId": "1"
        }
        await ws.send(json.dumps(get_msg))
        data = json.loads(await ws.recv())
        speed = data.get("data", {}).get("dp", {}).get("value", 0)
        print(f"Araç hızı: {speed} km/h")

        # Abonelik — gerçek zamanlı güncellemeler
        sub_msg = {
            "action": "subscribe",
            "path": "Vehicle.Speed",
            "requestId": "2"
        }
        await ws.send(json.dumps(sub_msg))

        async for message in ws:
            data = json.loads(message)
            if data.get("action") == "subscription":
                val = data["data"]["dp"]["value"]
                print(f"Güncelleme: {val} km/h")

asyncio.run(read_vehicle_speed())

DBC dosyasından sinyal tanımlama

vehicle.json (low-can sinyal tanımı)
{
  "version": "1.0",
  "messages": [
    {
      "name": "ENGINE_DATA",
      "id": 0x316,
      "length": 8,
      "signals": [
        {
          "name": "speed",
          "bit_position": 0,
          "bit_length": 16,
          "factor": 0.01,
          "offset": 0,
          "unit": "km/h",
          "generic_name": "Vehicle.Speed"
        },
        {
          "name": "rpm",
          "bit_position": 16,
          "bit_length": 16,
          "factor": 0.25,
          "offset": 0,
          "unit": "rpm",
          "generic_name": "Vehicle.Powertrain.CombustionEngine.Speed"
        }
      ]
    }
  ]
}

05 Ses mimarisi

AGL'nin ses mimarisi, araç içi ses rollerini (multimedya, telefon, navigasyon, acil durum uyarısı) yönetmek için PipeWire veya PulseAudio üzerine inşa edilmiş bir politika katmanı kullanır.

Ses rolü hiyerarşisi

RolÖncelikAçıklama
emergency100Acil durum uyarıları — her şeyin üzerinde
safety90Güvenlik uyarıları (kör nokta, şerit ihlali)
phone70Telefon görüşmesi — multimedyayı keser
navigation60Navigasyon yönlendirme sesi
notification50Bildirim sesleri
multimedia40Müzik, podcast, radyo
background10Arka plan müziği

AudioManager binding (4A)

AGL'nin 4A (AGL Advanced Audio Architecture) bileşeni, ses rollerini ve akışları yönetir. Bir uygulama ses kaynağı talep ettiğinde 4A politika motoruna danışır ve rol çakışmalarını çözer.

audio_client.c
#include <afb/afb-binding.h>

/* Ses kaynağı talep et */
static void request_audio_source(afb_req_t req)
{
    /* Multimedia rolü ile ses kaynağı oluştur */
    json_object *args = json_object_new_object();
    json_object_object_add(args, "audio_role",
                           json_object_new_string("multimedia"));
    json_object_object_add(args, "stream_type",
                           json_object_new_string("playback"));

    /* afb-binder üzerinden audiomgr binding'ine çağrı */
    afb_req_subcall(req, "audiomgr", "create_stream",
                    args, 0, audio_stream_created_cb, NULL);
}

static void audio_stream_created_cb(void *closure,
                                     struct json_object *obj,
                                     const char *error,
                                     const char *info,
                                     afb_api_t api)
{
    if (error) {
        AFB_API_ERROR(api, "Ses akışı oluşturulamadı: %s", error);
        return;
    }

    int stream_id;
    json_object_object_get_ex(obj, "stream_id",
                              (struct json_object **)&stream_id);
    AFB_API_NOTICE(api, "Ses akışı oluşturuldu: %d", stream_id);
}

PipeWire politika konfigürasyonu

/etc/wireplumber/policy.lua (özet)
-- AGL ses rolü politikası
agl_audio_roles = {
  { name = "emergency",  priority = 100, ducking_volume = 0   },
  { name = "phone",      priority = 70,  ducking_volume = 0.3 },
  { name = "navigation", priority = 60,  ducking_volume = 0.2 },
  { name = "multimedia", priority = 40,  ducking_volume = 1.0 },
}

-- Yüksek öncelikli rol geldiğinde düşük önceliklileri duck et
function apply_ducking(active_role, streams)
  for _, stream in ipairs(streams) do
    local role = stream.properties["agl.audio-role"]
    if get_priority(role) < get_priority(active_role) then
      local duck_vol = get_ducking_volume(active_role)
      stream:call("set-volume", duck_vol)
    end
  end
end

06 OTA güncelleme

AGL, OTA (Over-The-Air) güncellemeleri için OSTree + Hawkbit kombinasyonunu kullanır. OSTree atomik dosya sistemi güncellemeleri ve hızlı rollback sağlarken, Hawkbit güncelleme kampanyalarını sunucu tarafında yönetir.

OSTree ile atomik güncelleme

OSTree, yazılım dağıtımı için "Git benzeri" bir yaklaşım benimser. Her güncelleme yeni bir commit'tir; güncelleme başarısız olursa önceki commit'e saniyeler içinde dönülür. A/B bölümleme gerektirmez çünkü OSTree kendi atomic checkout mekanizmasını kullanır.

  Hawkbit Sunucu (bulut/şirket içi)
       │ HTTPS (DDI API)
       ▼
  ┌────────────────────────────────┐
  │  SWUpdate / RAUC agent         │
  │  (araçta çalışır)              │
  └───────────────┬────────────────┘
                  │ OSTree fetch
                  ▼
  ┌────────────────────────────────┐
  │  OSTree repo (araçta)          │
  │  • Pull delta güncellemeler    │
  │  • Stage → deploy → reboot     │
  └────────────────────────────────┘
    

OSTree repo oluşturma ve yayınlama

# Sunucu tarafında: OSTree repo oluştur
ostree init --repo=/srv/ostree/repo --mode=archive

# Rootfs'i OSTree repo'ya commit et
ostree commit \
    --repo=/srv/ostree/repo \
    --branch=agl/kirkstone/qemux86-64 \
    --subject="AGL 18.0.0 release" \
    --body="KUKSA.val 0.4, low-can binding güncellendi" \
    /path/to/rootfs/

# Delta oluştur (bant genişliği tasarrufu)
ostree static-delta generate \
    --repo=/srv/ostree/repo \
    --from=agl/kirkstone/qemux86-64@PREV_COMMIT \
    --to=agl/kirkstone/qemux86-64

# HTTP ile sun
ostree trivial-httpd /srv/ostree/repo --port=8080

Araç tarafı güncelleme

# Remote ekle
ostree remote add --no-gpg-verify \
    agl-updates \
    https://ota.example.com/ostree/repo

# Güncelleme kontrol et
ostree pull --dry-run agl-updates agl/kirkstone/qemux86-64

# Güncellemeyi çek ve uygula
ostree pull agl-updates agl/kirkstone/qemux86-64
ostree admin deploy agl/kirkstone/qemux86-64

# Bir sonraki boot'ta yeni sürüm aktif olur
# Sorun çıkarsa:
ostree admin rollback   # önceki versiyona dön
reboot

İmaj imzalama

# GPG anahtarı oluştur
gpg --full-generate-key
gpg --export --armor security@example.com > agl-signing.pub

# Commit imzalama
ostree commit \
    --repo=/srv/ostree/repo \
    --gpg-sign=KEYID \
    --gpg-homedir=/root/.gnupg \
    --branch=agl/kirkstone/qemux86-64 \
    /path/to/rootfs/

# Araçta imza doğrulama
ostree remote add --gpg-import=agl-signing.pub \
    agl-updates https://ota.example.com/ostree/repo

07 Profil konfigürasyonu

AGL'nin feature sistemi, hangi bileşenlerin build edileceğini ve hangi politikaların etkinleştirileceğini aglsetup.sh üzerinden kontrol eder. Farklı araç profilleri farklı feature setleri gerektirir.

Mevcut feature'lar

# Tüm mevcut feature'ları listele
source meta-agl/scripts/aglsetup.sh --help 2>&1 | grep "^  agl-"

# Önemli feature'lar:
# agl-demo         — demo uygulamaları ve araçları
# agl-devel        — geliştirici araçları, SSH, debug
# agl-localdev     — yerel geliştirici build optimizasyonları
# agl-netboot      — ağ boot (NFS rootfs)
# agl-ptest        — paket test altyapısı
# agl-sota         — SOTA (Software Over The Air) desteği
# agl-selinux      — SELinux mandatory access control
# agl-buildstats   — build istatistikleri
# agl-profile-graphical — grafik arayüz (Wayland/Weston)
# agl-profile-cluster — instrument cluster profili

Machine konfigürasyonu

conf/local.conf (özel ayarlar)
# Hedef makine
MACHINE = "raspberrypi4-64"

# Paralel build ve thread sayısı
BB_NUMBER_THREADS = "8"
PARALLEL_MAKE = "-j8"

# İndirme ve sstate cache dizinleri
DL_DIR = "/data/agl/downloads"
SSTATE_DIR = "/data/agl/sstate-cache"

# RPi4'e özgü ayarlar
ENABLE_UART = "1"
RPI_USE_U_BOOT = "1"
KERNEL_IMAGETYPE = "Image"

# Ekstra paketler
IMAGE_INSTALL:append = " \
    can-utils \
    python3 \
    python3-websockets \
    strace \
    gdbserver \
"

# Debug kolaylıkları (üretimde kaldırın!)
EXTRA_IMAGE_FEATURES += "debug-tweaks ssh-server-openssh"

Custom meta-layer oluşturma

# Yeni layer iskeletini oluştur
bitbake-layers create-layer ../sources/meta-mycar
cd ../sources/meta-mycar

# Layer yapısı:
# meta-mycar/
# ├── conf/
# │   └── layer.conf
# ├── recipes-apps/
# │   └── myapp/
# │       └── myapp_1.0.bb
# └── recipes-bsp/
#     └── custom-dtb/

# Layer'ı build'e ekle
bitbake-layers add-layer ../sources/meta-mycar

# Layer önceliğini ayarla (conf/layer.conf):
# BBFILE_PRIORITY_meta-mycar = "10"
İPUCU

Üretim araçları için agl-devel ve agl-demo feature'larını kaldırın; yerine agl-selinux ve imzalı boot ekleyin. Geliştirme sürümlerinde güvenlik katmanlarını etkinleştirmek zaman alabilir, bu yüzden geliştirme başından planlayın.

08 Pratik: RPi4 üzerinde AGL IVI

Bu bölümde Raspberry Pi 4 üzerinde tam bir AGL IVI imajı derleyecek, demo uygulamalarını çalıştıracak ve sanal CAN üzerinden araç verisi göndereceğiz.

Gereken malzeme

Raspberry Pi 4 (4GB+)Resmi RPi4 desteği meta-raspberrypi katmanı ile gelir
microSD (32GB+)Class 10 veya A1 önerilir — yazma hızı önemlidir
HDMI monitörWeston compositor grafik çıkışı için (micro-HDMI)
USB klavye/fareDemo uygulama etkileşimi için

Build ve kart yazma

# RPi4 için build ortamını hazırla
cd ~/agl-workspace
source meta-agl/scripts/aglsetup.sh \
    -f agl-demo agl-devel agl-profile-graphical \
    -m raspberrypi4 \
    agl-demo-platform

# Image'ı derle (~2-3 saat, sstate mevcut değilse)
bitbake agl-demo-platform

# SD karta yaz (cihaz adını doğrula!)
DEPLOY=tmp/deploy/images/raspberrypi4
xzcat $DEPLOY/agl-demo-platform-raspberrypi4.wic.xz | \
    sudo dd bs=4M of=/dev/sdX status=progress conv=fsync
sync

İlk boot ve demo uygulamaları

# RPi4'te seri konsol (UART0: GPIO 14/15)
# 115200 baud, 8N1
screen /dev/ttyUSB0 115200

# Ağ bağlantısı
ip addr show eth0
ssh root@<IP>   # şifre yok (debug-tweaks)

# Çalışan servisleri listele
systemctl list-units --state=running | grep agl

# Demo uygulamalarını kontrol et
afm-util list --runnable
afm-util list --running

can-utils ile araç verisi simülasyonu

# Sanal CAN arayüzü kur
modprobe vcan
ip link add dev vcan0 type vcan
ip link set vcan0 up

# Hız sinyali gönder (CAN ID: 0x316, 80 km/h)
# Byte 0-1: hız * 100 = 8000 = 0x1F40
cansend vcan0 316#1F400000000000000

# Sürekli sinyal (canplayer ile)
cat > vehicle-replay.asc << 'EOF'
begin 0.000000
  0.000000 vcan0 316#1F400000000000
  0.100000 vcan0 316#1F800000000000
  0.200000 vcan0 316#20000000000000
EOF
canplayer -I vehicle-replay.asc -l i vcan0=vcan0

# Dashboard'da hız gösterimini doğrula:
# AGL ana ekranında araç hız göstergesi güncellenmeli

Bağlama testi

# low-can binding'e bağlan
afb-client-demo -H ws://localhost:1234/api?token=MYSECRET \
    low-can subscribe '{"event":"Vehicle.Speed"}'

# KUKSA.val üzerinden oku
python3 -c "
import asyncio, websockets, json

async def test():
    async with websockets.connect('ws://localhost:8090') as ws:
        await ws.send(json.dumps({'action':'get',
                                  'path':'Vehicle.Speed',
                                  'requestId':'test1'}))
        print(await ws.recv())

asyncio.run(test())"
SONUÇ

RPi4 üzerinde çalışan AGL IVI sistemi, Weston Wayland compositor ile grafik arayüz, AFB binding'ler üzerinden araç verisi, ve OTA altyapısı için gerekli OSTree konfigürasyonuna sahiptir. Bir sonraki adım olarak kendi Flutter uygulamanızı wgtpkg-pack ile paketleyip afm-util install komutuyla kurabilirsiniz.