I am currently testing the subsystem update feature of Torizon Cloud and have some questions about versioning.
If I understand the explanation of get-firmware-info(First Steps With Subsystem Updates | Toradex Developer Center) correctly, the versioning of subsystems is handled by comparing the SHA-256 checksum of the local data on the device with the checksum of the packages currently on the cloud.
I now have the problem, that some of our subsystems are external devices connected to our Verdin-SOM via CAN-Bus or Ethernet and we are using the TorizonCloud to piggy-back the updates to these devices. Since there are no existing software-packages on our SOM for these connected device until an update is made, version checks with the cloud fail.
Is it possible to have TorizonCloud run a version check against other files? On the SOM side this could be easily handled by overwriting the get-firmware-info method of the action-handler script, but cloud side I don’t really see any options right now.
I might make mistakes or occasionally get you wrong. Our support team will step in if needed.
Understanding Subsystem Update Versioning
You’re correct that Torizon Cloud uses SHA-256 checksums for version comparison by default(1). However, the get-firmware-info action handler provides flexibility to handle your specific use case with external devices connected via CAN-Bus or Ethernet(1).
Solution: Custom Version Information in Action Handler
The get-firmware-info action handler can return custom version information that doesn’t rely on the default firmware file(1). Here’s how the output structure works:
Action Handler Output Options
When implementing get-firmware-info, your action handler can return a JSON string with these fields(1):
name (string): The name of the currently installed target (package)(1)
sha256 (string): The SHA-256 checksum of the currently installed version(1)
length (integer): Size in bytes of the currently installed firmware file(1)
message (string): A message for debugging purposes(1)
Key Point for Your Use Case
The documentation specifically states that if the sha256 field is not present or set to null, it will be automatically determined based on the current firmware file(1). However, you can override this by providing your own SHA-256 value in the JSON response(1).
Implementation Approach
For your external devices connected via CAN-Bus or Ethernet:
Query the external device within your get-firmware-info action to retrieve its current firmware version or identifier
Generate a consistent hash from the version information you receive from the external device
Return this custom hash in the sha256 field of your JSON response
Store version metadata locally on the SOM (perhaps in a configuration file) that corresponds to the external device’s actual firmware version
This approach allows you to maintain version tracking for external devices without requiring actual firmware files to be present on the SOM initially(1).
The action handler provides complete flexibility in how you determine and report version information, making it well-suited for your CAN-Bus and Ethernet-connected subsystems(1).
**
Did you like my answer?
If I answered your question, please tick the “Solution” checkbox.
For follow-up questions to me, please use @ToradexAI in your post.
I’m not sure I fully understand what your issue is here or what you want exactly.
So as you said some subsystems on your device do not any packages associated with them initially until an update is made. Meaning get-firmware-info has nothing to parse/provide back to the cloud. But this is an “acceptable” case no?
It has a few subsystems on it, two of these subsystems there’s no package available so there’s nothing to report. The last subsystem has a package/hash that is not even associated with any known packages in my account. But this is perfectly fine and acceptable in the sense that it does not cause any issues.
So then what behavior do you expect here exactly? Do you want your subsystems to produce some dummy version/hash if there is no existing package on the SOM yet?
You could just have the action handler for your subsystems return some dummy version/hash in such a case then. On the cloud side you would just upload some dummy file that has the same hash that the action handler will return. Then if a subsystem has this particular hash you know that it’s just a dummy hash and that this subsystem has not been updated yet.
best case scenario is being able to tell all software-versions of connected devices to our SOM.
The problem is, that binding versioning of connected devices to the SOM might be actively wrong, since a connected device might have changed for whatever reason.
So the basic idea was reading some files created containing the versioning info of connected devices and using it for the action-handler.
A version file created this way wouldn’t match a file on the cloud, besides maybe dummy-version display files? Which would need a dummy file for each viable version, which really sounds like a risk for human error in update cycles.
Okay so you want to always report an accurate version/hash to Torizon Cloud for your subsystems correct? That’s the root of your issue here?
Meaning you’re not okay with the scenario I showed in my screenshot earlier where subsystems may not be able to report back any version information.
The problem is, that binding versioning of connected devices to the SOM might be actively wrong, since a connected device might have changed for whatever reason.
This part confuses me a bit. If you can’t guarantee that you can accurately read the version/hash of your subsystems then how can you expect to ever report accurate information?
Mind you I don’t know anything about your subsystems and how they’re setup, but why can’t you just read the currently installed/running version? And if there is a reason you can’t get accurate information that sounds more like a flaw with how the subsystems here are setup.
From a general standpoint I’m not sure what else to recommend. Either you can guarantee that the subsystems report accurate info back to Torizon Cloud. Which means designing your subsystems in a way that something valid is always reported back in every scenario your system might be in. Or, if this can’t be guaranteed. You report back known dummy information that matches with dummy packages. That way at least some helpful information is shown in the Torizon Cloud UI.
If thats the case I guess my current way of versioning the subsystems might consist of having “_versioning”-packages on the cloud where my subsystem version is compared to this file.
These packages will most likely only contain a file with the given version to check against?
Since, if I understand this correctly my only other alternative is having the subsystem-microcontroller run a hash over its program-memory to check against the packages on cloud, which I am not even sure would result in a correct hash?
These packages will most likely only contain a file with the given version to check against?
Something like this yeah. The main comparison point will be the hash. Whatever hash your subsystem action handler reports back, is the hash that Torizon Cloud will believe is “installed” on that subsystem.
Now if you happen to have a package for that subsystem in your Torizon Cloud account with the same hash, then the server will assume its the same package and match it. This will show on the web UI as saying the installed package is “xyz-whatever-name”. Now if there isn’t a matching package, then you’ll see what I showed in my screenshot earlier. The hash will still be shown but the installed package and version will just be shown as NOT_FOUND. Which denotes that something is installed on that subsystem, but the server doesn’t know what exactly is installed.
Since, if I understand this correctly my only other alternative is having the subsystem-microcontroller run a hash over its program-memory to check against the packages on cloud, which I am not even sure would result in a correct hash?
Not sure if I’m following your thought here. How would your subsystem compare against packages on your Cloud server? You’d need to give your device and therefore subsystem credentials to perform such an operation, which is probably not advisable.
From a high-level perspective, the update client, and therefore subsystems don’t care about what packages are on the Cloud server. Their only responsibility in this context is reporting what they think is currently installed. Whether this matches something or not on the server-side is not a concern or an issue.
If you want it to always match something on the server, then you just need to design and architect everything such that this is always true. By either dummy-packages or having some way to always report back a hash that will match a known package.
This really isn’t a Torizon Cloud limitation. I mean if your subsystem is going to report whatever arbitrary hash, how can the server guarantee a match in every case? It would have to be some known hash, but you have to provide that known hash ahead of time.
The idea was more along the lines, that the subsystem creates a hash which is forwarded to my SOM to be used as versioning.
But I believe I will try the approach of dummy files instead.
On a further note: I have already run some tests with the update procedure of subsystems and I believe I have found a minor bug.
The fuse_actions.sh file which I used as a template for my own action-files calls the “check_target_sha256()” from common_actions.sh, which ends up running the following line: local sha256=$(SHA256SUM “$fname” | SED -Ene ‘s/^\s*([0-9a-f]{64})\s*.*$/\1/p’)
But it seems like “SED” is undefined in the common_actions.sh which leads the check to fail.
Adding an import to sed, fixes this problem. req_program “/usr/bin/sed” && alias SED=“$_”
Hmm on further inspection it’s not really a bug more like a small coding hiccup. The action handler scripts work when used together because sed is defined in both the fuse and bootloader action handlers:
This makes the behavior in common_actions.sh work. Of course if you take common_actions.sh as is then it would fail like you said. The more correct behavior would be to refactor the defining of sed to the common_actions.sh. But as it is right now it doesn’t fail with how our current action handlers are setup.
In any case, do you have any further questions or issues regarding the hashing/versioning of subsystems?