Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ embassy-sync = { git = "https://github.com/embassy-rs/embassy" }
embassy-time = { git = "https://github.com/embassy-rs/embassy" }
embassy-time-driver = { git = "https://github.com/embassy-rs/embassy" }
embedded-batteries-async = "0.1.0"
embedded-cfu-protocol = { git = "https://github.com/OpenDevicePartnership/embedded-cfu", version = "0.1.0" }
embedded-cfu-protocol = { git = "https://github.com/OpenDevicePartnership/embedded-cfu", version = "0.2.0" }
embedded-hal = "1.0"
embedded-hal-async = "1.0"
embedded-hal-nb = "1.0"
Expand Down
49 changes: 22 additions & 27 deletions cfu-service/src/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,39 @@ use core::future::Future;
use embedded_cfu_protocol::components::CfuComponentTraits;
use embedded_cfu_protocol::host::{CfuHostStates, CfuUpdater};
use embedded_cfu_protocol::protocol_definitions::*;
use embedded_cfu_protocol::{CfuImage, CfuWriter, CfuWriterDefault, CfuWriterError};
use embedded_cfu_protocol::{
CfuImage,
writer::{CfuWriterAsync, CfuWriterError, CfuWriterNop},
};
use heapless::Vec;

use crate::CfuError;

/// All host side Cfu traits, in some cases this will originate from a OS driver for CFU
pub trait CfuHost: CfuHostStates {
pub trait CfuHost<W>: CfuHostStates<W> {
/// Get all images
fn get_cfu_images<I: CfuImage>(&self) -> impl Future<Output = Result<Vec<I, MAX_CMPT_COUNT>, CfuError>>;
/// Gets the firmware version of all components
fn get_all_fw_versions<T: CfuWriter>(
fn get_all_fw_versions(
self,
writer: &mut T,
writer: &mut W,
primary_cmpt: ComponentId,
) -> impl Future<Output = Result<GetFwVersionResponse, CfuError>>;
/// Goes through the offer list and returns a slice of offer responses
fn process_cfu_offers<'a, T: CfuWriter>(
fn process_cfu_offers<'a>(
offer_commands: &'a [FwUpdateOffer],
writer: &mut T,
writer: &mut W,
) -> impl Future<Output = Result<&'a [FwUpdateOfferResponse], CfuError>>;
/// For a specific component, update its content
fn update_cfu_content<T: CfuWriter>(
writer: &mut T,
) -> impl Future<Output = Result<FwUpdateContentResponse, CfuError>>;
fn update_cfu_content(writer: &mut W) -> impl Future<Output = Result<FwUpdateContentResponse, CfuError>>;
/// For a specific image that was updated, validate its content
fn is_cfu_image_valid<I: CfuImage>(image: I) -> impl Future<Output = Result<bool, CfuError>>;
}

pub struct CfuHostInstance<I: CfuImage, C: CfuComponentTraits> {
pub updater: CfuUpdater,
pub images: heapless::Vec<I, MAX_CMPT_COUNT>,
pub writer: CfuWriterDefault,
pub writer: CfuWriterNop,
pub primary_cmpt: C,
pub host_token: HostToken,
}
Expand All @@ -45,15 +46,15 @@ impl<I: CfuImage, C: CfuComponentTraits> CfuHostInstance<I, C> {
Self {
updater: CfuUpdater {},
images: Vec::new(),
writer: CfuWriterDefault::default(),
writer: CfuWriterNop,
primary_cmpt,
host_token: HostToken::Driver,
}
}
}

