Join GitHub today
GitHub is home to over 36 million developers working together to host and review code, manage projects, and build software together.Sign up
LoRaWAN: Retiring LoRaWANBase class #9219
It was decided to retire LoRaWANBase class which served
Pull request type
There has been only one user of the LoRaWANBase class, the LoRaWANInterface. We anticipated that the third parties may use this class to provide their own LoRaWAN network stacks alongwith the default network stack provided by Mbed OS. However, a trend has been observed that the default stack provided by Mbed OS has become the de-facto choice. Having LoRaWANBase class adds 1K to the ROM in terms of footprint (for GCC, ARMCC and IAR optimize that already). It has been decided to do away with the LoRaWANBase class for now, and if the need arises it can be reintroduced back.
requested review from
Jan 1, 2019
I like this PR! :-)
In our build we modify
But, crucially, we also removed all the 'virtual' keywords from the member functions.
Making the member functions non-virtual reduced our executable size by over a 1000 bytes. 1000 bytes is a significant saving. My feeling is that making the functions non-virtual meant the linker could see that they weren't used and remove them from the executable. Obviously other people's mileage would vary.
Do you believe that
@mattbrown015 Unfortunately we need to pay the price of 1000 bytes here because we wish to leave a window for application developers to write a single application that can be used with any LoRaWAN network stack. Actually that was the sole purpose of the dear departed LoRaWANBase :).
It's fine by me if the functions remain virtual. Our build process has a mechanism for applying patches to make changes that we want and while not perfect it suits our needs.
But, I'm interested because I'm interested in C++ and API design! :-)
Is making the class run-time polymorphic the only way to make it flexible?
If an alternative implementation is required is it not possible to just override non-virtual functions in a new derived class?
Virtual functions are only necessary if the app needs to pass around base class pointers without caring which stack implementation is being used. Or to put it another way, do you expect clients to select the stack implementation at run-time.
If we were working on server software running on x64s we would probably put on our best C++ hats and program everything to interfaces. But we're embedded so we probably want to leverage compile-time techniques.
(Feel free not to reply, both of us should probably be concentrating on real work!)
I thought of another way of looking at it!
The phy class is polymorphic.
Currently we statically construct a EU868 phy and pass it to LoRaWAN as a base class pointer. In this case the polymorphism is an overhead that we're not using. But, I can see that a mobile device might need to change its phy at run-time as it moves RF jurisdictions. Or, perhaps more likely, production is simplified by building all devices to the same spec and then configuring them for the intended jurisdiction when they are deployed.
Comparing the phy to stack implementation. The API currently adds overhead for all your customers on the basis that you think you might have a few customers that want to select the stack implementation at run-time.
It's your API. You need to decide if the price paid by all your customers is worth it to make life easier for a few.
@mattbrown015 I'm curious - was your 1000 byte figure with GCC or one of the other toolchains? GCC is particularly disadvantaged here, as it can't do unused virtual function elimination, unlike IAR and ARM C.
We certainly want/need the polymorphism for the cases where we are passing around stuff where there are multiple viable implementations
I would like to regard optimising it as a tools issue - they should be capable of eliminating unused virtual stuff generally, and with Link-Time Optimisation, it should even be possible to totally eliminate the virtuals if the compiler+linker can see that only one derived type is instantiated.
Maybe I'm unduly optimistic though.
Hi @kjbracey-arm, yes we're using ARM GCC 7. I've just noticed that ARM GCC 8 was released in December; that means Mbed OS is even further behind in its support for ARM GCC 6. ;-)
It's interesting that this is an example of where the more expensive compilers add some value. We won't be changing compiler for our project though, in theory we're nearly finished!
If you have concrete examples that justify your design that's fair enough, like I say, it's your API! :-)
I think it would be interesting to do some tests with Link Time Optimization (LTO) enabled to identify and document the pattern that can be optimised and those that can't. The issue lies in making sure that the linker optimise the application as a whole and do not consider dynamic link which prevent vtable deletion.
@kjbracey-arm @pan- @AnttiKauppila I suggest that we do away with virtual modifier in LoRaWANInterface as it brings little value after retiring LoRaWANBase.
@hasnainvirk You are correct. LoRaWANStack is a bit problematic currently. But only because bind_phy_and_radio_driver() is called in the constructor (Cannot be overwritten). We need to think more about this. If we init the radio in constructor and call bind later, it should work.
@ARMmbed/mbed-os-maintainers this showcases how each team should be explicit about which APIs are:
In this case this PR maintains compatibility for users (using the typedef), however it is very much a breaking change for partners (even if no one is using it - but are we sure?). In that regard the TAM team (@screamerbg @MarceloSalazar @ashok-rao) should give their OK before this gets merged.
And we should make sure all teams clearly define what their porting layers are, but that's a much wider topic :).
referenced this pull request
Feb 18, 2019
referenced this pull request
Feb 20, 2019
Feb 21, 2019
22 checks passed
Could someone please update the content on our porting guide: https://github.com/ARMmbed/mbed-os-5-docs/blob/development/docs/porting/connectivity/LoRaPortingGuide.md