Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add os_type and os_version keys to erlang:system_info/1 #1117

Open
wants to merge 5 commits into
base: release-0.6
Choose a base branch
from

Conversation

UncleGrumpy
Copy link
Collaborator

@UncleGrumpy UncleGrumpy commented Mar 10, 2024

Adds support for erlang:system_info/1 keys os_type and os_version for obtaining a conveniently parse-able semantic version of the operating system (or runtime environment) the VM is running on.

These changes are made under both the "Apache 2.0" and the "GNU Lesser General
Public License 2.1 or later" license terms (dual license).

SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later

Copy link
Collaborator

@bettio bettio left a comment

Choose a reason for hiding this comment

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

I don't agree about this change, os module is used for this purpose.
e.g.

os:version().
{6,5,0}
os:type().
{unix,linux}

@UncleGrumpy
Copy link
Collaborator Author

That makes perfect sense. For some reason it did not occur to me that there was already an appropriate OTP function to get this information.

Just curious what the os:type() return for various MCUs should be? It seems like stm32 should be: {generic, libopencm3} and for esp32 maybe: {rtos, esp-idf} or {generic, esp-idf}? Since the intention is to know which version of an SDK is used, to help determine supported API functions.

@bettio
Copy link
Collaborator

bettio commented Apr 5, 2024

That makes perfect sense. For some reason it did not occur to me that there was already an appropriate OTP function to get this information.

Just curious what the os:type() return for various MCUs should be? It seems like stm32 should be: {generic, libopencm3} and for esp32 maybe: {rtos, esp-idf} or {generic, esp-idf}? Since the intention is to know which version of an SDK is used, to help determine supported API functions.

Good question.

My 2 cents: both macOS and Linux have {unix, Something} as os type, as they are both implemented using generic_unix, hence every different platform kind should be mentioned as first tuple member, and the specific type should be the second tuple member. But I'm not really sure.

@UncleGrumpy
Copy link
Collaborator Author

So I have looked into how os:type and os:version are implemented in OTP. They both are wrappers for erlang:system_info, using the keys os_type and os_version. I am undecided if I should add a minimal os module with wrapper function's, or just implement the system_info keys. The only advantage I see in adding the module is that we can have documentation for the os functions, since they may be returning values that differ from the OTP returns, specifically the os family has more options than just unix | win32. I already have the basic functionality implemented for esp32, stm32 and rp2040, and am currently working on implementation for generic_unix.

@bettio
Copy link
Collaborator

bettio commented Apr 14, 2024

Let's keep this PR small and let's just add erlang:system_info(os_type) and erlang:system_info(os_version).

So, let's recap:

  1. we are not going to introduce os module with this PR
  2. no esp_idf_* specific options, we are going to rely on default options
  3. it will be possible to use os_version for retrieving esp-idf version as a tuple (so no need for esp_idf_major/minor/patch options)
  4. I think that the first tuple component should be the platform name, similar to the ones we use in 'src/platforms' (they don't need to be exactly the same).

@UncleGrumpy UncleGrumpy changed the title Adds new keys to erlang:system_info/1 for ESP-IDF semantic version Add os_type and os_version keys to erlang:system_info/1 Apr 15, 2024
@UncleGrumpy UncleGrumpy force-pushed the get_idf_vers branch 3 times, most recently from a7f0ca6 to 6c3d51d Compare April 15, 2024 19:02
@UncleGrumpy
Copy link
Collaborator Author

Support for erlang:system_info/1 keys os_type and os_version is added for all platforms except WASM, I am not familiar enough with the port to be able to determine the node version, or detect the browser and version depending on how it's deployed, but that might be interesting for someone to add in a future PR.

set( IDE_VERSION_MINOR ${ide_version_minor} PARENT_SCOPE)
set( IDE_VERSION_PATCH ${ide_version_patch} PARENT_SCOPE)

endfunction( version_from_git )
Copy link
Collaborator

Choose a reason for hiding this comment

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

Missing new line at the end of file.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

fixed.

# Find Git
find_package(Git)
if(!Git_FOUND)
message( FATAL_ERROR "Git not found" )
Copy link
Collaborator

@bettio bettio Apr 20, 2024

Choose a reason for hiding this comment

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

This would make unsupported source only releases (without a .git directory). Am I right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I did not consider that specific possibility, but there is no way exposed from libopencm3 to determine the version used for the build. If a source code release of libopencm3 was used, then the version returned would be {undefined,undefined,undefined}.

CHANGELOG.md Outdated
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Added experimental optimized GC mode that makes use of C realloc instead of copying data around,
it can be enabled with `-DENABLE_REALLOC_GC=On`.
- Added support for `erlang:system_info/1` keys `os_type` and `os_version`.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's change this since v0.6.1 has been released.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done.

* `esp_idf_semantic` Returns a tuple containing `{Major :: integer(), Minor :: integer(), Patch :: integer()}`.
* `esp_idf_major` Returns the major version number as an integer.
* `esp_idf_minor` Returns the minor version number as an integer.
* `esp_idf_patch` Returns the patch version number as an integer.
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think they have been removed, let's remove them also from the doc.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

fixed.

add_compile_definitions(OS_VERSION_MAJOR=${PICO_SDK_VERSION_MAJOR})
add_compile_definitions(OS_VERSION_MINOR=${PICO_SDK_VERSION_MINOR})
add_compile_definitions(OS_VERSION_PATCH=${PICO_SDK_VERSION_REVISION})

Copy link
Collaborator

Choose a reason for hiding this comment

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

let's double-check. @pguyot are you aware of a cleaner approach?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I couldn't find anything better, it looks like the usual approach.

Also, we may want an additional avm_ or atomvm_* key for the chip versions. Pico SDK has functions to query chip and rom versions. This could be in another PR.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Also, we may want an additional avm_ or atomvm_* key for the chip versions. Pico SDK has functions to query chip and rom versions. This could be in another PR.

This would be good. Perhaps at the same time the ESP32 key esp_chip_info should be renamed, so that both (and eventually other) platforms can use the same key?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

But maybe that kind of breakage needs to be based on main (0.7.0)? Or add a deprecation warning and support both versions of the key on esp32 for a cycle...

const char *freebsd_os = "FreeBSD";
const char *openbsd_os = "OpenBSD";

if (strcmp(buf.sysname, linux_os) == 0) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's rather write if (strcmp(buf.sysname, "Linux") == 0) {, I think it is more readable.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

done.

return ERROR_ATOM;
}
p = buf.release;
while (*p) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

