تنفيذ منطق العمل

  1. تحقَّق من أنّ دليل كتالوج VSIDL يحتوي على ملفات الإصدار وprotobuf وVSIDL اللازمة. للبدء من نموذج حالي، يمكنك العثور على مثال لمجلد كتالوج صالح ضمن /system/software_defined_vehicle/samples/vsidl/stable/catalog.

    مثال على بنية الكتالوج:

    my_catalog/
    ├── Android.bp          # Defines rust_protobuf modules for .proto files
    ├── types.proto         # Protobuf message / RPC service definitions
    └── architecture.vsidl  # VSIDL service bundle definitions
    
  2. اكتب رمزًا مخصّصًا لتنفيذ منطق نشاطك التجاري.

    تُنشئ vsidlc عمليات ربط البرمجيات الوسيطة وهياكل حِزم الخدمات (lib.rs وservice_bundle.rs وmain.rs) للغة Rust. إذا كتبت حزمة خدمات بلغة ++C، يمكنك تنفيذ واجهات مراحل النشاط (libsdv_lifecycle_client_cpp) والاتصال (libsdv_comms_cpp) مباشرةً:

    • خوادم RPC (بلغة Rust): نفِّذ السمات التي تم إنشاؤها من lib.rs.
    • برامج النشر والاشتراك واستدعاء الإجراء عن بُعد (Rust): يمكنك استدعاء الدوال التي تم إنشاؤها ضمن service_bundle.rs للتفاعل مع الخدمات الأخرى.
    • مراحل النشاط والتواصل (C++‎): يمكنك إنشاء فئة فرعية من ServiceBundle وإعداد الناشرين أو المشتركين أو نقاط نهاية RPC في onStart.

    الصدأ (Rust)

    1. أنشِئ تنفيذًا أساسيًا من خلال تشغيل:

      vsidlc -c /path/to/catalog -o /path/to/output --services
      

      يؤدي تشغيل vsidlc مع العلامة --services إلى إنشاء نموذج تنفيذ Rust لكل حزمة خدمات. يوفّر ذلك الرمز المصدري (main.rs) وملف إعدادات التصميم (Android.bp) مع جميع التبعيات، حتى تتمكّن الحزمة من تبادل الرسائل التلقائية على الفور بينما تركّز على منطق نشاطك التجاري.

    2. لكل حزمة خدمات، يمكنك العثور على عملية تنفيذ Rust في:

      /path/to/output/services/ServiceBundleName/src/main.rs.

    3. By default, the generated implementation creates messages with default values and sends them between publishers and subscribers or RPC clients and servers. لتعديل هذا السلوك، ابحث عن تعليقات TODO في main.rs واضبطها وفقًا لتفضيلاتك. على سبيل المثال:

      rust async fn handle_tire_pressure_range_unique_publisher( publisher: sdv::mw::Publisher<TirePressureRange>, ) { loop { // TODO: Modify the frequency of publishing messages here. sleep(Duration::from_secs(1)).await; // TODO: Modify the message content here. let message = TirePressureRange::default(); info!("Publishing on TirePressureRange#UNIQUE"); publisher.publish(&message).unwrap(); } }

    4. لضمان عدم استبدال تعديلاتك على الملفات التي تم إنشاؤها في المرة التالية التي يتم فيها تشغيل vsidlc، يُرجى نقل المجلد services خارج المجلد /path/to/output.

    C++‎

    1. أنشئ ملف عنوان جديدًا، src/lib.hpp، مع فئة لحزمة الخدمة:

      #pragma once
      #include <sdv/service_bundle.h>
      #include <sdv/context.hpp>
      
      namespace com::sdv::oem::service_bundle {
      
      // Sample implementation of the service bundle interface.
      class ServiceBundleName : public android::sdv::service_bundle::ServiceBundle {
      public:
          ServiceBundleName(sdv_comms::ctx::Context context);
          ~ServiceBundleName();
          void onStart() override;
          void onStop() override;
      };
      }  // namespace com::sdv::oem::service_bundle
      
    2. أنشئ ملف مصدر جديدًا، src/lib.cpp، باستخدام تنفيذ الفئة:

      #include "src/lib.hpp"
      #include <sdv/sb_macro.h>
      #include <iostream>
      using com::sdv::oem::service_bundle::ServiceBundleName;
      
      // Register the new service bundle.
      REGISTER_SERVICE_BUNDLE(ServiceBundleName);
      
      // Sample implementation of the service bundle interface.
      namespace com::sdv::oem::service_bundle {
      // Creates a new instance of the ServiceBundleName.
      // Called when service bundle is created by the system.
      // Context object is provided as a parameter that gives access to the
      // communication stack APIs.
      ServiceBundleName::ServiceBundleName([[maybe_unused]] sdv_comms::ctx::Context context) :
        ServiceBundle(context) {
          // Memory allocations and static data loading should be done as
          // part of this method.
          //
          // Loading of the dynamic resources (sockets, files, etc)
          // is strongly discouraged due to possible Suspend-to-RAM scenario.
          //
          // The dynamic data can be loaded in the onStart method.
      }
      
      // Called when the service bundle is started by the system.
      void ServiceBundleName::onStart() {
          // Allocate dynamic resources (sockets, files, publishers, and
          // subscribers such as TirePressureRange#UNIQUE) during this call.
      }
      
      // Called when the service bundle is stopped by the system in preparation
      // for shutdown or suspend to RAM/Disc.
      void ServiceBundleName::onStop() {
          // Stop active publishing loops and release the dynamic resources
          // that were allocated in the onStart method.
      }
      
      // Called when the service bundle is destroyed by the system.
      ServiceBundleName::~ServiceBundleName() {
          // Static resources deallocation needs to be implemented in the destructor.
      }
      }  // namespace com::sdv::oem::service_bundle
      
    3. أنشئ هدف Soong لمكتبة حِزم الخدمات في ملف Android.bp جديد أو حالي:

      // Service bundle library.
      cc_library_shared {
        name: "libservice_bundle",
        srcs: ["src/lib.cpp",],
        // Allows the library to be available inside APEX.
        apex_available: [
            "//apex_available:platform",
            "//apex_available:anyapex",
        ],
        shared_libs: [
          // Service Bundle lifecycle C++ API.
          "libsdv_lifecycle_client_cpp",
          // commstack library that provides context object reference
          "libsdv_comms_cpp",
        ],
      
        // Service bundle package is packed into /product apexes.
        product_specific: true,
      }
      

الخطوات التالية

لنشر حِزم الخدمات، يُرجى الاطّلاع على إنشاء حِزم الخدمات ونشرها.