İş mantığınızı uygulamak için aşağıdaki adımları izleyin:
VSIDL katalog dizininizde gerekli derleme, protobuf ve VSIDL dosyalarının bulunduğunu doğrulayın. Mevcut bir örnekten başlamak için
/system/software_defined_vehicle/samples/vsidl/stable/catalogaltında geçerli bir katalog klasörü örneği bulabilirsiniz.Örnek katalog yapısı:
my_catalog/ ├── Android.bp # Defines rust_protobuf modules for .proto files ├── types.proto # Protobuf message / RPC service definitions └── architecture.vsidl # VSIDL service bundle definitionsİşletme mantığınızı uygulamak için özel kod yazın.
vsidlc, Rust için ara katman yazılımı bağlamaları ve hizmet paketi iskeleleri (lib.rs,service_bundle.rsvemain.rs) oluşturur. C++ dilinde bir hizmet paketi yazarsanız yaşam döngüsü (libsdv_lifecycle_client_cpp) ve iletişim (libsdv_comms_cpp) arayüzlerini doğrudan uygulayın:- RPC sunucuları (Rust):
lib.rstarafından oluşturulan özellikleri uygulayın. - Yayınlama, abone olma ve RPC istemcileri (Rust): Diğer hizmetlerle etkileşim kurmak için
service_bundle.rsiçinde oluşturulan işlevleri çağırın. Yaşam döngüsü ve iletişim (C++):
ServiceBundlealt sınıfını oluşturun ve yayıncılarınızı, abonelerinizi veya RPC uç noktalarınızıonStartiçinde başlatın.
Rust
Aşağıdaki komutu çalıştırarak iskelet uygulamasını oluşturun:
vsidlc -c /path/to/catalog -o /path/to/output --servicesvsidlckomutunu--servicesişaretiyle çalıştırmak, her hizmet paketi için standart bir Rust uygulaması oluşturur. Bu sayede, kaynak kodu (main.rs) ve tüm bağımlılıkları içeren bir derleme yapılandırma dosyası (Android.bp) sağlanır. Böylece, siz iş mantığınıza odaklanırken paketiniz varsayılan mesajları hemen değiştirebilir.Her hizmet paketi için Rust uygulamasını şurada bulabilirsiniz:
/path/to/output/services/ServiceBundleName/src/main.rs.Oluşturulan uygulama, varsayılan olarak varsayılan değerlere sahip mesajlar oluşturur ve bunları yayıncılar ile aboneler veya RPC istemcileri ile sunucular arasında gönderir. Bu davranışı değiştirmek için
main.rsdosyasındakiTODOyorumlarını bulun ve tercihlerinize göre düzenleyin. Örneğin: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(); } }Oluşturulan dosyalarda yaptığınız değişikliklerin,
vsidlcbir sonraki çalıştırılışında üzerine yazılmasını önlemek içinservicesklasörünü/path/to/outputklasörünün dışına taşıyın.
C++
Hizmet paketiniz için bir sınıf içeren yeni bir üstbilgi dosyası (
src/lib.hpp) oluşturun:#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_bundleSınıf uygulamasıyla yeni bir kaynak dosya (
src/lib.cpp) oluşturun:#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_bundleYeni veya mevcut bir
Android.bpdosyasında hizmet paketi kitaplığı Soong hedefi oluşturun:// 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, }
- RPC sunucuları (Rust):
Sonraki adımlar
Hizmet paketlerinizi dağıtmak için Hizmet paketleri oluşturma ve dağıtma başlıklı makaleyi inceleyin.