Skip to content

Add Product Store Component to enable save/restore for a selection of data products - #196

Open
owhite7128 wants to merge 1 commit into
lasp:mainfrom
owhite7128:product-store-component
Open

Add Product Store Component to enable save/restore for a selection of data products#196
owhite7128 wants to merge 1 commit into
lasp:mainfrom
owhite7128:product-store-component

Conversation

@owhite7128

Copy link
Copy Markdown
Collaborator

This component adds the functionality to save a set of data products to specified memory region. It has the ability to restore data products with different set times depending on the desired behavior.

@owhite7128
owhite7128 force-pushed the product-store-component branch from 11c1efc to 0f89ae7 Compare July 30, 2026 19:04
@owhite7128
owhite7128 requested a review from dinkelk July 30, 2026 19:05
@@ -0,0 +1,52 @@
---
description: |
The product store saves a predefined set of data products from the database to a byte array (memory region) provided at initialization, usually located in nonvolatile storage (i.e. MRAM). The set of data products to save is configured via an autocoded table provided at instantiation, produced from a stored_products.yaml model file. Data products are saved upon receipt of a tick or by command, and can be restored back into the data product database by command or at Set_Up. The store is protected by a CRC which is written on every save and checked prior to every restore, protecting against the restoration of corrupted or never-initialized memory contents. A command is provided to dump the current contents of the store into a packet. The autocoder limits the total size of the store to fit within a single Packet.T.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe say <assembly_name>.stored_products.yaml to be more clear. I assume .<assembly_name>.stored_products.yaml also works? Please verify, otherwise we will only be able to instantiate this component one time in a given assembly.

@@ -0,0 +1,52 @@
---
description: |
The product store saves a predefined set of data products from the database to a byte array (memory region) provided at initialization, usually located in nonvolatile storage (i.e. MRAM). The set of data products to save is configured via an autocoded table provided at instantiation, produced from a stored_products.yaml model file. Data products are saved upon receipt of a tick or by command, and can be restored back into the data product database by command or at Set_Up. The store is protected by a CRC which is written on every save and checked prior to every restore, protecting against the restoration of corrupted or never-initialized memory contents. A command is provided to dump the current contents of the store into a packet. The autocoder limits the total size of the store to fit within a single Packet.T.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea of not restoring corrupted data makes sense. To be safe, I think we should also require that any data product included in this model is proven to have a type that is ALWAYS_VALID. this will prevent any errant constraint_error from taking down a system.

- name: Bytes
type: Basic_Types.Byte_Array_Access
not_null: true
description: A pointer to an allocation of bytes to be used for storing the data products. The size of this byte array MUST be at least Store_Description.Store_Size bytes in length. Only the first Store_Description.Store_Size bytes will be used by this component.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hopefully that includes the CRC.

commands:
- name: Save_Products
description: Save the configured data products from the database into the store. This performs the same operation as the receipt of a tick. If the store's save time is configured as Tick_Time, the current time is used instead, since no tick is available.
- name: Restore_Products

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am thinking two more commands might be useful

  1. Enable_Save_On_Tick
  2. Disable_Save_On_Tick

I feel like these could potentially be mission saving in some sort of crazy scenario where bad data is feeding the store and you need to override and disable the automatic save.

description: The data products held in the store were restored into the data product database.
- name: Store_Dumped
description: Produced a packet with the contents of the store.
- name: Data_Product_Missing_On_Save

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This potentially could be spammy. One way we have dealt with this in Adamant is to have a boolean at init for the component that is Issue_Missing_On_Save event, so you could disable this feature when you know you potentially could be running for a long time without DPs in the database.

param_type: Invalid_Command_Info.T
- name: Dropped_Command
description: A command was dropped due to a full queue.
param_type: Command_Header.T

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am thinking that this component could benefit from some simple counter data products:

  1. U16 roll over save count
  2. U16 roll over restore count
  3. U16 roll over CRC mismatch on restore count

description: A data product stored with its timestamp and restored with that timestamp.
store_timestamp: True
restore_time: Use_Stored_Dp_Time
event_on_missing: True

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ahh, i like this for event control. ignore my earlier comment in the events.yaml about this

restore_time: Use_Save_Time
event_on_missing: False
- name: Test_Component_1_Instance.Data_Product_C
description: A data product stored without its timestamp and restored with a timestamp of zero.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at this now, I am wondering why we are supporting saving WITHOUT a timestamp at all... will think more on this. I am not sure what the benefit is of this use case except maybe to save space in MRAM/memory dump

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, having second thoughts. Maybe the feature is OK. But my issue with this is that the default behavior here is to restore with a TS of zero, which i think is bad. The default should be Use_Save_Time in this case, since the save time is always available.

# Current_Time - The current time, fetched from the time connector, is written on each save.
# Tick_Time - The time found on the incoming Tick.T is written on each save. If a save is
# commanded, the current time is used instead.
# No_Time - No save time is written to the store. The store header contains only the CRC.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if we should support No_Time here. A default of always saving either current or tick time seem reasonable, costs basically nothing, and only helps inform a dump.

Pkt : Packet.T;
Stat : constant Serialization_Status := Self.Packets.Stored_Products (Self.Sys_Time_T_Get, Self.Bytes.all (Self.Bytes.all'First .. Self.Store_Last), Pkt);
begin
-- This should never fail since both the autocoder and an assertion at Init

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there such an assertion at Init?

begin
-- Handle any commands in the queue. Service up to N commands per tick:
Messages_Dispatched := Self.Dispatch_N (Self.Commands_Dispatched_Per_Tick);
pragma Assert (Messages_Dispatched <= Self.Commands_Dispatched_Per_Tick);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm. I am not sure I like command handling done here. What if the tick rate is really low. Like 1x every 10 minutes. This would mean that we can only execute commands every 10 minutes.

To get around this we may want to set up an initial divider at Init. So we could run this at something reasonable for commands, like 1 Hz, but then slow saving down to 10 minutes using a Ticks_Per_Save parameter (default 1) at 600.

Messages_Dispatched : Natural;
begin
-- Handle any commands in the queue. Service up to N commands per tick:
Messages_Dispatched := Self.Dispatch_N (Self.Commands_Dispatched_Per_Tick);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This dispatch should be done after the business logic.

-- Save using the current time as the save time. Note that if the store is
-- configured for Tick_Time, the current time is used for a commanded save,
-- since no tick is available:
case Self.Store_Description.Save_Time is

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code duplication here with the tick. consolidate.

use Command_Execution_Status;
Restore_Ok : Boolean;
begin
Self.Do_Restore (Restore_Ok);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just use function with return boolean instead to clean this up;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants