Open AnanthAtSamraksh opened 8 years ago
I haven't read through your implementation details, but I was actually on the verge of making a very similar request as a result of my working with the new LRR driver. I'm glad you see the need as well.
One comment. I am against the use of templates.
I am against the use of templates.
What is the reason?
In C++ templates are:
· The method of polymorphism, which is nearly the first step in achieving any sort of code reuse and is very core to quality. It’s sometimes a bit ugly compared to languages that are designed to accentuate polymorphism, but it’s not a bad system.
· The most powerful method of creating portable compile time optimizations. It’s common when people rewrite numerical C code into C++ for them to achieve a 10% to 15% improvement in performance due to the use of templates. Very few modern languages offer anything like this, but 30 years ago macro systems were which did something similar were more common.
Meta-programming is less key to quality than unit level testing, but it’s still a key part of creating commercial grade code. C++ directly supports only 2 meta-programing methods (it indirectly support the ability to “role your own” methods):
· Inheritance which requires the creation of annoyingly many types, like FftInt8, FftUint8, FftShort8, and so on, and creates enough runtime overhead in the method table to sometimes be an issue.
· Templates which sometimes require that you explicitly separate different dimensions of the implementation space and therefor sometimes leads to annoying over-factorization. You should be using both methods somewhat regularly. But because we are doing embedded programing (and not enterprise programing) templates should be your mainstay and inheritance should be the more occasional tool.
If you’re not fluent with the material in C++ Templates: The Complete Guidehttp://www.amazon.com/Templates-Complete-Guide-David-Vandevoorde/dp/0201734842/ref=sr_1_1?ie=UTF8&qid=1452198873&sr=8-1&keywords=C%2B%2B+templates, have Alvaro get you a copy and read it carefully. It’s a bit dated, but it’s still the core stuff, that you simply must know and use in order to be any good.
Slightly more advanced material (which is probably helpful, but more optional) includes:
· C++ Template Metaprogramming: Concepts, Tools, and Techniques from Boost and Beyondhttp://www.amazon.com/Template-Metaprogramming-Concepts-Techniques-Beyond/dp/0321227255/ref=sr_1_3?ie=UTF8&qid=1452198873&sr=8-3&keywords=C%2B%2B+templates. It slightly overstates the importance of iterators, but the Blitz++ stuff is worth the book and the Domain-Specific Embedded Languages is highly releveling.
· Modern C++ Design: Generic Programming and Design Patterns Appliedhttp://www.amazon.com/Modern-Design-Generic-Programming-Patterns/dp/0201704315/ref=sr_1_4?ie=UTF8&qid=1452198873&sr=8-4&keywords=C%2B%2B+templates. This is a boarder coverage, includes things like smart pointers, and closers.
We do not use the Standard Template Library (STL) because:
· It doesn’t address many of our core issues (formatting IO is not our big issue).
· It’s not very portable.
· It’s big and we often suck too much unused (or unimportant) stuff into the final executable. However we should have created stuff like the STL that avoids these issues.
Kenneth W. Parker, Ph.D.
From: Nathan Stohs [mailto:notifications@github.com] Sent: Thursday, January 7, 2016 2:04 PM To: Samraksh/MF MF@noreply.github.com Subject: Re: [MF] Decoupling radio layer from the MAC layers (#378)
I haven't read through your implementation details, but I was actually on the verge of making a very similar request as a result of my working with the new LRR driver. I'm glad you see the need as well.
One comment. I am against the use of templates.
— Reply to this email directly or view it on GitHubhttps://github.com/Samraksh/MF/issues/378#issuecomment-169775378.
Thanks Ken. I have the David Vandevoorde book that you have mentioned. I am aware of Templates and their pit falls, but I wanted to know Nathan's reasoning for not using them. At Samraksh, we do make use of templates (VirtualTimer for instance), but not to a great extent. It is elegant, IMO and is useful when used carefully. In this particular scenario I felt templates would be elegant and avoid the use of the static array that is currently being used.
To give a little background, the app layer creates an instance of
MacEventHandler
, fills it up with the APP callback functions, passes it down to the MAC layer to be initialized. The MAC layer in turn creates an instance ofRadioEventHandler
, fills it up with the MAC callback functions and passes it down to the radio layer to be initialized. So, when there is a send or receive interrupt, radio calls the MAC which in turn calls the app layer's corresponding callback functions. Ideally it should be possible to test each of these layers separately. But while trying to test the radio driver (just a plain send and receive), it was observed that it is not possible to test just the radio layer without having to go through the MAC layer (MAC layer had to be initialized - either OMAC or CSMA). The reason is as follows:active_mac_index
(RF231.cpp
):active_mac_index = Radio<Message_15_4_t>::GetMacIdIndex()
RF231.cpp
):Radio.h's Initialize
):MacHandlers[MacIDIndex] = event_handler
active_mac_index
is used in the send and receive interrupt handler functions in invoking the respective handlers like this:(Radio<Message_15_4_t>::GetMacHandler(active_mac_index)->GetReceiveHandler())(rx_msg_ptr, rx_length)
(Radio_event_handler->GetReceiveHandler())(rx_msg_ptr, rx_length)
where
Radio_event_handler
in RF231's initialize function is initialized with the callbacks from either the MAC or from a standalone radio driver test program.MacHandlers
was used so that multiple MACs could use the radio. However, a much better implementation would be to make use of templates.So, instead of this:
(Radio<Message_15_4_t>::GetMacHandler(active_mac_index)->GetReceiveHandler())(rx_msg_ptr, rx_length)
below can be used:
(assuming that we set a variable to indicate that a MAC has been initialized)
Please let me know your thoughts. I have an implementation that decouples the MAC from the radio, but I have not yet done the template part.
EDIT 1: RF231 initialize takes a
mac_id
as a parameter which is not correct and is not used anywhere.RF231Radio::Initialize(RadioEventHandler *event_handler, UINT8 radio, UINT8 mac_id)