Skip to content

Conversation

@rolandreichweinbmw
Copy link
Contributor

As being discussed in #51 , this is a first request for review via pull request.

@marcmo
Copy link
Contributor

marcmo commented Feb 8, 2025

thanks for your PR. It's impressive...it's massive! there is a lot of code that still needs formatting and it does not yet compile—those 2 things we need to solve first.

@rolandreichweinbmw
Copy link
Contributor Author

rolandreichweinbmw commented Feb 8, 2025

Regarding code formatting: I did as "treefmt" suggested.

@rolandreichweinbmw
Copy link
Contributor Author

rolandreichweinbmw commented Feb 8, 2025

Regarding compile: For me, it compiles and runs (on C++14).

Update: I also fixed it for the CI builds C++17 and C++20.

Or do you mean a different compile error I'm not aware of?

I compiled:

  • Unit tests
  • POSIX
  • S32K148

@rolandreichweinbmw rolandreichweinbmw force-pushed the use-etl branch 3 times, most recently from b385542 to 80dff0c Compare February 8, 2025 23:08
@rolandreichweinbmw
Copy link
Contributor Author

rolandreichweinbmw commented Feb 9, 2025

BTW: I'm using my fork/branch of ETL at https://github.com/rolandreichweinbmw/etl/tree/openbsw-replace-estd - just for your reference.

It includes some additions that I already contributed upstream, but no ETL release happened yet.

Copy link
Contributor

@christian-schilling christian-schilling left a comment

Choose a reason for hiding this comment

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

I'm raising a few points where I see etl being a step back from estl to put them up for discussion.
Apart from those we should think about how to treat etl and it's development. Do we want to upstream changes? Maintain patches? Keep it as is? Maintain an "add-on" library for missing pieces (like the ones I commented on).

Also I'm wondering if we really gain a lot by adopting etl. Just because we can does not mean we should.

