התחלה מהירה: יצירה והפעלה של חבילות שירות SDV

בדף הזה מוסבר איך ליצור חבילת שירות SDV, לארוז אותה בפורמט קובץ APEX ולהריץ אותה במכשיר וירטואלי של Cuttlefish. היחידות העיקריות של ביצוע קוד במערכת SDV הן חבילות השירות. חבילות השירות מספקות שיטות מחזור חיים שהמערכת מבצעת כשהמצב של המערכת משתנה.

  1. הגדרת סביבת ה-build

    בספריית העבודה, מריצים את הסקריפט envsetup.sh כדי להגדיר את סביבת build, להגדיר את Cuttlefish כיעד ה-build ולפתח את כלי ליצירת קוד vsidlc:

    source build/envsetup.sh
    lunch sdv_core_cf-trunk_staging-userdebug
    m vsidlc
    
  2. מגדירים את הארכיטקטורה על ידי יצירת תיקייה בשם my_catalog עם הקבצים הבאים:

    • tire.proto: מגדיר את מבנה הנתונים שאתם שולחים:

      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: מגדיר את חבילות השירות ואת התקשורת שלהן:

      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: הגדרת תהליך ה-build:

      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: ["**/*"],
      }
      
      rust_protobuf
  3. מריצים את הפקודה הבאה כדי ליצור קובץ תצורה וקובץ הטמעה שלד:

    vsidlc -c /path/to/catalog -o /path/to/output --services --apex
    
  4. לכל חבילת שירותים, מחפשים את ההטמעה של Rust בכתובת /path/to/output/services/ServiceBundleName/src/main.rs.

  5. כברירת מחדל, ההטמעה שנוצרת יוצרת הודעות עם ערכי ברירת מחדל ושולחת אותן בין בעלי אתרים למנויים או בין לקוחות ושרתים של RPC. כדי לשנות את ההתנהגות הזו, מחפשים את TODO ההערות ב-main.rs ומשנים אותן בהתאם להעדפות. לדוגמה:

      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. כדי לכלול את החבילה בקובץ אימג' של המערכת, מוסיפים את שם מודול ה-APEX שנוצר לקובץ ה-Makefile של המוצר.

    1. פותחים את קובץ ה-Makefile של המוצר (לדוגמה, /device/google/sdv/sdv_core_base/sdv_samples_core_services.mk).

    2. מוסיפים את המודול ל-PRODUCT_PACKAGES על ידי הוספת:

      PRODUCT_PACKAGES += com.android.sdv.sample.quickstart
      PRODUCT_PACKAGES += com_android_sdv_sample_quickstart_orchestration_configurations
      
  7. יוצרים את התמונה:

    m
    
  8. מריצים את חבילת השירות ומאמתים את ההרצה:

    1. מפעילים מכשיר Cuttlefish וירטואלי:

      sdv-cf create --instance_name=instance1
      
    2. הפעלת חבילת השירותים כשהמערכת מופעלת:

      באופן ידני

      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
      

      מתזמר

      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. מוודאים שהחבילה של השירות מופעלת:

      adb logcat *:F com_android_sdv_sample_quickstart_Manager_instance:* com_android_sdv_sample_quickstart_Monitor_instance:*
      

      הפקודה הזו מציגה יומנים שבהם אפשר לראות את חבילות השירותים שמעבירות הודעות:

      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 } } }
      

המאמרים הבאים

מידע נוסף על שפת ההגדרה של ממשק שירותי הרכב (VSIDL) ועל הגדרת חבילות שירותים משלכם מאפס