If for any reason any operating system has something like 1.2.3.4 as version number we get a stack corruption, that might be super hard to find (int ver[3];).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I fixed this. I wanted to stick to OTP compliance here which is specific about returning {Major, Minor, Patch}, so for your example OS that has a version 1.2.3.4 the return will be {1.2.3}.

@UncleGrumpy UncleGrumpy force-pushed the get_idf_vers branch 4 times, most recently from e997854 to 6c2bcdf Compare April 22, 2024 19:22
@UncleGrumpy UncleGrumpy requested a review from pguyot April 25, 2024 04:53
@@ -612,6 +612,9 @@ For more information about Erlang external term format, consult the [Erlang Docu

You can obtain system information about the AtomVM virtual machine via the [`erlang:system_info/1`](./apidocs/erlang/estdlib/erlang.md#system_info1) function, which takes an atom parameter designating the desired datum. Allowable parameters include

* `os_type` The operating system or runtime environment.
* `os_version` The sematic version of the currently running operating system or runtime environment.
* `system_architecture` The processor architecture and OS release (as a binary string).
Copy link
Collaborator

Choose a reason for hiding this comment

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

This didn't make it :-)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Right, I didn't add that for Pico, I just noticed it was completely missing from the docs and didn't want to forget to add it, but Pico support for this key would be good to add.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I realized this is currently only implemented on generic_unix, so I removed the entry (It should probably have been added in a separate PR anyway). The edocs incorrectly state it is supported on all systems, I will put in a separate PR to correct that to list it as only supported on generic_unix, until support has been added for other platforms.

Adds support for `erlang:system_info/1` keys `os_type` and `os_version` for
obtaining a conveniently parse-able semantic version of esp-idf the VM is built
with. Adding `os_type`, which currently will return `{esp32, esp-idf}` is mainly
for completeness, but could be helpful to differentiate, if future ports end up
supporting esp32, such as zephyr or nuttx.

Signed-off-by: Winford <winford@object.stream>
Adds support for `erlang:system_info/1` keys `os_type` and `os_version` for
obtaining a conveniently parse-able semantic version of libopencm3 the VM is
built with. Adding `os_type`, which currently will return `{stm32, opencm3}`
is mainly for completeness, but could be helpful to differentiate, if future
ports end up supporting stm32, such as zephyr or nuttx.

Signed-off-by: Winford <winford@object.stream>
Adds support for `erlang:system_info/1` keys `os_type` and `os_version` for
obtaining a conveniently parse-able semantic version of pico-sdk the VM is built
with. Adding `os_type`, which currently will return `{rp2040, pico-sdk}` is
mainly for completeness, but could be helpful to differentiate, if future ports
end up supporting the rp2040 platform, such as zephyr or nuttx.

Signed-off-by: Winford <winford@object.stream>
Adds support for `erlang:system_info/1` keys `os_type` and `os_version` for
obtaining a conveniently parse-able semantic version of the operating system
the VM is running on. The `os_type` key which currently will recognize `linux`,
`darwin`, `freebsd`, and `openbsd`, other sytems will return `unknown` atom as
the `Osname` in `{Osfamily, Osname}`.

Signed-off-by: Winford <winford@object.stream>
Adds edoc and "Programmers Guide" documentation for `os_type` and `os_version`
keys that have been added to `erlang:system_info/1`, and adds entry to
CHANGELOG.md

Signed-off-by: Winford <winford@object.stream>
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.

None yet

3 participants