Guide de démarrage rapide : créer et exécuter des bundles de services SDV

Cette page explique comment créer un bundle de services SDV, le compresser au format de fichier APEX et l'exécuter sur un appareil Cuttlefish virtuel. Les principales unités d'exécution de code sur le système SDV sont les bundles de services. Les bundles de services fournissent des méthodes de cycle de vie que le système exécute lorsque l'état du système change.

  1. Configurer votre environnement de compilation

    Dans votre répertoire de travail, exécutez le envsetup.sh script pour configurer votre environnement de compilation, définissez Cuttlefish comme cible de compilation et compilez le vsidlc générateur de code :

    source build/envsetup.sh
    lunch sdv_core_cf-trunk_staging-userdebug
    m vsidlc
    
  2. Définissez votre architecture en créant un dossier nommé my_catalog avec les fichiers suivants :

    • tire.proto : définit la structure de données que vous envoyez :

      syntax = "proto3";
      
      package com.android.sdv.sample.quickstart;
      
      import "google/protobuf/empty.proto";
      import "sdv/vsidl/v1/annotations.proto";
      
      message TirePressure {
        uint32 pressure = 1;
      }
      
      message TireInfoResponse {
        string serial_number = 1;
        uint32 max_pressure = 2;
      }
      
      service TireService {
        rpc GetTireInfo(google.protobuf.Empty) returns (TireInfoResponse);
      }
      
    • architecture.vsidl : définit les bundles de services et leur communication :

      package: "com.android.sdv.sample.quickstart"
      
      service_bundle {
        name: "Manager"
      
        publisher {
          message: "TirePressure"
          topic: "pressure"
          capacity: 8
        }
      
        server {
          service: "TireService"
          channel: "tire-service"
        }
      }
      
      service_bundle {
        name: "Monitor"
      
        subscriber {
          message: "TirePressure"
          topic: "pressure"
        }
      
        client {
          service: "TireService"
          channel: "tire-service"
        }
      }
      
    • Android.bp : définit le processus de compilation :

      rust_protobuf {
          name: "libquickstart_sample_tire_proto",
          crate_name: "quickstart_sample_tire_proto",
          protos: [
              "tire.proto",
          ],
          source_stem: "quickstart_sample_tire_proto_source",
          rustlibs: [
              "libvsidl_v1_stdlib_proto_rs",
          ],
          proto_flags: [
              "-I external/protobuf/src",
          ],
          vendor_available: true,
          product_available: true,
          apex_available: [
              "//apex_available:platform",
              "//apex_available:anyapex",
          ],
          min_sdk_version: "35",
      }
      
      filegroup {
          name: "vsidl_quickstart_catalog",
          srcs: ["**/*"],
      }
      
  3. Générez une implémentation squelette et des fichiers de configuration en exécutant :

    vsidlc -c /path/to/catalog -o /path/to/output --services --apex
    
  4. Pour chaque bundle de services, recherchez l'implémentation Rust dans /path/to/output/services/ServiceBundleName/src/main.rs.

  5. Par défaut, l'implémentation générée crée des messages avec des valeurs par défaut et les envoie entre les éditeurs et les abonnés, ou entre les clients et les serveurs RPC. Pour modifier ce comportement, recherchez les commentaires TODO dans main.rs et ajustez-les selon vos préférences. Exemple :

      async fn handle_tire_pressure_front_left_publisher(publisher: sdv::mw::Publisher<TirePressure>) {
          loop {
              // TODO: Modify the frequency of publishing messages here.
              sleep(Duration::from_secs(1)).await;
              // TODO: Modify the message content here.
              let message = TirePressure::default();
              info!("Publishing on TirePressure#FRONT_LEFT");
              publisher.publish(&message).unwrap();
          }
      }
    
  6. Pour inclure votre bundle dans l'image système, ajoutez le nom du module APEX généré à votre fichier makefile de produit.

    1. Ouvrez votre fichier makefile de produit (par exemple, /device/google/sdv/sdv_core_base/sdv_samples_core_services.mk).

    2. Ajoutez le module à PRODUCT_PACKAGES en ajoutant :

      PRODUCT_PACKAGES += com.android.sdv.sample.quickstart
      PRODUCT_PACKAGES += com_android_sdv_sample_quickstart_orchestration_configurations
      
  7. Créez l'image comme suit :

    m
    
  8. Exécutez et vérifiez l'exécution du bundle de services :

    1. Démarrez un appareil Cuttlefish virtuel :

      sdv-cf create --instance_name=instance1
      
    2. Exécutez le bundle de services lorsque le système est démarré :

      Manuellement

      adb wait-for-device
      adb root
      adb shell sdv_service_bundle start local-vm:com.android.sdv.sample.quickstart.Manager/instance
      adb shell sdv_service_bundle start local-vm:com.android.sdv.sample.quickstart.Monitor/instance
      

      Outil d'orchestration

      adb wait-for-device
      adb root
      # Apply global orchestration configuration by setting system property
      adb shell setprop persist.sdv.orchestrator_config_path "etc/orch/vm_quickstart_orch_config.textproto"
      adb reboot
      
    3. Vérifiez l'exécution du bundle de services :

      adb logcat *:F com_android_sdv_sample_quickstart_Manager_instance:* com_android_sdv_sample_quickstart_Monitor_instance:*
      

      Cette commande affiche les journaux qui montrent les bundles de services échangeant des messages :

      03-30 13:41:31.505   967   976 I com_android_sdv_sample_quickstart_Manager_instance: sdv_lm_manager: Publishing on TirePressure#PRESSURE
      03-30 13:41:31.505   983   991 I com_android_sdv_sample_quickstart_Monitor_instance: sdv_lm_monitor: Received message on TirePressure#PRESSURE: [TirePressure { pressure: 0, special_fields: SpecialFields { unknown_fields: UnknownFields { fields: None }, cached_size: CachedSize { size: 0 } } }]
      03-30 13:41:31.626   983   991 I com_android_sdv_sample_quickstart_Monitor_instance: sdv_lm_monitor: Sending request on Monitor/TireService
      03-30 13:41:31.627   967   976 I com_android_sdv_sample_quickstart_Manager_instance: sdv_lm_manager: Received request on Manager/TireService: Empty { special_fields: SpecialFields { unknown_fields: UnknownFields { fields: None }, cached_size: CachedSize { size: 0 } } }
      03-30 13:41:31.627   983   991 I com_android_sdv_sample_quickstart_Monitor_instance: sdv_lm_monitor: Received response on Monitor/TireService: TireInfoResponse { serial_number: "", max_pressure: 0, special_fields: SpecialFields { unknown_fields: UnknownFields { fields: None }, cached_size: CachedSize { size: 0 } } }
      

Étape suivante

Découvrez le langage de définition d'interface des services de véhicule (VSIDL) et comment définir vos propres bundles de services à partir de zéro.