void DoCanSystem::init()
{
_classicAddressingFilter.init(::estd::make_slice(_addresses), ::estd::make_slice(_codecs));
_classicAddressingFilter.init(
Copy link
Contributor

Choose a reason for hiding this comment

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

Are there no comparable make_span helpers in etl that offer type deduction? I think it's quite beneficial to have/use those.

Copy link
Contributor Author

@rolandreichweinbmw rolandreichweinbmw Feb 10, 2025

Choose a reason for hiding this comment

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

I agree that they are really helpful.

There are deduction guides to the etl::span ctors:

https://github.com/ETLCPP/etl/blob/99d75375060b61aae49bb2fc06349b45cb2c3380/include/etl/span.h#L750

Unfortunately, only available w/ ETL_USING_CPP17

Maybe we can consider switching to C++17 in OpenBSW soon? :-)

For C++14, I can provide etl::make_span helper as we know from estd.

Update:
See: https://github.com/rolandreichweinbmw/etl/tree/span-make-span
And: ETLCPP/etl#1027

Now using it accordingly here.

Copy link
Contributor

Choose a reason for hiding this comment

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

Agreed not sure why it was not added to etl, because they have make_array for example. Could be a suggestion for ETL

uint16_t getSize() const
{
return (fBufferLength == 0U) ? 0U : ::estd::read_be<uint16_t>(fpData);
return (fBufferLength == 0U)
Copy link
Contributor

Choose a reason for hiding this comment

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

This is quite a step back in readability. I wonder if this can be expressed more concisely with etl.
One of the things we tried to achieve with estl was to eleminate the need to use reinterpret_cast from most code as far as possible by providing safer alternatives. One reasoning for this is also that reinterpret_cast often triggers warnings with safty related rulesets and using a safe wrapper api seems like a better approach over always adding suppression comments for those warnings.

Copy link
Contributor

Choose a reason for hiding this comment

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

Agreed. I think the goal of ETL is also to achieve that "less usage of reinterpret_cast". Probably there is some other workaround for this specific use-case. Didn't try that out myself though.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree!

That's why I contributed two alternative solutions to ETL some time ago:

I haven't used it yet in the above OpenBSW line since upstream has not decided yet which one to merge.

@@ -248,8 +258,9 @@ void TaskInitializer<Adapter>::create(
TaskFunctionType const taskFunction,
TaskConfigType const& config)
{
::estd::slice<uint8_t> bytes = ::estd::make_slice(stack).template reinterpret_as<uint8_t>();
::estd::memory::align(alignof(StackType_t), bytes);
::etl::span<uint8_t> bytes = ::etl::span<uint8_t>(
Copy link
Contributor

Choose a reason for hiding this comment

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

Another case of reinterpret_cast being reintroduced in place of an api specifially designed to avoid it. (reinterpret_as, which is safer as it also includes the length adjustment calculations)

Copy link
Contributor

@filipe-cuim filipe-cuim Feb 10, 2025

Choose a reason for hiding this comment

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

Agreed! But I wonder if this could be done in another way. Or if span could be construct in a different manner, because etl also offers reinterpret_as in etl/span.h. Haven't had the time to try that out myself.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree. I already contributed span::reinterpret_as() some time ago at:

https://github.com/rolandreichweinbmw/etl/tree/span-advance-copy-reinterpret-as

(Not yet available in upstream release, but we can already use it if you like as it is available in the ETL copy in this PR.)

{
(void)lastFrameIndex;
if (!_sendPending)
{
::estd::slice<uint8_t> payload = ::estd::slice<uint8_t>::from_pointer(
::etl::span<uint8_t> payload(
Copy link
Contributor

Choose a reason for hiding this comment

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

We chose to use from_pointer intead of overloading the constructor to make this less-safe and therefore less preferable way of creating slices/spans easier to spot.

Copy link
Contributor

Choose a reason for hiding this comment

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

Makes sense. Could be something to suggest also for ETL

::estd::slice<uint8_t> payload = payloadBuffer;
EXPECT_TRUE(::estd::memory::is_equal(expectedPayload, payload));
::etl::span<uint8_t> payload = payloadBuffer;
EXPECT_TRUE(
Copy link
Contributor

Choose a reason for hiding this comment

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

I think here the estl api was way better. It also has different behaviour, checking the equality of the sizes. However it does look like etl has etl::eqal, why not use that here?

Copy link
Contributor

Choose a reason for hiding this comment

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

agreed. We could have used etl::equal here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed. Adjusted accordingly.

frame.id = *reinterpret_cast<::etl::be_uint32_t*>(data.data());
data = data.subspan(sizeof(etl::be_uint32_t));
::etl::mem_copy(data.begin(), data.end(), frame.data.begin());
frame.data = frame.data.subspan(0, data.size());
Copy link
Contributor

Choose a reason for hiding this comment

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

.trim() as an inplace operation was introduced because some compilers used significantly more stack space when using .subslice(). This may or may not be an issue with the compilers being used in the future, but it certainly was quite significant in the past.

Copy link
Contributor

Choose a reason for hiding this comment

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

I have no knowledge about this issue, but subspan seems more clear than trim. I know estd also has subslice, but they seem to be doing the same thing (both etl::span::subspan and estd::slice::subslice).
Also the fact that trim may reset the size of the slice to zero seems to be strange in my view (even though it is documented).
But really not sure about this point.

@@ -84,7 +85,7 @@ inline ::estd::slice<uint8_t> ForwardingReader::peek() const
inline void ForwardingReader::release()
{
// If _destinationData is an empty slice, copy will not copy any data.
(void)::estd::memory::copy(_destinationData, _sourceData);
(void)::etl::mem_copy(_sourceData.begin(), _sourceData.end(), _destinationData.begin());
Copy link
Contributor

Choose a reason for hiding this comment

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

estd::memory::copy is safer here as it also checks the destination length, which etl::mem_copy obviously can't.

Copy link
Contributor

Choose a reason for hiding this comment

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

if we want safe copies, etl also offers that in copy_s in etl/algorithm.h
Also etl::mem_copy shouldn't check the length since it is a low level copy (basically memcpy but with pointers of the same time), so in this case it makes sense.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right.

When I previously contributed this addition to ETL:

ETLCPP/etl#1024
https://github.com/rolandreichweinbmw/etl/tree/span-advance-copy-reinterpret-as

... then I better also use it. :-)

Adjusting accordingly.

auto const v = ::estd::be_uint32_t::make(data);
return appendData(v.bytes, 4) == 4;
auto const v = ::etl::be_uint32_t(data);
return appendData(static_cast<uint8_t const*>(v.data()), 4) == 4;
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the estl api is more clear here.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think the static_cast wasn't needed here. The method etl::unaligned_type_common::data() already returns a const uint8_t*.
Honestly since data is used on most containers to get a pointer to its raw buffer, I think data seems more aligned with the rest of the apis.
About the make method, seems to be a bit redundant.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agree. I removed static_cast.

@rolandreichweinbmw
Copy link
Contributor Author

rolandreichweinbmw commented Feb 10, 2025

I'm raising a few points where I see etl being a step back from estl to put them up for discussion. Apart from those we should think about how to treat etl and it's development. Do we want to upstream changes? Maintain patches? Keep it as is? Maintain an "add-on" library for missing pieces (like the ones I commented on).

Also I'm wondering if we really gain a lot by adopting etl. Just because we can does not mean we should.

During the process for this PR, I already contributed some additions to ETL to easen its use in OpenBSW, and the author is quite responsive:

https://github.com/ETLCPP/etl/issues?q=is%3Apr%20author%3Arolandreichweinbmw

Most of it he already merged, but unfortunately, they are not yet in the master branch or released yet due to the ETL development process.

However, I'm maintaining the changes relevant to OpenBSW in:

https://github.com/rolandreichweinbmw/etl/tree/openbsw-replace-estd - see also the individual feature branches.

I think for this purpose, we can maintain a fork or branches for changes not yet released in upstream ETL even though we should contribute all of it.

One point for ETL is that some of the features I would like to contribute to OpenBSW are already based on ETL. And ETL is being used in projects where I would like to merge OpenBSW. Apart from ETL being established in the industry and public since many years.

@rolandreichweinbmw
Copy link
Contributor Author

Just updated the branch and PR with new ETL upstream update, based on new ETL version 20.40.0, but with yet unmerged changes upstream that we need for easy switchover of OpenBSW to ETL. (As before, copied into the openbsw branch "use-etl".)

New ETL branch with those additions for reference is: https://github.com/rolandreichweinbmw/etl/tree/openbsw-replace-estd

@rolandreichweinbmw
Copy link
Contributor Author

Can you please do a new review?

@marcmo
Copy link
Contributor

marcmo commented Mar 13, 2025

@rolandreichweinbmw could you please mark the PR as draft?

@rolandreichweinbmw
Copy link
Contributor Author

rolandreichweinbmw commented Mar 13, 2025

@rolandreichweinbmw could you please mark the PR as draft?

This would be a "label"?

I'm missing the permissions to do so. But as a committer, you can add this I guess?

@rolandreichweinbmw rolandreichweinbmw force-pushed the use-etl branch 2 times, most recently from f99f944 to dcce456 Compare March 18, 2025 13:55
@rolandreichweinbmw
Copy link
Contributor Author

I just pushed a new version, including the use of the new etl::inplace_function as function wrapper.

Please also note that semantics of etl::ipool is different from estd's pool: full() means: "all items allocated" while in estd it is rather: "a full pool of items ready for allocation", i.e. I needed to swap full() with empty().

@rolandreichweinbmw
Copy link
Contributor Author

Tested on S32K148EVB

@rolandreichweinbmw
Copy link
Contributor Author

Rebased and adjusted documentation.

@rolandreichweinbmw rolandreichweinbmw force-pushed the use-etl branch 3 times, most recently from 64d8991 to 3d92d8b Compare May 21, 2025 14:01
@rolandreichweinbmw
Copy link
Contributor Author

Updated to new ETL 20.41.0. See also eclipse-openbsw/etl#2 for maintenance branch of deviations from upstream etl.

@rolandreichweinbmw
Copy link
Contributor Author

Updated to new ETL 20.41.1. The only deviation left is the etl::inplace_function Function Wrapper (not yet available in released ETL).

Also, libs/3rdparty now includes the whole copy of ETL 20.41.1, not just the headers in etl/include/etl/*

@rolandreichweinbmw rolandreichweinbmw force-pushed the use-etl branch 5 times, most recently from 7574c3b to 1bedac5 Compare June 3, 2025 21:18
@rolandreichweinbmw
Copy link
Contributor Author

Using etl::delegate and etl::closure in async Function/Call now.

@rolandreichweinbmw
Copy link
Contributor Author

Now separated libs/3rdparty/etl into:

  • etl/ : pristine upstream release 20.41.7
  • etl_configuration/: etl_profile.h : OpenBSW specific Configuration of ETL
  • etl_addons/: closure.h : As long as closure.h is not in the official ETL release (merged already, though). Good place for future addons as long as they are not yet merged upstream ETL.

@mthiede-acn2 mthiede-acn2 merged commit b39648e into eclipse-openbsw:main Jul 2, 2025
23 checks passed
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.

7 participants