impl<I: CfuImage, C: CfuComponentTraits> CfuHostStates for CfuHostInstance<I, C> {
async fn start_transaction<T: CfuWriter>(self, _writer: &mut T) -> Result<FwUpdateOfferResponse, CfuProtocolError> {
impl<I: CfuImage, C: CfuComponentTraits, W: CfuWriterAsync> CfuHostStates<W> for CfuHostInstance<I, C> {
async fn start_transaction(self, _writer: &mut W) -> Result<FwUpdateOfferResponse, CfuProtocolError> {
let _mock_cmd = FwUpdateOfferInformation::new(OfferInformationComponentInfo::new(
HostToken::Driver,
SpecialComponentIds::Info,
Expand All @@ -62,10 +63,7 @@ impl<I: CfuImage, C: CfuComponentTraits> CfuHostStates for CfuHostInstance<I, C>
let mockresponse = FwUpdateOfferResponse::default();
Ok(mockresponse)
}
async fn notify_start_offer_list<T: CfuWriter>(
self,
writer: &mut T,
) -> Result<FwUpdateOfferResponse, CfuProtocolError> {
async fn notify_start_offer_list(self, writer: &mut W) -> Result<FwUpdateOfferResponse, CfuProtocolError> {
// Serialize FwUpdateOfferInformation to bytes
let mock_cmd = FwUpdateOfferInformation::new(OfferInformationComponentInfo::new(
HostToken::Driver,
Expand All @@ -89,10 +87,7 @@ impl<I: CfuImage, C: CfuComponentTraits> CfuHostStates for CfuHostInstance<I, C>
}
}

async fn notify_end_offer_list<T: CfuWriter>(
self,
writer: &mut T,
) -> Result<FwUpdateOfferResponse, CfuProtocolError> {
async fn notify_end_offer_list(self, writer: &mut W) -> Result<FwUpdateOfferResponse, CfuProtocolError> {
let mock_cmd = FwUpdateOfferInformation::new(OfferInformationComponentInfo::new(
HostToken::Driver,
SpecialComponentIds::Info,
Expand Down Expand Up @@ -128,14 +123,14 @@ impl<I: CfuImage, C: CfuComponentTraits> CfuHostStates for CfuHostInstance<I, C>
}
}

impl<I: CfuImage, C: CfuComponentTraits> CfuHost for CfuHostInstance<I, C> {
impl<I: CfuImage, C: CfuComponentTraits, W: CfuWriterAsync> CfuHost<W> for CfuHostInstance<I, C> {
async fn get_cfu_images<T: CfuImage>(&self) -> Result<Vec<T, MAX_CMPT_COUNT>, CfuError> {
Err(CfuError::BadImage)
}

async fn get_all_fw_versions<T: CfuWriter>(
async fn get_all_fw_versions(
self,
_writer: &mut T,
_writer: &mut W,
primary_cmpt: ComponentId,
) -> Result<GetFwVersionResponse, CfuError> {
let mut component_count: u8 = 0;
Expand Down Expand Up @@ -172,15 +167,15 @@ impl<I: CfuImage, C: CfuComponentTraits> CfuHost for CfuHostInstance<I, C> {
}
}

async fn process_cfu_offers<'a, T: CfuWriter>(
async fn process_cfu_offers<'a>(
_offer_commands: &'a [FwUpdateOffer],
_writer: &mut T,
_writer: &mut W,
) -> Result<&'a [FwUpdateOfferResponse], CfuError> {
// TODO
Err(CfuError::BadImage)
}

async fn update_cfu_content<T: CfuWriter>(_writer: &mut T) -> Result<FwUpdateContentResponse, CfuError> {
async fn update_cfu_content(_writer: &mut W) -> Result<FwUpdateContentResponse, CfuError> {
Err(CfuError::ProtocolError(CfuProtocolError::WriterError(
CfuWriterError::Other,
)))
Expand Down
21 changes: 18 additions & 3 deletions cfu-service/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
#![no_std]

use embassy_sync::once_lock::OnceLock;
use embedded_cfu_protocol::client::CfuReceiveContent;
use embedded_cfu_protocol::components::CfuComponentTraits;
use embedded_cfu_protocol::protocol_definitions::*;
use embedded_services::cfu::component::*;
use embedded_services::cfu::{CfuError, ContextToken};
use embedded_services::{comms, error, info};
use embedded_services::{comms, error, info, trace};

pub mod buffer;
pub mod host;
Expand All @@ -17,8 +19,21 @@ pub struct CfuClient {
tp: comms::Endpoint,
}

/// use default "do-nothing" implementations
impl<T, C, E: Default> CfuReceiveContent<T, C, E> for CfuClient {}
impl<T, C> CfuReceiveContent<T, C, ()> for CfuClient {
async fn process_command(&self, _args: Option<T>, _cmd: C) -> Result<(), ()> {
trace!("CfuClient CfuReceiveContent::process_command do nothing implementation.");
Ok(())
}

async fn prepare_components(
&self,
_args: Option<T>,
_primary_component: impl CfuComponentTraits,
) -> Result<(), ()> {
trace!("CfuClient CfuReceiveContent::prepare_components do nothing implementation.");
Ok(())
}
}

impl CfuClient {
/// Create a new Cfu Client
Expand Down
28 changes: 16 additions & 12 deletions embedded-service/src/cfu/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use embassy_sync::channel::Channel;
use embassy_sync::mutex::Mutex;
use embedded_cfu_protocol::components::{CfuComponentInfo, CfuComponentStorage, CfuComponentTraits};
use embedded_cfu_protocol::protocol_definitions::*;
use embedded_cfu_protocol::{CfuWriter, CfuWriterError};
use embedded_cfu_protocol::writer::{CfuWriterAsync, CfuWriterError};
use heapless::Vec;

use super::CfuError;
Expand Down Expand Up @@ -173,7 +173,7 @@ impl CfuDevice {
}

/// Example for CFU Component
pub struct CfuComponentDefault<W: CfuWriter> {
pub struct CfuComponentDefault<W> {
device: CfuDevice,
is_dual_bank: bool,
is_primary: bool,
Expand All @@ -182,19 +182,19 @@ pub struct CfuComponentDefault<W: CfuWriter> {
writer: Mutex<GlobalRawMutex, W>,
}

impl<W: CfuWriter + Default> Default for CfuComponentDefault<W> {
impl<W: CfuWriterAsync + Default> Default for CfuComponentDefault<W> {
fn default() -> Self {
Self::new(1, false, [None; MAX_SUBCMPT_COUNT], W::default())
}
}

impl<W: CfuWriter> CfuDeviceContainer for CfuComponentDefault<W> {
impl<W: CfuWriterAsync> CfuDeviceContainer for CfuComponentDefault<W> {
fn get_cfu_component_device(&self) -> &CfuDevice {
&self.device
}
}

impl<W: CfuWriter> CfuComponentDefault<W> {
impl<W: CfuWriterAsync> CfuComponentDefault<W> {
/// Constructor
pub fn new(
id: ComponentId,
Expand Down Expand Up @@ -283,7 +283,7 @@ impl<W: CfuWriter> CfuComponentDefault<W> {
}
}

impl<W: CfuWriter> CfuComponentInfo for CfuComponentDefault<W> {
impl<W: CfuWriterAsync> CfuComponentInfo for CfuComponentDefault<W> {
fn get_component_id(&self) -> ComponentId {
self.device.component_id()
}
Expand All @@ -304,25 +304,29 @@ impl<W: CfuWriter> CfuComponentInfo for CfuComponentDefault<W> {
}
}

impl<W: CfuWriter> CfuWriter for CfuComponentDefault<W> {
async fn cfu_write(&self, mem_offset: Option<usize>, data: &[u8]) -> Result<(), CfuWriterError> {
impl<W: CfuWriterAsync> CfuWriterAsync for CfuComponentDefault<W> {
async fn cfu_write(&mut self, mem_offset: Option<usize>, data: &[u8]) -> Result<(), CfuWriterError> {
self.writer.lock().await.cfu_write(mem_offset, data).await
}
async fn cfu_write_read(
&self,
&mut self,
mem_offset: Option<usize>,
data: &[u8],
read: &mut [u8],
) -> Result<(), CfuWriterError> {
self.writer.lock().await.cfu_write_read(mem_offset, data, read).await
}

async fn cfu_read(&self, mem_offset: Option<usize>, read: &mut [u8]) -> Result<(), CfuWriterError> {
async fn cfu_read(&mut self, mem_offset: Option<usize>, read: &mut [u8]) -> Result<(), CfuWriterError> {
self.writer.lock().await.cfu_read(mem_offset, read).await
}

async fn cfu_storage(&mut self, mem_offset: usize, read: &[u8]) -> Result<(), CfuWriterError> {
self.writer.lock().await.cfu_storage(mem_offset, read).await
}
}

impl<W: CfuWriter> CfuComponentStorage for CfuComponentDefault<W> {
impl<W: CfuWriterAsync> CfuComponentStorage for CfuComponentDefault<W> {
fn get_storage_offset(&self) -> usize {
self.storage_offset
}
Expand All @@ -344,7 +348,7 @@ async fn default_get_fw_version() -> Result<FwVersion, CfuProtocolError> {
Ok(FwVersion::default())
}

impl<W: CfuWriter + Default> CfuComponentTraits for CfuComponentDefault<W> {}
impl<W: CfuWriterAsync + Default> CfuComponentTraits for CfuComponentDefault<W> {}

/// Example Wrapper for CFU Component
/// Takes type which implements `CFUComponentTraits` and `CfuDeviceContainer`
Expand Down
2 changes: 1 addition & 1 deletion examples/rt685s-evk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ futures = { version = "0.3.30", default-features = false, features = [
mimxrt600-fcb = "0.1.0"
mimxrt685s-pac = { version = "*", features = ["rt", "critical-section"] }

embedded-cfu-protocol = { git = "https://github.com/OpenDevicePartnership/embedded-cfu" }
embedded-cfu-protocol = { git = "https://github.com/OpenDevicePartnership/embedded-cfu", version = "0.2.0"}
embedded-services = { path = "../../embedded-service", features = ["defmt"] }
power-button-service = { path = "../../power-button-service", features = [
"defmt",
Expand Down
2 changes: 1 addition & 1 deletion examples/std/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ power-policy-service = { path = "../../power-policy-service", features = [
"log",
] }
cfu-service = { path = "../../cfu-service", features = ["log"] }
embedded-cfu-protocol = { git = "https://github.com/OpenDevicePartnership/embedded-cfu" }
embedded-cfu-protocol = { git = "https://github.com/OpenDevicePartnership/embedded-cfu", version = "0.2.0" }

embedded-batteries-async = "0.1.0"
battery-service = { path = "../../battery-service", features = ["log"] }
Expand Down
Loading